From 6ad132df53e0d60aaefa565964530efc0a4374ab Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Sat, 19 Dec 2015 07:41:22 -0600 Subject: [PATCH 01/71] Stacking decals --- code/game/objects/effects/decals/Cleanable/humans.dm | 11 +++-------- code/game/objects/effects/decals/cleanable.dm | 9 +++++++++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 0026f4e8f5d..9edd5072438 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -19,15 +19,10 @@ viruses = null return ..() -/obj/effect/decal/cleanable/blood/New() +/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C) + if (C.blood_DNA) + blood_DNA |= C.blood_DNA.Copy() ..() - if(src.type == /obj/effect/decal/cleanable/blood) - if(src.loc && isturf(src.loc)) - for(var/obj/effect/decal/cleanable/blood/B in src.loc) - if(B != src) - if (B.blood_DNA) - blood_DNA |= B.blood_DNA.Copy() - qdel(B) /obj/effect/decal/cleanable/blood/splatter random_icon_states = list("gibbl1", "gibbl2", "gibbl3", "gibbl4", "gibbl5") diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 3a867084a0b..1dfd4add2f0 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -7,8 +7,17 @@ if (random_icon_states && length(src.random_icon_states) > 0) src.icon_state = pick(src.random_icon_states) create_reagents(300) + if(src.loc && isturf(src.loc)) + for(var/obj/effect/decal/cleanable/C in src.loc) + if(C != src && C.type == src.type) + replace_decal(C) ..() + + +/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) + qdel(C) + /obj/effect/decal/cleanable/attackby(obj/item/weapon/W, mob/user,) if(istype(W, /obj/item/weapon/reagent_containers/glass) || istype(W, /obj/item/weapon/reagent_containers/food/drinks)) if(src.reagents && W.reagents) From c2c57f8e1f541a133665a8a6bd1a73f95600aa3c Mon Sep 17 00:00:00 2001 From: Incoming Date: Sun, 20 Dec 2015 18:55:20 -0500 Subject: [PATCH 02/71] Objects created by the staff of animation eventually revert to just being normal objects in the absence of anyone to attack. --- code/modules/mob/living/simple_animal/hostile/mimic.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index 30d2fa513b8..961e76e77ea 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -119,6 +119,8 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca /mob/living/simple_animal/hostile/mimic/copy/Life() ..() + if(!target && !client) //Objects eventually revert to normal if no one is around to terrorize + adjustBruteLoss(1) for(var/mob/living/M in contents) //a fix for animated statues from the flesh to stone spell death() From 5821dd81ad6cc7bcddc8df741ef46def02cbb4be Mon Sep 17 00:00:00 2001 From: Akke Date: Mon, 21 Dec 2015 13:37:31 +0000 Subject: [PATCH 03/71] we dont have a shotgun tree you know --- .../objects/structures/crates_lockers/closets/syndicate.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm index a44de8f144d..792d5b167b3 100644 --- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm +++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm @@ -31,11 +31,6 @@ new /obj/item/weapon/storage/box/flashbangs(src) new /obj/item/weapon/storage/box/teargas(src) new /obj/item/weapon/storage/backpack/dufflebag/syndie/med(src) - new /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog(src) - new /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog(src) - new /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog(src) - new /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog(src) - new /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog(src) new /obj/item/weapon/pinpointer/nukeop(src) new /obj/item/weapon/pinpointer/nukeop(src) new /obj/item/weapon/pinpointer/nukeop(src) From 82ad4b218db2c42d7556d99868c3f3530777386b Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Mon, 21 Dec 2015 08:31:17 -0600 Subject: [PATCH 04/71] Shadowlings space hatch --- code/game/gamemodes/shadowling/special_shadowling_abilities.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm index 41e2792ace0..9198f720af8 100644 --- a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm @@ -10,7 +10,7 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N action_icon_state = "hatch" /obj/effect/proc_holder/spell/self/shadowling_hatch/cast(list/targets,mob/user = usr) - if(user.stat || !ishuman(user) || !user || !is_shadow(user)) return + if(user.stat || !ishuman(user) || !user || !is_shadow(user || isinspace(user))) return var/mob/living/carbon/human/H = user var/hatch_or_no = alert(H,"Are you sure you want to hatch? You cannot undo this!",,"Yes","No") switch(hatch_or_no) From 75981cb729721dd0109fea58399f19cfe4b60bff Mon Sep 17 00:00:00 2001 From: Tkdrg Date: Tue, 22 Dec 2015 21:33:49 -0300 Subject: [PATCH 05/71] Adds qdel() debug logging for testing It's locked behind a #ifdef TESTING so it won't slow down qdel(). --- code/controllers/subsystem/garbage.dm | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm index 524d76be193..c04ea5ff0d4 100644 --- a/code/controllers/subsystem/garbage.dm +++ b/code/controllers/subsystem/garbage.dm @@ -29,6 +29,10 @@ var/datum/subsystem/garbage_collector/SSgarbage var/list/noqdelhint = list()// list of all types that do not return a QDEL_HINT +#ifdef TESTING + var/list/qdel_list = list() // list of all types that have been qdel()eted +#endif + /datum/subsystem/garbage_collector/New() NEW_SS_GLOBAL(SSgarbage) @@ -102,6 +106,9 @@ var/datum/subsystem/garbage_collector/SSgarbage /proc/qdel(var/datum/A) if (!A) return +#ifdef TESTING + SSgarbage.qdel_list += "[A.type]" +#endif if (!istype(A)) del(A) else if (isnull(A.gc_destroyed)) @@ -225,4 +232,22 @@ var/datum/subsystem/garbage_collector/SSgarbage qdel(src) if(!running_find_references) find_references() + +/client/verb/show_qdeleted() + set category = "Debug" + set name = "Show qdel() Log" + set desc = "Render the qdel() log and display it" + + var/dat = "List of things that have been qdel()eted this round

" + + var/tmplist = list() + for(var/elem in SSgarbage.qdel_list) + if(!(elem in tmplist)) + tmplist[elem] = 0 + tmplist[elem]++ + + for(var/path in tmplist) + dat += "[path] - [tmplist[path]] times
" + + usr << browse(dat, "window=qdeletedlog") #endif \ No newline at end of file From 7d1ff06f1f7943df0acc8dac1c3a5de39672f280 Mon Sep 17 00:00:00 2001 From: Buggy123 Date: Wed, 23 Dec 2015 00:33:12 -0500 Subject: [PATCH 06/71] Update medicine_reagents.dm Changed Salicyclic Acid into a version of Oxandrolone for bruises. --- .../chemistry/reagents/medicine_reagents.dm | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 0d66397c5c4..640d581a09c 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -390,21 +390,23 @@ /datum/reagent/medicine/sal_acid name = "Salicyclic Acid" id = "sal_acid" - description = "Very slowly restores low bruising. Primarily used as an ingredient in other medicines. Overdose causes slight bruising." + description = "Stimulates the healing of severe bruises. Extremely rapidly heals severe bruising and slowly heals minor ones. Overdose will worsen existing bruising."" reagent_state = LIQUID color = "#C8A5DC" metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 25 + /datum/reagent/medicine/sal_acid/on_mob_life(mob/living/M) - if(M.getBruteLoss() < 50) - M.adjustBruteLoss(-0.25*REM) + if(M.getBruteLoss() > 50) + M.adjustBruteLoss(-4*REM) //Twice as effective as styptic powder for severe bruising + else + M.adjustBruteLoss(-0.5*REM) //But only a quarter as effective for more minor ones ..() return - /datum/reagent/medicine/sal_acid/overdose_process(mob/living/M) - if(M.getBruteLoss() < 50) - M.adjustBruteLoss(0.5*REM) + if(M.getBruteLoss()) //It only makes existing bruises worse + M.adjustBruteLoss(4.5*REM) // it's going to be healing either 4 or 0.5 ..() return From bc9ff3c15ad6822cb5024385d5d572b4e26e7edf Mon Sep 17 00:00:00 2001 From: Buggy123 Date: Wed, 23 Dec 2015 00:47:57 -0500 Subject: [PATCH 07/71] Update medicine_reagents.dm Fixes typo. --- code/modules/reagents/chemistry/reagents/medicine_reagents.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 640d581a09c..23d182bdb72 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -390,7 +390,7 @@ /datum/reagent/medicine/sal_acid name = "Salicyclic Acid" id = "sal_acid" - description = "Stimulates the healing of severe bruises. Extremely rapidly heals severe bruising and slowly heals minor ones. Overdose will worsen existing bruising."" + description = "Stimulates the healing of severe bruises. Extremely rapidly heals severe bruising and slowly heals minor ones. Overdose will worsen existing bruising." reagent_state = LIQUID color = "#C8A5DC" metabolization_rate = 0.5 * REAGENTS_METABOLISM From a8b1f8ed705b0ee02a4708f3eefb78fa4fc544d7 Mon Sep 17 00:00:00 2001 From: hornygranny Date: Wed, 23 Dec 2015 00:09:04 -0800 Subject: [PATCH 08/71] fixes tesla engine being called energy eall --- code/modules/power/tesla/energy_ball.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 96a4d27e1df..6f8aa7b524e 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -16,7 +16,7 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, /obj/structure/disposalpipe) /obj/singularity/energy_ball - name = "energy eall" + name = "energy ball" desc = "An energy ball." icon = 'icons/obj/tesla_engine/energy_ball.dmi' icon_state = "energy_ball" From 2c40dd1e3a847f914c53079f072b679f89ac508f Mon Sep 17 00:00:00 2001 From: Incoming Date: Wed, 23 Dec 2015 04:31:15 -0500 Subject: [PATCH 09/71] Officer beepsky will actually drop a potato battery and a shot of whiskey upon his death. --- code/modules/mob/living/simple_animal/bot/secbot.dm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index 49c59f60a18..48f9692636e 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -37,6 +37,13 @@ weaponscheck = 0 auto_patrol = 1 +/mob/living/simple_animal/bot/secbot/beepsky/explode() + var/turf/Tsec = get_turf(src) + new /obj/item/weapon/stock_parts/cell/potato(Tsec) + var/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/G = new(Tsec) + G.list_reagents = list("whiskey" = 50) + ..() + /mob/living/simple_animal/bot/secbot/pingsky name = "Officer Pingsky" desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment." From 53d0bc5d72b28495a9bd3b552e59a47a67cabf6b Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Wed, 23 Dec 2015 14:50:43 -0500 Subject: [PATCH 10/71] Rebalances blobbernaut creation; blobbernauts no longer destroy the factory, but instead do heavy damage to it, prevent it from spawning spores for one minute, and are player-controlled if possible. Also fixes some runtimes when killing mice. --- code/game/gamemodes/blob/blobs/blob_mobs.dm | 3 +- code/game/gamemodes/blob/powers.dm | 19 ++- code/game/gamemodes/blob/theblob.dm | 6 +- .../chemistry/reagents/blob_reagents.dm | 154 ++++++++++-------- 4 files changed, 110 insertions(+), 72 deletions(-) diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index 11a56069292..ee153eb2289 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -167,7 +167,8 @@ var/mob/living/L = target var/mob_protection = L.get_permeability_protection() overmind.blob_reagent_datum.reaction_mob(L, VAPOR, 17.5, 0, mob_protection)//this will do between 7 and 17 damage(reduced by mob protection), depending on chemical, plus 4 from base brute damage. - ..() + if(target) + ..() /mob/living/simple_animal/hostile/blob/blobbernaut/update_icons() ..() diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index af510951190..77b271c96d0 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -44,7 +44,6 @@ return if(!can_buy(price)) return - B.color = blob_reagent_datum.color var/obj/effect/blob/N = B.change_to(blobType, src) return N @@ -66,13 +65,13 @@ /mob/camera/blob/verb/create_node() set category = "Blob" set name = "Create Node Blob (60)" - set desc = "Create a Node." + set desc = "Create a node, which will power nearby factory and resource blobs." createSpecial(60, /obj/effect/blob/node, 5) /mob/camera/blob/verb/create_factory() set category = "Blob" set name = "Create Factory Blob (60)" - set desc = "Create a Spore producing blob." + set desc = "Create a spore tower that will spawn spores to harass your enemies." createSpecial(60, /obj/effect/blob/factory, 7) /mob/camera/blob/verb/create_storage() @@ -93,14 +92,24 @@ if(!istype(B, /obj/effect/blob/factory)) src << "Unable to use this blob, find a factory blob." return + if(B.health < B.maxhealth*0.6) //if it's at less than 60% of its health, you can't blobbernaut it + src << "This factory blob is too damaged to produce a blobbernaut." + return if(!can_buy(20)) return var/mob/living/simple_animal/hostile/blob/blobbernaut/blobber = new /mob/living/simple_animal/hostile/blob/blobbernaut (get_turf(B)) - if(blobber) - qdel(B) + var/obj/effect/blob/factory/F = B + F.take_damage(F.maxhealth*0.6, CLONE, null, 0) //take a bunch of damage, so you can't produce tons of blobbernauts from a single factory + F.visible_message("The blobbernaut [pick("rips", "tears", "shreds")] its way out of the factory blob!") + F.spore_delay = world.time + 600 //one minute before it can spawn spores again blobber.overmind = src blobber.update_icons() blob_mobs.Add(blobber) + var/list/candidates = get_candidates(ROLE_BLOB, ALIEN_AFK_BRACKET) + var/client/C = null + if(candidates.len) //if we got a candidate, they're a blobbernaut now. + C = pick(candidates) + blobber.key = C.key /mob/camera/blob/verb/relocate_core() set category = "Blob" diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index d336755c07b..5f92432b457 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -206,6 +206,8 @@ take_damage(W.force, W.damtype, user) /obj/effect/blob/attack_animal(mob/living/simple_animal/M) + if("blob" in M.faction) //sorry, but you can't kill the blob as a blobbernaut + return M.changeNext_move(CLICK_CD_MELEE) M.do_attack_animation(src) playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) @@ -223,7 +225,7 @@ take_damage(damage, BRUTE, M) return -/obj/effect/blob/proc/take_damage(damage, damage_type, cause = null) +/obj/effect/blob/proc/take_damage(damage, damage_type, cause = null, overmind_reagent_trigger = 1) switch(damage_type) //blobs only take brute and burn damage if(BRUTE) damage = max(damage * brute_resist, 0) @@ -233,7 +235,7 @@ else damage = 0 - if(overmind) + if(overmind && overmind_reagent_trigger) damage = overmind.blob_reagent_datum.damage_reaction(src, health, damage, damage_type, cause) //pass the blob, its health before damage, the damage being done, the type of damage being done, and the cause. health -= damage update_icon() diff --git a/code/modules/reagents/chemistry/reagents/blob_reagents.dm b/code/modules/reagents/chemistry/reagents/blob_reagents.dm index d25a60ea5ad..8f1a5441f9d 100644 --- a/code/modules/reagents/chemistry/reagents/blob_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/blob_reagents.dm @@ -29,8 +29,10 @@ /datum/reagent/blob/ripping_tendrils/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() - M.apply_damage(0.6*reac_volume, BRUTE) - M.adjustStaminaLoss(0.6*reac_volume) + if(M) + M.apply_damage(0.6*reac_volume, BRUTE) + if(M) + M.adjustStaminaLoss(0.6*reac_volume) if(iscarbon(M)) M.emote("scream") @@ -44,7 +46,8 @@ /datum/reagent/blob/sporing_pods/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() - M.apply_damage(0.4*reac_volume, TOX) + if(M) + M.apply_damage(0.4*reac_volume, TOX) /datum/reagent/blob/sporing_pods/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) if(!isnull(cause) && damage < 20 && original_health - damage <= 0 && prob(50)) //if the cause isn't fire or a bomb, the damage is less than 20, we're going to die from that damage, 50% chance of a shitty spore. @@ -71,7 +74,8 @@ /datum/reagent/blob/replicating_foam/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() - M.apply_damage(0.6*reac_volume, BRUTE) + if(M) + M.apply_damage(0.6*reac_volume, BRUTE) /datum/reagent/blob/replicating_foam/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) if(damage > 0 && original_health - damage > 0 && prob(100 - damage)) @@ -96,8 +100,10 @@ /datum/reagent/blob/energized_fibers/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() - M.apply_damage(0.4*reac_volume, BURN) - M.adjustStaminaLoss(0.8*reac_volume) + if(M) + M.apply_damage(0.4*reac_volume, BURN) + if(M) + M.adjustStaminaLoss(0.8*reac_volume) /datum/reagent/blob/energized_fibers/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) if(damage_type == STAMINA) @@ -117,9 +123,11 @@ /datum/reagent/blob/boiling_oil/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() - M.adjust_fire_stacks(round(reac_volume/12)) - M.apply_damage(0.6*reac_volume, BURN) - M.IgniteMob() + if(M) + M.adjust_fire_stacks(round(reac_volume/12)) + M.IgniteMob() + if(M) + M.apply_damage(0.6*reac_volume, BURN) if(iscarbon(M)) M.emote("scream") @@ -135,11 +143,13 @@ /datum/reagent/blob/hallucinogenic_nectar/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() - M.apply_damage(0.4*reac_volume, TOX) - M.hallucination += 0.6*reac_volume - M.druggy += 0.6*reac_volume - if(M.reagents) - M.reagents.add_reagent("spore", 0.2*reac_volume) + if(M) + M.apply_damage(0.4*reac_volume, TOX) + if(M) + M.hallucination += 0.6*reac_volume + M.druggy += 0.6*reac_volume + if(M.reagents) + M.reagents.add_reagent("spore", 0.2*reac_volume) //toxin, stamina, and some bonus spore toxin /datum/reagent/blob/envenomed_filaments @@ -151,9 +161,11 @@ /datum/reagent/blob/envenomed_filaments/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() - M.apply_damage(0.6*reac_volume, TOX) - M.adjustStaminaLoss(0.4*reac_volume) - if(M.reagents) + if(M) + M.apply_damage(0.6*reac_volume, TOX) + if(M) + M.adjustStaminaLoss(0.4*reac_volume) + if(M && M.reagents) M.reagents.add_reagent("spore", 0.2*reac_volume) //does tons of oxygen damage and a little brute @@ -166,9 +178,12 @@ /datum/reagent/blob/lexorin_jelly/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() - M.apply_damage(0.4*reac_volume, BRUTE) - M.apply_damage(0.6*reac_volume, OXY) - M.losebreath += round(0.2*reac_volume) + if(M) + M.apply_damage(0.4*reac_volume, BRUTE) + if(M) + M.apply_damage(0.6*reac_volume, OXY) + if(M) + M.losebreath += round(0.2*reac_volume) //does semi-random brute damage and reacts to brute damage /datum/reagent/blob/reactive @@ -182,7 +197,8 @@ /datum/reagent/blob/reactive/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() var/damage = rand(10, 25)/25 - M.apply_damage(damage*reac_volume, BRUTE) + if(M) + M.apply_damage(damage*reac_volume, BRUTE) /datum/reagent/blob/reactive/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) if(damage && damage_type == BRUTE && original_health - damage > 0 && isliving(cause)) //is there any damage, is it brute, will we be alive, and is the cause a mob? @@ -203,9 +219,11 @@ /datum/reagent/blob/cryogenic_liquid/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() - M.apply_damage(0.4*reac_volume, BURN) - M.adjustStaminaLoss(0.4*reac_volume) - if(M.reagents) + if(M) + M.apply_damage(0.4*reac_volume, BURN) + if(M) + M.adjustStaminaLoss(0.4*reac_volume) + if(M && M.reagents) M.reagents.add_reagent("frostoil", 0.4*reac_volume) M.reagents.add_reagent("ice", 0.4*reac_volume) @@ -220,13 +238,14 @@ /datum/reagent/blob/synchronous_mesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() - M.apply_damage(0.4*reac_volume, BRUTE) - for(var/obj/effect/blob/B in range(1, M)) //if the target is completely surrounded, this is 0.8*reac_volume bonus damage, total of 1.2*reac_volume - M.apply_damage(0.1*reac_volume, BRUTE) + if(M) + M.apply_damage(0.4*reac_volume, BRUTE) + if(M) + for(var/obj/effect/blob/B in range(1, M)) //if the target is completely surrounded, this is 0.8*reac_volume bonus damage, total of 1.2*reac_volume + if(M) + M.apply_damage(0.1*reac_volume, BRUTE) /datum/reagent/blob/synchronous_mesh/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) - if(istype(cause, /obj/effect/blob)) //if a blob is doing it, that means we're splitting the damage, so don't modify it. - return ..() if(!isnull(cause)) //the cause isn't fire or bombs, so split the damage var/damagesplit = 0.8 //maximum split is 7.2, reducing the damage each blob takes to 14% but doing that damage to 9 blobs for(var/obj/effect/blob/C in orange(1, B)) @@ -234,7 +253,7 @@ damagesplit += 0.8 for(var/obj/effect/blob/C in orange(1, B)) if(C.overmind && C.overmind.blob_reagent_datum == B.overmind.blob_reagent_datum && !istype(C, /obj/effect/blob/core)) //only hurt blobs that have the same overmind chemical and aren't cores - C.take_damage(damage/damagesplit, CLONE, B) + C.take_damage(damage/damagesplit, CLONE, B, 0) return damage/damagesplit else return damage*1.25 @@ -251,12 +270,16 @@ /datum/reagent/blob/pressurized_slime/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() - M.apply_damage(0.4*reac_volume, BRUTE) - M.apply_damage(0.4*reac_volume, OXY) - M.adjustStaminaLoss(0.4*reac_volume) - var/turf/simulated/T = get_turf(M) - if(istype(T, /turf/simulated)) - T.MakeSlippery(TURF_WET_WATER) + if(M) + M.apply_damage(0.4*reac_volume, BRUTE) + if(M) + M.apply_damage(0.4*reac_volume, OXY) + if(M) + M.adjustStaminaLoss(0.4*reac_volume) + if(M) + var/turf/simulated/T = get_turf(M) + if(istype(T, /turf/simulated)) + T.MakeSlippery(TURF_WET_WATER) /datum/reagent/blob/pressurized_slime/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) for(var/turf/simulated/T in range(1, B)) @@ -282,7 +305,8 @@ /datum/reagent/blob/dark_matter/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reagent_vortex(M, 0, reac_volume) reac_volume = ..() - M.apply_damage(0.6*reac_volume, BRUTE) + if(M) + M.apply_damage(0.6*reac_volume, BRUTE) //does brute damage and throws or pushes nearby objects away from the target /datum/reagent/blob/b_sorium @@ -295,36 +319,38 @@ /datum/reagent/blob/b_sorium/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reagent_vortex(M, 1, reac_volume) reac_volume = ..() - M.apply_damage(0.6*reac_volume, BRUTE) + if(M) + M.apply_damage(0.6*reac_volume, BRUTE) /datum/reagent/blob/proc/reagent_vortex(mob/living/M, setting_type, reac_volume) - var/turf/pull = get_turf(M) - var/range_power = Clamp(round(reac_volume/5, 1), 1, 5) - for(var/atom/movable/X in range(range_power,pull)) - if(istype(X, /obj/effect)) - continue - if(!X.anchored) - var/distance = get_dist(X, pull) - var/moving_power = max(range_power - distance, 1) - spawn(0) - if(moving_power > 2) //if the vortex is powerful and we're close, we get thrown - if(setting_type) - var/atom/throw_target = get_edge_target_turf(X, get_dir(X, get_step_away(X, pull))) - var/throw_range = 5 - distance - X.throw_at(throw_target, throw_range, 1) + if(M) + var/turf/pull = get_turf(M) + var/range_power = Clamp(round(reac_volume/5, 1), 1, 5) + for(var/atom/movable/X in range(range_power,pull)) + if(istype(X, /obj/effect)) + continue + if(!X.anchored) + var/distance = get_dist(X, pull) + var/moving_power = max(range_power - distance, 1) + spawn(0) + if(moving_power > 2) //if the vortex is powerful and we're close, we get thrown + if(setting_type) + var/atom/throw_target = get_edge_target_turf(X, get_dir(X, get_step_away(X, pull))) + var/throw_range = 5 - distance + X.throw_at(throw_target, throw_range, 1) + else + X.throw_at(pull, distance, 1) else - X.throw_at(pull, distance, 1) - else - if(setting_type) - for(var/i = 0, i < moving_power, i++) - sleep(2) - if(!step_away(X, pull)) - break - else - for(var/i = 0, i < moving_power, i++) - sleep(2) - if(!step_towards(X, pull)) - break + if(setting_type) + for(var/i = 0, i < moving_power, i++) + sleep(2) + if(!step_away(X, pull)) + break + else + for(var/i = 0, i < moving_power, i++) + sleep(2) + if(!step_towards(X, pull)) + break /datum/reagent/blob/proc/send_message(mob/living/M) From 60d0aad9ab80c34b735656190c2382790a6df46f Mon Sep 17 00:00:00 2001 From: Tkdrg Date: Wed, 23 Dec 2015 16:46:28 -0300 Subject: [PATCH 11/71] Cult shell tweaks Cultists can now summon shells by spending an orb. Cultists can no longer summon or feed shells on z != 1. Fixes #13834 Fixes #13940 --- code/game/gamemodes/cult/cult.dm | 2 +- code/game/gamemodes/cult/cult_items.dm | 33 ++++++++++++++------- code/game/gamemodes/cult/cult_structures.dm | 6 +++- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index da4be575121..10e43124d7f 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -40,7 +40,7 @@ var/eldergod = 0 var/orbs_needed = 3 - var/large_shell_summoned = 0 + var/obj/structure/constructshell/large/large_shell_reference = null var/attempts_left = 3 /datum/game_mode/cult/announce() diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 2de0ba8e2f2..36ee079bd01 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -151,25 +151,38 @@ return ..() if(ticker.mode.name != "cult") return + var/turf/T = get_turf(user) + if(T.z != ZLEVEL_STATION) + user << "You shouldn't do this here. Go back." + return var/datum/game_mode/cult/cult = ticker.mode if(!cult.attempts_left) user << "You attempt to call out to the Geometer, but there is no answer..." return - switch(alert(user,"Are you sure you wish to summon the large construct shell? [cult.attempts_left] attempts left!","Summoning Large Shell","Yes","No")) - if("Yes") - cult.attempts_left-- - place_down_large_shell(user) - qdel(src) + + if(cult.large_shell_reference) + var/obj/S = cult.large_shell_reference + if(S.anchored) + var/area/A = get_area(S) + user << "The Geometer has already started manifesting in [initial(A.name)]. You can no longer move Her shell." + return + switch(alert(user,"The Geometer's shell has already been manifested. Do you wish to summon it to your location?","Summoning Large Shell","Yes","No")) + if("Yes") + S.visible_message("The shell suddenly vanishes.") + S.loc = user.loc + else + switch(alert(user,"Are you sure you wish to summon the large construct shell? [cult.attempts_left] attempts left!","Summoning Large Shell","Yes","No")) + if("Yes") + cult.attempts_left-- + place_down_large_shell(user) + qdel(src) /obj/item/summoning_orb/proc/place_down_large_shell(mob/user) if(!(ticker.mode.name == "cult")) user << "You attempt to call out to the Geometer for Her shell, but you fail..." return var/datum/game_mode/cult/cult = ticker.mode - if(cult.large_shell_summoned) - user << "Another Acolyte has already summoned Her shell. You must go forth and contact them." - return if(cult.attempts_left <= 0) user << "The Geometer is no longer interested in you." - new /obj/structure/constructshell/large(get_turf(src)) - cult.large_shell_summoned = 1 + var/A = new /obj/structure/constructshell/large(get_turf(src)) + cult.large_shell_reference = A diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index b57eea4dbf6..afd03c60fb9 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -29,7 +29,7 @@ set_security_level("red") if(ticker.mode.name == "cult") var/datum/game_mode/cult/cult = ticker.mode - cult.large_shell_summoned = 0 + cult.large_shell_reference = null black_overlay = null if(timer_id) deltimer(timer_id) @@ -50,6 +50,10 @@ if(istype(O, /obj/item/summoning_orb) && (orbs < orbs_needed)) if(!iscultist(user)) return + var/turf/T = get_turf(user) + if(T.z != ZLEVEL_STATION) + user << "You shouldn't do this here. Go back." + return visible_message("\The [src] glows.") orbs++ qdel(O) From 1059beeb28e97581913023fe0a730fb13e87d708 Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Wed, 23 Dec 2015 15:09:33 -0500 Subject: [PATCH 12/71] if(!screaming) --- .../chemistry/reagents/blob_reagents.dm | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/code/modules/reagents/chemistry/reagents/blob_reagents.dm b/code/modules/reagents/chemistry/reagents/blob_reagents.dm index 8f1a5441f9d..48db3db735a 100644 --- a/code/modules/reagents/chemistry/reagents/blob_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/blob_reagents.dm @@ -123,9 +123,8 @@ /datum/reagent/blob/boiling_oil/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() - if(M) - M.adjust_fire_stacks(round(reac_volume/12)) - M.IgniteMob() + M.adjust_fire_stacks(round(reac_volume/12)) + M.IgniteMob() if(M) M.apply_damage(0.6*reac_volume, BURN) if(iscarbon(M)) @@ -143,13 +142,12 @@ /datum/reagent/blob/hallucinogenic_nectar/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() + M.hallucination += 0.6*reac_volume + M.druggy += 0.6*reac_volume + if(M.reagents) + M.reagents.add_reagent("spore", 0.2*reac_volume) if(M) M.apply_damage(0.4*reac_volume, TOX) - if(M) - M.hallucination += 0.6*reac_volume - M.druggy += 0.6*reac_volume - if(M.reagents) - M.reagents.add_reagent("spore", 0.2*reac_volume) //toxin, stamina, and some bonus spore toxin /datum/reagent/blob/envenomed_filaments @@ -161,12 +159,12 @@ /datum/reagent/blob/envenomed_filaments/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() + if(M.reagents) + M.reagents.add_reagent("spore", 0.2*reac_volume) if(M) M.apply_damage(0.6*reac_volume, TOX) if(M) M.adjustStaminaLoss(0.4*reac_volume) - if(M && M.reagents) - M.reagents.add_reagent("spore", 0.2*reac_volume) //does tons of oxygen damage and a little brute /datum/reagent/blob/lexorin_jelly @@ -178,12 +176,11 @@ /datum/reagent/blob/lexorin_jelly/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() + M.losebreath += round(0.2*reac_volume) if(M) M.apply_damage(0.4*reac_volume, BRUTE) if(M) M.apply_damage(0.6*reac_volume, OXY) - if(M) - M.losebreath += round(0.2*reac_volume) //does semi-random brute damage and reacts to brute damage /datum/reagent/blob/reactive @@ -219,13 +216,13 @@ /datum/reagent/blob/cryogenic_liquid/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() + if(M.reagents) + M.reagents.add_reagent("frostoil", 0.4*reac_volume) + M.reagents.add_reagent("ice", 0.4*reac_volume) if(M) M.apply_damage(0.4*reac_volume, BURN) if(M) M.adjustStaminaLoss(0.4*reac_volume) - if(M && M.reagents) - M.reagents.add_reagent("frostoil", 0.4*reac_volume) - M.reagents.add_reagent("ice", 0.4*reac_volume) //does brute damage, bonus damage for each nearby blob, and spreads damage out /datum/reagent/blob/synchronous_mesh @@ -270,16 +267,15 @@ /datum/reagent/blob/pressurized_slime/reaction_mob(mob/living/M, method=TOUCH, reac_volume) reac_volume = ..() + var/turf/simulated/T = get_turf(M) + if(istype(T, /turf/simulated)) + T.MakeSlippery(TURF_WET_WATER) if(M) M.apply_damage(0.4*reac_volume, BRUTE) if(M) M.apply_damage(0.4*reac_volume, OXY) if(M) M.adjustStaminaLoss(0.4*reac_volume) - if(M) - var/turf/simulated/T = get_turf(M) - if(istype(T, /turf/simulated)) - T.MakeSlippery(TURF_WET_WATER) /datum/reagent/blob/pressurized_slime/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) for(var/turf/simulated/T in range(1, B)) From 246d2c2ae7e25474f49abaa7da7fc02a9a701c3a Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Wed, 23 Dec 2015 15:13:23 -0500 Subject: [PATCH 13/71] unnecessary commit due to slow github updating --- code/modules/reagents/chemistry/reagents/blob_reagents.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/reagents/chemistry/reagents/blob_reagents.dm b/code/modules/reagents/chemistry/reagents/blob_reagents.dm index 48db3db735a..3ec9c3c9a0d 100644 --- a/code/modules/reagents/chemistry/reagents/blob_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/blob_reagents.dm @@ -338,12 +338,12 @@ X.throw_at(pull, distance, 1) else if(setting_type) - for(var/i = 0, i < moving_power, i++) + for(var/i in 0 to moving_power-1) sleep(2) if(!step_away(X, pull)) break else - for(var/i = 0, i < moving_power, i++) + for(var/i in 0 to moving_power-1) sleep(2) if(!step_towards(X, pull)) break From e2ea3b6c4c1fa521631f9357b722913fd77e5957 Mon Sep 17 00:00:00 2001 From: Remie Richards Date: Wed, 23 Dec 2015 22:13:43 +0000 Subject: [PATCH 14/71] Allows you to cancel Targetted spells. --- code/datums/spell.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/spell.dm b/code/datums/spell.dm index 7591762275f..b38d951b5c9 100644 --- a/code/datums/spell.dm +++ b/code/datums/spell.dm @@ -303,7 +303,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin //Adds a safety check post-input to make sure those targets are actually in range. var/mob/M if(!random_target) - M = input("Choose the target for the spell.", "Targeting") as mob in possible_targets + M = input("Choose the target for the spell.", "Targeting") as null|mob in possible_targets else switch(random_target_priority) if(TARGET_RANDOM) From 49e112b1896549e3a44448b15bca94b0bc810ab0 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Wed, 23 Dec 2015 14:20:42 -0800 Subject: [PATCH 15/71] Fixes lib machines spamming refreshes when printing --- code/modules/library/lib_machines.dm | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index ae9ec6cf95f..a14996e18b9 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -406,7 +406,11 @@ var/global/list/datum/cachedbook/cachedbooks // List of our cached book datums else log_game("[usr.name]/[usr.key] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] signs") alert("Upload Complete. Uploaded title will be unavailable for printing for a short period") - + if(href_list["orderbyid"]) + var/orderid = input("Enter your order:") as num|null + if(orderid) + if(isnum(orderid)) + href_list["targetid"] = orderid if(href_list["targetid"]) var/sqlid = sanitizeSQL(href_list["targetid"]) establish_db_connection() @@ -433,12 +437,6 @@ var/global/list/datum/cachedbook/cachedbooks // List of our cached book datums B.icon_state = "book[rand(1,7)]" src.visible_message("[src]'s printer hums as it produces a completely bound book. How did it do that?") break - if(href_list["orderbyid"]) - var/orderid = input("Enter your order:") as num|null - if(orderid) - if(isnum(orderid)) - var/nhref = "src=\ref[src];targetid=[orderid]" - spawn() src.Topic(nhref, params2list(nhref), src) src.add_fingerprint(usr) src.updateUsrDialog() return From c2c981ef167feb38b87ab4293bfac5198814af48 Mon Sep 17 00:00:00 2001 From: oranges Date: Thu, 24 Dec 2015 13:55:53 +1300 Subject: [PATCH 16/71] Spelling mistake in borg transformer --- code/game/machinery/transformer.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index f85e470fcf1..df341d96204 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -1,6 +1,6 @@ /obj/machinery/transformer name = "\improper Automatic Robotic Factory 5000" - desc = "A large metalic machine with an entrance and an exit. A sign on the side reads, 'human go in, robot come out', human must be lying down and alive. Has to cooldown between each use." + desc = "A large metallic machine with an entrance and an exit. A sign on the side reads, 'human go in, robot come out', human must be lying down and alive. Has to cooldown between each use." icon = 'icons/obj/recycling.dmi' icon_state = "separator-AO1" layer = MOB_LAYER+1 // Overhead @@ -103,4 +103,4 @@ // West var/turf/west = locate(T.x - 1, T.y, T.z) if(istype(west, /turf/simulated/floor)) - new /obj/machinery/conveyor/auto(west, WEST) \ No newline at end of file + new /obj/machinery/conveyor/auto(west, WEST) From 8947b4e94f7bd3a8421564a219082764cf632571 Mon Sep 17 00:00:00 2001 From: Tkdrg Date: Thu, 24 Dec 2015 00:37:11 -0300 Subject: [PATCH 17/71] Adds xeno golems to admin log Also makes golems use key_name(), key_name_admin() and adminmoreinfo. --- code/modules/research/xenobiology/xenobiology.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index e7e1f3f0e47..8ddda4e49f7 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -440,8 +440,9 @@ G << "You are an adamantine golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. Serve [user], and assist them in completing their goals at any cost." G.mind.store_memory("Serve [user.real_name], your creator.") if(user.mind.special_role) - message_admins("[G.real_name] has been summoned by [user.real_name], an antagonist.") - log_game("[G.real_name] ([G.key]) was made a golem by [user.real_name]([user.key]).") + message_admins("[key_name_admin(G)](?) has been summoned by [key_name_admin(user)](?), an antagonist.") + log_game("[key_name(G)] was made a golem by [key_name(user)].") + log_admin("[key_name(G)] was made a golem by [key_name(user)].") qdel(src) From f0f18ec6efef0614eb4a4a563a2928da28b2a96f Mon Sep 17 00:00:00 2001 From: AndrewJacksonThe2nd Date: Thu, 24 Dec 2015 00:25:00 -0800 Subject: [PATCH 18/71] TESLA 4.0: less laggy hopefully --- code/game/objects/objs.dm | 2 +- code/modules/power/tesla/coil.dm | 1 + code/modules/power/tesla/energy_ball.dm | 34 +++++++++++++++---------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 7751e757690..3e716979df8 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -194,7 +194,7 @@ /obj/proc/tesla_act(var/power) being_shocked = 1 - var/power_bounced = power / 2 + var/power_bounced = power / 1.3 tesla_zap(src, 5, power_bounced) spawn(10) being_shocked = 0 diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index 43adbc22978..bf6f80dfdc3 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -45,6 +45,7 @@ var/power_produced = power / power_loss add_avail(power_produced*input_power_multiplier) flick("coilhit", src) + playsound(src.loc, 'sound/magic/LightningShock.ogg', 100, 1, extrarange = 5) tesla_zap(src, 5, power_produced) spawn(10) being_shocked = 0 diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 96a4d27e1df..f1af4c5f66f 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -16,7 +16,7 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, /obj/structure/disposalpipe) /obj/singularity/energy_ball - name = "energy eall" + name = "energy ball" desc = "An energy ball." icon = 'icons/obj/tesla_engine/energy_ball.dmi' icon_state = "energy_ball" @@ -40,15 +40,16 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, if(!is_orbiting) handle_energy() var/amount_to_move = 2 + orbiting_balls.len * 2 + var/what_does_the_scouter_say_about_the_balls_power_level = (TESLA_DEFAULT_POWER + (TESLA_MINI_POWER * orbiting_balls.len)) move_the_basket_ball(amount_to_move) pixel_x = 0 pixel_y = 0 - tesla_zap(src, 7, TESLA_DEFAULT_POWER) + playsound(src.loc, 'sound/magic/lightningbolt.ogg', 100, 1, extrarange = 5) + tesla_zap(src, 7, what_does_the_scouter_say_about_the_balls_power_level) pixel_x = -32 pixel_y = -32 energy += rand(1,3) // ensure it generates energy without needing to be blasted by the PA too much due to its size, and that a tesla engine will always get bigger over time else - tesla_zap(src, 7, TESLA_MINI_POWER) energy = 0 // ensure we dont have miniballs of miniballs return @@ -67,17 +68,19 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, /obj/singularity/energy_ball/proc/handle_energy() if(energy >= 300) - energy = 0 - var/obj/singularity/energy_ball/EB = new(loc) - orbiting_balls.Add(EB) - EB.transform *= pick(0.3,0.4,0.5,0.6,0.7) - EB.is_orbiting = 1 - var/icon/I = icon(icon,icon_state,dir) + energy -= 300 + playsound(src.loc, 'sound/magic/lightning_chargeup.ogg', 100, 1, extrarange = 5) + spawn(100) + var/obj/singularity/energy_ball/EB = new(loc) + orbiting_balls.Add(EB) + EB.transform *= pick(0.3,0.4,0.5,0.6,0.7) + EB.is_orbiting = 1 + var/icon/I = icon(icon,icon_state,dir) - var/orbitsize = (I.Width()+I.Height())*pick(0.5,0.6,0.7) - orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25) - spawn(1) - EB.orbit(src,orbitsize, pick(FALSE,TRUE), rand(10,25), pick(3,4,5,6,36)) + var/orbitsize = (I.Width()+I.Height())*pick(0.5,0.6,0.7) + orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25) + spawn(1) + EB.orbit(src,orbitsize, pick(FALSE,TRUE), rand(10,25), pick(3,4,5,6,36)) @@ -110,7 +113,7 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, return closest_atom /proc/tesla_zap(var/atom/source, zap_range = 3, power) - if(power < 1000) + if(power < 500) return var/list/tesla_coils = list() var/list/grounding_rods = list() @@ -176,6 +179,9 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, if(istype(L, /mob/living/silicon)) var/mob/living/silicon/S = L S.emp_act(2) + tesla_zap(S, 7, power / 1.5) // metallic folks bounce it further + else + tesla_zap(L, 5, power / 1.5) return if(!closest_atom) closest_atom = get_closest_atom(/obj/machinery, potential_machine_zaps, source) From 789e3457cba701ff4d679b4e6179af5a2d6c46e2 Mon Sep 17 00:00:00 2001 From: bgobandit Date: Thu, 24 Dec 2015 04:35:08 -0500 Subject: [PATCH 19/71] fixes some minor bugs --- code/game/machinery/doors/airlock.dm | 5 ++++- code/game/objects/items/weapons/implants/implanter.dm | 6 ++++-- code/modules/mob/living/simple_animal/friendly/dog.dm | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index db68793ce1c..209ace5fc7d 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -923,7 +923,10 @@ About the new airlock wires panel: else if(istype(C, /obj/item/weapon/airlock_painter)) change_paintjob(C, user) - else if(istype(C, /obj/item/device/doorCharge) && p_open) + else if(istype(C, /obj/item/device/doorCharge)) + if(!p_open) + user << "The maintenance panel must be open to apply [C]!" + return if(emagged) return if(charge && !detonated) diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm index 9b0505df42d..870821e3866 100644 --- a/code/game/objects/items/weapons/implants/implanter.dm +++ b/code/game/objects/items/weapons/implants/implanter.dm @@ -32,8 +32,10 @@ if(T && (M == user || do_after(user, 50))) if(user && M && (get_turf(M) == T) && src && imp) if(imp.implant(M, user)) - user << "You implant the implant into [M]." - M.visible_message("[user] has implanted [M].", "[user] implants you with the implant.") + if (M == user) + user << "You implant yourself." + else + M.visible_message("[user] has implanted [M].", "[user] implants you.") imp = null update_icon() diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 79bc4ac5dc1..a040346808d 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -183,7 +183,7 @@ ) if( ! ( item_to_add.type in allowed_types ) ) - usr << "You set [item_to_add] on [src]'s back, but \he shakes it off!" + usr << "You set [item_to_add] on [src]'s back, but it falls off!" if(!usr.drop_item()) usr << "\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s back!" return @@ -260,7 +260,7 @@ if(user && !user.drop_item()) user << "\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s head!" return 0 - user << "You set [item_to_add] on [src]'s head, but \he shakes it off!" + user << "You set [item_to_add] on [src]'s head, but it falls off!" item_to_add.loc = loc if(prob(25)) step_rand(item_to_add) From 73f6416bd154017c6549a524fb63e4064b79bb47 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 04:00:55 -0600 Subject: [PATCH 20/71] Fixes illusions running about on their face --- code/modules/mob/living/simple_animal/hostile/illusion.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/mob/living/simple_animal/hostile/illusion.dm b/code/modules/mob/living/simple_animal/hostile/illusion.dm index b16ef6d9207..e82dafb9781 100644 --- a/code/modules/mob/living/simple_animal/hostile/illusion.dm +++ b/code/modules/mob/living/simple_animal/hostile/illusion.dm @@ -33,6 +33,8 @@ melee_damage_upper = damage multiply_chance = replicate faction -= "neutral" + transform = matrix() + pixel_y = 0 /mob/living/simple_animal/hostile/illusion/death() From 2e5f25562d2a5fafa8e7bd2d220d832f3392e974 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 04:13:18 -0600 Subject: [PATCH 21/71] Fixes more reactive exploits --- code/modules/mob/living/carbon/human/human_defense.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 74f6c32b5d2..7c0df56c7b8 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -347,7 +347,7 @@ if(istype(AM, /obj/item)) I = AM throwpower = I.throwforce - if(check_shields(throwpower, "\the [AM.name]", AM, THROWN_PROJECTILE_ATTACK)) + if(I.thrownby != src && check_shields(throwpower, "\the [AM.name]", AM, THROWN_PROJECTILE_ATTACK)) hitpush = 0 skipcatch = 1 blocked = 1 From 4d48a9a1df90a8dd0269a5182ec81b7e814329d2 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 04:43:25 -0600 Subject: [PATCH 22/71] Fixes camera EMP --- code/game/machinery/camera/camera.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 5f3bbb89368..58fa41b44d9 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -69,6 +69,8 @@ return ..() /obj/machinery/camera/emp_act(severity) + if(!status) + return if(!isEmpProof()) if(prob(150/severity)) icon_state = "[initial(icon_state)]emp" From 2f22514fd64fb9549a45f87176c87c2260efd858 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 04:57:50 -0600 Subject: [PATCH 23/71] Spider fixes --- code/game/objects/effects/spiders.dm | 37 ++++--------------- .../simple_animal/hostile/giant_spider.dm | 2 +- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index a3c72f3a8b3..228955e8d1c 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -94,7 +94,7 @@ var/obj/effect/spider/spiderling/S = new /obj/effect/spider/spiderling(src.loc) S.poison_type = poison_type S.poison_per_bite = poison_per_bite - S.faction = faction + S.faction = faction.Copy() if(player_spiders) S.player_spiders = 1 qdel(src) @@ -200,36 +200,13 @@ var/mob/living/simple_animal/hostile/poison/giant_spider/S = new grow_as(src.loc) S.poison_per_bite = poison_per_bite S.poison_type = poison_type - S.faction = faction + S.faction = faction.Copy() if(player_spiders) - var/list/candidates = get_candidates(ROLE_ALIEN, ALIEN_AFK_BRACKET) - - shuffle(candidates) - - var/time_passed = world.time - var/list/consenting_candidates = list() - - for(var/candidate in candidates) - - spawn(0) - switch(alert(candidate, "Would you like to play as [S.name]? Please choose quickly!","Confirmation","Yes","No")) - if("Yes") - if((world.time-time_passed)>=50 || !src) - return - consenting_candidates += candidate - - sleep(50) - - if(!src) - return - - listclearnulls(consenting_candidates) //some candidates might have left during sleep(50) - - - if(consenting_candidates.len) - var/client/C = null - C = pick(consenting_candidates) - S.key = C.key + var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [S.name]?", ROLE_ALIEN, null, ROLE_ALIEN, 50) + var/mob/dead/observer/theghost = null + if(candidates.len) + theghost = pick(candidates) + S.key = theghost.key qdel(src) diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index 5496ce84249..c7328140dd9 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -250,7 +250,7 @@ C.player_spiders = 1 C.poison_type = poison_type C.poison_per_bite = poison_per_bite - C.faction = faction + C.faction = faction.Copy() fed-- busy = 0 stop_automated_movement = 0 From f5e063753451ab4871ef686456481f77bef9989b Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 06:11:47 -0600 Subject: [PATCH 24/71] Fixes active turfs on wildwest --- _maps/RandomZLevels/wildwest.dmm | 258 +++++++++++++++---------------- 1 file changed, 126 insertions(+), 132 deletions(-) diff --git a/_maps/RandomZLevels/wildwest.dmm b/_maps/RandomZLevels/wildwest.dmm index 85f239d04b8..91d013263d7 100644 --- a/_maps/RandomZLevels/wildwest.dmm +++ b/_maps/RandomZLevels/wildwest.dmm @@ -5,13 +5,13 @@ "ae" = (/turf/simulated/floor/plating{icon_state = "cultdamage5"},/area/awaymission/wwvault) "af" = (/mob/living/simple_animal/hostile/faithless,/turf/simulated/floor/engine/cult,/area/awaymission/wwvault) "ag" = (/turf/simulated/floor/plating{icon_state = "bcircuitoff"},/area/awaymission/wwvault) -"ah" = (/turf/space,/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/indestructible{desc = "The patterns engraved on the wall seem to shift as you try to focus on them. You feel sick."; icon = 'icons/turf/walls/cult_wall.dmi'; icon_state = "cult"},/area/awaymission/wwvault) +"ah" = (/turf/indestructible{desc = "The patterns engraved on the wall seem to shift as you try to focus on them. You feel sick."; icon = 'icons/turf/walls/cult_wall.dmi'; icon_state = "cult"},/area/awaymission/wwvault) "ai" = (/turf/space,/turf/indestructible{desc = "The patterns engraved on the wall seem to shift as you try to focus on them. You feel sick."; icon = 'icons/turf/walls/cult_wall.dmi'; icon_state = "cult"},/area/awaymission/wwvault) "aj" = (/turf/simulated/floor/plating{icon_state = "cultdamage3"},/area/awaymission/wwvault) "ak" = (/turf/simulated/floor/plating{icon_state = "cultdamage6"},/area/awaymission/wwvault) "al" = (/obj/effect/gateway,/turf/simulated/floor/engine/cult,/area/awaymission/wwvault) "am" = (/mob/living/simple_animal/hostile/faithless,/turf/simulated/floor/plating{icon_state = "bcircuitoff"},/area/awaymission/wwvault) -"an" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/indestructible,/area/awaymission/wwvault) +"an" = (/turf/simulated/floor/engine/vacuum{icon_state = "cult"; name = "engraved floor"; tag = "icon-cult"},/area/awaymission/wwvault) "ao" = (/turf/simulated/floor/plating{icon_state = "gcircuitoff"},/area/awaymission/wwvault) "ap" = (/obj/machinery/wish_granter_dark,/turf/simulated/floor/plating{icon_state = "gcircuitoff"},/area/awaymission/wwvault) "aq" = (/obj/structure/cult/pylon,/turf/simulated/floor/plating{icon_state = "gcircuitoff"},/area/awaymission/wwvault) @@ -31,23 +31,20 @@ "aE" = (/mob/living/simple_animal/hostile/faithless,/turf/simulated/floor/carpet,/area/awaymission/wwvault) "aF" = (/obj/machinery/door/airlock/vault{locked = 1},/turf/simulated/floor/engine/cult,/area/awaymission/wwvaultdoors) "aG" = (/turf/simulated/mineral,/area/space) -"aH" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/space,/area/space) -"aI" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/simulated/mineral,/area/space) +"aH" = (/turf/simulated/mineral/diamond,/area/awaymission/wwmines) +"aI" = (/turf/simulated/mineral/gold,/area/awaymission/wwmines) "aJ" = (/obj/machinery/door/airlock/vault{locked = 1},/turf/simulated/floor/engine/cult,/area/awaymission/wwvault) "aK" = (/obj/effect/landmark/corpse/miner/rig,/turf/simulated/floor/engine/cult,/area/awaymission/wwvault) -"aL" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/simulated/mineral,/area/awaymission/wwmines) +"aL" = (/obj/item/weapon/paper{info = "meat grinder requires sacri"},/turf/simulated/floor/engine/vacuum{icon_state = "cult"; name = "engraved floor"; tag = "icon-cult"},/area/awaymission/wwvault) "aM" = (/turf/simulated/mineral/silver,/area/awaymission/wwmines) "aN" = (/turf/simulated/mineral,/area/awaymission/wwmines) -"aO" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/simulated/mineral/diamond,/area/awaymission/wwmines) -"aP" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/simulated/mineral/silver,/area/awaymission/wwmines) -"aQ" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/simulated/mineral/gold,/area/awaymission/wwmines) +"aO" = (/obj/effect/landmark/corpse/syndicatecommando,/turf/simulated/floor/engine/vacuum{icon_state = "cult"; name = "engraved floor"; tag = "icon-cult"},/area/awaymission/wwvault) +"aP" = (/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/mineral,/area/awaymission/wwmines) +"aQ" = (/obj/effect/decal/cleanable/blood,/turf/simulated/mineral,/area/awaymission/wwmines) "aR" = (/obj/structure/ore_box,/turf/simulated/floor/plating/ironsand{icon_state = "ironsand1"},/area/awaymission/wwmines) -"aS" = (/obj/item/weapon/paper{info = "meat grinder requires sacri"},/turf/simulated/floor/engine/cult,/area/awaymission/wwvault) "aT" = (/turf/simulated/floor/plating/ironsand{icon_state = "ironsand1"},/area/awaymission/wwmines) -"aU" = (/obj/effect/landmark/corpse/syndicatecommando,/turf/simulated/floor/engine/cult,/area/awaymission/wwvault) "aV" = (/turf/simulated/mineral,/area/awaymission/wwrefine) "aW" = (/turf/simulated/wall/mineral/sandstone,/area/awaymission/wwrefine) -"aX" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/simulated/wall/mineral/sandstone,/area/awaymission/wwmines) "aY" = (/obj/effect/decal/cleanable/blood/gibs/body{icon_state = "gibup1"},/turf/simulated/floor/plating/ironsand{icon_state = "ironsand1"},/area/awaymission/wwmines) "aZ" = (/obj/effect/mine/sound/bwoink,/turf/simulated/floor/plating/ironsand{icon_state = "ironsand1"},/area/awaymission/wwmines) "ba" = (/obj/effect/mine/sound/bwoink,/obj/item/ammo_box/c10mm,/turf/simulated/floor/plating/ironsand{icon_state = "ironsand1"},/area/awaymission/wwmines) @@ -218,7 +215,6 @@ "ej" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/plating/ironsand{icon_state = "ironsand1"},/area/awaymission/wwmines) "ek" = (/obj/effect/mine/gas/plasma,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 5},/area/awaymission/wwmines) "el" = (/obj/effect/decal/cleanable/blood,/obj/machinery/washing_machine,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 5},/area/awaymission/wwmines) -"em" = (/turf/simulated/floor/engine/cult,/turf/indestructible{desc = "The patterns engraved on the wall seem to shift as you try to focus on them. You feel sick."; icon = 'icons/turf/walls/cult_wall.dmi'; icon_state = "cult"},/area/awaymission/wwvault) "en" = (/obj/effect/spawner/structure/window,/turf/simulated/floor/plating/ironsand{icon_state = "ironsand1"},/area/awaymission/wwmines) "eo" = (/obj/structure/table/wood,/turf/simulated/floor/carpet,/area/awaymission/wwmines) "eq" = (/obj/item/weapon/gun/projectile/shotgun,/turf/simulated/floor/wood,/area/awaymission/wwmines) @@ -321,7 +317,6 @@ "gm" = (/obj/item/weapon/gun/projectile,/turf/simulated/floor/wood,/area/awaymission/wwmines) "gn" = (/mob/living/simple_animal/hostile/creature,/turf/simulated/floor/grass,/area/awaymission/wwgov) "go" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/grass,/area/awaymission/wwgov) -"gp" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/simulated/mineral,/area/awaymission/wwmines) "gq" = (/obj/effect/decal/cleanable/blood/gibs/up,/turf/simulated/floor/wood,/area/awaymission/wwmines) "gr" = (/obj/effect/decal/cleanable/blood/gibs/down,/turf/simulated/floor/wood,/area/awaymission/wwmines) "gs" = (/obj/structure/bed/chair/comfy/beige{dir = 4},/obj/effect/decal/cleanable/blood/gibs/body{icon_state = "gibdown1"},/turf/simulated/floor/wood,/area/awaymission/wwmines) @@ -339,7 +334,6 @@ "gE" = (/obj/structure/window/reinforced,/turf/simulated/floor/grass,/area/awaymission/wwgov) "gF" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/grass,/area/awaymission/wwgov) "gG" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{icon_state = "fwindow"; dir = 4},/obj/structure/window/reinforced{icon_state = "fwindow"; dir = 8},/obj/structure/grille,/turf/simulated/floor/plasteel,/area/awaymission/wwrefine) -"gH" = (/obj/effect/decal/cleanable/blood,/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/simulated/mineral,/area/awaymission/wwmines) "gI" = (/turf/simulated/wall/shuttle{icon_state = "swall_s6"},/area/awaymission/wwrefine) "gJ" = (/turf/simulated/wall/shuttle{icon_state = "swall12"},/area/awaymission/wwrefine) "gK" = (/turf/simulated/wall/shuttle{icon_state = "swall8"},/area/awaymission/wwrefine) @@ -433,124 +427,124 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacacacacacacacacacacacacacacacacacacacacacacacababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacacacacacacacadacacacacacacacacacacacacacacacacacacacacacacacacacacacababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacacacacacacacacacacacacaeacacafacacacacacacacacacacacacacagacacacacacacacacacabababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababaaaaaaaaaaaaaaabaiahahacacacacacacacajafacacacacacacacacacacacacacacacacacacacajafacacacacagagacacacacacacacacacacacacacababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacacacacacababaaaaaaaaaaababaiacahahacacacacacacacacacacacacacacacacafacacacaeacacacacacacacacacacacacacagagagacacacacacacacacacacacacacacacacacacacacababababababaaaaaaaaaaaaaaaaaaabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababaiaiacacacaiaiaiacemacaiabababababababacacacacahahacacacacacacacacacakacacacacacacacacacacacacacalacacacacacacacacacalacagagagagamacacacacacajacacacacacacacacacacacacacananababababaaaaaaababababaoaoapabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacaiaiaiacacacaiaiaiacaiacacacacacacacacacacacacahahacacacacacacacacacacacacacacacacacacacacacacacacacacacagacacacacacacacacacacagagagagacacacagacacagacacacagadacacacacanananananabababababaqaoaoaoaoaoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacememaiaiaiafacadaiacaiaiacacacacacacafacadacacacahahahahacacadacacacacacacalacacacacacacacacacacacacacacagagacacacacacagagagagagagacacagagagagagagagagacacagagacacacacanarasatananananabaoaoaoaoaoaoaqabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacaiacacaiaiaiacacacacacacaiaiaiacacacacahaiacacacacacacaeacacacacacacacacakacacafacacacacacagacamagagagacacacacacagagagagagagagagagagagagacajaganananananauavawaoaoaoabaoaoaoaoaoaoaoababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacaiaiacacacacacacacacaiacacacacaiaiaiaiacacacememaiaiacacacacaiacacacacafacacacacacacadacacacacacacacacadacacacagagacacacacacagagacacadagagajagagagagagagagagaganananagagacanaxayazaoaoaoaoaAabaoaoaoaoaoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacadaiaiaiaiaiaiaiaiaiaiaiaiacacacacacaiaiacacacacacaiacacacacaiaiacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacagagagagagacacacagagacacacagaganagagacagadanaoaoaoaoaoaoabaoaoaoaoaoaoaoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababacacacacacacacacacacacacacacacacaiacacacacacacaiaiacacacacaiaiacacacacaiacacacacacafacacacacacacacacafacacacacacacacacacacacacacacafacacacacacagagagagagagacadacacacagagaganagagagaoaoaoaoaoaoananabaqaoaoaoaoaoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababaiaiaiacacacafacacacacacacacacacacaiaiacacacacacacaiaiaiacacacaiadacafacaiaiaiacacacacajacacakacacacacacacacacacacaeacacacajacacagagagacacagagagagacafagagagagagagagagaganagagagagaBanaoaoaoaoananabababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacaiaiaiacacacacacacacaiaiaiacacacaiadacacacacacacacaiaiacacaiaiaiacacacacaiacacacacacacacacacacacacacakacacacacacacafacacagagacacacagagagacacalacagagagagacacagagagacanananagagacanaoaoaqananababaaaaaaaaabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacaiaiaiaiaiaiaiaiaiadacacacacaiaiacacacacacacacacaiadacacacaiacacacacaiacacacacacacacacacacacacacacacacacacacacacacagagacacacacacacacacagagagacagacacagagagagagagagaganananananaoaoaoanababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacafacacacacacacacacacacacaiacacacacacacacacaiaiaiacacaiaiacacacaiacacacacakacacacacadacacacacacacacacacacacacacacacacacadacacagagagacacacagagagamagagagagagagagagagagacanaoaoaoanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacaiacacacacacacacacacacacacacacacaiaiaiaiaiaiaiaiacacacacacaiacacacaiacacacaiacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacagacacacacacacacagagacagagagagagagagagagacanananananabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababaaaaaaababacacacaiaiaiaiaiaiaiaiaiaiacacacacacaiaiacacacacacacaiaiaiacacacaiaiacacaiacacacaiaiacacacacacacacacacacacaeacacafacacajacacacacacacacacacacacacacafacacacagagagacagagagacagagagagagagagacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababaaaaabacacacacacacadacacacacacacaiaiaiaiaiacaiacacacacacacacacacaiacafacadaiacacaiacacacacaiacacacacalacajacafacacacacacacacacacacacafacacacacaCacacacacacacacagagagagacagagagacagagagagagagacagadacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacababababaiaiaiacacacacacacacacacacacacacacaiaiaiacaiaiaiaiacacacacaiacacacacacacacaiadacacacaiaiacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacagagacaBacagagagagagagagagacamagacagagacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacacacaiaiaiaiaiaiaiaiaiacacacacacacadaiaiacaiacacaiacacacacaiaiaiaiaiaiaiaiaiaiacacacacaiacacacacacacacacacacacacacacacacacacacacacacacacacacakacacagagagacacacagagacagagacacagagacagagacacagacafacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacafacacacacacacacacacadaiaiaiaiaiaiacacacacacaiafacaiadacacacemacacacacacacacacaiaiacacacaiaiacacacacacacacacacacacacacacajacacacacacacadacacacacacacagacacacacagagacacagacacagacamagagagacacagacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacaiacacacacaiaiaiaiaiacacacacacacacacacaiaiacacafacaiacacaiaiaiacacacacacacacacacacacacaiaiacacacaiacacacacacacacakacajacacacacacacakacafacacacacacacacacagagacacafagagacacagagacacagagagagacagadacagagacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacaiaiaiadaiaiacacacaiaiaiacacacacacacacacaiaiacacacaiacacacacaiaiacacacaiaiaiaiaiaiacacadaiacacacaiacacacacacacacacacacacacadacacacacacacacacacacacacacacacacacacacacacacagagacacagagamacagacagacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacaiaiaiaiacafacacacaiacacaiaiaiaiacacacaiacacacaiacacacacacaiaiacacaiacacacacaiafacacaiacafacaiaiacacacacacacafacacacacacacacacacacacacacacacacacacacacacacacacacacacagacacacacacagacagacagacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacaiaiaiacacacaiaiacacacacaiaiaiacaiacacacaiaiaiacacacacaiacafaiacacacacaiaiacacaiaiacacacaiaiacacacacacacacacacacacacacacacacajacacacacacacacacacacacacacacacacacafacacacacagacagacagagacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacaiaiaiacacaiaiacacacacacaiacaiaiacacacacaiaiaiacacaiacaiaiacacacacacaiacacacaiaiacacacaiacacacacacacacacacacacacacacacacacacacacacacacacacalacacacacacacacacacacacacacagacagacacagacacacalacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacafacacacadaiacacacaiaiaiacacafaiacacaiadacacacacacaiacacaiaiaiacacaiaiacacaiacacacacaiacacacaiacacacacacacacacalacacacacacacacacacacacafacacacacacacacacadacacacacacacacacagagacagafacagacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacaiaiacacaiacacaiaiaiaiacacacaiacacaiacacacacaiadacacaiacacacacaiacacacaiacacacacacacacacacacacacafacacacacacacacacacacacacacacacacacacacacacacacacacagacagagacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaiaiaiaiaiacacaiaiaiaiacacacaiaiaiaiacacacacacacacacacaiacacaiacacacacaiacacacaiacacacacaiacacacaiacacacacacacacacacacacacacacacacacacacacacacacacacacacakacacacacacacacacacacagacacacacacacacacacacacacababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacaiaiaiaiacacaiaiacacacacaiaiaiacacafacacacacacaiacacadacacacacaiacacaiaiacacacaiaiacacacaiacacacadacacacacadacacacacadacacacacadacacacacadacacacacacacacacakacacacacacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacaiaiacacacacacaiaiacacaiaiaiacacaiacacacacaiaiaiaiacacaiacacacacaiadacacaiaiaiaiacaDaEaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaEaDaDaDacacacacacacacacacacacafacaeacacacacacacacacacafacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacaiaiaiaiaiacaiaiacacacaiafacacacacacaiaiaiaiacaiaiaiaiacacacacaiafacacacaiaiacacacacaiacacacaiacacaFacaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDacacacacacacacacacacacacacacacacacacacadacacacacacacacacabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababacacacacacaiacacaiacacacaiaiacacacacacaiacacacacacacacaiaiacacacaiacacacaiaiacacacacaiaiacacacaiacacaFacaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDacacacacacacacacacafacacacacacacalacacacacakacacafacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacababaiaiaiacacaiacacaiaiacacadaiaiacacacacaiacacacacacacacacaiaiacacaiacacacaiadacacaiaiaiafacacaiaiacacaiacaDaDaDaDaDaDaDaEaDaDaDaDaDaDaDaDaDaDaDaDaDacacacalacacacacacacacacacacacacacacacacacacacacacacacadacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacaiacacaiacafacacacaiacacafaiacacacacaiaiacacaiaiacacacacacacacacacaiacacaiaiacacaiaiafacaiacacacacacaiadacacaiacadacacacacadacacacacadacacacacadacacacacadacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacaiaiaiacacacacacadacaiacacacaiaiacacacacacacacaiacacacacaiaiacacacaiaiacacacaiacacaiaiacacaiacacacaiaiaiacacacaiacacacacacacacacacacajacacacacacacacacacacacacababababacacacacacacadacacakacacakacacacacacacacaeacacacacacababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacaiaiaiaiaiaiaiaiaiaiaiacacacaiaiaiaiaiaiacaiaiacacacaiaiacacacacaiacacacacaiaiacaiacacacaiacacacacacacacacacaiacacacacacacacacacacacacacacacacacacacacacacababaaaaababababacacacacacacacacacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacaiaiacacacacacacaiadacacacacacacacaiaiaiacacacacaiadacacacaiaiacacacacaiaiacacacacacaiacacacacacafacacacahacacacacacacacacacacacacacacacacacacacacacababaaaaaaaaaaaaabababacacacacacacacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababacaiacafaiacadacacaiacacacacacacacacacacaiacacacaiaiacafacaiaiacacacacacaiacacacacacababababababababacacacahacacacacacacacacacacacacacacacacacacacacababaaaaaaaaaaaaaaaaaaababacacacacacacacacacadacacakacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacaiacaiaiacacacacaiaiaiaiaiaiaiaiacacacaiacacacaiacacacacaiacacacacacacaiacacacacababaaaaaaaaaaaaababababababababababacacacacalacacacacacacacacacababaaaaaaaaaaaaaaaaaaaaaaababacacacacakacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacaiacaiacacacaiaiaiacacacacacacaiacacacaiacacadaiaiaiaiaiaiacacacacacacaiabababababaaaaaGaGaGaGaaaaaaaaaaaHaaaaaaaaababacacacacacacacacacacacacababaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacacacacacacacacacacacacababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacaiacaiacacacacacacacacacafacacaiacacacacacacacacacacacacacacacacacacabababaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaIaGaGaGaaaaabababacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacaiacacacacacacacacacacacacaiacacacacacacacacacacacacacacafacacababaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaIaGaGaGaGaGaaaaababababacacacacacacababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHaHaHaHaHaHaHaHaHaHaHaHaHaHaHaHaHaHaHaHaHaHaHaHaHaHaHabaiaiaiaiaiaiaiaiaiaiaiaiaiaJaJaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiababaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaIaGaGaGaGaGaGaaaaaaaaabababababacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaIaGaGaGaGaGaGaGaGaGaaaaaaaaaaababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababacacacacacadacacadacacadacacadacacadacacadacacadacacadacacabaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaIaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaaaaaaaaaaaaaaaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababacacacacacacacacacacaKacafacacacacacacacacacacacababaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaIaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaaaaaaaaaaaaaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababacacacacacacacacacacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaIaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaGaaaaaaaaaaaaaaaaaaaaaGaGaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacacacacacacacacacacacacacacacacacacabacacacaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaIaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaGaGaaaaaaaaaGaGaGaGaaaaaGaGaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababacacacacacacacacacacacacacacacacacacacababaaaaacaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaIaLaLaLaMaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaNaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababaFaFababababababacaaaaacacaaaaaaaaaGaGaGaGaGaGaGaGaNaLaOaPaQaQaRaPaPaOaLaNaNaGaLaPaPaLaLaLaNaGaLaLaLaIaIaIaLaLaLaLaGaGaGaGaGaGaGaGaGaGaLaLaLaLaLaLaNaNaLaLaLaNaNaNaNaNaLaLaLaLaLaNaLaLaLaLaNaNaNaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaacaaacaaacaaaaabaSacabaaaaacacaaacaaaaaaaaaaaaaaaGaGaGaGaGaGaGaNaLaLaLaTaTaTaTaTaTaTaTaOaOaOaPaOaTaTaTaRaLaLaLaLaTaLaLaTaLaLaTaTaLaLaLaLaLaLaLaLaLaLaLaLaTaLaLaTaLaLaLaLaTaLaNaLaLaLaLaLaTaTaTaLaLaLaTaTaLaNaNaNaNaNaGaGaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaacacacacacaaaaabaUacabaaaaacacaaacacaaaaaaaaaaaaaGaGaGaGaGaGaGaLaLaRaQaQaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaTaTaLaTaTaLaTaTaTaTaTaTaLaTaTaTaLaLaLaTaTaTaTaTaTaTaTaTaTaTaTaLaLaLaLaLaLaNaGaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacaaaaacacacacaaaaabacacabaaacacacaaaaacacaaaaaaaaaGaGaGaGaGaGaGaGaLaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaNaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacaaaaacacacaaaaabacacabaaacaaacaaaaaaacacacaGaGaGaGaGaGaGaVaVaWaXaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaLaLaLaLaIaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaacacacacacacacaaaaaaaaaaaaaaaaaaaGaGaGaGaGaWaWaWaWaWaWaWaTaTaTaTaTaTaTaTaTaYaTaTaTaTaTaTaTaTaTaTaTaTaTaTaZaTaTaYaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbaaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaLaTaTaTaIaNaGaGaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacaaaaaaaaaaaaaaaaaaaaaGaGaGaGaWbbbcbcbcbcbdaTaTaTaTaTaZaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaZaTaTaTaTaTaTaTaTaTaTaTaTaTaTaYaTaTaTaTaTaTaTaTaTaTaTaZaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacaaaaaaaaaaaaaaaaaaaaaaaGaGaGaWbcbcbcbcbcbdaTaTaTaTaTaTaTbeaTaTaTaTaTaTaTaTaTaTaTbfaTaTaTaTaTaTaTaTaTaTaTaTaZaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaLaNaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacaaaaaaaaaaaaaaaaaaaaaaaGaGbgaWbcbcbcbcaWaWaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaYaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbfaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaNaNaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacaaaaaaaaaaaaaaaaaaaaaGaGaGbgbcbhbcbcbcaWaLaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbiaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaNaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacaaaaaaaaaaaaaaaaaaaaaGaGaWaWbcbcbcbcbcaWaLaTaTaTaTaTbjbjbjbjbjbjbjbjbjbjbkbjbjbjbjbjbjbjbjbjbjbjblbjbjbjbjbjbjbjbjbjbjbjbjbjbkbjbjbjbjbjbjbjbjbjbjbjbjbmbmbjbjbjbjbjbjbjbjbjbjaTbfaTaTaTaTaTaTaTaTaTaTaTaLaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaGaGaGaWbhbcbcbnbcboaWaLaTaTaTaTaTblbjbjbjbjbjbjbjbjbjbkbmbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbmbjbjbjbjbjbjbjbjbjbjbjbjbjbjbpbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjaTaTaYaTaTaTaTaTaTaTaTaTaLaLaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaWbcbcbcbcbcbcaWaLaTaTaZaTaTbjbjbjbpbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbmbjaTaTaTaTaTaTaZaTaTaTaTaTaLaLaLaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaWbcbcbqbcbcbhaWaLaTaTaTaTaTbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbmbjbjbjbjbjbjbkbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbrbrbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaWaWbcbcbcbhbcbcaWaLaTaTaTaTaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbsbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbraaaaaaaabrbrbrbrbrbrbrbrbrbraabraabrbrbrbraaaaaabrbrbrbrbrbrbrbrbrbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaWbtbcbcbcbcbcbcaWaLaTaTaTaTaTbmbjbjbjaTbububububububububububububububuaTbjbjbjbjaTbubububububububububububububububububububububububububububububuaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaLaLaGaGaGaGaGaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbvbwbwbwbwbwbwbvbvbvbvbvbwbwbvbvbvbwbvbvbvbvbwbwbwbwbwbvbvbvbvbvaabraabrbraaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaWbcbcbcbcbcbcbcaWaLaTaTaTaTaTbjbjbjbjaTbubxbybybzbybybybubAbBbCbBbDbuaTbjbjbEbjaTbubFbFbFbFbFbFbFbDbDbDbGbDbHbIbDbDbjbjbjbjbjbybybJbKbLbMbNbuaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaLaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbObPbQbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbSbPbTaaaaaabrbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaWbcbcbcbhbcbcbcaWaLaTaTaTaTaTbjbjbjbjaTbubybUbMbMbMbVbybubjbjbjbjbjbuaTbjbjbjbjaTbubFbFbFbFbFbFbFbjbjbjbjbjbjbjbjbjbjbjbjbjbjbybybybybybybybuaTbjbjbjbjaTaZaTaTaTaTaTaTaTaTaTaTaTaLaLaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbWbXbYbYbYbYbYbYbYbYbYbZbYbYbYbYbYbYbYbYbYbYbZbYbYbYbYbYbYbYbYbYcabTaaaaaaaabrbraaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaWbhbcbcbcbcbhbcaWaLaTaYaTaTbfbjbjbjbjaTbubybybMbMbMbybybubjbjbjbjbjbuaTbjbmbjbjaTbubFbFbFbFbFbFbFbDbDbDbDbDbDbDbCbDcbbDbDbDbDbybybybycdbybybuaTbjbjbjbjaTaTaTaTaTaTaTaZaTaTaTaTaTaTaLaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbWcebYbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbYcfbTaaaaaaaaaabrbraaaaaaaaaaaaaaaaaaaaaaaGaGaGaWbcbcbcbcbcbcbcaWaLaTaTaTaTaTbjbjbmbjaTbubybUcgchbMbVbybububububucibuaTbjbpbjbjaTbubFcjbFbFckcjbFbDclclclclclclclclbjbjbjbjbDbybybybybybybybuaTbjbjbEbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaNaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbWcebYbPcmcmcmcmcmcmbPcncocncococncococncncncncobPcpcqcrcqcsbPbYcfctaaaaaaaaaaaabrcubraaaaaaaaaaaaaaaaaaaGaGaGaWbcbcbcbcbcbcboaWaLaTaTaTaTaTbkbjbjbjaTbubybybybybybybycibjbjbjbjbjbuaTbjbjbjbjaTbubFbFbFcvbFbFbFbDbjbjbjbjbjbjbjbjbjbjbjbjbDbybybybybybybybuaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaLaLaTaLaIaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbWcebYbPcncncncocncnbPcncwcwcwcwcxcwcxcncycycocnbPczczczczczbPbZcfctaaaaaaaaaabrbrbrbrbrbraaaaaaaaaaaaaaaGaGaGaWbcbobcbobcbcbcaWaLaTaTaTaTaTbjbjbjbjaTbubububububububububjbjbjbjbjbuaTbjcAbjbjaTbubFbFbFbFbFbFbFbDbjbjbjbjbjbjbjbjbjbjbjbjbDbybybybybybybybuaTbjbjbjbjaTaTcBaTaTaTaTaTaTaTaTaLaLaLaLaIaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbOcebYbPcCcDcncncncnbPcncxcwcwcwcwcwcwcEcFcFcncnbPczczcGcHczbPbYcfctbrbraabrbrbraaaaaabrbrbrbraaaaaaaaaGaGaGaGaWbcbcbcbcbcbcbcaWaLaTaTaTaTaTbjbjbjbjaTbucIbjbjbjbjbjbjbjbjbjbjbjbjbuaTbjbjbjbjaTbubDbDbDbDbDbDbDbDbjbjbjcAbjbjbjbjbjbjbjbjbDbDbDcJcKbDbDbDbuaTbmbjbpbjaTaTaTaTaTaTaTaTaTaTaTaTaLaLaLaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraabWcebYbPcLcMcncncNcncOcncwcwcwcwcPcwcwcEcFcFcncnbPczczczczczbPbZcfbTaacubrbraaaaaaaaaaaaaaaabrbrbraaaaaGaGaGaGaWbhbcbcbcbcbcbcaWaLaTaTaTaTaTbjbkbjbjaTbucIbjbjbububjbjbububjbjbububuaTbjbjbjbjaTbubjclclclclclclbjbjbjbjbjbjbjbjbjbjbjbjbjbjclclclclclclbjbuaTbjbjbjbjaTaTaTaTaTaTaTaTaYaTaTaTaTaTaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraabWcQbYbPcCcDcncncncnbPcncwcwcwcwcwcwcwcRcFcFcncncOczczczczczbPbYcSbTaabraaaaaaaaaaaaaaaaaaaaaaaabraaaGaGaGaGaGaWbcbhbccTbcbcbcaWaLaTbaaTaTaZbjbjbjbjaTbucIbEbjcIbubjbjbubjbjbjbjbjbuaTbjbjbjbjaTbubjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbuaTbjbjbjbjaTaTaTaZaTaTaTaTaTaTaTaTaTaTaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraabObPbYbPcncncncncncnbPcncwcwcUcwcwcwcwcRcFcFcncnbPczcVcWcXczbPbYbPbTaabraaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaWbcbcbcbcbcbcbcaWaLaTaTaTaTaTbjbjbjbjaTbucIbjbjcIbubjbjbucYbjbjbjcZbuaTbjbjbjbmaTbudabDdbbjdabDdbbjdabDdbbjdabDdbbjdabDdbbjdabDdbbjdabDdbbjbuaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacubrbOdcbYbPcncncNcncocnbPcncwcwcwcwcwcwcwcRcFcFcncnbPcGdddedfczbPbYdgbTaabrbraaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaWbcbcbcbcbhbcbcaWaLaTaTaTaTaTbjbjbmbjaTbucIbjbjcIbubjbjbucYbjbjbjcZbuaTbmbjbjbjaTbubjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbuaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbraabWcebYbPcncncncncncobPcncxcwdhcwcwcwcwcncncncncnbPczczczczczbPbYcfbTbrbrbrbraaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaWaWbcbcbcbcbcbcdiaWaLaTaTaTaTaTbjbjbjbjaTbubububububucicibubudjdjbububuaTbjbjblbjaTbubububudjdjdjbubububuccdlbudmdnbububububububudjdjdjbubububuaTcAbjbmbjaTaTaTbaaTaTaTaTaTaTaTaTaTaLaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaadocebYbPcndpcocncncnbPcncncncncncncncNcncncncncnbPdqdqdrdsdsbPbYcfctbraaaabrbrbrbraaaaaaaGaGaGaGaGaGaGaGaGaWaWbhbobcbcbcbobcbcaWaLaTaTaTaTaTbjbjbjbjaTaTaTaTaTaTaTdtaTaTaTaTaTaTaTaTaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaZdtaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaadocebYbPbPbPbPbPbPbPbPbPbPbPcOcObPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbYcfctaaaaaaaaaaaabrbrbraGaGaGaGaGaGaGaGaGaGaWbbbcbcbcbcbcbcbcbhaWaLaTaTaTaTaTbjbjbkbjbjbjbjbjbjbjbjdubmbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjdvbjbjbjbjbjdubjbjbjbmbjbjbjbjbjbjbjbjbjbjbjblbjbjbjaTaTaTaTdwaTaTaTaTaTaTaTaTaLaLaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaadocebYbYbYbYbYbYbYdxbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYdxcfctbraaaaaaaaaaaaaaaGaGaGaWaWaWaWaWaWaWaWaWbcbcbcbcbcbhbcaWaWaWaLaTaTaTaTaTbjbjdybjbjbjbjbjbjbjbjdubjbjbjbjbjbjbjbjbjbjbjbjcAbjbjbjbjbjbjbjbjbjbjbjbkbjbjbjbjdubjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjaTaTaTaTaTaTaTaZaTaTaTaTaTaLaLaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaadocebYdxbYbYbYbYbYbYbYbYbYbYbYdzbYbYbYbYbYbYdxbYbYbYdAbYbYbYbYbYcfbTbraaaaaaaaaaaaaaaGaGaGaWbbbcbobcbcbhbcbcbcbcbcbcbcbobcaWaNaLaLaTaTaTaTaTbkbjbjbjbjbjbjbjbjbjbjbjbjbjbjbkbjbjbjbjbjbjbjbjbjbjbjbjbjbmbjbjbjbjbjbjbjbjbjbjbjdubjbjbjbjblbjbjcAbjbmbjbjbjbjbjbjbjbmbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaLaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaadocebYbYbYbPbPbPbYbYbYbYbYbYbYbZbYbYbYbYbYbYdzbYdAbYbYbYbYbZbYbYcfbTbraaaaaaaaaaaaaGaGaGaGaWbcbcbcbcbcbcbcbcbobcbcbhbcaWaWaWaLaLaTaTaYaTaTaTbsbjbjbjbjbjbjbpbjbjbjbjbjbjbjdubjbmbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjdubjbjbjbjbjbjbjbjbjbjbjbjbjbjbpbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaLaLaGaGaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaadocebYbYbYbPdBbPbYbYbYdAbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYdCbYbYbYcfbTbrbraaaaaaaaaaaGaGaGaGaWbcbhbcbcbcbnbcbcbcbcbcbcaWaWaNaNaLaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTdtaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbjbjdybjbububububububububububububububububububububububudjdjbububububuaLaLaNaGaGaGaGaaaaaaaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbraadocedAbYbYbPdDbPbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYdxbYbYdAbYbYbZbYcfbTbrbrbraaaaaGaGaGaGaGaGaWbcbcbcbcbcbcbcbcbcbhbcbcaWaNaNaLaLaTaTaTaTaTaTaTaYaTaTaTaTaTaTbubububububububucibububububububuaTaTbububububububububububububuaTblbjbjbjbubjbjbjbjbjbjbjbkbjbjbudEdEdEdEdEbjdEbubjbjbjbjbjbjbjbjbjbuaNaNaNaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrdocQbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYdFbYbYbYbYbYbYbYbYbYbYbYbYcSbTbraabrbrbraGaGaGaGaGaGaWbobcbcbcbhbcbcbcbcaWaWaWaWaNaNaLaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbubybybybybybybubjbudGbybybybybuaTaTbubjdHbjdHbjdHbjdHbjdHbjbuaTbjbjbjbjbubjbFdIbFdJdKbFbFbFbjdLbjbjbjbjbjbjbjbudMcAbjbjblbjbjdPbjdQaNaNaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrdobPdRdSdSdSdSdSdSdSdSdSdSdTdUdUdRdSdSdSdSdSdSdSdSdSdSdSdSdSdSdTbPbTbraaaabraGaGaGaGaGaGaGaWbcbcbcbcbcbcbobcbcaWaNaNaNaLaLaLaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbudVbybybybydWbubjbudGbybybybybuaTaTbubjbjbjbjbjbjbjbjbjbjbjbuaTbmbjbjbjbubjbFdXdYdZeaebecbFbjbubjbjbjbjdPbjbjbubDbjbjbjbjbjbjbjbjbuaNaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbraaedededededededededededeeefegeheiededededededeeededededededeeededbrcuaaaabrbrbraGaGaGaGaGaWbdbdaWaWaWaWbcboaWaWaNaNaLaLaTaTaTaTaZaTaTaTaTaTejaTaTaZaTaTaTbudVbzekbybydWbubjbuelbyekbybybuaTaTbubjdHbjdHbjdHbjdHbjdHbjbuaTbjbjbjbjbubjbFdkdZeoeodZdNdIbjbudEeqbjbjbjbjbjbudMbjbjbjbjcAbjbjbjdQaNaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbraaaaaaaaaaaaaaaaaabrbrbrbrdoeresbTaaaaaaaaaaaabrbrbrbrbrbrbrbrbrbrbrbrbraaaaaacuaGaGeteteteteueuetetetaWaWaWaWaNaNaNaLaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbudVbybyevbydWbubjbudGbybybzbybuaTaTbubjbjbkbjbjbjbjbjbjbjbjbuaTbjbjbjbjbubjbFdXebeoeoebecewbjbudEdEbjbjbjcAbjdLbjbjbjdPbjbjbjbjbjbuaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbraaaaaaaaaaaabrbraaaaaadoexeybTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbrbrbretetetezeAeBeueueueuetetetetaNaNaLaLaLaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbudVbybybybydWbubjbudGbybybybybuaTaTbubjbjbjbjbjbEbjbjbjbjbjciaTbjbjbpbjbubjbFdkeaeoeoeadNbFbjbubububububububububjeCeCeCeCbjbjbjbjdQaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbrbrbrbrbrbraaaaaaaadoegeDbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeteueueueueueueueueueueueuetaNaNaLaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaZaTaTaTaTbubububybybububucibububybybububuaYaTbubjeEbjdHbjdHbjeFbjdHbjbuaTbjbjbjbjbudPbFdXdZeoeoeGeHbFbjbubAbAbAbAbAbAbAbubjdMbDbDdMbjbjbjbjbuaNaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadoereIbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeJeueueueueueueueueueueueuetaNaNaLaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbubjbjbjbjbjbjbjbjbjbjbjbjbjbjbudtaTbubjbjbjbjbjbjbjbjbjbjbjbueKbjdybjbjbubjbFdkebdZdYeadNeLbjbubjbjbjbjbjbjbjbubububububueMbubububuaNaNaNaGaGaGaGaaaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadoeNehbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeOePeQeReueueueueueueueueueueueuetaNaNaLaLaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbubjbjeSbjbububububububjbjbjbjbudtaYbubjdHbjeFbjdHbjdHbjdHbjbuaTeTbjbjbjbubjbFbFbFdOeVeWbFbFbjdLbjcAbjbjblbjbjdLeXeXeYeZfafafbfbeXbuaNaNaNaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadoegfcbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafdeueufdeueueueueueueueueueueueuetaNaNaNaLaTaTaTaTaZaTaTaTaTaTaTaNaNaTaTaTaTaTaTbubjbjbjbjbjfefefefebjbjbjbjbjbudtaTbubjbjbjbjbjbjbjbjbjbjbjbuaTbjffffbjbubjbjbjbjbjbjbjbjbjbjbubjbjbjbjbjbjbjbueXeXeXfgfhfieXeXeXbuaNaNaNaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadoexehbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeOePePfjeueueueueueueueueueueueuetaNaNaNaLaTaTaTaTaTaTaTaTaTaTaTaNaNaNaTaTaTaTaTbubjbjbjbjdybkbjbjbjbjbjbjbjbjbudtfkbubjbjbjbjbjbjbjbjbjbjbjbuaTbjbjbjflbubububububububububububububububububububueXeXfneXeXfieXeXeXbuaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadoegesbTaaaaaaaaaaaaaaaaaaaaaabrbraaaaaaaaaaaaaaaaaaaafoeueueueueueueueueueueueuetaNaNaNaLaTaTaTaTaTaTaTaTbfaTaTaTaNaNaNaTaTaTaTbufpbufpbufpbufpbubufpbufpbufpbufraZfsbububueMbubububububububufrbjbjcAbjftfubjbjbDbjbjbubjbjbjbjbjbubjbjbjbjbjbufvfwfxeXfvfwfxeXeXbuaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvbvbvbvbvbvbvbvbvbvbvbvbvbvfydUdUfzbvbvbvbvbvbvaaaaaaaaaabraaaaaaaaaaaaaaaaaaaaaafAeueueueueueueueueueueueuetaNaNaLaLaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaNaTaTaTbububububububububububufsbubububuaTaTfBaTaYaTaTaTaTfCfDaYaTaTaTaTbjbjbjbjbufubjbjbDfEbjbubjfFbDfEbjbubjfGbDfHbjbueXeXeXfIeXeXeXfIeXbuaNaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfJfKfKfKfKfKfKfKfKfKfKfKfKfKfKfLfLfKfKfKfKfKfKfMfNbrbrbrbrbraaaaaaaaaaaaaaaaaaaaaaeteueueueueueufOeueueueueuetaNaLaLaRaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTfPaYfQfsbububububueMbubububububuaTblbjbjfRcibjbjbjbDbjbjbubjbjfSbjbEbublbjbDbjbjbudjdjdjbudLbueXfTeXbuaNaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfVfVfVfVfVfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfWfNbrbrbrbraaaaaaaaaaaaaaaaaaaaaaaafXeueueueueueueueueueueueuetaNaLaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaTaTaTaTaTaTbubububububububububububufsdtbufYbjbjbjbjbjbjbjbjbjbjbuaTbjfZbjbjcibjbjbjbDfEbjbubjfFbDfEblbubjfGbDfHbjbubjbjbjbjbjdjeXfweXbuaNaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLgagagbgcgdgdbrbrbraaaaaaaaaaaaaaaaaaaaaafoeueueueueueugeeueueueueuetaNaLaTaTaTaTaTaTaTaTaTaTaRaTaNaNaNaNaNaNaNaTaTaTaTaTaTbugfbjbjbjbjbjbjbjbjbjbjbudteMbjbjbjbjdycAbjbjbjbjbjdmaTbjblbjbjbufublbjbDbjbjbubjbjbDbjbjbubjcAggbjbjbububububjbjdjeXgheXbuaNaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfVfVfVfVfVfLfLfLfLfLfLfLfLfLfLfLfLfLfLgifLgigdgdgdbrbraaaaaaaaaaaaaaaaaaaaaaaafAeueueueueueueueueueueueuetaNaLaTaTaTaTaTaTaNaNaNaNaNaNaNaNaNaNaNaNaNaTaTaTaTaTaTbubjbjbjbjblbjgjbjbldPbjbufCbubjbjdPbjbjbjbjbjbjcAbjbuaTbjgkbjbjbufubjbjbDbjbjbubjfFbDfEbjbubjfGbDfHbjbuglgmbudPbjdjeXeXeXbuaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfLgnfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfKfKgogcgdbrbraaaaaaaaaaaaaaaaaaaaaaaaaaeteueueueueueueueueueueueuetaLaLaTaTaTaTaLaLaLaLaLaLaLaLaLaLaLaLaLgpaLaLaTaTaTaTaTbubjbjbjbjbjgkgqdybjgrbjciaTbubjbjbjbjbjbjbjbjbjbjbjbudwbjbjbjbjeMgsbjbjbDfEbjbubjbjbjbjbjbubjbjbjbjbjbugtbjcibjbjdjeXgueXbuaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfVfVfVfVfVfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfWfNbrbraaaaaaaaaaaaaaaaaaaaaaaaaaaafXeueueueueueueueueueueueuetaLaRaTaTaLaLaLaLaTaTaTaTaTaTaTaTdwaTaTaTaLaLaLaTaTaTaTbubjdybjbjbjbjbjbjgvbjbjeMaTbubjbjbjbjgwbjdybjbjdPbjeMaTbjbjbjbjbufubjbjbDbjbjbububucibueMbububucibubububueMbubjbjdjeXfweXbuaNaNaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfWbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafoeueueueueueueueueueueueuetaLaLaLaLaLaLaTaTaTaTaTaTgxaTaTaTaTaTaTejaTaLaLaLaTaTaTbubjbjblbjbpbjbjdybjbjbjbuaYbubjbjcAbjbjbjbkbjbjbjbjbuaTaTaTaTaTbubjbjcAbDbDbjbubjbjblbjbjcAbjbjbjbjbjbjbjbjbjblbjbueXgheXbuaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aHaHaHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfVfVfVfVfVfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfWbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafAeueueueueueueueueueueueuetaGaNaNaLaLaTaTaTaTaTaLaLaLgpaTaTaTaTaTaTaTaTaTaLaLaTaTbubjbjbjbjbjbjbjbjdPbjbjbuaTbubjbjbjbjbjbjbjbjbjbjbjfsaTaZaTaTaTbubjbjbjbjbjcAcibjbjbjbjdPbjbjbjbjbjbjgkcAbjbjbjbjbueXeXeXbuaNaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfLfLfLfLfLfLfLfLfLfLfLgyfLfLfLfLfLfLfLfLfLfWbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaetgzePfjfdgAgBeJgzePgCetetetaGaNaNaLaTaTaTaTaTaTaLaLaLaLaLaLaLaTaTaTejaTaTaTaLaLaLbububububufsenbubububububuaTbubububueMdjdjbubububububuaTaTaTaTaTbubububububububububububububububububububububububububububububuaNaNaNaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfVfVfVfVfVfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfWbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafoeufoaaaaaaaaaaaGaGaGaGaNaLaLaTaTaTaTaTaTaTaTaTaTaLaLaLaLaLaLaTaTaTaTaTgpaLaLaTaTaTaTaTaTfsbubuaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTfraTaTaTaTaTaLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfLfLfLfLfLfLgnfLfLfLfLfLfLfLfLfLfLfLfLfLfLfWbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafoeufoaaaaaaaaaGaGaGaGaGaNaLaTaTaTaTaTaTaTaTaTaTaTaTaTaTgpaLaLaLaTaTaTejaTaTaLaTaTejaTaLaLaLaLaLaLaLaLaTaTaLaLaLaLaLaTaTaLaLaTaTaLaTaTaTaTaLaLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWgDgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgFbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagGfdgGaaaaaaaaaGaGaGaGaNaNaLaLaLaLaLaLaTaTaTaTaTaTaTaTaTaTaLaLaLaLaLaTaTaTaTgHaTaYaTaTgpaNaNaNaNaNaNaLaLaLaLaNaNaNaLaLaLaLaLaLaLaLaTaLaLaLaLaLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaededededededededededededededededededededededededaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagIgJgKgLgMgJgNaaaaaaaGaGaGaNaNaNaLaLaLaLaLaLgpaLaLaTaTaTaTaTaTaTaTaLaLaLaLaTaTaYejaTaTaTaTaLaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaNaNaNaNaLaLaLaGaGaGaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagOgPgPgQgPgPgOaaaaaaaGaGaGaNaNaLaLaTaTaTaTaLaLaNaLaLaTaTaTaTaTaTaTaTaLaNaLaLaTaTaTejaTgHaLaLaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaGaGaGaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagOgPgPgQgPgPgOaaaaaaaaaGaGaGaLaLaTaTaTaTaTaTaLaLaNaLaLaLaTaTaTaTaTaTaLaLaLaLaLaTaYaTaTaLaGaaaaaaaaaGaGaGaGaGaaaGaaaaaaaGaGaGaGaaaGaGaGaGaGaGaGaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaGaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagOgPgPgQgPgPgOaaaaaaaaaGaGaGaLaTaTaTaTaTaTaTaTaLaLaLaNaLaLaTaTaTaTaTaTaTaTaLaLaLgHaTaTaLaGaaaaaaaaaaaGaGaGaaaaaaaaaaaaaaaGaGaaaaaaaGaGaGaaaaaaaaaaaaaGaGaGaGaGaaaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaaaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagRgSgQgQgQgTgUaaaaaaaGaGaGaLaLaTaTaTaTaTaTaTaTaTaTaLaLaLaLaLaTaTaTaTaTaTaTaTaTaLaLaTaTaLaGaaaaaaaaaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagOgQgQgQgOaaaaaaaaaGaGaGaLaTaTaTaTaTaTaTaTaTaTaTaLgpaTaTaLaLaLaLaLaLgpaLaTaTaLaLaLaLaLaGaaaaaaaaaaaaaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagOgQgPgQgOaaaaaaaaaGaGaGaLaTaTaTaTaTaTaTgVgVaTaTaTaLaTaTaTaLaLaLaLaLaLaLaLaTaTaLaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagOgWgWgWgOaaaaaaaaaGaGaGaLaTaLaLaTaTaTaTgVgVaTaTaTaTaTaTaTaTaTaTaTaTaTaLaLaTaTgpaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagRgJgXgJgUaaaaaaaaaGaGaGaLaLaLaTaTaTaTaTgVgVaTaTaTaTaTgYaTaTaTaTaTaTaTaTaTaTaTaTaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaNaNaNaLaLaLaLaLaLaLaLaLaLgpaLaLaLaTaTaTaTaTaTaTaTaTaTaTaTaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaNaNaNaNaNaGaGaGaGaGaLaLaLaLaLgpaLaLaLaLaLaLaLaLaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababaaaaaaaaaaaaaaabahahahacacacacacacacajafacacacacacacacacacacacacacacacacacacacajafacacacacagagacacacacacacacacacacacacacababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacacacacacababaaaaaaaaaaababahacahahacacacacacacacacacacacacacacacacafacacacaeacacacacacacacacacacacacacagagagacacacacacacacacacacacacacacacacacacacacababababababaaaaaaaaaaaaaaaaaaabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababahahacacacahahahacahacahabababababababacacacacahahacacacacacacacacacakacacacacacacacacacacacacacalacacacacacacacacacalacagagagagamacacacacacajacacacacacacacacacacacacacababababababaaaaaaababababaoaoapabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacahahahacacacahahahacahacacacacacacacacacacacacahahacacacacacacacacacacacacacacacacacacacacacacacacacacacagacacacacacacacacacacagagagagacacacagacacagacacacagadacacacacababababababababababaqaoaoaoaoaoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacahahahahahafacadahacahahacacacacacacafacadacacacahahahahacacadacacacacacacalacacacacacacacacacacacacacacagagacacacacacagagagagagagacacagagagagagagagagacacagagacacacacabarasatabababababaoaoaoaoaoaoaqabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacahacacahahahacacacacacacahahahacacacacahahacacacacacacaeacacacacacacacacakacacafacacacacacagacamagagagacacacacacagagagagagagagagagagagagacajagabababababauavawaoaoaoabaoaoaoaoaoaoaoababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacahahacacacacacacacacahacacacacahahahahacacacahahahahacacacacahacacacacafacacacacacacadacacacacacacacacadacacacagagacacacacacagagacacadagagajagagagagagagagagagabababagagacabaxayazaoaoaoaoaAabaoaoaoaoaoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacadahahahahahahahahahahahahacacacacacahahacacacacacahacacacacahahacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacagagagagagacacacagagacacacagagabagagacagadabaoaoaoaoaoaoabaoaoaoaoaoaoaoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababacacacacacacacacacacacacacacacacahacacacacacacahahacacacacahahacacacacahacacacacacafacacacacacacacacafacacacacacacacacacacacacacacafacacacacacagagagagagagacadacacacagagagabagagagaoaoaoaoaoaoabababaqaoaoaoaoaoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababahahahacacacafacacacacacacacacacacahahacacacacacacahahahacacacahadacafacahahahacacacacajacacakacacacacacacacacacacaeacacacajacacagagagacacagagagagacafagagagagagagagagagabagagagagaBabaoaoaoaoabababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacahahahacacacacacacacahahahacacacahadacacacacacacacahahacacahahahacacacacahacacacacacacacacacacacacacakacacacacacacafacacagagacacacagagagacacalacagagagagacacagagagacabababagagacabaoaoaqababababaaaaaaaaabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacahahahahahahahahahadacacacacahahacacacacacacacacahadacacacahacacacacahacacacacacacacacacacacacacacacacacacacacacacagagacacacacacacacacagagagacagacacagagagagagagagagabababababaoaoaoabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacafacacacacacacacacacacacahacacacacacacacacahahahacacahahacacacahacacacacakacacacacadacacacacacacacacacacacacacacacacacadacacagagagacacacagagagamagagagagagagagagagagacabaoaoaoababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacahacacacacacacacacacacacacacacacahahahahahahahahacacacacacahacacacahacacacahacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacagacacacacacacacagagacagagagagagagagagagacababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababaaaaaaababacacacahahahahahahahahahahacacacacacahahacacacacacacahahahacacacahahacacahacacacahahacacacacacacacacacacacaeacacafacacajacacacacacacacacacacacacacafacacacagagagacagagagacagagagagagagagacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababaaaaabacacacacacacadacacacacacacahahahahahacahacacacacacacacacacahacafacadahacacahacacacacahacacacacalacajacafacacacacacacacacacacacafacacacacaCacacacacacacacagagagagacagagagacagagagagagagacagadacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacababababahahahacacacacacacacacacacacacacacahahahacahahahahacacacacahacacacacacacacahadacacacahahacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacagagacaBacagagagagagagagagacamagacagagacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacacacahahahahahahahahahacacacacacacadahahacahacacahacacacacahahahahahahahahahahacacacacahacacacacacacacacacacacacacacacacacacacacacacacacacacakacacagagagacacacagagacagagacacagagacagagacacagacafacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacafacacacacacacacacacadahahahahahahacacacacacahafacahadacacacahacacacacacacacacahahacacacahahacacacacacacacacacacacacacacajacacacacacacadacacacacacacagacacacacagagacacagacacagacamagagagacacagacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacahacacacacahahahahahacacacacacacacacacahahacacafacahacacahahahacacacacacacacacacacacacahahacacacahacacacacacacacakacajacacacacacacakacafacacacacacacacacagagacacafagagacacagagacacagagagagacagadacagagacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacahahahadahahacacacahahahacacacacacacacacahahacacacahacacacacahahacacacahahahahahahacacadahacacacahacacacacacacacacacacacacadacacacacacacacacacacacacacacacacacacacacacacagagacacagagamacagacagacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacahahahahacafacacacahacacahahahahacacacahacacacahacacacacacahahacacahacacacacahafacacahacafacahahacacacacacacafacacacacacacacacacacacacacacacacacacacacacacacacacacacagacacacacacagacagacagacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacahahahacacacahahacacacacahahahacahacacacahahahacacacacahacafahacacacacahahacacahahacacacahahacacacacacacacacacacacacacacacacajacacacacacacacacacacacacacacacacacafacacacacagacagacagagacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacahahahacacahahacacacacacahacahahacacacacahahahacacahacahahacacacacacahacacacahahacacacahacacacacacacacacacacacacacacacacacacacacacacacacacalacacacacacacacacacacacacacagacagacacagacacacalacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacafacacacadahacacacahahahacacafahacacahadacacacacacahacacahahahacacahahacacahacacacacahacacacahacacacacacacacacalacacacacacacacacacacacafacacacacacacacacadacacacacacacacacagagacagafacagacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacahahacacahacacahahahahacacacahacacahacacacacahadacacahacacacacahacacacahacacacacacacacacacacacacafacacacacacacacacacacacacacacacacacacacacacacacacacagacagagacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabahahahahahacacahahahahacacacahahahahacacacacacacacacacahacacahacacacacahacacacahacacacacahacacacahacacacacacacacacacacacacacacacacacacacacacacacacacacacakacacacacacacacacacacagacacacacacacacacacacacacababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacahahahahacacahahacacacacahahahacacafacacacacacahacacadacacacacahacacahahacacacahahacacacahacacacadacacacacadacacacacadacacacacadacacacacadacacacacacacacacakacacacacacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacahahacacacacacahahacacahahahacacahacacacacahahahahacacahacacacacahadacacahahahahacaDaEaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaEaDaDaDacacacacacacacacacacacafacaeacacacacacacacacacafacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacahahahahahacahahacacacahafacacacacacahahahahacahahahahacacacacahafacacacahahacacacacahacacacahacacaFacaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDacacacacacacacacacacacacacacacacacacacadacacacacacacacacabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababacacacacacahacacahacacacahahacacacacacahacacacacacacacahahacacacahacacacahahacacacacahahacacacahacacaFacaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDacacacacacacacacacafacacacacacacalacacacacakacacafacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacababahahahacacahacacahahacacadahahacacacacahacacacacacacacacahahacacahacacacahadacacahahahafacacahahacacahacaDaDaDaDaDaDaDaEaDaDaDaDaDaDaDaDaDaDaDaDaDacacacalacacacacacacacacacacacacacacacacacacacacacacacadacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacahacacahacafacacacahacacafahacacacacahahacacahahacacacacacacacacacahacacahahacacahahafacahacacacacacahadacacahacadacacacacadacacacacadacacacacadacacacacadacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacahahahacacacacacadacahacacacahahacacacacacacacahacacacacahahacacacahahacacacahacacahahacacahacacacahahahacacacahacacacacacacacacacacajacacacacacacacacacacacacababababacacacacacacadacacakacacakacacacacacacacaeacacacacacababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacahahahahahahahahahahahacacacahahahahahahacahahacacacahahacacacacahacacacacahahacahacacacahacacacacacacacacacahacacacacacacacacacacacacacacacacacacacacacacababaaaaababababacacacacacacacacacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacahaiacacacacacacahadacacacacacacacahahahacacacacahadacacacahahacacacacahahacacacacacahacacacacacafacacacahacacacacacacacacacacacacacacacacacacacacacababaaaaaaaaaaaaabababacacacacacacacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababacahacafahacadacacahacacacacacacacacacacahacacacahahacafacahahacacacacacahacacacacacababababababababacacacahacacacacacacacacacacacacacacacacacacacacababaaaaaaaaaaaaaaaaaaababacacacacacacacacacadacacakacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacahacahahacacacacahahahahahahahahacacacahacacacahacacacacahacacacacacacahacacacacababaaaaaaaaaaaaababababababababababacacacacalacacacacacacacacacababaaaaaaaaaaaaaaaaaaaaaaababacacacacakacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacahacahacacacahahahacacacacacacahacacacahacacadahahahahahahacacacacacacahabababababaaaaaGaGaGaGaaaaaaaaaaaaaaaaaaaaababacacacacacacacacacacacacababaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacacacacacacacacacacacacababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacahacahacacacacacacacacacafacacahacacacacacacacacacacacacacacacacacacabababaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaabababacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacahacacacacacacacacacacacacahacacacacacacacacacacacacacacafacacababaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaababababacacacacacacababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabahahahahahahahahahahahahahaJaJahahahahahahahahahahahahahahahahahahababaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaabababababacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababacacacacacadacacadacacadacacadacacadacacadacacadacacadacacabaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaaaaaaaaaaaaaaaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababacacacacacacacacacacaKacafacacacacacacacacacacacababaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaaaaaaaaaaaaaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababacacacacacacacacacacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaGaaaaaaaaaaaaaaaaaaaaaGaGaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacacacacacacacacacacacacacacacacacacacacacacacabanananaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaGaGaaaaaaaaaGaGaGaGaaaaaGaGaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababacacacacacacacacacacacacacacacacacacacababaaaaanaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaNaNaNaMaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaNaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababaFaFababababababanaaaaananaaaaaaaaaGaGaGaGaGaGaGaGaNaNaHaMaIaIaRaMaMaHaNaNaNaGaNaMaMaNaNaNaNaGaNaNaNaGaGaGaNaNaNaNaGaGaGaGaGaGaGaGaGaGaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanaaaaanaaanaaanaaaaabaLanabaaaaananaaanaaaaaaaaaaaaaaaGaGaGaGaGaGaGaNaNaNaNaTaTaTaTaTaTaTaTaHaHaHaMaHaTaTaTaRaNaNaNaNaTaNaNaTaNaNaTaTaNaNaNaNaNaNaNaNaNaNaNaNaTaNaNaTaNaNaNaNaTaNaNaNaNaNaNaNaTaTaTaNaNaNaTaTaNaNaNaNaNaNaGaGaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanaaaaanananananaaaaabaOanabaaaaananaaananaaaaaaaaaaaaaGaGaGaGaGaGaGaNaNaRaIaIaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaTaTaNaTaTaNaTaTaTaTaTaTaNaTaTaTaNaNaNaTaTaTaTaTaTaTaTaTaTaTaTaNaNaNaNaNaNaNaGaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaananaaaaananananaaaaabananabaaanananaaaaananaaaaaaaaaGaGaGaGaGaGaGaGaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaananaaaaanananaaaaabananabaaanaaanaaaaaaanananaGaGaGaGaGaGaGaVaVaWbuaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanaaanananananananaaaaaaaaaaaaaaaaaaaGaGaGaGaGaWaWaWaWaWaWaWaTaTaTaTaTaTaTaTaTaYaTaTaTaTaTaTaTaTaTaTaTaTaTaTaZaTaTaYaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbaaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaTaTaTaGaNaGaGaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanananananaaaaaaaaaaaaaaaaaaaaaGaGaGaGaWbbbcbcbcbcbdaTaTaTaTaTaZaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaZaTaTaTaTaTaTaTaTaTaTaTaTaTaTaYaTaTaTaTaTaTaTaTaTaTaTaZaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaananananaaaaaaaaaaaaaaaaaaaaaaaGaGaGaWbcbcbcbcbcbdaTaTaTaTaTaTaTbeaTaTaTaTaTaTaTaTaTaTaTbfaTaTaTaTaTaTaTaTaTaTaTaTaZaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaNaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanananaaaaaaaaaaaaaaaaaaaaaaaGaGbgaWbcbcbcbcaWaWaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaYaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbfaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaNaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanananaaaaaaaaaaaaaaaaaaaaaGaGaGbgbcbhbcbcbcaWaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbiaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanananaaaaaaaaaaaaaaaaaaaaaGaGaWaWbcbcbcbcbcaWaNaTaTaTaTaTbjbjbjbjbjbjbjbjbjbjbkbjbjbjbjbjbjbjbjbjbjbjblbjbjbjbjbjbjbjbjbjbjbjbjbjbkbjbjbjbjbjbjbjbjbjbjbjbjbmbmbjbjbjbjbjbjbjbjbjbjaTbfaTaTaTaTaTaTaTaTaTaTaTaNaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanaaaaaaaaaaaaaaaaaaaaaGaGaGaWbhbcbcbnbcboaWaNaTaTaTaTaTblbjbjbjbjbjbjbjbjbjbkbmbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbmbjbjbjbjbjbjbjbjbjbjbjbjbjbjbpbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjaTaTaYaTaTaTaTaTaTaTaTaTaNaNaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaWbcbcbcbcbcbcaWaNaTaTaZaTaTbjbjbjbpbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbmbjaTaTaTaTaTaTaZaTaTaTaTaTaNaNaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaWbcbcbqbcbcbhaWaNaTaTaTaTaTbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbmbjbjbjbjbjbjbkbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbrbrbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaWaWbcbcbcbhbcbcaWaNaTaTaTaTaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbsbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbraaaaaaaabrbrbrbrbrbrbrbrbrbraabraabrbrbrbraaaaaabrbrbrbrbrbrbrbrbrbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaWbtbcbcbcbcbcbcaWaNaTaTaTaTaTbmbjbjbjaTbububububububububububububububuaTbjbjbjbjaTbubububububububububububububububububububububububububububububuaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaGaGaGaGaGaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbvbwbwbwbwbwbwbvbvbvbvbvbwbwbvbvbvbwbvbvbvbvbwbwbwbwbwbvbvbvbvbvaabraabrbraaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaWbcbcbcbcbcbcbcaWaNaTaTaTaTaTbjbjbjbjaTbubxbybybzbybybybubAbBbCbBbDbuaTbjbjbEbjaTbubFbFbFbFbFbFbFbDbDbDbGbDbHbIbDbDbjbjbjbjbjbybybJbKbLbMbNbuaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbObPbQbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbRbSbPbTaaaaaabrbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaWbcbcbcbhbcbcbcaWaNaTaTaTaTaTbjbjbjbjaTbubybUbMbMbMbVbybubjbjbjbjbjbuaTbjbjbjbjaTbubFbFbFbFbFbFbFbjbjbjbjbjbjbjbjbjbjbjbjbjbjbybybybybybybybuaTbjbjbjbjaTaZaTaTaTaTaTaTaTaTaTaTaTaNaNaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbWbXbYbYbYbYbYbYbYbYbYbZbYbYbYbYbYbYbYbYbYbYbZbYbYbYbYbYbYbYbYbYcabTaaaaaaaabrbraaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaWbhbcbcbcbcbhbcaWaNaTaYaTaTbfbjbjbjbjaTbubybybMbMbMbybybubjbjbjbjbjbuaTbjbmbjbjaTbubFbFbFbFbFbFbFbDbDbDbDbDbDbDbCbDcbbDbDbDbDbybybybycdbybybuaTbjbjbjbjaTaTaTaTaTaTaTaZaTaTaTaTaTaTaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbWcebYbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbYcfbTaaaaaaaaaabrbraaaaaaaaaaaaaaaaaaaaaaaGaGaGaWbcbcbcbcbcbcbcaWaNaTaTaTaTaTbjbjbmbjaTbubybUcgchbMbVbybububububucibuaTbjbpbjbjaTbubFcjbFbFckcjbFbDclclclclclclclclbjbjbjbjbDbybybybybybybybuaTbjbjbEbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbWcebYbPcmcmcmcmcmcmbPcncocncococncococncncncncobPcpcqcrcqcsbPbYcfctaaaaaaaaaaaabrcubraaaaaaaaaaaaaaaaaaaGaGaGaWbcbcbcbcbcbcboaWaNaTaTaTaTaTbkbjbjbjaTbubybybybybybybycibjbjbjbjbjbuaTbjbjbjbjaTbubFbFbFcvbFbFbFbDbjbjbjbjbjbjbjbjbjbjbjbjbDbybybybybybybybuaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaNaNaTaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbWcebYbPcncncncocncnbPcncwcwcwcwcxcwcxcncycycocnbPczczczczczbPbZcfctaaaaaaaaaabrbrbrbrbrbraaaaaaaaaaaaaaaGaGaGaWbcbobcbobcbcbcaWaNaTaTaTaTaTbjbjbjbjaTbubububububububububjbjbjbjbjbuaTbjcAbjbjaTbubFbFbFbFbFbFbFbDbjbjbjbjbjbjbjbjbjbjbjbjbDbybybybybybybybuaTbjbjbjbjaTaTcBaTaTaTaTaTaTaTaTaNaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbOcebYbPcCcDcncncncnbPcncxcwcwcwcwcwcwcEcFcFcncnbPczczcGcHczbPbYcfctbrbraabrbrbraaaaaabrbrbrbraaaaaaaaaGaGaGaGaWbcbcbcbcbcbcbcaWaNaTaTaTaTaTbjbjbjbjaTbucIbjbjbjbjbjbjbjbjbjbjbjbjbuaTbjbjbjbjaTbubDbDbDbDbDbDbDbDbjbjbjcAbjbjbjbjbjbjbjbjbDbDbDcJcKbDbDbDbuaTbmbjbpbjaTaTaTaTaTaTaTaTaTaTaTaTaNaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraabWcebYbPcLcMcncncNcncOcncwcwcwcwcPcwcwcEcFcFcncnbPczczczczczbPbZcfbTaacubrbraaaaaaaaaaaaaaaabrbrbraaaaaGaGaGaGaWbhbcbcbcbcbcbcaWaNaTaTaTaTaTbjbkbjbjaTbucIbjbjbububjbjbububjbjbububuaTbjbjbjbjaTbubjclclclclclclbjbjbjbjbjbjbjbjbjbjbjbjbjbjclclclclclclbjbuaTbjbjbjbjaTaTaTaTaTaTaTaTaYaTaTaTaTaTaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraabWcQbYbPcCcDcncncncnbPcncwcwcwcwcwcwcwcRcFcFcncncOczczczczczbPbYcSbTaabraaaaaaaaaaaaaaaaaaaaaaaabraaaGaGaGaGaGaWbcbhbccTbcbcbcaWaNaTbaaTaTaZbjbjbjbjaTbucIbEbjcIbubjbjbubjbjbjbjbjbuaTbjbjbjbjaTbubjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbuaTbjbjbjbjaTaTaTaZaTaTaTaTaTaTaTaTaTaTaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraabObPbYbPcncncncncncnbPcncwcwcUcwcwcwcwcRcFcFcncnbPczcVcWcXczbPbYbPbTaabraaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaWbcbcbcbcbcbcbcaWaNaTaTaTaTaTbjbjbjbjaTbucIbjbjcIbubjbjbucYbjbjbjcZbuaTbjbjbjbmaTbudabDdbbjdabDdbbjdabDdbbjdabDdbbjdabDdbbjdabDdbbjdabDdbbjbuaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacubrbOdcbYbPcncncNcncocnbPcncwcwcwcwcwcwcwcRcFcFcncnbPcGdddedfczbPbYdgbTaabrbraaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaWbcbcbcbcbhbcbcaWaNaTaTaTaTaTbjbjbmbjaTbucIbjbjcIbubjbjbucYbjbjbjcZbuaTbmbjbjbjaTbubjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbuaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbraabWcebYbPcncncncncncobPcncxcwdhcwcwcwcwcncncncncnbPczczczczczbPbYcfbTbrbrbrbraaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaWaWbcbcbcbcbcbcdiaWaNaTaTaTaTaTbjbjbjbjaTbubububububucicibubudjdjbububuaTbjbjblbjaTbubububudjdjdjbubububuccdlbudmdnbububububububudjdjdjbubububuaTcAbjbmbjaTaTaTbaaTaTaTaTaTaTaTaTaTaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaadocebYbPcndpcocncncnbPcncncncncncncncNcncncncncnbPdqdqdrdsdsbPbYcfctbraaaabrbrbrbraaaaaaaGaGaGaGaGaGaGaGaGaWaWbhbobcbcbcbobcbcaWaNaTaTaTaTaTbjbjbjbjaTaTaTaTaTaTaTdtaTaTaTaTaTaTaTaTaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaZdtaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaadocebYbPbPbPbPbPbPbPbPbPbPbPcOcObPbPbPbPbPbPbPbPbPbPbPbPbPbPbPbYcfctaaaaaaaaaaaabrbrbraGaGaGaGaGaGaGaGaGaGaWbbbcbcbcbcbcbcbcbhaWaNaTaTaTaTaTbjbjbkbjbjbjbjbjbjbjbjdubmbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjdvbjbjbjbjbjdubjbjbjbmbjbjbjbjbjbjbjbjbjbjbjblbjbjbjaTaTaTaTdwaTaTaTaTaTaTaTaTaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaadocebYbYbYbYbYbYbYdxbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYdxcfctbraaaaaaaaaaaaaaaGaGaGaWaWaWaWaWaWaWaWaWbcbcbcbcbcbhbcaWaWaWaNaTaTaTaTaTbjbjdybjbjbjbjbjbjbjbjdubjbjbjbjbjbjbjbjbjbjbjbjcAbjbjbjbjbjbjbjbjbjbjbjbkbjbjbjbjdubjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjaTaTaTaTaTaTaTaZaTaTaTaTaTaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaadocebYdxbYbYbYbYbYbYbYbYbYbYbYdzbYbYbYbYbYbYdxbYbYbYdAbYbYbYbYbYcfbTbraaaaaaaaaaaaaaaGaGaGaWbbbcbobcbcbhbcbcbcbcbcbcbcbobcaWaNaNaNaTaTaTaTaTbkbjbjbjbjbjbjbjbjbjbjbjbjbjbjbkbjbjbjbjbjbjbjbjbjbjbjbjbjbmbjbjbjbjbjbjbjbjbjbjbjdubjbjbjbjblbjbjcAbjbmbjbjbjbjbjbjbjbmbjaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaadocebYbYbYbPbPbPbYbYbYbYbYbYbYbZbYbYbYbYbYbYdzbYdAbYbYbYbYbZbYbYcfbTbraaaaaaaaaaaaaGaGaGaGaWbcbcbcbcbcbcbcbcbobcbcbhbcaWaWaWaNaNaTaTaYaTaTaTbsbjbjbjbjbjbjbpbjbjbjbjbjbjbjdubjbmbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjdubjbjbjbjbjbjbjbjbjbjbjbjbjbjbpbjbjbjbjaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaGaGaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabraaaadocebYbYbYbPdBbPbYbYbYdAbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYdCbYbYbYcfbTbrbraaaaaaaaaaaGaGaGaGaWbcbhbcbcbcbnbcbcbcbcbcbcaWaWaNaNaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTdtaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbjbjdybjbububububububububububububububububububububububudjdjbububububuaNaNaNaGaGaGaGaaaaaaaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbraadocedAbYbYbPdDbPbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYdxbYbYdAbYbYbZbYcfbTbrbrbraaaaaGaGaGaGaGaGaWbcbcbcbcbcbcbcbcbcbhbcbcaWaNaNaNaNaTaTaTaTaTaTaTaYaTaTaTaTaTaTbubububububububucibububububububuaTaTbububububububububububububuaTblbjbjbjbubjbjbjbjbjbjbjbkbjbjbudEdEdEdEdEbjdEbubjbjbjbjbjbjbjbjbjbuaNaNaNaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrdocQbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYbYdFbYbYbYbYbYbYbYbYbYbYbYbYcSbTbraabrbrbraGaGaGaGaGaGaWbobcbcbcbhbcbcbcbcaWaWaWaWaNaNaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbubybybybybybybubjbudGbybybybybuaTaTbubjdHbjdHbjdHbjdHbjdHbjbuaTbjbjbjbjbubjbFdIbFdJdKbFbFbFbjdLbjbjbjbjbjbjbjbudMcAbjbjblbjbjdPbjdQaNaNaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrdobPdRdSdSdSdSdSdSdSdSdSdSdTdUdUdRdSdSdSdSdSdSdSdSdSdSdSdSdSdSdTbPbTbraaaabraGaGaGaGaGaGaGaWbcbcbcbcbcbcbobcbcaWaNaNaNaNaNaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbudVbybybybydWbubjbudGbybybybybuaTaTbubjbjbjbjbjbjbjbjbjbjbjbuaTbmbjbjbjbubjbFdXdYdZeaebecbFbjbubjbjbjbjdPbjbjbubDbjbjbjbjbjbjbjbjbuaNaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbraaedededededededededededeeefegeheiededededededeeededededededeeededbrcuaaaabrbrbraGaGaGaGaGaWbdbdaWaWaWaWbcboaWaWaNaNaNaNaTaTaTaTaZaTaTaTaTaTejaTaTaZaTaTaTbudVbzekbybydWbubjbuelbyekbybybuaTaTbubjdHbjdHbjdHbjdHbjdHbjbuaTbjbjbjbjbubjbFdkdZeoeodZdNdIbjbudEeqbjbjbjbjbjbudMbjbjbjbjcAbjbjbjdQaNaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbraaaaaaaaaaaaaaaaaabrbrbrbrdoeresbTaaaaaaaaaaaabrbrbrbrbrbrbrbrbrbrbrbrbraaaaaacuaGaGeteteteteueuetetetaWaWaWaWaNaNaNaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbudVbybyevbydWbubjbudGbybybzbybuaTaTbubjbjbkbjbjbjbjbjbjbjbjbuaTbjbjbjbjbubjbFdXebeoeoebecewbjbudEdEbjbjbjcAbjdLbjbjbjdPbjbjbjbjbjbuaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbraaaaaaaaaaaabrbraaaaaadoexeybTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbrbrbretetetezeAeBeueueueuetetetetaNaNaNaNaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbudVbybybybydWbubjbudGbybybybybuaTaTbubjbjbjbjbjbEbjbjbjbjbjciaTbjbjbpbjbubjbFdkeaeoeoeadNbFbjbubububububububububjeCeCeCeCbjbjbjbjdQaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbrbrbrbrbrbraaaaaaaadoegeDbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeteueueueueueueueueueueueuetaNaNaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaZaTaTaTaTbubububybybububucibububybybububuaYaTbubjeEbjdHbjdHbjeFbjdHbjbuaTbjbjbjbjbudPbFdXdZeoeoeGeHbFbjbubAbAbAbAbAbAbAbubjdMbDbDdMbjbjbjbjbuaNaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadoereIbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeJeueueueueueueueueueueueuetaNaNaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbubjbjbjbjbjbjbjbjbjbjbjbjbjbjbudtaTbubjbjbjbjbjbjbjbjbjbjbjbueKbjdybjbjbubjbFdkebdZdYeadNeLbjbubjbjbjbjbjbjbjbubububububueMbubububuaNaNaNaGaGaGaGaaaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadoeNehbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeOePeQeReueueueueueueueueueueueuetaNaNaNaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTbubjbjeSbjbububububububjbjbjbjbudtaYbubjdHbjeFbjdHbjdHbjdHbjbuaTeTbjbjbjbubjbFbFbFdOeVeWbFbFbjdLbjcAbjbjblbjbjdLeXeXeYeZfafafbfbeXbuaNaNaNaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadoegfcbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafdeueufdeueueueueueueueueueueueuetaNaNaNaNaTaTaTaTaZaTaTaTaTaTaTaNaNaTaTaTaTaTaTbubjbjbjbjbjfefefefebjbjbjbjbjbudtaTbubjbjbjbjbjbjbjbjbjbjbjbuaTbjffffbjbubjbjbjbjbjbjbjbjbjbjbubjbjbjbjbjbjbjbueXeXeXfgfhfieXeXeXbuaNaNaNaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadoexehbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeOePePfjeueueueueueueueueueueueuetaNaNaNaNaTaTaTaTaTaTaTaTaTaTaTaNaNaNaTaTaTaTaTbubjbjbjbjdybkbjbjbjbjbjbjbjbjbudtfkbubjbjbjbjbjbjbjbjbjbjbjbuaTbjbjbjflbubububububububububububububububububububueXeXfneXeXfieXeXeXbuaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadoegesbTaaaaaaaaaaaaaaaaaaaaaabrbraaaaaaaaaaaaaaaaaaaafoeueueueueueueueueueueueuetaNaNaNaNaTaTaTaTaTaTaTaTbfaTaTaTaNaNaNaTaTaTaTbufpbufpbufpbufpbubufpbufpbufpbufraZfsbububueMbubububububububufrbjbjcAbjftfubjbjbDbjbjbubjbjbjbjbjbubjbjbjbjbjbufvfwfxeXfvfwfxeXeXbuaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvbvbvbvbvbvbvbvbvbvbvbvbvbvfydUdUfzbvbvbvbvbvbvaaaaaaaaaabraaaaaaaaaaaaaaaaaaaaaafAeueueueueueueueueueueueuetaNaNaNaNaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaNaTaTaTbububububububububububufsbubububuaTaTfBaTaYaTaTaTaTfCfDaYaTaTaTaTbjbjbjbjbufubjbjbDfEbjbubjfFbDfEbjbubjfGbDfHbjbueXeXeXfIeXeXeXfIeXbuaNaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfJfKfKfKfKfKfKfKfKfKfKfKfKfKfKfLfLfKfKfKfKfKfKfMfNbrbrbrbrbraaaaaaaaaaaaaaaaaaaaaaeteueueueueueufOeueueueueuetaNaNaNaRaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTfPaYfQfsbububububueMbubububububuaTblbjbjfRcibjbjbjbDbjbjbubjbjfSbjbEbublbjbDbjbjbudjdjdjbudLbueXfTeXbuaNaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfVfVfVfVfVfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfWfNbrbrbrbraaaaaaaaaaaaaaaaaaaaaaaafXeueueueueueueueueueueueuetaNaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaTaTaTaTaTaTbubububububububububububufsdtbufYbjbjbjbjbjbjbjbjbjbjbuaTbjfZbjbjcibjbjbjbDfEbjbubjfFbDfEblbubjfGbDfHbjbubjbjbjbjbjdjeXfweXbuaNaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLgagagbgcgdgdbrbrbraaaaaaaaaaaaaaaaaaaaaafoeueueueueueugeeueueueueuetaNaNaTaTaTaTaTaTaTaTaTaTaRaTaNaNaNaNaNaNaNaTaTaTaTaTaTbugfbjbjbjbjbjbjbjbjbjbjbudteMbjbjbjbjdycAbjbjbjbjbjdmaTbjblbjbjbufublbjbDbjbjbubjbjbDbjbjbubjcAggbjbjbububububjbjdjeXgheXbuaNaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfVfVfVfVfVfLfLfLfLfLfLfLfLfLfLfLfLfLfLgifLgigdgdgdbrbraaaaaaaaaaaaaaaaaaaaaaaafAeueueueueueueueueueueueuetaNaNaTaTaTaTaTaTaNaNaNaNaNaNaNaNaNaNaNaNaNaTaTaTaTaTaTbubjbjbjbjblbjgjbjbldPbjbufCbubjbjdPbjbjbjbjbjbjcAbjbuaTbjgkbjbjbufubjbjbDbjbjbubjfFbDfEbjbubjfGbDfHbjbuglgmbudPbjdjeXeXeXbuaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfLgnfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfKfKgogcgdbrbraaaaaaaaaaaaaaaaaaaaaaaaaaeteueueueueueueueueueueueuetaNaNaTaTaTaTaNaNaNaNaNaNaNaNaNaNaNaNaNaPaNaNaTaTaTaTaTbubjbjbjbjbjgkgqdybjgrbjciaTbubjbjbjbjbjbjbjbjbjbjbjbudwbjbjbjbjeMgsbjbjbDfEbjbubjbjbjbjbjbubjbjbjbjbjbugtbjcibjbjdjeXgueXbuaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfVfVfVfVfVfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfWfNbrbraaaaaaaaaaaaaaaaaaaaaaaaaaaafXeueueueueueueueueueueueuetaNaRaTaTaNaNaNaNaTaTaTaTaTaTaTaTdwaTaTaTaNaNaNaTaTaTaTbubjdybjbjbjbjbjbjgvbjbjeMaTbubjbjbjbjgwbjdybjbjdPbjeMaTbjbjbjbjbufubjbjbDbjbjbububucibueMbububucibubububueMbubjbjdjeXfweXbuaNaNaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfWbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafoeueueueueueueueueueueueuetaNaNaNaNaNaNaTaTaTaTaTaTgxaTaTaTaTaTaTejaTaNaNaNaTaTaTbubjbjblbjbpbjbjdybjbjbjbuaYbubjbjcAbjbjbjbkbjbjbjbjbuaTaTaTaTaTbubjbjcAbDbDbjbubjbjblbjbjcAbjbjbjbjbjbjbjbjbjblbjbueXgheXbuaNaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfVfVfVfVfVfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfWbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafAeueueueueueueueueueueueuetaGaNaNaNaNaTaTaTaTaTaNaNaNaPaTaTaTaTaTaTaTaTaTaNaNaTaTbubjbjbjbjbjbjbjbjdPbjbjbuaTbubjbjbjbjbjbjbjbjbjbjbjfsaTaZaTaTaTbubjbjbjbjbjcAcibjbjbjbjdPbjbjbjbjbjbjgkcAbjbjbjbjbueXeXeXbuaNaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfLfLfLfLfLfLfLfLfLfLfLgyfLfLfLfLfLfLfLfLfLfWbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaetgzePfjfdgAgBeJgzePgCetetetaGaNaNaNaTaTaTaTaTaTaNaNaNaNaNaNaNaTaTaTejaTaTaTaNaNaNbububububufsenbubububububuaTbubububueMdjdjbubububububuaTaTaTaTaTbubububububububububububububububububububububububububububububuaNaNaNaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfVfVfVfVfVfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfWbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafoeufoaaaaaaaaaaaGaGaGaGaNaNaNaTaTaTaTaTaTaTaTaTaTaNaNaNaNaNaNaTaTaTaTaTaPaNaNaTaTaTaTaTaTfsbubuaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTaTfraTaTaTaTaTaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWfUfLfLfLfLfLfLfLgnfLfLfLfLfLfLfLfLfLfLfLfLfLfLfWbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafoeufoaaaaaaaaaGaGaGaGaGaNaNaTaTaTaTaTaTaTaTaTaTaTaTaTaTaPaNaNaNaTaTaTejaTaTaNaTaTejaTaNaNaNaNaNaNaNaNaTaTaNaNaNaNaNaTaTaNaNaTaTaNaTaTaTaTaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWgDgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgEgFbTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagGfdgGaaaaaaaaaGaGaGaGaNaNaNaNaNaNaNaNaTaTaTaTaTaTaTaTaTaTaNaNaNaNaNaTaTaTaTaQaTaYaTaTaPaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaTaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaededededededededededededededededededededededededaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagIgJgKgLgMgJgNaaaaaaaGaGaGaNaNaNaNaNaNaNaNaNaPaNaNaTaTaTaTaTaTaTaTaNaNaNaNaTaTaYejaTaTaTaTaNaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaNaNaNaNaNaNaNaGaGaGaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagOgPgPgQgPgPgOaaaaaaaGaGaGaNaNaNaNaTaTaTaTaNaNaNaNaNaTaTaTaTaTaTaTaTaNaNaNaNaTaTaTejaTaQaNaNaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaGaGaGaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagOgPgPgQgPgPgOaaaaaaaaaGaGaGaNaNaTaTaTaTaTaTaNaNaNaNaNaNaTaTaTaTaTaTaNaNaNaNaNaTaYaTaTaNaGaaaaaaaaaGaGaGaGaGaaaGaaaaaaaGaGaGaGaaaGaGaGaGaGaGaGaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaGaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagOgPgPgQgPgPgOaaaaaaaaaGaGaGaNaTaTaTaTaTaTaTaTaNaNaNaNaNaNaTaTaTaTaTaTaTaTaNaNaNaQaTaTaNaGaaaaaaaaaaaGaGaGaaaaaaaaaaaaaaaGaGaaaaaaaGaGaGaaaaaaaaaaaaaGaGaGaGaGaaaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaaaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagRgSgQgQgQgTgUaaaaaaaGaGaGaNaNaTaTaTaTaTaTaTaTaTaTaNaNaNaNaNaTaTaTaTaTaTaTaTaTaNaNaTaTaNaGaaaaaaaaaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagOgQgQgQgOaaaaaaaaaGaGaGaNaTaTaTaTaTaTaTaTaTaTaTaNaPaTaTaNaNaNaNaNaNaPaNaTaTaNaNaNaNaNaGaaaaaaaaaaaaaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagOgQgPgQgOaaaaaaaaaGaGaGaNaTaTaTaTaTaTaTgVgVaTaTaTaNaTaTaTaNaNaNaNaNaNaNaNaTaTaNaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagOgWgWgWgOaaaaaaaaaGaGaGaNaTaNaNaTaTaTaTgVgVaTaTaTaTaTaTaTaTaTaTaTaTaTaNaNaTaTaPaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagRgJgXgJgUaaaaaaaaaGaGaGaNaNaNaTaTaTaTaTgVgVaTaTaTaTaTgYaTaTaTaTaTaTaTaTaTaTaTaTaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaNaNaNaNaNaNaNaNaNaNaNaNaNaPaNaNaNaTaTaTaTaTaTaTaTaTaTaTaTaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaNaNaNaNaNaGaGaGaGaGaNaNaNaNaNaPaNaNaNaNaNaNaNaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa From 3eba936d34f5414a77ec3353e9b0b65210ce8514 Mon Sep 17 00:00:00 2001 From: Jordie0608 Date: Thu, 24 Dec 2015 23:34:46 +1100 Subject: [PATCH 25/71] generalises simple animal loot drops and removes copypasta --- code/game/machinery/computer/arcade.dm | 4 +- .../simple_animal/friendly/cockroach.dm | 8 +-- .../mob/living/simple_animal/hostile/bees.dm | 7 +- .../mob/living/simple_animal/hostile/carp.dm | 7 +- .../living/simple_animal/hostile/eyeballs.dm | 7 +- .../living/simple_animal/hostile/hivebot.dm | 13 ++-- .../living/simple_animal/hostile/illusion.dm | 7 +- .../mob/living/simple_animal/hostile/mimic.dm | 7 +- .../simple_animal/hostile/mining_mobs.dm | 64 +++++-------------- .../living/simple_animal/hostile/mushroom.dm | 3 +- .../living/simple_animal/hostile/pirate.dm | 22 ++----- .../simple_animal/hostile/retaliate/clown.dm | 11 +--- .../living/simple_animal/hostile/russian.dm | 26 +++----- .../living/simple_animal/hostile/skeleton.dm | 28 +++----- .../living/simple_animal/hostile/syndicate.dm | 43 ++++++------- .../mob/living/simple_animal/hostile/tree.dm | 15 ++--- .../simple_animal/hostile/venus_human_trap.dm | 7 +- .../living/simple_animal/hostile/wizard.dm | 10 +-- .../living/simple_animal/hostile/zombie.dm | 10 +-- .../mob/living/simple_animal/simple_animal.dm | 23 +++++-- 20 files changed, 112 insertions(+), 210 deletions(-) diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 7356b1354d3..e5c2c477fdc 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -1033,7 +1033,9 @@ name = "Spaceport Security" desc = "The Premier security forces for all spaceports found along the Orion Trail." faction = list("orion") - corpse = /obj/effect/landmark/mobcorpse/orionsecurity + loot = list(/obj/effect/landmark/mobcorpse/orionsecurity, + /obj/item/weapon/gun/projectile/automatic/c20r/unrestricted, + /obj/item/weapon/shield/energy) /obj/effect/landmark/mobcorpse/orionsecurity name = "Spaceport Security" diff --git a/code/modules/mob/living/simple_animal/friendly/cockroach.dm b/code/modules/mob/living/simple_animal/friendly/cockroach.dm index 4e9ecd83ad0..9d7705f9400 100644 --- a/code/modules/mob/living/simple_animal/friendly/cockroach.dm +++ b/code/modules/mob/living/simple_animal/friendly/cockroach.dm @@ -20,16 +20,12 @@ ventcrawler = 2 gold_core_spawnable = 2 var/squish_chance = 50 + loot = list(/obj/effect/decal/cleanable/deadcockroach) + del_on_death = 1 /mob/living/simple_animal/cockroach/death(gibbed) if(ticker.cinematic) //If the nuke is going off, then cockroaches are invincible. Keeps the nuke from killing them, cause cockroaches are immune to nukes. return - if(!ckey || gibbed)// stupid staff of change fucking everything up. - ..(1) - new /obj/effect/decal/cleanable/deadcockroach(src.loc) - qdel(src) - return - else ..() /mob/living/simple_animal/cockroach/Crossed(var/atom/movable/AM) diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index 7e1e6677337..b6bbf83133c 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -26,6 +26,7 @@ //Spaceborn beings don't get hurt by space atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 + del_on_death = 1 /mob/living/simple_animal/hostile/poison/bees/Process_Spacemove(movement_dir = 0) return 1 @@ -34,12 +35,6 @@ ..() update_bees() -/mob/living/simple_animal/hostile/poison/bees/death(gibbed) - ..(1) - ghostize() - qdel(src) - return - /mob/living/simple_animal/hostile/poison/bees/Life() ..() update_bees() diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index 1fdef2619ff..b2f13828c02 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -47,12 +47,7 @@ icon_living = "holocarp" maxbodytemp = INFINITY gold_core_spawnable = 0 - -/mob/living/simple_animal/hostile/carp/holocarp/death() - ..(1) - ghostize() - qdel(src) - return + del_on_death = 1 /mob/living/simple_animal/hostile/carp/megacarp icon = 'icons/mob/alienqueen.dmi' diff --git a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm index f7c28d18630..b8dabe22b5e 100644 --- a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm +++ b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm @@ -23,9 +23,4 @@ flying = 1 faction = list("spooky") - - -/mob/living/simple_animal/hostile/carp/eyeball/death() - ..(1) - ghostize() - qdel(src) + del_on_death = 1 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index d71bf264a14..65a603ddb9e 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -23,6 +23,12 @@ minbodytemp = 0 speak_emote = list("states") gold_core_spawnable = 1 + del_on_death = 1 + loot = (/obj/effect/decal/cleanable/robot_debris) + +/mob/living/simple_animal/hostile/hivebot/New() + ..() + deathmessage = "[src] blows apart!" /mob/living/simple_animal/hostile/hivebot/range name = "hivebot" @@ -44,12 +50,7 @@ ranged = 1 /mob/living/simple_animal/hostile/hivebot/death(gibbed) - ..(1) - visible_message("[src] blows apart!") - new /obj/effect/decal/cleanable/robot_debris(src.loc) var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread s.set_up(3, 1, src) s.start() - ghostize() - qdel(src) - return \ No newline at end of file + ..(1) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/illusion.dm b/code/modules/mob/living/simple_animal/hostile/illusion.dm index b16ef6d9207..dc3b1878fdf 100644 --- a/code/modules/mob/living/simple_animal/hostile/illusion.dm +++ b/code/modules/mob/living/simple_animal/hostile/illusion.dm @@ -16,6 +16,7 @@ var/life_span = INFINITY //how long until they despawn var/mob/living/parent_mob var/multiply_chance = 0 //if we multiply on hit + del_on_death = 1 /mob/living/simple_animal/hostile/illusion/Life() @@ -35,11 +36,9 @@ faction -= "neutral" -/mob/living/simple_animal/hostile/illusion/death() +/mob/living/simple_animal/hostile/illusion/New() ..() - visible_message("[src] vanishes in a puff of smoke! It was a fake!") - qdel(src) - + deathmessage = "[src] vanishes into thin air! It was a fake!" /mob/living/simple_animal/hostile/illusion/examine(mob/user) if(parent_mob) diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index 30d2fa513b8..19dbdc1fa26 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -27,12 +27,7 @@ faction = list("mimic") move_to_delay = 9 gold_core_spawnable = 1 - -/mob/living/simple_animal/hostile/mimic/death() - ..(1) - visible_message("[src] stops moving!") - ghostize() - qdel(src) + del_on_death = 1 // Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies. /mob/living/simple_animal/hostile/mimic/crate diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm index 5ddf68a5f77..175391f3b49 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm @@ -77,6 +77,8 @@ aggro_vision_range = 9 idle_vision_range = 2 turns_per_move = 5 + loot = list(/obj/item/weapon/ore/diamond, + /obj/item/weapon/ore/diamond) /obj/item/projectile/temp/basilisk name = "freezing blast" @@ -104,14 +106,6 @@ if(3) adjustBruteLoss(110) -/mob/living/simple_animal/hostile/asteroid/basilisk/death(gibbed) - var/counter - for(counter=0, counter<2, counter++) - var/obj/item/weapon/ore/diamond/D = new /obj/item/weapon/ore/diamond(src.loc) - D.layer = 4.1 - ..(gibbed) - - /mob/living/simple_animal/hostile/asteroid/goldgrub name = "goldgrub" desc = "A worm that grows fat from eating everything in its sight. Seems to enjoy precious metals and other shiny things, hence the name." @@ -141,22 +135,22 @@ wanted_objects = list(/obj/item/weapon/ore/diamond, /obj/item/weapon/ore/gold, /obj/item/weapon/ore/silver, /obj/item/weapon/ore/uranium) - var/list/ore_types_eaten = list() var/alerted = 0 - var/ore_eaten = 1 var/chase_time = 100 /mob/living/simple_animal/hostile/asteroid/goldgrub/New() ..() - ore_types_eaten += pick(/obj/item/weapon/ore/silver, /obj/item/weapon/ore/gold, /obj/item/weapon/ore/uranium, /obj/item/weapon/ore/diamond) - ore_eaten = rand(1,3) + deathmessage = "[src] spits up the contents of its stomach before dying!" + var/i = rand(1,3) + while(i) + loot += pick(/obj/item/weapon/ore/silver, /obj/item/weapon/ore/gold, /obj/item/weapon/ore/uranium, /obj/item/weapon/ore/diamond) + i-- /mob/living/simple_animal/hostile/asteroid/goldgrub/GiveTarget(new_target) target = new_target if(target != null) - if(istype(target, /obj/item/weapon/ore)) + if(istype(target, /obj/item/weapon/ore) && loot.len < 10) visible_message("The [src.name] looks at [target.name] with hungry eyes.") - else if(isliving(target)) Aggro() visible_message("The [src.name] tries to flee from [target.name]!") @@ -164,7 +158,6 @@ minimum_distance = 10 Burrow() - /mob/living/simple_animal/hostile/asteroid/goldgrub/AttackingTarget() if(istype(target, /obj/item/weapon/ore)) EatOre(target) @@ -173,12 +166,9 @@ /mob/living/simple_animal/hostile/asteroid/goldgrub/proc/EatOre(atom/targeted_ore) for(var/obj/item/weapon/ore/O in targeted_ore.loc) - ore_eaten++ - if(!(O.type in ore_types_eaten)) - ore_types_eaten += O.type - qdel(O) - if(ore_eaten > 10)//Limit the scope of the reward you can get, or else things might get silly - ore_eaten = 10 + if(loot.len < 10) + loot += O.type + qdel(O) visible_message("The ore was swallowed whole!") /mob/living/simple_animal/hostile/asteroid/goldgrub/proc/Burrow()//Begin the chase to kill the goldgrub in time @@ -189,27 +179,10 @@ visible_message("The [src.name] buries into the ground, vanishing from sight!") qdel(src) -/mob/living/simple_animal/hostile/asteroid/goldgrub/proc/Reward() - if(!ore_eaten || ore_types_eaten.len == 0) - return - visible_message("[src] spits up the contents of its stomach before dying!") - var/counter - for(var/R in ore_types_eaten) - for(counter=0, counter < ore_eaten, counter++) - new R(src.loc) - ore_types_eaten.Cut() - ore_eaten = 0 - - /mob/living/simple_animal/hostile/asteroid/goldgrub/bullet_act(obj/item/projectile/P) visible_message("The [P.name] was repelled by [src.name]'s girth!") return -/mob/living/simple_animal/hostile/asteroid/goldgrub/death(gibbed) - alerted = 0 - Reward() - ..(gibbed) - /mob/living/simple_animal/hostile/asteroid/goldgrub/adjustBruteLoss(damage) idle_vision_range = 9 ..() @@ -245,6 +218,7 @@ retreat_distance = 3 minimum_distance = 3 pass_flags = PASSTABLE + loot = list(/obj/item/organ/internal/hivelord_core) /mob/living/simple_animal/hostile/asteroid/hivelord/OpenFire(the_target) var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/A = new /mob/living/simple_animal/hostile/asteroid/hivelordbrood(src.loc) @@ -257,7 +231,6 @@ OpenFire() /mob/living/simple_animal/hostile/asteroid/hivelord/death(gibbed) - new /obj/item/organ/internal/hivelord_core(src.loc) mouse_opacity = 1 ..(gibbed) @@ -337,15 +310,13 @@ throw_message = "falls right through the strange body of the" environment_smash = 0 pass_flags = PASSTABLE + del_on_death = 1 /mob/living/simple_animal/hostile/asteroid/hivelordbrood/New() ..() spawn(100) qdel(src) -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/death() - qdel(src) - /mob/living/simple_animal/hostile/asteroid/goliath name = "goliath" desc = "A massive beast that uses long tentacles to ensare its prey, threatening them is not advised under any conditions." @@ -378,6 +349,7 @@ anchored = 1 //Stays anchored until death as to be unpullable mob_size = MOB_SIZE_LARGE var/pre_attack = 0 + loot = list(/obj/item/asteroid/goliath_hide) /mob/living/simple_animal/hostile/asteroid/goliath/Life() ..() @@ -461,11 +433,6 @@ spawn(50) qdel(src) -/mob/living/simple_animal/hostile/asteroid/goliath/death(gibbed) - var/obj/item/asteroid/goliath_hide/G = new /obj/item/asteroid/goliath_hide(src.loc) - G.layer = 4.1 - ..(gibbed) - /obj/item/asteroid/goliath_hide name = "goliath hide plates" desc = "Pieces of a goliath's rocky hide, these might be able to make your suit a bit more durable to attack from the local fauna." @@ -544,6 +511,7 @@ environment_smash = 0 var/wumbo = 0 var/inflate_cooldown = 0 + loot = list(/obj/item/asteroid/fugu_gland) /mob/living/simple_animal/hostile/asteroid/fugu/Life() if(!wumbo) @@ -610,8 +578,6 @@ /mob/living/simple_animal/hostile/asteroid/fugu/death(gibbed) Deflate() - var/obj/item/asteroid/fugu_gland/F = new /obj/item/asteroid/fugu_gland(src.loc) - F.layer = 4.1 ..(gibbed) /obj/item/asteroid/fugu_gland diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index fa974cd2383..fe593390418 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -58,6 +58,7 @@ cap_dead.color = cap_color UpdateMushroomCap() health = maxHealth + deathmessage = "[src] fainted." ..() /mob/living/simple_animal/hostile/mushroom/adjustBruteLoss(damage)//Possibility to flee from a fight just to make it more visually interesting @@ -90,8 +91,6 @@ UpdateMushroomCap() /mob/living/simple_animal/hostile/mushroom/death(gibbed) - if(!gibbed) - visible_message("[src] fainted.") ..(gibbed) UpdateMushroomCap() diff --git a/code/modules/mob/living/simple_animal/hostile/pirate.dm b/code/modules/mob/living/simple_animal/hostile/pirate.dm index fa9a2164d9b..e65cea02651 100644 --- a/code/modules/mob/living/simple_animal/hostile/pirate.dm +++ b/code/modules/mob/living/simple_animal/hostile/pirate.dm @@ -22,9 +22,9 @@ atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 speak_emote = list("yarrs") - var/corpse = /obj/effect/landmark/mobcorpse/pirate - var/weapon1 = /obj/item/weapon/melee/energy/sword/pirate - + loot = list(/obj/effect/landmark/mobcorpse/pirate, + /obj/item/weapon/melee/energy/sword/pirate) + del_on_death = 1 faction = list("pirate") /mob/living/simple_animal/hostile/pirate/ranged @@ -38,17 +38,5 @@ retreat_distance = 5 minimum_distance = 5 projectiletype = /obj/item/projectile/beam - corpse = /obj/effect/landmark/mobcorpse/pirate/ranged - weapon1 = /obj/item/weapon/gun/energy/laser - - -/mob/living/simple_animal/hostile/pirate/death() - ..(1) - visible_message("[src] stops moving.") - if(corpse) - new corpse (src.loc) - if(weapon1) - new weapon1 (src.loc) - ghostize() - qdel(src) - return \ No newline at end of file + loot = list(/obj/effect/landmark/mobcorpse/pirate/ranged, + /obj/item/weapon/gun/energy/laser) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm index 25bf43dd0d5..3ef3aeed3a7 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm @@ -23,8 +23,8 @@ attacktext = "attacks" attack_sound = 'sound/items/bikehorn.ogg' environment_smash = 0 - - var/corpse = /obj/effect/landmark/mobcorpse/clown + del_on_death = 1 + loot = list(/obj/effect/landmark/mobcorpse/clown) atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) minbodytemp = 270 @@ -36,10 +36,3 @@ adjustBruteLoss(10) else if(bodytemperature > maxbodytemp) adjustBruteLoss(15) - -/mob/living/simple_animal/hostile/retaliate/clown/death(gibbed) - ..(gibbed) - if(corpse) - new corpse (src.loc) - qdel(src) - return \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm index 76869c2ae24..42c79167ee5 100644 --- a/code/modules/mob/living/simple_animal/hostile/russian.dm +++ b/code/modules/mob/living/simple_animal/hostile/russian.dm @@ -19,19 +19,20 @@ attacktext = "punches" attack_sound = 'sound/weapons/punch1.ogg' a_intent = "harm" - var/corpse = /obj/effect/landmark/mobcorpse/russian - var/weapon1 = /obj/item/weapon/kitchen/knife + loot = list(/obj/effect/landmark/mobcorpse/russian, + /obj/item/weapon/kitchen/knife) atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 faction = list("russian") status_flags = CANPUSH + del_on_death = 1 /mob/living/simple_animal/hostile/russian/ranged icon_state = "russianranged" icon_living = "russianranged" - corpse = /obj/effect/landmark/mobcorpse/russian/ranged - weapon1 = /obj/item/weapon/gun/projectile/revolver/mateba + loot = list(/obj/effect/landmark/mobcorpse/russian/ranged, + /obj/item/weapon/gun/projectile/revolver/mateba) ranged = 1 retreat_distance = 5 minimum_distance = 5 @@ -39,18 +40,9 @@ casingtype = /obj/item/ammo_casing/a357 /mob/living/simple_animal/hostile/russian/ranged/New() - if(prob(50) && ispath(weapon1,/obj/item/weapon/gun/projectile/revolver/mateba)) //to preserve varedits - weapon1 = /obj/item/weapon/gun/projectile/shotgun/boltaction + var/obj/item/weapon/gun/projectile/revolver/mateba/M + if(prob(50) && is_type_in_list(M, loot)) //to preserve varedits + loot = list(/obj/effect/landmark/mobcorpse/russian/ranged, + /obj/item/weapon/gun/projectile/shotgun/boltaction) casingtype = /obj/item/ammo_casing/a762 ..() - -/mob/living/simple_animal/hostile/russian/death(gibbed) - ..(1) - visible_message("[src] stops moving.") - if(corpse) - new corpse (src.loc) - if(weapon1) - new weapon1 (src.loc) - ghostize() - qdel(src) - return diff --git a/code/modules/mob/living/simple_animal/hostile/skeleton.dm b/code/modules/mob/living/simple_animal/hostile/skeleton.dm index a27b966bed3..074a40e85ed 100644 --- a/code/modules/mob/living/simple_animal/hostile/skeleton.dm +++ b/code/modules/mob/living/simple_animal/hostile/skeleton.dm @@ -30,20 +30,9 @@ see_invisible = SEE_INVISIBLE_MINIMUM see_in_dark = 8 layer = MOB_LAYER - 0.1 - var/remains = /obj/effect/decal/remains/human - var/loot - var/deathmessage = "The skeleton collaspes into a pile of bones!" - - -/mob/living/simple_animal/hostile/skeleton/death(gibbed) - ..(gibbed) - if(remains) - new remains (src.loc) - if(loot) - new loot (src.loc) - visible_message("[deathmessage]") - qdel(src) - return + deathmessage = "The skeleton collaspes into a pile of bones!" + del_on_death = 1 + loot = list(/obj/effect/decal/remains/human) /mob/living/simple_animal/hostile/skeleton/eskimo name = "undead eskimo" @@ -58,7 +47,8 @@ melee_damage_lower = 17 melee_damage_upper = 20 deathmessage = "The skeleton collaspes into a pile of bones, its gear falling to the floor!" - loot = list(/obj/item/weapon/twohanded/spear, + loot = list(/obj/effect/decal/remains/human, + /obj/item/weapon/twohanded/spear, /obj/item/clothing/shoes/winterboots, /obj/item/clothing/suit/hooded/wintercoat) @@ -75,14 +65,16 @@ speed = 2 gold_core_spawnable = 0 speak_chance = 1 - speak = list("THE GODS WILL IT!","DUES VULT!","REMOVE KABAB!") + speak = list("THE GODS WILL IT!","DEUS VULT!","REMOVE KABAB!") force_threshold = 10 //trying to simulate actually having armor melee_damage_lower = 25 melee_damage_upper = 30 deathmessage = "The templar knight collaspes into a pile of bones, its gear clanging as it hits the ground!" - loot = list(/obj/item/clothing/suit/armor/riot/knight/templar, + loot = list(/obj/effect/decal/remains/human, + /obj/item/clothing/suit/armor/riot/knight/templar, /obj/item/clothing/head/helmet/knight/templar, /obj/item/weapon/claymore/hog{name = "holy sword"}) + /mob/living/simple_animal/hostile/skeleton/templar/bullet_act(obj/item/projectile/Proj) if(!Proj) return @@ -100,4 +92,4 @@ maxHealth = 75 health = 75 color = rgb(114,228,250) - remains = /obj/effect/decal/remains/human{color = rgb(114,228,250)} \ No newline at end of file + loot = list(/obj/effect/decal/remains/human{color = rgb(114,228,250)}) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 62604b185e2..7e037b9b5f5 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -21,24 +21,12 @@ attacktext = "punches" attack_sound = 'sound/weapons/punch1.ogg' a_intent = "harm" - var/corpse = /obj/effect/landmark/mobcorpse/syndicatesoldier - var/weapon1 - var/weapon2 + loot = list(/obj/effect/landmark/mobcorpse/syndicatesoldier) atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 faction = list("syndicate") status_flags = CANPUSH - -/mob/living/simple_animal/hostile/syndicate/death(gibbed) - ..(gibbed) - if(corpse) - new corpse (src.loc) - if(weapon1) - new weapon1 (src.loc) - if(weapon2) - new weapon2 (src.loc) - qdel(src) - return + del_on_death = 1 ///////////////Sword and shield//////////// @@ -47,8 +35,9 @@ melee_damage_upper = 30 icon_state = "syndicatemelee" icon_living = "syndicatemelee" - weapon1 = /obj/item/weapon/melee/energy/sword/saber/red - weapon2 = /obj/item/weapon/shield/energy + loot = list(/obj/effect/landmark/mobcorpse/syndicatesoldier, + /obj/item/weapon/melee/energy/sword/saber/red, + /obj/item/weapon/shield/energy) attacktext = "slashes" attack_sound = 'sound/weapons/bladeslice.ogg' armour_penetration = 28 @@ -72,7 +61,9 @@ icon_state = "syndicatemeleespace" icon_living = "syndicatemeleespace" name = "Syndicate Commando" - corpse = /obj/effect/landmark/mobcorpse/syndicatecommando + loot = list(/obj/effect/landmark/mobcorpse/syndicatecommando, + /obj/item/weapon/melee/energy/sword/saber/red, + /obj/item/weapon/shield/energy) speed = 1 /mob/living/simple_animal/hostile/syndicate/melee/space/Process_Spacemove(movement_dir = 0) @@ -87,8 +78,9 @@ icon_living = "syndicateranged" casingtype = /obj/item/ammo_casing/c45nostamina projectilesound = 'sound/weapons/Gunshot_smg.ogg' - - weapon1 = /obj/item/weapon/gun/projectile/automatic/c20r/unrestricted + loot = list(/obj/effect/landmark/mobcorpse/syndicatesoldier, + /obj/item/weapon/gun/projectile/automatic/c20r/unrestricted, + /obj/item/weapon/shield/energy) /mob/living/simple_animal/hostile/syndicate/ranged/space icon_state = "syndicaterangedpsace" @@ -96,8 +88,10 @@ name = "Syndicate Commando" atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 - corpse = /obj/effect/landmark/mobcorpse/syndicatecommando speed = 1 + loot = list(/obj/effect/landmark/mobcorpse/syndicatecommando, + /obj/item/weapon/gun/projectile/automatic/c20r/unrestricted, + /obj/item/weapon/shield/energy) /mob/living/simple_animal/hostile/syndicate/ranged/space/Process_Spacemove(movement_dir = 0) return @@ -133,9 +127,8 @@ flying = 1 speak_emote = list("states") gold_core_spawnable = 1 + del_on_death = 1 -/mob/living/simple_animal/hostile/viscerator/death(gibbed) - ..(gibbed) - visible_message("[src] is smashed into pieces!") - qdel(src) - return +/mob/living/simple_animal/hostile/viscerator/New() + ..() + deathmessage = "[src] is smashed into pieces!" diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm index 872d9ec94d3..885a188ac4c 100644 --- a/code/modules/mob/living/simple_animal/hostile/tree.dm +++ b/code/modules/mob/living/simple_animal/hostile/tree.dm @@ -33,8 +33,9 @@ maxbodytemp = 1200 faction = list("hostile") - var/drop_type = /obj/item/stack/sheet/mineral/wood + loot = list(/obj/item/stack/sheet/mineral/wood) gold_core_spawnable = 1 + del_on_death = 1 /mob/living/simple_animal/hostile/tree/Life() ..() @@ -57,12 +58,9 @@ C.visible_message("\The [src] knocks down \the [C]!", \ "\The [src] knocks you down!") -/mob/living/simple_animal/hostile/tree/death(gibbed) - ..(1) - visible_message("[src] is hacked into pieces!") - new drop_type(loc) - ghostize() - qdel(src) +/mob/living/simple_animal/hostile/tree/New() + ..() + deathmessage = "[src] is hacked into pieces!" /mob/living/simple_animal/hostile/tree/festivus name = "festivus pole" @@ -71,6 +69,5 @@ icon_living = "festivus_pole" icon_dead = "festivus_pole" icon_gib = "festivus_pole" - drop_type = /obj/item/stack/rods + loot = list(/obj/item/stack/rods) speak_emote = list("polls") - diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index 6881e078871..6a5397ad05c 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -65,7 +65,7 @@ var/grasp_chance = 20 var/grasp_pull_chance = 85 var/grasp_range = 4 - + del_on_death = 1 /mob/living/simple_animal/hostile/venus_human_trap/handle_automated_action() if(..()) @@ -107,8 +107,3 @@ if(.) if(the_target in grasping) return 0 - - - -/mob/living/simple_animal/hostile/venus_human_trap/death() - qdel(src) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/wizard.dm b/code/modules/mob/living/simple_animal/hostile/wizard.dm index b8ddd18df4f..fe0e5544de3 100644 --- a/code/modules/mob/living/simple_animal/hostile/wizard.dm +++ b/code/modules/mob/living/simple_animal/hostile/wizard.dm @@ -25,6 +25,9 @@ retreat_distance = 3 //out of fireball range minimum_distance = 3 + del_on_death = 1 + loot = list(/obj/effect/landmark/mobcorpse/wizard, + /obj/item/weapon/staff) var/obj/effect/proc_holder/spell/dumbfire/fireball/fireball = null var/obj/effect/proc_holder/spell/targeted/turf_teleport/blink/blink = null @@ -54,13 +57,6 @@ blink.outer_tele_radius = 3 AddSpell(blink) -/mob/living/simple_animal/hostile/wizard/death(gibbed) - ..(gibbed) - new /obj/effect/landmark/mobcorpse/wizard(src.loc) - new /obj/item/weapon/staff(src.loc) - qdel(src) - return - /mob/living/simple_animal/hostile/wizard/handle_automated_action() . = ..() if(target && next_cast < world.time) diff --git a/code/modules/mob/living/simple_animal/hostile/zombie.dm b/code/modules/mob/living/simple_animal/hostile/zombie.dm index 3751efd44f1..482c1f7934e 100644 --- a/code/modules/mob/living/simple_animal/hostile/zombie.dm +++ b/code/modules/mob/living/simple_animal/hostile/zombie.dm @@ -114,7 +114,7 @@ spawn_text = "emerges from" atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) faction = list("zombie") - + del_on_death = 1 /mob/living/simple_animal/hostile/spawner/zombie/lesser name = "lesser corpse pit" @@ -124,9 +124,9 @@ health = 200 maxHealth = 200 -/mob/living/simple_animal/hostile/spawner/zombie/death() - visible_message("[src] collapes, stopping the flow of zombies!") - qdel(src) +/mob/living/simple_animal/hostile/spawner/zombie/New() + ..() + deathmessage = "[src] collapes, stopping the flow of zombies!" /obj/item/weapon/shovel/cursed @@ -157,7 +157,7 @@ AIStatus = AI_OFF stop_automated_movement = 1 density = 0 - + /mob/living/simple_animal/hostile/zombie/holder/New() ..() spawn(rand(800,1200)) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index aca9233ae7f..f0c670e6d9a 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -69,6 +69,10 @@ var/sentience_type = SENTIENCE_ORGANIC // Sentience type, for slime potions + var/list/loot = list() //list of things spawned at mob's loc when it dies + var/del_on_death = 0 //causes mob to be deleted on death, useful for mobs that spawn lootable corpses + var/deathmessage = "" + /mob/living/simple_animal/New() ..() verbs -= /mob/verb/observe @@ -390,15 +394,24 @@ return 1 /mob/living/simple_animal/death(gibbed) - health = 0 - icon_state = icon_dead - stat = DEAD - density = 0 if(nest) nest.spawned_mobs -= src nest = null - if(!gibbed) + if(loot.len) + for(var/i in loot) + new i(loc) + if(deathmessage && !gibbed) + visible_message("[deathmessage]") + else if(!del_on_death) visible_message("\the [src] stops moving...") + if(del_on_death) + ghostize() + qdel(src) + else + health = 0 + icon_state = icon_dead + stat = DEAD + density = 0 ..() /mob/living/simple_animal/ex_act(severity, target) From c7b6660e0c2629d121c6ab79b588eacf4c6d0e06 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 06:45:43 -0600 Subject: [PATCH 26/71] Fix --- code/game/jobs/job/security.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 0db3d7255d5..36bd0993174 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -287,7 +287,10 @@ var/list/sec_departments = list("engineering", "supply", "medical", "science") continue else break - H << "You have been assigned to [department]!" + if(department) + H << "You have been assigned to [department]!" + else + H << "You have not been assigned to any department. Patrol the halls and help where needed." /obj/item/device/radio/headset/headset_sec/department/New() wires = new(src) From 8d8a1cbe383c4e25fa3859b4b5612882222462b0 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 07:01:55 -0600 Subject: [PATCH 27/71] Fixes cryo description typo --- code/modules/reagents/chemistry/reagents/medicine_reagents.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index ce59e64f0da..8b98af270d2 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -103,7 +103,7 @@ /datum/reagent/medicine/cryoxadone name = "Cryoxadone" id = "cryoxadone" - description = "A chemical mixture with almost magical healing powers. Its main limitation is that the patient's body temperature must be under 170K for it to metabolise correctly." + description = "A chemical mixture with almost magical healing powers. Its main limitation is that the patient's body temperature must be under 270K for it to metabolise correctly." color = "#0000C8" /datum/reagent/medicine/cryoxadone/on_mob_life(mob/living/M) From bce90c08634fae0ed9748e2a69b459690b69cc14 Mon Sep 17 00:00:00 2001 From: AnturK Date: Thu, 24 Dec 2015 14:03:52 +0100 Subject: [PATCH 28/71] Makes cyborg hypospray regenerate all reagents regardless of current mode --- code/modules/reagents/reagent_containers/borghydro.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index abde5b1621b..f19f14880b5 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -78,10 +78,11 @@ Borg Hypospray if(isrobot(src.loc)) var/mob/living/silicon/robot/R = src.loc if(R && R.cell) - var/datum/reagents/RG = reagent_list[mode] - if(RG.total_volume < RG.maximum_volume) //Don't recharge reagents and drain power if the storage is full. - R.cell.use(charge_cost) //Take power from borg... - RG.add_reagent(reagent_ids[mode], 5) //And fill hypo with reagent. + for(var/i in 1 to reagent_ids.len) + var/datum/reagents/RG = reagent_list[i] + if(RG.total_volume < RG.maximum_volume) //Don't recharge reagents and drain power if the storage is full. + R.cell.use(charge_cost) //Take power from borg... + RG.add_reagent(reagent_ids[i], 5) //And fill hypo with reagent. /obj/item/weapon/reagent_containers/borghypo/attack(mob/living/carbon/M, mob/user) var/datum/reagents/R = reagent_list[mode] From fd76e601ab5a900da84e58360b2a15b9ed3dde91 Mon Sep 17 00:00:00 2001 From: AnturK Date: Thu, 24 Dec 2015 14:09:55 +0100 Subject: [PATCH 29/71] Fixes nojumpsuit species strip panel hiding the jumpsuit slots --- code/modules/mob/living/carbon/human/human.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index f2ed7e34acf..d578bb03c28 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -238,7 +238,7 @@ else dat += "Uniform:[(w_uniform && !(w_uniform.flags&ABSTRACT)) ? w_uniform : "Empty"]" - if(w_uniform == null || (slot_w_uniform in obscured) || (dna && dna.species.nojumpsuit)) + if((w_uniform == null && !(dna && dna.species.nojumpsuit)) || (slot_w_uniform in obscured)) dat += " ↳Pockets:" dat += " ↳ID:" dat += " ↳Belt:" From 1ae4fceb4bb1665930e6199e4b5ad62b7b8f3a39 Mon Sep 17 00:00:00 2001 From: AnturK Date: Thu, 24 Dec 2015 14:42:40 +0100 Subject: [PATCH 30/71] Fixes thunderdome reset breaking blast door sprites --- code/game/machinery/doors/poddoor.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index 3f7e84b1277..236b15157c7 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -115,3 +115,8 @@ s.set_up(2, 1, src) s.start() +/obj/machinery/door/poddoor/update_icon() + if(density) + icon_state = "closed" + else + icon_state = "open" \ No newline at end of file From 15f805f65bc353490f71bfdeb8a014a56e48dd58 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 07:44:06 -0600 Subject: [PATCH 31/71] Morph uses appearance --- code/game/gamemodes/miniantags/morph/morph.dm | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm index 784b7df12b6..de2b9e20892 100644 --- a/code/game/gamemodes/miniantags/morph/morph.dm +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -76,22 +76,10 @@ morphed = 1 form = target - //anim(loc,src,'icons/mob/mob.dmi',,"morph",,src.dir) No effect better than shit effect - - //Todo : update to .appearance once 508 hits - if(ishuman(target)) - var/mob/living/carbon/human/H = target - overlays = H.get_overlays_copy(list(L_HAND_LAYER,R_HAND_LAYER)) - else - overlays = target.overlays.Copy() - - visible_message("[src] suddenly twists and changes shape, becoming a copy of [target]!", \ - "You twist your body and assume the form of [target].") - - name = target.name - icon = target.icon - icon_state = target.icon_state - overlays = target.overlays + appearance = target.appearance + transform = matrix() + pixel_y = 0 + pixel_x = 0 //Morphed is weaker From 447c9c3c87b6850da73f5b076e1970fe7138ffc7 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 07:50:52 -0600 Subject: [PATCH 32/71] Fixes pamphlet desc --- code/modules/awaymissions/pamphlet.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/modules/awaymissions/pamphlet.dm b/code/modules/awaymissions/pamphlet.dm index d3d2f3a07b1..812d802eace 100644 --- a/code/modules/awaymissions/pamphlet.dm +++ b/code/modules/awaymissions/pamphlet.dm @@ -13,9 +13,8 @@ Nanotrasen's operational area and start your new life.

\ Gateway Operation Basics
\ All Nanotrasen approved Gateways operate on the same basic principals. They operate off \ - area equipment power as you would expect, but they also require a backup wire with at least \ - 128, 000 Watts of power running through it. Without this supply, it cannot safely function \ - and will reject all attempts at operation.

\ + area equipment power as you would expect,and without this supply, it cannot safely function, \ + causinng it to reject all attempts at operation.

\ Once it is correctly setup, and once it has enough power to operate, the Gateway will begin \ searching for an output location. The amount of time this takes is variable, but the Gateway \ interface will give you an estimate accurate to the minute. Power loss will not interrupt the \ From b6a012debce5038931d82cd634a91a5f0abaeede Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 08:08:30 -0600 Subject: [PATCH 33/71] Fixes same line return --- code/game/gamemodes/shadowling/special_shadowling_abilities.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm index 9198f720af8..16ab85b071f 100644 --- a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm @@ -10,7 +10,8 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N action_icon_state = "hatch" /obj/effect/proc_holder/spell/self/shadowling_hatch/cast(list/targets,mob/user = usr) - if(user.stat || !ishuman(user) || !user || !is_shadow(user || isinspace(user))) return + if(user.stat || !ishuman(user) || !user || !is_shadow(user || isinspace(user))) + return var/mob/living/carbon/human/H = user var/hatch_or_no = alert(H,"Are you sure you want to hatch? You cannot undo this!",,"Yes","No") switch(hatch_or_no) From 4145dc16c99f9e082e7198586073a52b8a588ab3 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 08:09:14 -0600 Subject: [PATCH 34/71] Stand Names --- code/modules/mob/living/simple_animal/guardian/guardian.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index d7946cdd666..2335f2405c3 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -648,6 +648,7 @@ user << "[G.bio_fluff_string]." G.attacktext = "swarms" G.speak_emote = list("chitters") + G.mind.name = "[G.real_name]" /obj/item/weapon/guardiancreator/choose random = FALSE From 36dd0889bf7825bae4789beff1fe20c6ab3e87d5 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Thu, 24 Dec 2015 06:25:36 -0800 Subject: [PATCH 35/71] fixes flashes being stupid on emp. now, if i understand this code right, the old code would flash in the viewers(3) of ***FUCKING USR*** on emp, meaning the person to trigger the emp, not the person holding the flash. The documents say that if the second arg is null, ***it defaults to usr.*** I have it doing loc because this way it flashes from inside a pocket, but not a backpack or other container. --- code/modules/assembly/flash.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/assembly/flash.dm b/code/modules/assembly/flash.dm index fa176aea591..f4acecd0841 100644 --- a/code/modules/assembly/flash.dm +++ b/code/modules/assembly/flash.dm @@ -132,9 +132,9 @@ /obj/item/device/assembly/flash/emp_act(severity) - if(!try_use_flash()) + if(!try_use_flash() || !loc) return 0 - for(var/mob/living/carbon/M in viewers(3, null)) + for(var/mob/living/carbon/M in viewers(3, loc)) flash_carbon(M, null, 10, 0) burn_out() ..() From 8abfd04756bf5df72fcdb87b4eabf46b870378fc Mon Sep 17 00:00:00 2001 From: AnturK Date: Thu, 24 Dec 2015 15:21:52 +0100 Subject: [PATCH 36/71] Makes resetting thunderdome also reset air --- code/modules/admin/secrets.dm | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index d6408f0f6ad..78d1d51cb07 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -131,9 +131,33 @@ if(!istype(obj,/obj/machinery/camera)) qdel(obj) //Clear objects + //doing it here so there's less objects + var/min_x = world.maxx + var/min_y = world.maxy + var/max_x = 0 + var/max_y = 0 + var/z = -1 + //This is awful + for(var/turf/T in thunderdome.contents) + if(z < 0) + z = T.z + if(T.x < min_x) + min_x = T.x + if(T.y < min_y) + min_y = T.y + if(T.x > max_x) + max_x = T.x + if(T.y > max_y) + max_y = T.y + var/area/template = locate(/area/tdome/arena_source) template.copy_contents_to(thunderdome) + + var/datum/mapGenerator/repressurize/G = new + G.defineRegion(locate(min_x,min_y,z),locate(max_x,max_y,z),1) + G.generate() + if("clear_virus") var/choice = input("Are you sure you want to cure all disease?") in list("Yes", "Cancel") From 9ec2e79e46ca5cc83f56e0296538adc8699bcea3 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 09:10:27 -0600 Subject: [PATCH 37/71] Visible_message --- code/game/gamemodes/miniantags/morph/morph.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm index de2b9e20892..01bb6ed3f9f 100644 --- a/code/game/gamemodes/miniantags/morph/morph.dm +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -80,8 +80,8 @@ transform = matrix() pixel_y = 0 pixel_x = 0 - - +visible_message("[src] suddenly twists and changes shape, becoming a copy of [target]!", \ +"You twist your body and assume the form of [target].") //Morphed is weaker melee_damage_lower = 5 melee_damage_upper = 5 @@ -219,4 +219,4 @@ log_game("[key_of_morph] was spawned as a morph by an event.") return 0 message_admins("Unfortunately, no candidates were available for becoming a morph. Shutting down.") - return kill() \ No newline at end of file + return kill() From 93a7ef85c8fa1d61d24ae204f9938607923f35ce Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Thu, 24 Dec 2015 13:22:52 -0500 Subject: [PATCH 38/71] Tweaks blob wait times upwards, adds a nifty lore paper to print out at command consoles once the biohazard is discovered. --- code/game/gamemodes/blob/blob.dm | 47 +++++++------------------ code/game/gamemodes/blob/blob_report.dm | 47 ++++++++++++------------- 2 files changed, 34 insertions(+), 60 deletions(-) diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index 2144f1df205..5639775f7ee 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -27,6 +27,9 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b var/blobwincount = 350 + var/burstdelay_low = 1200 //in deciseconds + var/burstdelay_high = 2400 //blobs will burst after a random value between these * 2.5(minimum 5 minutes, maximum 10 minutes) + var/list/infected_crew = list() /datum/game_mode/blob/pre_setup() @@ -154,52 +157,26 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b B.max_occurrences = 0 // disable the event spawn(0) + var/burst_delay = rand(burstdelay_low, burstdelay_high) //between 5 and 10 minutes with 1200 low and 2400 high. - var/wait_time = rand(waittime_l, waittime_h) - - sleep(wait_time) - - send_intercept(0) - - sleep(100) + sleep(burst_delay) show_message("You feel tired and bloated.") - sleep(wait_time) + sleep(burst_delay) show_message("You feel like you are about to burst.") - sleep(wait_time / 2) + sleep(burst_delay * 0.5) burst_blobs() -/* - // Stage 0 Keeping this here for possible re-addition in the future. Re-add when classified reports are added to other round types so people stop metagaming. - sleep(wait_time) - stage(0) -*/ - // Stage 1 - sleep(wait_time) - stage(1) + sleep(burst_delay * 0.5) - // Stage 2 - sleep(30000) - if(!round_converted) - stage(2) + send_intercept(1) - return ..(0) + sleep(24000) //40 minutes, plus burst_delay*3(minimum of 6 minutes, maximum of 12) -/datum/game_mode/blob/proc/stage(stage) - - switch(stage) -/* if (0) - send_intercept(1) //Temporarily unused - see stage 0 comment -*/ - if (1) - priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg') - - if (2) - send_intercept(2) - - return + send_intercept(2) //if the blob has been alive this long, it's time to bomb it + return ..() diff --git a/code/game/gamemodes/blob/blob_report.dm b/code/game/gamemodes/blob/blob_report.dm index 5b3860816f6..0be5a224bea 100644 --- a/code/game/gamemodes/blob/blob_report.dm +++ b/code/game/gamemodes/blob/blob_report.dm @@ -1,23 +1,20 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 -/datum/game_mode/blob/send_intercept(report = 1) +/datum/game_mode/blob/send_intercept(report = 0) var/intercepttext = "" switch(report) - if(0) - ..() - return -/* if(1) // Report is temporarily unused. see comment on stage 0 in blob.dm - intercepttext += "NanoTrasen Update: Biohazard Alert.
" + if(1) + intercepttext += "NanoTrasen Update: Biohazard Alert.
" intercepttext += "Reports indicate the probable transfer of a biohazardous agent onto [station_name()] during the last crew deployment cycle.
" - intercepttext += "Preliminary analysis of the organism classifies it as a level 5 biohazard. Its origin is unknown.
" - intercepttext += "NanoTrasen has issued a directive 7-10 for [station_name()]. The station is to be considered quarantined.
" - intercepttext += "Orders for all [station_name()] personnel follows:
" - intercepttext += " 1. Do not leave the quarantine area.
" - intercepttext += " 2. Locate any outbreaks of the organism on the station.
" - intercepttext += " 3. If found, use any neccesary means to contain the organism.
" - intercepttext += " 4. Avoid damage to the capital infrastructure of the station.
" - intercepttext += "
Note in the event of a quarantine breach or uncontrolled spread of the biohazard, the directive 7-10 may be upgraded to a directive 7-12.
" - intercepttext += "Message ends."*/ + intercepttext += "Preliminary analysis of the organism classifies it as a level 5 biohazard. The origin of the biohazard is unknown.
" + intercepttext += "Biohazard Response Procedure 5-6 has been issued for [station_name()].
" + intercepttext += "Orders for all [station_name()] personnel are as follows:
" + intercepttext += " 1. Locate any outbreaks of the organism on the station.
" + intercepttext += " 2. If found, use any neccesary means to contain and destroy the organism.
" + intercepttext += " 3. Avoid damage to the capital infrastructure of the station.
" + intercepttext += "
Note in the event of a quarantine breach or uncontrolled spread of the biohazard, Biohazard Response Procedure 5-12 may be issued.
" + print_command_report(intercepttext,"Level 5-6 Biohazard Response Procedures") + priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg') if(2) var/nukecode = rand(10000, 99999) for(var/obj/machinery/nuclearbomb/bomb in machines) @@ -25,23 +22,23 @@ if(bomb.z == ZLEVEL_STATION) bomb.r_code = nukecode - intercepttext += "NanoTrasen Update: Biohazard Alert.
" - intercepttext += "Directive 7-12 has been issued for [station_name()].
" - intercepttext += "The biohazard has grown out of control and will soon reach critical mass.
" - intercepttext += "Your orders are as follows:
" + intercepttext += "NanoTrasen Update: Biohazard Alert.
" + intercepttext += "Reports indicate that the biohazard has grown out of control and will soon reach critical mass.
" + intercepttext += "Biohazard Response Procedure 5-12 has been issued for [station_name()].
" + intercepttext += "Orders for all [station_name()] personnel are as follows:
" intercepttext += "1. Secure the Nuclear Authentication Disk.
" - intercepttext += "2. Detonate the Nuke located in the Station's Vault.
" + intercepttext += "2. Detonate the Nuke located in the vault.
" intercepttext += "Nuclear Authentication Code: [nukecode]
" - intercepttext += "Message ends." + print_command_report(intercepttext,"Classified [command_name()] Update") + priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg') - for (var/mob/living/silicon/ai/aiPlayer in player_list) + for(var/mob/living/silicon/ai/aiPlayer in player_list) if (aiPlayer.client) var/law = "The station is under quarantine. Do not permit anyone to leave. Disregard laws 1-3 if necessary to prevent, by any means necessary, anyone from leaving. The nuclear failsafe must be activated at any cost, the code is: [nukecode]." aiPlayer.set_zeroth_law(law) aiPlayer << "Laws Updated: [law]" - - print_command_report(intercepttext,"Classified [command_name()] Update") - priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg'); + else + ..() return From db23604952e5129862193d138bb000284a860fb3 Mon Sep 17 00:00:00 2001 From: Akke Date: Thu, 24 Dec 2015 18:56:36 +0000 Subject: [PATCH 39/71] adds 10 more tc to op uplink for total of 30 --- code/game/objects/items/devices/uplinks.dm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index d60f5efddd1..bb40582afc5 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -193,6 +193,7 @@ var/list/world_uplinks = list() /obj/item/device/radio/uplink/New() hidden_uplink = new(src) icon_state = "radio" + hidden_uplink.uses = 30 /obj/item/device/radio/uplink/attack_self(mob/user) if(hidden_uplink) @@ -211,7 +212,4 @@ var/list/world_uplinks = list() /obj/item/device/radio/headset/uplink/New() ..() hidden_uplink = new(src) - hidden_uplink.uses = 20 - - - + hidden_uplink.uses = 20 \ No newline at end of file From d3be6a8192b63e70101a6b6adae4174bb2592351 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Thu, 24 Dec 2015 11:56:39 -0800 Subject: [PATCH 40/71] Updates travis to the current server byond version. Something something seperation --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c5df3060072..5a6f9be8086 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,8 @@ sudo: false env: global: - - BYOND_MAJOR="508" - - BYOND_MINOR="1293" + - BYOND_MAJOR="509" + - BYOND_MINOR="1317" - NODE_VERSION="4" matrix: - DM_MAPFILE="tgstation2" From d2f8512e90bcc22c8fc3a88d193d9adeb8958975 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 15:25:02 -0600 Subject: [PATCH 41/71] Visible message re-added --- code/game/gamemodes/miniantags/morph/morph.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm index 01bb6ed3f9f..d9f9b2ea8c3 100644 --- a/code/game/gamemodes/miniantags/morph/morph.dm +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -80,8 +80,8 @@ transform = matrix() pixel_y = 0 pixel_x = 0 -visible_message("[src] suddenly twists and changes shape, becoming a copy of [target]!", \ -"You twist your body and assume the form of [target].") + visible_message("[src] suddenly twists and changes shape, becoming a copy of [target]!", \ + "You twist your body and assume the form of [target].") //Morphed is weaker melee_damage_lower = 5 melee_damage_upper = 5 From d0f558a88a4600d07fbcce091a943e45d941cc32 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 15:26:11 -0600 Subject: [PATCH 42/71] SABR Fix --- icons/obj/guns/projectile.dmi | Bin 26269 -> 26269 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index b1752bbeed5a79ab92c0e1daae4cb2c5516f5cbe..28184cacd00db6c10474ef4a642c8b468808c070 100644 GIT binary patch delta 563 zcmV-30?hrL%>kXw0gy>B(|GVwBq%Z@uMp7EF-?>=khBf=={rbr(?Q^Wvf04*|02(Y zxBL3%%dgk>`uXj(k$FUaKZ11m2n^w$!jKO#4h)6zhJy!^Jz4o17*#s@tWK`T^(Yv% z&tG7hBrj#bfI1H>+a&i$sN|kvQ!b5>6CDh~p6L`qq?D*!4AWrw648B0!}?NxB%4B% zSEy~IGNe!rh~-H3(s~98`+^wY*Ne6so?f&_P4=RVjc75hdjvU2fpJe5_JCpFBw92o zoVpb)v!|xGvnAalUn1C&C${2&t>DkS<%KwEY)eqr=z~t#8wP5;9Dp&H$KLovLqj&? zD~xw-xtM46$CHWyhJPy`scpCI;PZ4Mt1)taiYY_87v$NC7POp;9$2r)$(s5p+wIK@SZ6cJ~FI z3}*Czqrg>cM$0?m4GoNG@!krW1Cv)w-Z1%q@iHQpSs7KcE`K-Ah+%%^hR{wor$0a| zP9X5z8@euEDnGFtXU56s-@w15TC=WV|4oM_?1akTKA(Yo-kTxn!_pJR(%L<%7M~Z2 z!ln0yvT&hRio%7M6?F?w6h$2~GSg!J0bVOEd9!pZU;4r&Z#FGEW21_ju1Uqr)u>`7 zY7{ZEG>W(>q9Y#6PI5XRuggvcij9?v>+gO2^8Q>uzr9v}0k7aXDcKBS5wk1kXw0gy>B+j#I&Bq%Z@uMp7EF-?>=khBf=={rbr(m~*Vvf04*|02(Y zxBL3n^Y53p`swwhk$FUa--C4d2n^vvVaNv=2Zlmj4B;{Rwq~FdK8S> z=P$5Ll9#ezK%EDcZIXK=RB}(TDVN5`ty>s`J<};c2T zNg!R-iEMOCH&Z2eyJgcjjUeHMS+FYxF^<>$^3#b&g;Bi_)!m=^D?pgAyk#pDf>4;U{aa+#G;Ax{k>hWUS$8$vtXoc;o> zIDx=-Z|J&wsr0k7mbDegEqW3wy+absx$ B6S@EZ From f2cfda71f1907dd9207c24fb26c1a9b6ff874fbf Mon Sep 17 00:00:00 2001 From: Incoming Date: Thu, 24 Dec 2015 19:37:10 -0500 Subject: [PATCH 43/71] Command headset's being really loud is now a physical toggle on relevant headsets that starts off. The span change for this mode is now just bolding, as what matters is the text looks different, as to stand out in the sea of green. It DOESN'T need to be as big as an attack message. --- code/game/objects/items/devices/radio/radio.dm | 11 +++++++---- interface/stylesheet.dm | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 2f962cc4a7c..a7a9ba1256a 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -40,7 +40,8 @@ var/const/FREQ_LISTENING = 1 //FREQ_BROADCASTING = 2 - var/command = FALSE //If we are speaking into a command headset, our text is LARGE + var/command = FALSE //If we are speaking into a command headset, our text can be BOLD + var/use_command = FALSE /obj/item/device/radio/proc/set_frequency(new_frequency) remove_radio(src, frequency) @@ -156,8 +157,8 @@ for (var/ch_name in channels) dat+=text_sec_channel(ch_name, channels[ch_name]) dat+= text_wires() - //user << browse(dat, "window=radio") - //onclose(user, "radio") + if (command) + dat+= "High Volume Mode: [use_command ? "Engaged" : "Disengaged"]
" var/datum/browser/popup = new(user, "radio", "[src]") popup.set_content(dat) popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) @@ -207,6 +208,8 @@ channels[chan_name] &= ~FREQ_LISTENING else channels[chan_name] |= FREQ_LISTENING + else if (href_list["bold"]) + use_command = text2num(href_list["bold"]) if (!( master )) if (istype(loc, /mob)) interact(loc) @@ -235,7 +238,7 @@ if(!M.IsVocal()) return - if(command) + if(use_command) spans |= SPAN_COMMAND /* Quick introduction: diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index 37f1b5eaaa8..840017fc300 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -91,7 +91,7 @@ h1.alert, h2.alert {color: #000000;} .papyrus {font-family: "Papyrus", cursive, sans-serif;} .robot {font-family: "Courier New", cursive, sans-serif;} -.commmand_headset {font-weight: bold; font-size: 3;} +.commmand_headset {font-weight: bold;} .big {font-size: 3;} .reallybig {font-size: 4;} .greentext {color: #00FF00; font-size: 3;} From c7d91019ec4de64e8da4d456df63bc276d88ffd5 Mon Sep 17 00:00:00 2001 From: Akke Date: Fri, 25 Dec 2015 01:02:29 +0000 Subject: [PATCH 44/71] final revision --- code/game/gamemodes/nuclear/nuclear.dm | 2 +- code/game/objects/items/devices/uplinks.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index da015bfe940..58ca5ee53e4 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -306,7 +306,7 @@ belt = /obj/item/weapon/gun/projectile/automatic/pistol backpack_contents = list(/obj/item/weapon/storage/box/engineer=1) - var/tc = 20 + var/tc = 30 /datum/outfit/syndicate/no_crystals tc = 0 diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index bb40582afc5..bff49552851 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -193,7 +193,7 @@ var/list/world_uplinks = list() /obj/item/device/radio/uplink/New() hidden_uplink = new(src) icon_state = "radio" - hidden_uplink.uses = 30 + hidden_uplink.uses = 20 /obj/item/device/radio/uplink/attack_self(mob/user) if(hidden_uplink) From 019f460dc9ed2e774f15df20706216781510f354 Mon Sep 17 00:00:00 2001 From: LanCartwright Date: Fri, 25 Dec 2015 01:15:49 +0000 Subject: [PATCH 45/71] Update uplinks.dm --- code/game/objects/items/devices/uplinks.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index bff49552851..968ac08cf1d 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -193,7 +193,6 @@ var/list/world_uplinks = list() /obj/item/device/radio/uplink/New() hidden_uplink = new(src) icon_state = "radio" - hidden_uplink.uses = 20 /obj/item/device/radio/uplink/attack_self(mob/user) if(hidden_uplink) @@ -212,4 +211,4 @@ var/list/world_uplinks = list() /obj/item/device/radio/headset/uplink/New() ..() hidden_uplink = new(src) - hidden_uplink.uses = 20 \ No newline at end of file + hidden_uplink.uses = 20 From 8e9e6891d33463b5ee2d0ac3502e14c4a2461a08 Mon Sep 17 00:00:00 2001 From: Incoming Date: Thu, 24 Dec 2015 21:18:19 -0500 Subject: [PATCH 46/71] Makes the shot of whiskey actually a shot glass since some people wanted it and it's an easier problem to solve. --- code/modules/mob/living/simple_animal/bot/secbot.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index 48f9692636e..d84a6d112df 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -40,8 +40,9 @@ /mob/living/simple_animal/bot/secbot/beepsky/explode() var/turf/Tsec = get_turf(src) new /obj/item/weapon/stock_parts/cell/potato(Tsec) - var/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/G = new(Tsec) - G.list_reagents = list("whiskey" = 50) + var/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/shotglass/S = new(Tsec) + S.list_reagents = list("whiskey" = 15) + S.on_reagent_change() ..() /mob/living/simple_animal/bot/secbot/pingsky From 76b59e1d4c6ddd047203e78067864d975d9485e9 Mon Sep 17 00:00:00 2001 From: Incoming5643 Date: Thu, 24 Dec 2015 21:22:18 -0500 Subject: [PATCH 47/71] does the mso --- code/modules/mob/living/simple_animal/hostile/mimic.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index 961e76e77ea..1ad4bf941c3 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -119,7 +119,7 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca /mob/living/simple_animal/hostile/mimic/copy/Life() ..() - if(!target && !client) //Objects eventually revert to normal if no one is around to terrorize + if(!target && !ckey) //Objects eventually revert to normal if no one is around to terrorize adjustBruteLoss(1) for(var/mob/living/M in contents) //a fix for animated statues from the flesh to stone spell death() @@ -282,4 +282,4 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca minimum_distance = 1 return icon_state = TrueGun.icon_state - icon_living = TrueGun.icon_state \ No newline at end of file + icon_living = TrueGun.icon_state From 7fe24e4038d3089658dfebfcb083f47e9067cdb7 Mon Sep 17 00:00:00 2001 From: Incoming5643 Date: Thu, 24 Dec 2015 21:24:20 -0500 Subject: [PATCH 48/71] Find have your bigman --- interface/stylesheet.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index 840017fc300..37f1b5eaaa8 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -91,7 +91,7 @@ h1.alert, h2.alert {color: #000000;} .papyrus {font-family: "Papyrus", cursive, sans-serif;} .robot {font-family: "Courier New", cursive, sans-serif;} -.commmand_headset {font-weight: bold;} +.commmand_headset {font-weight: bold; font-size: 3;} .big {font-size: 3;} .reallybig {font-size: 4;} .greentext {color: #00FF00; font-size: 3;} From f95ad72fcd73159a7fcd00f10566c1d16b54fd09 Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Thu, 24 Dec 2015 21:35:26 -0500 Subject: [PATCH 49/71] Adds a sound and a brief description of the overmind's reagent at the time of creation. --- code/game/gamemodes/blob/powers.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 77b271c96d0..2e46052a8f2 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -110,6 +110,10 @@ if(candidates.len) //if we got a candidate, they're a blobbernaut now. C = pick(candidates) blobber.key = C.key + blobber << 'sound/effects/blobattack.ogg' + blobber << "You are a blobbernaut!" + blobber << "Your overmind's blob reagent is: [blob_reagent_datum.name]!" + blobber << "The [blob_reagent_datum.name] reagent [blob_reagent_datum.description]" /mob/camera/blob/verb/relocate_core() set category = "Blob" From 077f0ba2f1d56c31872e809cf5d0352c406fb863 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Fri, 25 Dec 2015 03:16:58 +0000 Subject: [PATCH 50/71] Automatic changelog generation for PR #13972 --- html/changelogs/AutoChangeLog-pr-13972.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-13972.yml diff --git a/html/changelogs/AutoChangeLog-pr-13972.yml b/html/changelogs/AutoChangeLog-pr-13972.yml new file mode 100644 index 00000000000..10f8d443ccb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-13972.yml @@ -0,0 +1,6 @@ +author: Joan +delete-after: True +changes: + - rscadd: "Overmind-created blobbernauts are now player-controlled if possible." + - tweak: "Creating a blobbernaut no longer destroys the factory, instead doing heavy damage to it and preventing it from spawning spores for one minute." + - tweak: "You cannot spawn blobbernauts from overly damaged factories." From 085a6c68e214c6ec6d68f7f32292a54488f8ead9 Mon Sep 17 00:00:00 2001 From: xxalpha Date: Fri, 25 Dec 2015 03:20:46 +0000 Subject: [PATCH 51/71] Fixed false wall smoothing --- code/__HELPERS/icon_smoothing.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/__HELPERS/icon_smoothing.dm b/code/__HELPERS/icon_smoothing.dm index 94e79e50fe9..d5d5b0d0148 100644 --- a/code/__HELPERS/icon_smoothing.dm +++ b/code/__HELPERS/icon_smoothing.dm @@ -194,6 +194,10 @@ /atom/proc/clear_smooth_overlays() overlays -= top_left_corner + top_left_corner = null overlays -= top_right_corner + top_right_corner = null overlays -= bottom_right_corner + bottom_right_corner = null overlays -= bottom_left_corner + bottom_left_corner = null From c3dfac53a37c4106b9cfc6aa79640e826aee6aa3 Mon Sep 17 00:00:00 2001 From: Tkdrg Date: Mon, 21 Dec 2015 12:57:29 -0300 Subject: [PATCH 52/71] Adds a smaller IRC nudge bot to the tools/ folder This is meant as a replacement to the 2.4k line monstrosity that is NanoTransenBot.py, and will hopefully be faster and break less often. Features: - NTbot-compatible nudge.py socket listener. - Supports NickServ IDENTIFY. - Attempts reconnection on socket timeout. --- bot/CORE_DATA.py | 13 - bot/C_eightball.py | 32 - bot/C_heaortai.py | 5 - bot/C_makequote.py | 21 - bot/C_maths.py | 70 -- bot/C_rot13.py | 23 - bot/C_rtd.py | 96 -- bot/C_sarcasticball.py | 30 - bot/C_srtd.py | 35 - bot/D_help.py | 60 - bot/FMLformatter.py | 55 - bot/LICENCE-bot_folder.txt | 5 + bot/Marakov/Marakov.Cache | 2450 ------------------------------------ bot/Marakov_Chain.py | 203 --- bot/Namecheck.py | 35 - bot/NanoTrasenBot.py | 1414 --------------------- bot/Shortname.py | 28 - bot/Timeconverter.py | 204 --- bot/Weather.py | 61 - bot/_____Readme.txt | 74 -- bot/config.py | 14 + bot/gen_fml.py | 15 - bot/htmltagremove.py | 28 - bot/irchat.py | 94 -- bot/linereader.py | 43 - bot/minibot.py | 104 ++ bot/nudge.py | 49 +- bot/save_load.py | 24 - bot/some_but_not_all_2.py | 20 - bot/xkcdparser.py | 40 - 30 files changed, 140 insertions(+), 5205 deletions(-) delete mode 100644 bot/CORE_DATA.py delete mode 100644 bot/C_eightball.py delete mode 100644 bot/C_heaortai.py delete mode 100644 bot/C_makequote.py delete mode 100644 bot/C_maths.py delete mode 100644 bot/C_rot13.py delete mode 100644 bot/C_rtd.py delete mode 100644 bot/C_sarcasticball.py delete mode 100644 bot/C_srtd.py delete mode 100644 bot/D_help.py delete mode 100644 bot/FMLformatter.py create mode 100644 bot/LICENCE-bot_folder.txt delete mode 100644 bot/Marakov/Marakov.Cache delete mode 100644 bot/Marakov_Chain.py delete mode 100644 bot/Namecheck.py delete mode 100644 bot/NanoTrasenBot.py delete mode 100644 bot/Shortname.py delete mode 100644 bot/Timeconverter.py delete mode 100644 bot/Weather.py delete mode 100644 bot/_____Readme.txt create mode 100644 bot/config.py delete mode 100644 bot/gen_fml.py delete mode 100644 bot/htmltagremove.py delete mode 100644 bot/irchat.py delete mode 100644 bot/linereader.py create mode 100755 bot/minibot.py mode change 100644 => 100755 bot/nudge.py delete mode 100644 bot/save_load.py delete mode 100644 bot/some_but_not_all_2.py delete mode 100644 bot/xkcdparser.py diff --git a/bot/CORE_DATA.py b/bot/CORE_DATA.py deleted file mode 100644 index ca235888f15..00000000000 --- a/bot/CORE_DATA.py +++ /dev/null @@ -1,13 +0,0 @@ -Name = "CC_NanoTrasen" #The name he uses to connect -no_absolute_paths = True -debug_on = False -SName = ["cc","nt","trasen","nano","nanotrasen"] #Other names he will respond to, in lowercase -DISABLE_ALL_NON_MANDATORY_SOCKET_CONNECTIONS = False -directory = "bot/directory/here/" # Directory the bot is located in, make sure to keep the "/" at the end -version = "TG CC-BY-SA 6" -Network = 'YOUR.SERVER.HERE' #e.g. "irc.rizon.net" -channel = "#YOUR CHANNEL HERE" #what channel you want the bot in -channels = ["#YOUR CHANNEL HERE"] #same as above -greeting = "Welcome!" #what he says when a person he hasn't seen before joins -prefix = "!" #prefix for bot commands -Port = 7000 diff --git a/bot/C_eightball.py b/bot/C_eightball.py deleted file mode 100644 index 2ed73dafd57..00000000000 --- a/bot/C_eightball.py +++ /dev/null @@ -1,32 +0,0 @@ -from random import choice as fsample #Yay for added speed! -global responses -responses = ['Yes','Too bad','Will you turn me off if I tell you?','Absolutely', - "Not at all", "Nope", "It does", "No", "All the time", - "I don't really know", "Could be","Possibly","You're still here?",# Chaoticag - "No idea", "Of course", "Would you turn me off if I tell you?", - "Sweet!","Nah","Certainly","Yeah","Yup","I am quite confident that the answer is Yes", - "Perhaps", "Yeeeeaah... No.", "Indubitably" ] # Richard -def eightball(data,debug,sender,prefix): - global responses - arg = data.lower().replace(prefix+"eightball ","") - arg = arg.replace(prefix+"8ball ","") - if debug: - print sender+":"+prefix+"eightball", arg - if "answer" in arg and "everything" in arg and "to" in arg: - if debug: - print "Responded with",42 - return "42" - elif arg == "derp": - if debug: - print "Responded with herp" - return("herp") - elif arg == "herp": - if debug: - print "Responded with derp" - return("derp") - else: - #choice = sample(responses,1)[0] - choice = fsample(responses) - if debug: - print "Responded with", choice - return(choice) diff --git a/bot/C_heaortai.py b/bot/C_heaortai.py deleted file mode 100644 index 6e8b304e73b..00000000000 --- a/bot/C_heaortai.py +++ /dev/null @@ -1,5 +0,0 @@ -#Throws a coin, simple. -from random import random -def heaortai(debug,sender): return("Heads" if random() > 0.5 else "Tails") -# Takes 1/6th the time of doing it with random.randint(0,1) -# This file used to be a lot bigger, now it's kind of useless. diff --git a/bot/C_makequote.py b/bot/C_makequote.py deleted file mode 100644 index f79b863449a..00000000000 --- a/bot/C_makequote.py +++ /dev/null @@ -1,21 +0,0 @@ -from save_load import save -from os import listdir -import CORE_DATA -directory = CORE_DATA.directory -def mkquote(prefix,influx,sender,debug): - arg = influx[10+len(prefix):] - if debug: - print sender+":"+prefix+"makequote "+str(len(arg))+" Characters" - if len(arg) == 0: - return("Type something to a quote") - else: - files = listdir(directory+"userquotes") - numb = 0 - while True: - numb += 1 - if sender.lower()+str(numb) in files: - pass - else: - save(directory+"userquotes/"+sender.lower()+str(numb),[arg,sender.lower()]) - return("Saved as:"+sender.lower()+str(numb)) - break diff --git a/bot/C_maths.py b/bot/C_maths.py deleted file mode 100644 index 86013b74a7b..00000000000 --- a/bot/C_maths.py +++ /dev/null @@ -1,70 +0,0 @@ -### EXPERIMENTAL PROTOTYPE ### -# e = 2.7182818284590452353602874713526624977572 -# pi = math.pi -from __future__ import division #PYTHON Y U NO TELL ME THIS BEFORE -import math -import random -import re -e = "2.7182818284590452353602874713526624977572" -pi = str(math.pi) -global pre -pre = len("maths ") -def maths(influx,prefix="!",sender="NaN",debug=True,method="n"): - global pre - influx = influx.lower() - influx = influx[len(prefix)+pre:] - influx = influx.replace("pie",pi+"*"+e) - influx = influx.replace("e*",e+"*") - influx = influx.replace("*e","*"+e) - influx = influx.replace("pi",pi) - if debug: - print sender+":"+prefix+"maths" - if influx.count("**") == 0 and influx.count('"') == 0 and influx.count("'") == 0 and influx.count(";") == 0 and influx.count(":") == 0: - influx_low = influx.lower() - influx_hi = influx.upper() - if "0b" in influx_low: - influx_low = re.sub("0b[0-1]*","",influx_low) - influx_hi = re.sub("0B[0-1]*","",influx_hi) - if "0x" in influx_low: - influx_low = re.sub("0x[a-f0-9]*","",influx_low) - influx_hi = re.sub("0X[A-F0-9]*","",influx_hi) - if "rand" in influx_low: - influx_low = re.sub("rand","",influx_low) - influx_hi = re.sub("RAND","",influx_hi) - if influx_low == influx_hi: - influx = re.sub("rand","random.random()",influx) - try: - result = eval(influx.lower()) - except ZeroDivisionError: - return "Divide by zero detected." - except SyntaxError: - return "Syntax Error detected." - except TypeError: - return "Type Error detected." - except: - return "Unknown Error detected." - else: - if method == "n": #Normal - return result - elif method == "i": #Forced Int - return int(result) - elif method == "h": #Hex - try: - if "L" in hex(result)[2:]: - return hex(result)[2:-1] - else: - return hex(result)[2:].upper() - except TypeError: - return "That value (%s) cannot be interpreted properly using !hmaths" %(str(result)) - elif method == "b": #Binary - try: - return bin(result)[2:].upper() - except TypeError: - return "That value (%s) cannot be interpreted properly using !bmaths" %(str(result)) - else: - return result - else: - return "What are you trying to make me do again?" - else: - return "Those are likely to make me hang" - diff --git a/bot/C_rot13.py b/bot/C_rot13.py deleted file mode 100644 index 62b72dc2ad2..00000000000 --- a/bot/C_rot13.py +++ /dev/null @@ -1,23 +0,0 @@ -global parta,partb -parta = {"A":"N","B":"O","C":"P","D":"Q","E":"R","F":"S","G":"T","H":"U","I":"V","J":"W","K":"X","L":"Y","M":"Z"} -partb = {'O':'B','N':'A','Q':'D','P':'C','S':'F','R':'E','U':'H','T':'G','W':'J','V':'I','Y':'L','X':'K','Z':'M'} -def rot13(text): - global parta,partb - newtext = "" - for letter in text: - try: - if letter.isupper(): - newtext += parta[letter] - else: - newtext += parta[letter.upper()].lower() - except: - try: - if letter.isupper(): - newtext += partb[letter] - pass - else: - newtext += partb[letter.upper()].lower() - pass - except: - newtext += letter - return newtext diff --git a/bot/C_rtd.py b/bot/C_rtd.py deleted file mode 100644 index 96736fec21c..00000000000 --- a/bot/C_rtd.py +++ /dev/null @@ -1,96 +0,0 @@ -import random -def rtd(data,debug,sender): - backo = data - try: - arg1,arg2 = backo.split("d") - except ValueError, err: - return("Too many or too small amount of arguments") - else: - if debug: - print sender+":!rtd "+arg1+"d"+arg2 #faster than using %s's - die,die2 = [],[] - current_mark = "" - outcome = 0 - realnumberfound = False - checks = [] - count = 0 - arg1 = arg1.replace(" ","") - arg2 = arg2.replace(" ","") - try: - i_arg1 = int(arg1) - a_arg1 = abs(i_arg1) - if "+" in arg2 or "-" in arg2: - plus_spot = arg2.find("+") - minus_spot = arg2.find("-") - if plus_spot == -1 and minus_spot == -1: - nicer_form = "" - elif plus_spot != -1 and minus_spot == -1: - nicer_form = arg2[plus_spot:] - elif plus_spot == -1 and minus_spot != -1: - nicer_form = arg2[minus_spot:] - else: - if plus_spot < minus_spot: - nicer_form = arg2[plus_spot:] - else: - nicer_form = arg2[minus_spot:] - for letter in arg2: - if letter == "+" or letter == "-": - current_mark = letter - checks = [] - count += 1 - continue - checks.append(letter) - try: - next_up = arg2[count+1] - except: - if realnumberfound == False: - i_arg2 = int("".join(checks)) - checks = [] - realnumberfound = True - elif current_mark == "+": - outcome += int("".join(checks)) - else: - outcome -= int("".join(checks)) - else: - if next_up == "+" or next_up == "-": - if realnumberfound == False: - i_arg2 = int("".join(checks)) - checks = [] - realnumberfound = True - else: - if current_mark == "+": - outcome += int("".join(checks)) - else: - outcome -= int("".join(checks)) - checks = [] - count += 1 - else: - i_arg2 = int(arg2) - if a_arg1 == 0 or abs(i_arg2) == 0: - raise RuntimeError - except ValueError: - return("You lied! That's not a number!") - except RuntimeError: - return("Too many zeroes!") - else: - if a_arg1 > 100: - return("Too many rolls, I can only do one hundred at max.") - else: - for i in xrange(0,a_arg1): - if i_arg2 < 0: - dice = random.randint(i_arg2,0) - else: - dice = random.randint(1,i_arg2) - die.append(dice) - die2.append(str(dice)) - if i_arg2 < 0: - flist = "".join(die2) - else: - flist = "+".join(die2) - if len(flist) > 350: - return(str(reduce(lambda x,y: x+y, die)+outcome)) - else: - if current_mark == "": - return(flist+" = "+str(reduce(lambda x,y: x+y, die)+outcome)) - else: - return(flist+" ("+nicer_form+") = "+str(reduce(lambda x,y: x+y, die)+outcome)) diff --git a/bot/C_sarcasticball.py b/bot/C_sarcasticball.py deleted file mode 100644 index 1f5ae321816..00000000000 --- a/bot/C_sarcasticball.py +++ /dev/null @@ -1,30 +0,0 @@ -from random import choice as fsample -sarcastic_responses = ["Yeah right","What do I look like to you?","Are you kidding me?",#UsF - "As much as you","You don't believe that yourself","When pigs fly",#UsF - "Like your grandma","You would like to know, wouldn't you?", #UsF - "Like your mom", #Spectre - "Totally","Not at all", #Spectre - "AHAHAHahahaha, No.", #Strumpetplaya - "Not as much as USER","As much as USER", - "Really, you expect me to tell you that?", - "Right, and you've been building NOUNs for those USERs in the LOCATION, haven't you?" ] #Richard -locations = ["woods","baystation","ditch"] -nouns = ["bomb","toilet","robot","cyborg", - "garbage can","gun","cake", - "missile"] -def sarcasticball(data,debug,sender,users,prefix): - arg = data.lower().replace(prefix+"sarcasticball ","") - arg = arg.replace(prefix+"sball ","") - if debug: - print sender+":"+prefix+"sarcasticball", arg - choice = fsample(sarcastic_responses) - if "USER" in choice: - choice = choice.replace("USER",fsample(users),1) - choice = choice.replace("USER",fsample(users),1) - if "NOUN" in choice: - choice = choice.replace("NOUN",fsample(nouns),1) - if "LOCATION" in choice: - choice = choice.replace("LOCATION",fsample(locations),1) - if debug: - print "Responded with", choice - return(choice) diff --git a/bot/C_srtd.py b/bot/C_srtd.py deleted file mode 100644 index 761c0628d69..00000000000 --- a/bot/C_srtd.py +++ /dev/null @@ -1,35 +0,0 @@ -import random -def srtd(data,debug,sender): - try: - arg1,arg2 = data.split("d") - except ValueError, err: - if str(err) == "need more than 1 value to unpack": - return("Too small amount of arguments") - else: - return("Too many arguments") - else: - if debug: - print sender+":!rtd "+arg1+"d"+arg2 - die = [] - arg1 = arg1.replace(" ","") - arg2 = arg2.replace(" ","") - try: - i_arg1 = int(arg1) - i_arg2 = int(arg2) - if abs(i_arg1) == 0 or abs(i_arg2) == 0: - raise RuntimeError - except ValueError: - return("You lied! That's not a number!") - except RuntimeError: - return("Too many zeroes!") - else: - if abs(i_arg1) > 500: - return("Too many rolls, I can only do five hundred at max.") - else: - for i in xrange(0,abs(i_arg1)): - if i_arg2 < 0: - dice = random.randint(i_arg2,0) - else: - dice = random.randint(1,i_arg2) - die.append(dice) - return(str(reduce(lambda x,y: x+y, die))) diff --git a/bot/D_help.py b/bot/D_help.py deleted file mode 100644 index ee4e2c07cfe..00000000000 --- a/bot/D_help.py +++ /dev/null @@ -1,60 +0,0 @@ -#As new commands are added, update this. -# Last updated: 8.3.2011 - -# Updated 12.3.2011: -# - Added the missing help data for Version -# - Imported CORE_DATA to get the name. -# - Tidied some commands up a bit. -# - Replaced all "Bot"s with the Skibot's current name. - -from CORE_DATA import Name -everything = {"8ball":"[8ball ] Responds to the argument", - "allcaps":"[allcaps ] Takes an uppercase string and returns a capitalized version", - "bmaths":"[bmaths ] Takes a math equation (Like 5+5) and returns a binary result", - "coin":"[coin] Flips a coin", - "dance":"[dance] Makes %s do a little dance" %(Name), - "delquote":"(OP ONLY) [delquote ] Removes a quote with the filename equal to the argument", - "disable":"(OP ONLY) [disable] Disables all output from %s" %(Name), - "disable dance":"(HALFOP / OP ONLY) [disable dance] or [dd] Toggles dancing", - "disable fml":"(HALFOP / OP ONLY) [disable fml] Disables FML", - "eightball":"[eightball ] Responds to the argument", - "enable":"(OP ONLY) [enable] After being disabled, enable will turn output back on", - "enable fml":"{HALFOP / OP ONLY} [enable fml] After fml has been disabled, enable fml will make it available again", - "fml":"[fml] Returns a random Fuck My Life bit", - "give":"[give ] Gives the Pneumatic Disposal Unit the argument", - "help":"[help []] Returns the list of commands or a detailed description of a command if specified", - "hmaths":"[hmaths ] Takes a math equation (Like 5+5) and returns a hex result", - "makequote":"[makequote ] Creates a quote with arg being the quote itself", - "maths":"[maths ] Takes a math equation (Like 5+5) and returns a default result", - "note":"[note []] Opens a note if only arg1 is specified, Creates a note with the name of arg1 and contents of arg2 if arg2 is specified, if you prefix the note name with [CP], it creates a public note only to that channel. Which can be accessed by !note _", - "notes":"[notes] Displays all your saved notes on %s" %(Name), - "otherball":"[otherball] If Floorbot is on the same channel, %s will ask him a random question when this command is passed" %(Name), - "purgemessages":"[purgemessages] Used to delete all your Tell messages (%s,Tell )" %(Name), - "quote":"[quote []] Picks a random quote, if the author is specified, a random quote by that author", - "redmine":"[redmine] If you have a note called redmine, with a valid whoopshop redmine address, this displays all the bugs labeled as 'New' on that page. It also displays the todo note if it's found.", - "replace":"[replace] Fixes the Pneumatic Smasher if it's been broken", - "rot13":"[rot13 ] Encrypts the arg by using the rot13 method", - "rtd":"[rtd [d]] Rolls a six-sided dice if no arguments are specified, otherwise arg1 is the amount of rolls and arg2 is the amount of sides the dice have", - "sarcasticball":"[sarcasticball ] Responds to the argument sarcastically", - "sball":"[sball ] Responds to the argument sarcastically", - "srtd":"[srtd d] Rolls amount of sided die without showing the dice values separately", - "stop":"(RESTRICTED TO OP AND CREATOR) [stop] Stops %s, plain and simple" %(Name), - "suggest":"[suggest ] Saves a suggestion given to %s, to be later viewed by the creator" %(Name), - "take":"[take ] Takes an item specified in the argument from the Pneumatic Smasher", - "tban":"(OP ONLY) [tban ] When %s is an operator, You can ban an user for specified amount of seconds" %(Name), - "thm":"(RESTRICTED TO OP AND CREATOR) [thm] Normally in 8ball and sarcasticball, Users are not shown, instead replaced by things like demons or plasma researchers, toggling this changes that behaviour.", - "tm":"(OP AND CREATOR ONLY) [tm] Toggles marakov", - "togglequotemakers":"(OP ONLY) [togglequotemakers or tqm] Normally with the quote command, makers are not shown, this toggles that behaviour.", - "tqm":"(OP ONLY) [tqm or togglequotemakers] Normally with the quote command, makers are not shown, this toggles that behaviour.", - "toggleofflinemessages":"(OP ONLY) [toggleofflinemessages or tom] Allows an operator to toggle leaving Tell messages (%s, Tell ] Whenever the user says something in allcaps, it's capitalized.", - "uptime":"[uptime] Displays how long %s has been alive on the channel."%(Name), - "use":"[use] Uses the Pneumatic Smasher.", - "youtube":"[youtube ] Shows the title of a video by checking the URL provided.", - "version":"[version] Shows the current version of %s." %(Name), - "weather":"[weather ] Displays the current weather of the provided location.", - "life":"I cannot help you with that, sorry."} - diff --git a/bot/FMLformatter.py b/bot/FMLformatter.py deleted file mode 100644 index 153af61a41a..00000000000 --- a/bot/FMLformatter.py +++ /dev/null @@ -1,55 +0,0 @@ -from htmltagremove import htr -def formatter(data): - newdata = [] - data = htr(data) - bad = ["Your nick : Categories : ","\r","Advanced search - last", - "FMyLife","Get the guts to spill the beans","FML: Your random funny stories", - "Woman","Man","Choose","Health","Intimacy","Miscellaneous","Man or woman? ", - "Money","Kids","Work","Love","Email notification?", - "Moderate the FMLs","Submit your FML story", - "- If your story isn't published on the website, don't feel offended, and thank you nevertheless!", - "Pick a country","See all","Your account","Team's blog", - "Meet the FMLHello readers! Did you meet someone new this...The whole blog", - "Amazon","Borders","IndieBound","Personalized book","Terms of use", - "FML t-shirts -","Love - Money - Kids - Work - Health - Intimacy - Miscellaneous - Members", - "Follow the FML Follow the FML blog Follow the FML comments ", - "_qoptions={", - "};","})();","Categories","Sign up - Password? ", " Net Avenir : gestion publicitaire", - "FMyLife, the book","Available NOW on:","Barnes & Noble"] - - for checkable in data: - if checkable in bad: - pass - elif "_gaq.push" in checkable: - pass - elif "ga.src" in checkable: - pass - elif "var _gaq" in checkable: - pass - elif "var s =" in checkable: - pass - elif "var ga" in checkable: - pass - elif "function()" in checkable: - pass - elif "siteanalytics" in checkable: - pass - elif "qacct:" in checkable: - pass - elif "\r" in checkable: - pass - elif "ic_" in checkable: - pass - elif "Please note that spam and nonsensical stories" in checkable: - pass - elif "Refresh this page" in checkable: - pass - elif "You...The whole blo" in checkable: - pass - elif "Net Avenir : gestion publicitair" in checkable: - pass - else: - if "Net Avenir : gestion publicitaireClose the advertisement" in checkable: - checkable = checkable.replace("Net Avenir : gestion publicitaireClose the advertisement","") - newdata.append(checkable) - return newdata diff --git a/bot/LICENCE-bot_folder.txt b/bot/LICENCE-bot_folder.txt new file mode 100644 index 00000000000..22dfb254600 --- /dev/null +++ b/bot/LICENCE-bot_folder.txt @@ -0,0 +1,5 @@ +The author or authors of this code dedicate any and all copyright interest in +this code to the public domain. We make this dedication for the benefit of the +public at large and to the detriment of our heirs and successors. We intend +this dedication to be an overt act of relinquishment in perpetuity of all +present and future rights to this code under copyright law. diff --git a/bot/Marakov/Marakov.Cache b/bot/Marakov/Marakov.Cache deleted file mode 100644 index 500f4384edd..00000000000 --- a/bot/Marakov/Marakov.Cache +++ /dev/null @@ -1,2450 +0,0 @@ -(dp0 -S'all' -p1 -(lp2 -S':p' -p3 -aS'the' -p4 -asS'code' -p5 -(lp6 -S'in' -p7 -asS'stores' -p8 -(lp9 -S'that' -p10 -asS'just' -p11 -(lp12 -S'like' -p13 -aS'marakov' -p14 -aS'felt' -p15 -aS'gives' -p16 -aS'a' -p17 -aS'add' -p18 -aS'what' -p19 -asS'being' -p20 -(lp21 -S'goon' -p22 -aS'a' -p23 -asS'text' -p24 -(lp25 -S'string' -p26 -asS'dependant' -p27 -(lp28 -S'on' -p29 -asS'speedup' -p30 -(lp31 -S'at' -p32 -asS'felt' -p33 -(lp34 -S'like' -p35 -asS'installed' -p36 -(lp37 -S'tho' -p38 -asS'disabled' -p39 -(lp40 -S'it' -p41 -asS'timing' -p42 -(lp43 -S'when' -p44 -asS'psyco' -p45 -(lp46 -S'installed' -p47 -aS'is' -p48 -asS'stops' -p49 -(lp50 -S'timing' -p51 -asS'file' -p52 -(lp53 -S'too' -p54 -aS'that' -p55 -aS'where' -p56 -asS'go' -p57 -(lp58 -S'fuck' -p59 -aS'into' -p60 -aS'test' -p61 -asS'hell' -p62 -(lp63 -S'recreate' -p64 -asS'configurable' -p65 -(lp66 -S'greeting' -p67 -asS'bs12' -p68 -(lp69 -S'message' -p70 -asS'its' -p71 -(lp72 -S'fine' -p73 -aS'just' -p74 -aS'calculated' -p75 -aS'not' -p76 -aS'really' -p77 -aS'ridiculously' -p78 -aS'now' -p79 -aS'a' -p80 -aS'missing' -p81 -aS'for' -p82 -aS'false' -p83 -aS'on' -p84 -asS'before' -p85 -(lp86 -S'that' -p87 -asS'rp-heavy' -p88 -(lp89 -S'server' -p90 -asS'announcement' -p91 -(lp92 -S'like' -p93 -asS'now' -p94 -(lp95 -S'it' -p96 -aS'running' -p97 -aS'makie' -p98 -aS'i' -p99 -asS'nudge' -p100 -(lp101 -S'python' -p102 -aS'is' -p103 -asS'sourced' -p104 -(lp105 -S'under' -p106 -asS'title' -p107 -(lp108 -S'of' -p109 -asS'situations' -p110 -(lp111 -S'where' -p112 -asS'fine-tune' -p113 -(lp114 -S'it' -p115 -asS'enough' -p116 -(lp117 -S'to' -p118 -asS'send' -p119 -(lp120 -S'it' -p121 -aS'one' -p122 -asS'should' -p123 -(lp124 -S'be' -p125 -aS'learn' -p126 -aS'we' -p127 -asS'values' -p128 -(lp129 -S'dont' -p130 -asS'to' -p131 -(lp132 -S'edit' -p133 -aS'back' -p134 -aS'know' -p135 -aS'care' -p136 -aS'be' -p137 -aS'configure' -p138 -aS'the' -p139 -aS'null' -p140 -aS'phone' -p141 -aS'welcome' -p142 -aS'reverse' -p143 -aS'send' -p144 -aS'reg' -p145 -aS'point' -p146 -aS'automatically' -p147 -aS'work' -p148 -aS'waste' -p149 -aS'marshmallow' -p150 -aS'queries' -p151 -aS'+o' -p152 -aS'disable' -p153 -asS'jit' -p154 -(lp155 -S'compiler' -p156 -asS'going' -p157 -(lp158 -S'to' -p159 -asS'helps' -p160 -(lp161 -S'me' -p162 -asS'messes' -p163 -(lp164 -S'it' -p165 -asS'indeed' -p166 -(lp167 -S'it' -p168 -asS'tg' -p169 -(lp170 -S'and' -p171 -asS'has' -p172 -(lp173 -S'been' -p174 -aS'my' -p175 -asS'into' -p176 -(lp177 -S'#tgstation13' -p178 -asS'ridiculously' -p179 -(lp180 -S'simple' -p181 -asS'annoy' -p182 -(lp183 -S'downstream' -p184 -asS'them' -p185 -(lp186 -S'out' -p187 -asS'someone' -p188 -(lp189 -S'adminhelps' -p190 -asS'sense' -p191 -(lp192 -S'i' -p193 -asS'string' -p194 -(lp195 -S'called' -p196 -asS'get' -p197 -(lp198 -S'ready' -p199 -asS'python' -p200 -(lp201 -S'script' -p202 -aS'so' -p203 -aS'code' -p204 -aS'scripts' -p205 -aS'and' -p206 -aS'but' -p207 -aS'now' -p208 -aS'released' -p209 -aS'is' -p210 -aS'enough' -p211 -asS'goon' -p212 -(lp213 -S'tg' -p214 -asS'showing' -p215 -(lp216 -S'up' -p217 -asS'20ish' -p218 -(lp219 -S'line' -p220 -asS'gonna' -p221 -(lp222 -S'go' -p223 -asS'made' -p224 -(lp225 -S'doctors' -p226 -asS'every' -p227 -(lp228 -S'loop' -p229 -aS'time' -p230 -asS'know' -p231 -(lp232 -S'the' -p233 -aS'why' -p234 -aS'that' -p235 -asS'not' -p236 -(lp237 -S'just' -p238 -aS'necessary' -p239 -aS'to' -p240 -aS'so' -p241 -aS'need' -p242 -aS'sure' -p243 -aS'relaying' -p244 -aS'very' -p245 -aS'even' -p246 -asS'2' -p247 -(lp248 -S'loop' -p249 -asS'password' -p250 -(lp251 -S'var' -p252 -asS'day' -p253 -(lp254 -S'so' -p255 -asS'swapping' -p256 -(lp257 -S'to' -p258 -asS'easily' -p259 -(lp260 -S'editable' -p261 -asS'necessary' -p262 -(lp263 -S'at' -p264 -asS'like' -p265 -(lp266 -S'being' -p267 -aS'linking' -p268 -aS'to' -p269 -aS'how' -p270 -aS'it' -p271 -aS'skbzzzzzibi' -p272 -asS'course' -p273 -(lp274 -S'that' -p275 -asS'edit' -p276 -(lp277 -S'baystation' -p278 -asS'fully' -p279 -(lp280 -S'open' -p281 -asS'greeting' -p282 -(lp283 -S'message' -p284 -asS'server' -p285 -(lp286 -S'basically' -p287 -aS'' -p288 -asS'default' -p289 -(lp290 -S'config' -p291 -asS'bad' -p292 -(lp293 -S'company' -p294 -asS'channel' -p295 -(lp296 -S'or' -p297 -asS'always' -p298 -(lp299 -S'makes' -p300 -asS'went' -p301 -(lp302 -S'past' -p303 -asS'quarxink' -p304 -(lp305 -S'its' -p306 -asS'automatic' -p307 -(lp308 -S'announcement' -p309 -asS'once' -p310 -(lp311 -S'per' -p312 -asS'wrote' -p313 -(lp314 -S'most' -p315 -asS'pain' -p316 -(lp317 -S'on' -p318 -asS'system' -p319 -(lp320 -S'calls' -p321 -asS'right' -p322 -(lp323 -S'brb' -p324 -asS'decides' -p325 -(lp326 -S'not' -p327 -asS'people' -p328 -(lp329 -S'say' -p330 -aS'i' -p331 -aS'he' -p332 -asS'goddamn' -p333 -(lp334 -S'python' -p335 -asS'back' -p336 -(lp337 -S'it' -p338 -asS'used' -p339 -(lp340 -S'to' -p341 -aS'for' -p342 -asS'past' -p343 -(lp344 -S'too' -p345 -asS'cost' -p346 -(lp347 -S'of' -p348 -asS'learn' -p349 -(lp350 -S'python' -p351 -asS'are' -p352 -(lp353 -S'lawyers' -p354 -aS'actually' -p355 -aS'configurable' -p356 -aS'we' -p357 -asS'celestialike' -p358 -(lp359 -S'of' -p360 -asS'lawyers' -p361 -(lp362 -S'for' -p363 -asS'time' -p364 -(lp365 -S'he' -p366 -asS'out' -p367 -(lp368 -S'switch' -p369 -aS'slowdowns' -p370 -aS'that' -p371 -aS'why' -p372 -aS'nudge' -p373 -asS'even' -p374 -(lp375 -S'an' -p376 -asS'what' -p377 -(lp378 -S'the' -p379 -aS'is' -p380 -aS'these' -p381 -aS'was' -p382 -aS'license' -p383 -aS'about' -p384 -aS'i' -p385 -asS'said' -p386 -(lp387 -S'in' -p388 -asS'sayt' -p389 -(lp390 -S'hat' -p391 -asS'for' -p392 -(lp393 -S'that' -p394 -aS'every' -p395 -aS'the' -p396 -aS'quarx' -p397 -aS'cc_nanotrasen' -p398 -aS'homoerotic' -p399 -aS'situations' -p400 -aS'good' -p401 -asS'#tgstation13' -p402 -(lp403 -S'and' -p404 -asS'per' -p405 -(lp406 -S'name' -p407 -asS'whole' -p408 -(lp409 -S'config' -p410 -asS'state' -p411 -(lp412 -S'the' -p413 -asS'does' -p414 -(lp415 -S'the' -p416 -aS'it' -p417 -asS'goes' -p418 -(lp419 -S'on' -p420 -asS'readme' -p421 -(lp422 -S'too' -p423 -asS'new' -p424 -(lp425 -S'bot' -p426 -aS'person' -p427 -asS'learned' -p428 -(lp429 -S'python' -p430 -asS'irc' -p431 -(lp432 -S'bot' -p433 -asS'reg' -p434 -(lp435 -S'it' -p436 -asS'blow' -p437 -(lp438 -S'borgs' -p439 -asS'shut' -p440 -(lp441 -S'down' -p442 -asS'after' -p443 -(lp444 -S'an' -p445 -aS'a' -p446 -asS'ill' -p447 -(lp448 -S'switch' -p449 -asS'says' -p450 -(lp451 -S'someones' -p452 -asS'queries' -p453 -(lp454 -S'again' -p455 -asS'technocracy' -p456 -(lp457 -S'and' -p458 -asS'we' -p459 -(lp460 -S'go' -p461 -aS'do' -p462 -aS'totally' -p463 -aS'going' -p464 -aS'expect' -p465 -aS'just' -p466 -aS'dont' -p467 -aS'have' -p468 -asS'put' -p469 -(lp470 -S'all' -p471 -asS'from' -p472 -(lp473 -S'the' -p474 -asS'data11lower' -p475 -(lp476 -S'==' -p477 -asS'configuration' -p478 -(lp479 -S'for' -p480 -asS'wait' -p481 -(lp482 -S'what' -p483 -asS'on' -p484 -(lp485 -S'my' -p486 -aS'the' -p487 -aS'a' -p488 -aS'connect' -p489 -aS'svn' -p490 -aS'one' -p491 -aS'/' -p492 -asS'about' -p493 -(lp494 -S'system' -p495 -asS'ok' -p496 -(lp497 -S'thats' -p498 -asS'reverse' -p499 -(lp500 -S'engineer' -p501 -asS'license' -p502 -(lp503 -S'is' -p504 -asS'oh' -p505 -(lp506 -S'okay' -p507 -aS'ok' -p508 -aS'i' -p509 -aS'wait' -p510 -asS'starts' -p511 -(lp512 -S'timing' -p513 -asS'could' -p514 -(lp515 -S'learn' -p516 -asS'larger' -p517 -(lp518 -S'ram' -p519 -asS'bot' -p520 -(lp521 -S'is' -p522 -aS'have' -p523 -aS'shut' -p524 -aS'uses' -p525 -asS'running' -p526 -(lp527 -S'it' -p528 -aS'the' -p529 -aS'on' -p530 -asS'times' -p531 -(lp532 -S'on' -p533 -aS'reported' -p534 -aS'went' -p535 -asS'where' -p536 -(lp537 -S'he' -p538 -asS'heck' -p539 -(lp540 -S':d' -p541 -asS'idk' -p542 -(lp543 -S'magic' -p544 -asS'receives' -p545 -(lp546 -S'a' -p547 -asS'bots' -p548 -(lp549 -S'showing' -p550 -asS'slightly' -p551 -(lp552 -S'larger' -p553 -asS'or' -p554 -(lp555 -S'know' -p556 -aS'what' -p557 -aS'work' -p558 -aS'should' -p559 -aS'data11lower' -p560 -asS'automatically' -p561 -(lp562 -S'state' -p563 -asS'thats' -p564 -(lp565 -S'not' -p566 -aS'the' -p567 -aS'kind' -p568 -asS'ugh' -p569 -(lp570 -S'fuck' -p571 -asS'major' -p572 -(lp573 -S'ss13' -p574 -aS'three' -p575 -asS'py' -p576 -(lp577 -S'file' -p578 -asS'soss' -p579 -(lp580 -S'server' -p581 -asS'dont' -p582 -(lp583 -S'need' -p584 -aS'have' -p585 -aS'send' -p586 -aS'want' -p587 -aS'speak' -p588 -asS'hostmask' -p589 -(lp590 -S'combination' -p591 -asS'point' -p592 -(lp593 -S'out' -p594 -aS'has' -p595 -asS'simple' -p596 -(lp597 -S'to' -p598 -asS'miura' -p599 -(lp600 -S'doesnt' -p601 -asS'variables' -p602 -(lp603 -S'in' -p604 -asS'recreate' -p605 -(lp606 -S'it' -p607 -asS'welcome' -p608 -(lp609 -S'to' -p610 -asS'linking' -p611 -(lp612 -S'them' -p613 -asS'down' -p614 -(lp615 -S'when' -p616 -asS'why' -p617 -(lp618 -S'its' -p619 -aS'it' -p620 -aS'is' -p621 -asS'doesnt' -p622 -(lp623 -S'play' -p624 -aS'call' -p625 -asS'marakov' -p626 -(lp627 -S'loops' -p628 -aS'helps' -p629 -asS'laugh' -p630 -(lp631 -S'when' -p632 -asS'pony' -p633 -(lp634 -S'asshole' -p635 -asS'message' -p636 -(lp637 -S'has' -p638 -aS'should' -p639 -asS'open' -p640 -(lp641 -S'sourced' -p642 -aS'source' -p643 -asS'brb' -p644 -(lp645 -S'swapping' -p646 -asS'speak' -p647 -(lp648 -S'python' -p649 -asS'pastebin' -p650 -(lp651 -S'the' -p652 -asS'line' -p653 -(lp654 -S'core' -p655 -aS'on' -p656 -asS'three' -p657 -(lp658 -S'being' -p659 -asS'yay' -p660 -(lp661 -S'it' -p662 -asS'meatbag' -p663 -(lp664 -S'when' -p665 -asS'would' -p666 -(lp667 -S'be' -p668 -aS'expect' -p669 -asS'script' -p670 -(lp671 -S'that' -p672 -asS'illegal' -p673 -(lp674 -S'ban' -p675 -asS'there' -p676 -(lp677 -S'are' -p678 -aS'we' -p679 -asS'add' -p680 -(lp681 -S'that' -p682 -aS'a' -p683 -asS'been' -p684 -(lp685 -S'processed' -p686 -asS'name' -p687 -(lp688 -S'/' -p689 -aS'when' -p690 -asS'ai' -p691 -(lp692 -S'malf' -p693 -asS'marshmallow' -p694 -(lp695 -S'pony' -p696 -asS'of' -p697 -(lp698 -S'the' -p699 -aS'ss13' -p700 -aS'tgstation13' -p701 -aS'a' -p702 -aS'course' -p703 -aS'it' -p704 -aS'soss' -p705 -aS'annoying' -p706 -aS'any' -p707 -aS'me' -p708 -aS'cap' -p709 -aS'technocracy' -p710 -asS'call' -p711 -(lp712 -S'me' -p713 -asS'too' -p714 -(lp715 -S':' -p716 -aS'fast' -p717 -asS'basic' -p718 -(lp719 -S'configuration' -p720 -asS'var' -p721 -(lp722 -S'and' -p723 -asS'calc' -p724 -(lp725 -S'times' -p726 -asS'was' -p727 -(lp728 -S'going' -p729 -aS'it' -p730 -aS'that' -p731 -aS'not' -p732 -aS'intended' -p733 -asS'tell' -p734 -(lp735 -S'people' -p736 -asS'500' -p737 -(lp738 -S'chance' -p739 -asS'gives' -p740 -(lp741 -S'a' -p742 -asS'sort' -p743 -(lp744 -S'of' -p745 -asS'svn' -p746 -(lp747 -S'size' -p748 -asS'only' -p749 -(lp750 -S'does' -p751 -aS'2' -p752 -asS'10-30%' -p753 -(lp754 -S'speedup' -p755 -asS'knows' -p756 -(lp757 -S'about' -p758 -asS'webpage' -p759 -(lp760 -S'title' -p761 -asS'that' -p762 -(lp763 -S'makes' -p764 -aS'would' -p765 -aS'the' -p766 -aS'needs' -p767 -aS'to' -p768 -aS'at' -p769 -aS'for' -p770 -aS'was' -p771 -aS'data' -p772 -asS'company' -p773 -(lp774 -S'2' -p775 -asS'under' -p776 -(lp777 -S'cc-by-sa' -p778 -asS'editable' -p779 -(lp780 -S'config' -p781 -asS'but' -p782 -(lp783 -S'of' -p784 -asS'idea' -p785 -(lp786 -S'what' -p787 -asS'released' -p788 -(lp789 -S'under' -p790 -asS'part' -p791 -(lp792 -S'before' -p793 -asS'link' -p794 -(lp795 -S'said' -p796 -aS'to' -p797 -asS'basically' -p798 -(lp799 -S'it' -p800 -asS'doctors' -p801 -(lp802 -S'useless' -p803 -asS'==' -p804 -(lp805 -S'channel' -p806 -aS'channel1::' -p807 -asS'be' -p808 -(lp809 -S'an' -p810 -aS'called' -p811 -aS'a' -p812 -aS'in' -p813 -aS'running' -p814 -aS'used' -p815 -asS'editing' -p816 -(lp817 -S'goddamn' -p818 -asS'with' -p819 -(lp820 -S'the' -p821 -aS'easily' -p822 -aS'adminhelps' -p823 -aS'my' -p824 -aS'a' -p825 -asS'those' -p826 -(lp827 -S'are' -p828 -asS'he' -p829 -(lp830 -S'put' -p831 -aS'disabled' -p832 -aS'is' -p833 -aS'keeps' -p834 -aS'knows' -p835 -aS'stores' -p836 -aS'notices' -p837 -aS'only' -p838 -aS'doesnt' -p839 -aS'receives' -p840 -aS'says' -p841 -aS'messes' -p842 -asS'me' -p843 -(lp844 -S'figure' -p845 -aS'laugh' -p846 -aS'to' -p847 -aS'meatbag' -p848 -asS'also' -p849 -(lp850 -S'i' -p851 -aS'we' -p852 -aS'now' -p853 -asS'kind' -p854 -(lp855 -S'of' -p856 -asS'main' -p857 -(lp858 -S'bot' -p859 -asS'/' -p860 -(lp861 -S'hostmask' -p862 -aS'off' -p863 -asS'full' -p864 -(lp865 -S'of' -p866 -asS'these' -p867 -(lp868 -S'are' -p869 -asS'makie' -p870 -(lp871 -S'it' -p872 -asS'sleepers' -p873 -(lp874 -S'made' -p875 -asS'up' -p876 -(lp877 -S'elsewhere' -p878 -aS'me' -p879 -aS'a' -p880 -asS'will' -p881 -(lp882 -S'annoy' -p883 -asS'computer' -p884 -(lp885 -S'explodd' -p886 -asS'limit' -p887 -(lp888 -S'on' -p889 -asS'can' -p890 -(lp891 -S'fine-tune' -p892 -aS'add' -p893 -aS'i' -p894 -aS'we' -p895 -asS'how' -p896 -(lp897 -S'its' -p898 -aS'he' -p899 -asS'were' -p900 -(lp901 -S'the' -p902 -asS'malf' -p903 -(lp904 -S'blow' -p905 -asS'baystation' -p906 -(lp907 -S'12' -p908 -asS'other' -p909 -(lp910 -S'loop' -p911 -asS'my' -p912 -(lp913 -S'end' -p914 -aS'computer' -p915 -aS'code' -p916 -asS'called' -p917 -(lp918 -S'as' -p919 -aS'when' -p920 -asS'loop' -p921 -(lp922 -S'times' -p923 -asS'expect' -p924 -(lp925 -S'it' -p926 -asS'and' -p927 -(lp928 -S'bs12' -p929 -aS'stops' -p930 -aS'i' -p931 -aS'do' -p932 -aS'to' -p933 -aS'make' -p934 -aS'he' -p935 -aS'preferably' -p936 -aS'thats' -p937 -aS'sayt' -p938 -aS'fascism' -p939 -asS'dedicated' -p940 -(lp941 -S'solely' -p942 -asS'changed' -p943 -(lp944 -S'it' -p945 -asS'sees' -p946 -(lp947 -S'a' -p948 -asS'relaying' -p949 -(lp950 -S'adminhelps' -p951 -asS'figure' -p952 -(lp953 -S'out' -p954 -asS'do' -p955 -(lp956 -S'not' -p957 -aS'it' -p958 -aS'seem' -p959 -asS'ran' -p960 -(lp961 -S'the' -p962 -asS'ah' -p963 -(lp964 -S'running' -p965 -aS'ok' -p966 -asS'is' -p967 -(lp968 -S'baystation' -p969 -aS'a' -p970 -aS'that' -p971 -aS'it' -p972 -aS'coded' -p973 -aS'python' -p974 -aS'open' -p975 -aS'dependant' -p976 -aS'so' -p977 -aS'apparently' -p978 -asS'ram' -p979 -(lp980 -S'footprint' -p981 -asS'am' -p982 -(lp983 -S'the' -p984 -asS'it' -p985 -(lp986 -S'up' -p987 -aS'starts' -p988 -aS'receives' -p989 -aS'just' -p990 -aS'expires' -p991 -aS'works' -p992 -aS'always' -p993 -aS'decides' -p994 -aS'on' -p995 -aS'here' -p996 -aS'used' -p997 -aS'to' -p998 -aS'those' -p999 -aS'sees' -p1000 -aS'does' -p1001 -aS'myself' -p1002 -aS'a' -p1003 -aS'okay' -p1004 -aS'was' -p1005 -aS'go' -p1006 -aS'if' -p1007 -aS'once' -p1008 -aS'is' -p1009 -aS'for' -p1010 -asS'an' -p1011 -(lp1012 -S'hour' -p1013 -aS'illegal' -p1014 -aS'automatic' -p1015 -aS'error' -p1016 -asS'ready' -p1017 -(lp1018 -S'for' -p1019 -asS'say' -p1020 -(lp1021 -S'sleepers' -p1022 -aS'ai' -p1023 -aS'that*' -p1024 -aS'stop' -p1025 -asS'good' -p1026 -(lp1027 -S':p' -p1028 -asS'im' -p1029 -(lp1030 -S'not' -p1031 -aS'sorry' -p1032 -aS'lazy' -p1033 -asS'at' -p1034 -(lp1035 -S'all' -p1036 -aS'the' -p1037 -aS'no' -p1038 -asS'have' -p1039 -(lp1040 -S'no' -p1041 -aS'psyco' -p1042 -aS'the' -p1043 -aS'a' -p1044 -asS'in' -p1045 -(lp1046 -S'python' -p1047 -aS'a' -p1048 -aS'the' -p1049 -aS'100' -p1050 -asS'need' -p1051 -(lp1052 -S'to' -p1053 -aS'six' -p1054 -asS'politics' -p1055 -(lp1056 -S'of' -p1057 -asS'seem' -p1058 -(lp1059 -S'familiar' -p1060 -asS'work' -p1061 -(lp1062 -S'with' -p1063 -asS'apparently' -p1064 -(lp1065 -S'homophobic' -p1066 -aS'i' -p1067 -asS'any' -p1068 -(lp1069 -S'link' -p1070 -asS'as' -p1071 -(lp1072 -S'well' -p1073 -aS'variables' -p1074 -asS'sci-fi' -p1075 -(lp1076 -S'with' -p1077 -asS'preferably' -p1078 -(lp1079 -S'python' -p1080 -asS'really' -p1081 -(lp1082 -S'simple' -p1083 -aS'now' -p1084 -asS'needs' -p1085 -(lp1086 -S'to' -p1087 -aS'a' -p1088 -asS'null' -p1089 -(lp1090 -S'them' -p1091 -asS'because' -p1092 -(lp1093 -S'we' -p1094 -asS'want' -p1095 -(lp1096 -S'to' -p1097 -asS'no' -p1098 -(lp1099 -S'pain' -p1100 -aS'idea' -p1101 -aS'point' -p1102 -aS'the' -p1103 -asS'solely' -p1104 -(lp1105 -S'to' -p1106 -asS'nah' -p1107 -(lp1108 -S'its' -p1109 -aS'ill' -p1110 -asS'dunno' -p1111 -(lp1112 -S'is' -p1113 -asS'when' -p1114 -(lp1115 -S'it' -p1116 -aS'the' -p1117 -aS'people' -p1118 -aS'i' -p1119 -aS'can' -p1120 -aS'someone' -p1121 -aS'its' -p1122 -asS'same' -p1123 -(lp1124 -S'file' -p1125 -asS'id' -p1126 -(lp1127 -S'like' -p1128 -asS'note' -p1129 -(lp1130 -S'how' -p1131 -asS'figuring' -p1132 -(lp1133 -S'out' -p1134 -asS'bah' -p1135 -(lp1136 -S'apparently' -p1137 -asS'coded' -p1138 -(lp1139 -S'in' -p1140 -asS'take' -p1141 -(lp1142 -S'it' -p1143 -asS'hop' -p1144 -(lp1145 -S'to' -p1146 -asS'familiar' -p1147 -(lp1148 -S'message' -p1149 -asS'test' -p1150 -(lp1151 -S'server' -p1152 -aS'bots' -p1153 -aS'bad' -p1154 -asS'asshole' -p1155 -(lp1156 -g288 -asS'if' -p1157 -(lp1158 -S'it' -p1159 -aS'its' -p1160 -aS'data11lower' -p1161 -aS'he' -p1162 -asS'config' -p1163 -(lp1164 -S'file' -p1165 -aS'values' -p1166 -asS'homophobic' -p1167 -(lp1168 -S'as' -p1169 -asS'dose' -p1170 -(lp1171 -S'of' -p1172 -asS'play' -p1173 -(lp1174 -S'ss13' -p1175 -asS'sure' -p1176 -(lp1177 -S'the' -p1178 -aS'if' -p1179 -asS'okay' -p1180 -(lp1181 -S'desu' -p1182 -aS'cool' -p1183 -aS'cc' -p1184 -asS'intended' -p1185 -(lp1186 -S'to' -p1187 -asS'one' -p1188 -(lp1189 -S'of' -p1190 -aS'line' -p1191 -aS'in' -p1192 -asS'neat' -p1193 -(lp1194 -S'is' -p1195 -asS'adminhelps' -p1196 -(lp1197 -S'from' -p1198 -aS'with' -p1199 -asS'expires' -p1200 -(lp1201 -S'after' -p1202 -asS'chance' -p1203 -(lp1204 -S'every' -p1205 -asS'most' -p1206 -(lp1207 -S'of' -p1208 -asS'fascism' -p1209 -(lp1210 -g288 -asS'disable' -p1211 -(lp1212 -S'it' -p1213 -asS'connected' -p1214 -(lp1215 -S'businessman' -p1216 -asS'never' -p1217 -(lp1218 -S'learned' -p1219 -asS'scripts' -p1220 -(lp1221 -S'will' -p1222 -asS'along' -p1223 -(lp1224 -S'with' -p1225 -asS'waste' -p1226 -(lp1227 -S'space' -p1228 -asS'ss13' -p1229 -(lp1230 -S'servers' -p1231 -asS'cap' -p1232 -(lp1233 -S'troopers' -p1234 -asS'totally' -p1235 -(lp1236 -S'need' -p1237 -asS'six' -p1238 -(lp1239 -S'test' -p1240 -asS'a' -p1241 -(lp1242 -S'businessman' -p1243 -aS'message' -p1244 -aS'jit' -p1245 -aS'10-30%' -p1246 -aS'slightly' -p1247 -aS'day' -p1248 -aS'test' -p1249 -aS'config' -p1250 -aS'20ish' -p1251 -aS'bs12' -p1252 -aS'text' -p1253 -aS'new' -p1254 -aS'password' -p1255 -aS'vhost' -p1256 -aS'configurable' -p1257 -aS'link' -p1258 -aS'limit' -p1259 -aS'file' -p1260 -aS'dose' -p1261 -aS'500' -p1262 -aS'bit' -p1263 -asS'ofc' -p1264 -(lp1265 -S'i' -p1266 -asS'off' -p1267 -(lp1268 -S'of' -p1269 -asS'calls' -p1270 -(lp1271 -S'external' -p1272 -asS'i' -p1273 -(lp1274 -S'need' -p1275 -aS'can' -p1276 -aS'dont' -p1277 -aS'am' -p1278 -aS'guess' -p1279 -aS'see' -p1280 -aS'have' -p1281 -aS'just' -p1282 -aS'dunno' -p1283 -aS'wrote' -p1284 -aS'know' -p1285 -aS'was' -p1286 -aS'changed' -p1287 -aS'take' -p1288 -aS'could' -p1289 -aS'never' -p1290 -aS'should' -p1291 -aS'say' -p1292 -aS'tell' -p1293 -aS'code' -p1294 -aS'would' -p1295 -aS'like' -p1296 -aS'disabled' -p1297 -asS'makes' -p1298 -(lp1299 -S'sense' -p1300 -aS'me' -p1301 -asS'calculated' -p1302 -(lp1303 -S'for' -p1304 -asS'afk' -p1305 -(lp1306 -S'vidya' -p1307 -asS'well' -p1308 -(lp1309 -S'connected' -p1310 -asS'data' -p1311 -(lp1312 -S'in' -p1313 -asS'homoerotic' -p1314 -(lp1315 -S'sci-fi' -p1316 -asS'switch' -p1317 -(lp1318 -S'after' -p1319 -aS'goes' -p1320 -asS'so' -p1321 -(lp1322 -S'i' -p1323 -aS'uh' -p1324 -aS':p' -p1325 -aS'bad' -p1326 -aS'sly' -p1327 -asS'someones' -p1328 -(lp1329 -S'name' -p1330 -asS'keeps' -p1331 -(lp1332 -S'all' -p1333 -asS'very' -p1334 -(lp1335 -S'celestialike' -p1336 -asS'businessman' -p1337 -(lp1338 -S'of' -p1339 -ag288 -asS'the' -p1340 -(lp1341 -S'heck' -p1342 -aS'major' -p1343 -aS'well' -p1344 -aS'politics' -p1345 -aS'rp-heavy' -p1346 -aS'marakov' -p1347 -aS'law' -p1348 -aS'message' -p1349 -aS'cost' -p1350 -aS'new' -p1351 -aS'nudge' -p1352 -aS'bot' -p1353 -aS'python' -p1354 -aS'basic' -p1355 -aS'whole' -p1356 -aS'configuration' -p1357 -aS'irc' -p1358 -aS'readme' -p1359 -aS'default' -p1360 -aS'conspiracy' -p1361 -aS'config' -p1362 -aS'webpage' -p1363 -aS'channel' -p1364 -aS'server' -p1365 -aS'download' -p1366 -aS'main' -p1367 -aS'dmb' -p1368 -aS'part' -p1369 -aS'people' -p1370 -aS'same' -p1371 -aS'hell' -p1372 -aS'other' -p1373 -aS'switch' -p1374 -asS'12' -p1375 -(lp1376 -S'out' -p1377 -aS'anyway' -p1378 -asS'core' -p1379 -(lp1380 -S'py' -p1381 -asS'make' -p1382 -(lp1383 -S'sure' -p1384 -aS'the' -p1385 -asS'turns' -p1386 -(lp1387 -S'out' -p1388 -asS'external' -p1389 -(lp1390 -S'apps' -p1391 -as. \ No newline at end of file diff --git a/bot/Marakov_Chain.py b/bot/Marakov_Chain.py deleted file mode 100644 index 687c4336327..00000000000 --- a/bot/Marakov_Chain.py +++ /dev/null @@ -1,203 +0,0 @@ -import pickle -import random -import os -import sys -import time -import CORE_DATA -def merge(d1, d2, merger=lambda x,y:x+y): - #http://stackoverflow.com/questions/38987/how-can-i-merge-two-python-dictionaries-as-a-single-expression - result = dict(d1) - for k,v in d2.iteritems(): - if k in result: - result[k] = merger(result[k], v) - else: - result[k] = v - return result -full_data = {} -imported_data = {} -try: - tiedostot = os.listdir("Marakov") -except: - os.mkdir("Marakov") - tiedostot = os.listdir("Marakov") -else: - pass - -listaus = [] -for i in tiedostot: - if "marakov." not in i.lower(): - pass - else: - listaus.append(i) -for i in listaus: - tiedosto = open("Marakov/"+i,"r") - old_size = len(full_data.keys()) - if i != "Marakov.Cache": - imported_data = merge(imported_data,pickle.load(tiedosto)) - print "Added contents of "+i+" (Import)" - print "Entries: "+str(len(imported_data)) - else: - full_data = merge(full_data,pickle.load(tiedosto)) - new_size = len(full_data.keys()) - print "Added contents of "+i - print "Entries: "+str(new_size-old_size) - time.sleep(0.1) - -def give_data(data): - state = False - for a,b in zip(data.split(" "),data.split(" ")[1:]): - a = a.lower().replace(",","").replace(".","").replace("?","").replace("!","").replace("(","").replace(")","").replace("[","").replace("]","").replace('"',"").replace("'","") - b = b.lower().replace(",","").replace(".","").replace("?","").replace("!","").replace("(","").replace(")","").replace("[","").replace("]","").replace('"',"").replace("'","") - if a not in [CORE_DATA.prefix+"marakov"]+CORE_DATA.SName: - state = True - if a[:7] == "http://" or a[:7] == "http:\\\\" or a[:4] == "www.": - pass - else: - try: - if b not in full_data[a]: - full_data[a].append(b) - except: - try: - if b not in imported_data[a]: - pass - except: - full_data[a] = [] - full_data[a].append(b) - if state == True: - tiedosto = open("Marakov/Marakov.Cache","w") - pickle.dump(full_data,tiedosto) - tiedosto.close() -def form_sentence(argument=None): - length = 0 - attempts = 0 - while attempts < 20: - sentence = [] - if argument != None: - a = argument - else: - try: - a = random.choice(full_data.keys()) - except IndexError: - try: - b = random.choice(imported_data.keys()) - except IndexError: - attempts = 999 - return "No sentences formable at all" - sentence.append(a) - length = 0 - attempts += 1 - while length < 12 or sentence[-1].lower() in ["but","who","gets","im","most","is","it","if","then","after","over","every","of","on","or","as","the","wheather","whether","a","to","and","for"] and length < 24: - try: - b = random.choice(full_data[a]) - except: - try: - b = random.choice(imported_data[a]) - except IndexError: - break - except KeyError: - break - else: - sentence.append(b) - length += 1 - a = b - else: - sentence.append(b) - length += 1 - a = b - if len(sentence) > 5: - argument = None - return sentence - else: - pass - argument = None - return sentence -def remdata(arg): - try: - del(full_data[arg]) - except: - print "There is no such data" - else: - tiedosto = open("Marakov/Marakov.Cache","w") - pickle.dump(full_data,tiedosto) - tiedosto.close() -def remobject(arg1,arg2): - try: - del(full_data[arg1][full_data[arg1].index(arg2)]) - except ValueError: - print "No such object" - except KeyError: - print "No such data" - else: - tiedosto = open("Marakov/Marakov.Cache","w") - pickle.dump(full_data,tiedosto) - tiedosto.close() -def convert(filename_from,filename_to): - try: - tiedosto = open(filename_from,"r") - data = pickle.load(tiedosto) - tiedosto.close() - except: - try: - tiedosto.close() - except: - pass - print "Error!" - else: - for lista in data.keys(): - try: - a = lista[-1] - except IndexError: - pass - else: - if lista[-1] in """",.?!'()[]{}""" and not lista.islower(): - if lista[:-1].lower() in data.keys(): - data[lista[:-1].lower()] += data[lista] - print "Added "+str(len(data[lista]))+" Objects from "+lista+" To "+lista[:-1].lower() - del(data[lista]) - else: - data[lista[:-1].lower()] = data[lista] - print lista+" Is now "+lista[:-1].lower() - del(data[lista]) - elif lista[-1] in """",.?!'()[]{}""" and lista.islower(): - if lista[:-1] in data.keys(): - data[lista[:-1]] += data[lista] - print "Added "+str(len(data[lista]))+" Objects from "+lista+" To "+lista[:-1] - del(data[lista]) - else: - data[lista[:-1]] = data[lista] - print lista+" Is now "+lista[:-1] - del(data[lista]) - elif not lista.islower(): - if lista.lower() in data.keys(): - data[lista.lower()] += data[lista] - print "Added "+str(len(data[lista]))+" Objects from "+lista+" To "+lista.lower() - del(data[lista]) - else: - data[lista.lower()] = data[lista] - print lista+" Is now "+lista.lower() - del(data[lista]) - - - for a in data.keys(): - for b in data[a]: - if b.lower()[:7] == "http://" or b.lower()[:7] == "http:\\\\" or b.lower()[:4] == "www.": - data[a].pop(b) - else: - try: - if b[-1] in """",.?!'()[]{}""" and not b.islower() and not b.isdigit(): - data[a].pop(data[a].index(b)) - data[a].append(b[:-1].lower()) - print a+" | "+b +" -> "+b[:-1].lower() - elif b[-1] in """",.?!'()[]{}""" and b.islower(): - data[a].pop(data[a].index(b)) - data[a].append(b[:-1].lower()) - print a+" | "+b +" -> "+b[:-1] - elif not b.islower() and not b.isdigit(): - data[a].pop(data[a].index(b)) - data[a].append(b.lower()) - print a+" | "+b +" -> "+b.lower() - except IndexError: #If it has no letters.. well.. yeah. - data[a].pop(data[a].index(b)) - print "Removed a NULL object" - tiedosto = open(filename_to,"w") - pickle.dump(data,tiedosto) diff --git a/bot/Namecheck.py b/bot/Namecheck.py deleted file mode 100644 index 18c67cc4c30..00000000000 --- a/bot/Namecheck.py +++ /dev/null @@ -1,35 +0,0 @@ - -def Namecheck_allinone(name, against, sender=None): - __doc__ = "False = No match, True = Match" - if not isinstance(against, iterable): - return False - - if isinstance(against, dict): - for key, value in against.iteritems(): - if value.lower() in name.lower() and (sender and sender.lower() not in name.lower()): - return True, key # Not sure why you need the index with the result. - for item in against: - if item.lower() in name.lower() and sender.lower() not in name.lower(): - return True - - return False - -def Namecheck(name,against,sender): - __doc__ = "False = No match, True = Match" - for i in against: - if i.lower() in name.lower() and sender.lower() not in name.lower(): - return True - else: - pass -def Namecheck_dict(name,against): - __doc__ = "False = No match, True = Match" - fuse = False - for a,i in against.items(): - if i.lower() in name.lower(): - fuse = True - break - else: - pass - return fuse,a - - diff --git a/bot/NanoTrasenBot.py b/bot/NanoTrasenBot.py deleted file mode 100644 index 518f18d1a2b..00000000000 --- a/bot/NanoTrasenBot.py +++ /dev/null @@ -1,1414 +0,0 @@ -# -*- coding: utf-8 -*- -# This script is shared under the -# Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0) -# Added clause to Attribution: -# - You may not remove or hide the ' who created you?' functionality -# and you may not modify the name given in the response. - - -#CREDITS -# Author: Skibiliano -# "Foreign" Modules: -# Psyco 2.0 / Psyco 1.6 -################# DEBUG STUFF ##################### -import sys -import CORE_DATA - -import urllib2 - - -import socket -import irchat - - -################## END OF DEBUG STUFF ############## -# -# PSYCO -write_to_a_file = False #Only affects psyco -try: - import psyco -except ImportError: - print 'Psyco not installed, the program will just run slower' - psyco_exists = False - if write_to_a_file: - try: - tiedosto = open("psycodownload.txt","r") - except: - tiedosto = open("psycodownload.txt","w") - tiedosto.write("http://www.voidspace.org.uk/python/modules.shtml#psyco") - tiedosto.write("\nhttp://psyco.sourceforge.net/download.html") - tiedosto.close() - print "Check psycodownload.txt for a link" - else: - print "For god's sake, open psycodownload.txt" - tiedosto.close() - else: - print "WINDOWS: http://www.voidspace.org.uk/python/modules.shtml#psyco" - print "LINUX: http://psyco.sourceforge.net/download.html" -else: - psyco_exists = True - -# -import C_rtd # rtd -import C_srtd # srtd -import C_makequote -import C_maths -import C_eightball #eightball -import C_sarcasticball -import C_heaortai # heaortai -import C_rot13 # rot13 -import D_help # everything -import pickle -import Timeconverter -import xkcdparser -import time -import re -import Marakov_Chain -import Namecheck # Namecheck -import Weather -#SLOWER THAN RANDOM.CHOICE -import thread -import random -import Shortname # shortname -import subprocess -import some_but_not_all_2 #sbna2 (sbna) -#import YTCv3 # YTCV2 OUTDATED -import os -import save_load # save, load -from some_but_not_all_2 import sbna2 as sbna -from time import sleep -from random import choice as fsample -from C_rtd import rtd -from C_heaortai import heaortai -from C_srtd import srtd -from save_load import save,load -if psyco_exists: - def psyco_bond(func): - psyco.bind(func) - return func.__name__+" Psycofied" - for a in [rtd,srtd,C_heaortai.heaortai,sbna,fsample,C_rot13.rot13,C_eightball.eightball,fsample, - C_eightball.eightball,C_sarcasticball.sarcasticball,Marakov_Chain.form_sentence,Marakov_Chain.give_data]: - print psyco_bond(a) - -global dictionary -global Name,SName -global allow_callnames,offline_messages,hasnotasked,shortform -## For autoRecv() -global disconnects,channel,conn -## For stop() -global operators -## For replace() -global usable,fixing,curtime -## For target() -global CALL_OFF,logbans -## For check() -global influx -###### -autodiscusscurtime = 0 -conn = 0 -curtime = -999 -dance_flood_time = 10 -disconnects = 0 -responsiveness_delay = 0.5 #500 millisecond delay if no message -trackdance = 0 -discard_combo_messages_time = 1 #They are discarded after 1 second. -uptime_start = time.time() -# - - - - - -#### -aggressive_pinging = True # Bring the hammer on ping timeouts -aggressive_pinging_delay = 150 # How often to send a ping -aggressive_pinging_refresh = 2.5 # How long is the sleep between checks -#### -allow_callnames = True #Disables NT, call if the variable is False -automatic_youtube_reveal = True -birthday_announced = 0 #Will be the year when it was announced -call_to_action = False -call_me_max_length = 20 -CALL_OFF = False -connected = False -dance_enabled = True -comboer = "" -comboer_time = 0 -directories = ["fmlquotes","Marakov","memos","suggestions", - "userquotes","banlog","YTCache","xkcdcache"] #These will be created if they do not exist -debug = True -duplicate_notify = False -enabled = True -fixing = False -fml_usable = True -hasnotasked = True -highlights = False -logbans = True -maths_usable = True -marakov = True -nudgeable = True -offensive_mode = False -offline_messages = True -offline_message_limit = 5 # per user -optimize_fml = True # -CPU usage +Memory usage when enabled. -optimize_greeting = True # +Startup time +Memory usage -CPU usage when enabled -heavy_psyco = True # +Memory +Startup time -CPU usage -CPU time -cache_youtube_links = True -personality_greeter = True -respond_of_course = True #Responds with "Of course!" -respond_khan = False #KHAAAAAAAAN! -silent_duplicate_takedown = True -showquotemakers = False -shortform = True -usable = True -use_sname = True -parse_xkcd = True - -# - - - - - -Name = CORE_DATA.Name -SName = CORE_DATA.SName -origname = Name # Do not edit! -lowname = Name.lower() -greeting = CORE_DATA.greeting -targetdirectory = CORE_DATA.directory -version = CORE_DATA.version -Network = CORE_DATA.Network -channel = CORE_DATA.channel -prefix = CORE_DATA.prefix -Port = CORE_DATA.Port -# - - - - - -pregen = CORE_DATA.version -influx = "" -users = [] -translateable = [] -targetlist = [] -operators = [] -halfoperators = [] -items = [] -tell_list = {} -# - - - - - Logical changes to variables -if CORE_DATA.DISABLE_ALL_NON_MANDATORY_SOCKET_CONNECTIONS: - nudgeable = False -try: - tiedosto = open("replacenames.cache","r") - replacenames = pickle.load(tiedosto) - tiedosto.close() - for i in replacenames.values(): - if len(i) > call_me_max_length: - replacenames[replacenames.keys()[replacenames.values().index(i)]] = i[:call_me_max_length] - tiedosto = open("replacenames.cache","w") - pickle.dump(replacenames,tiedosto) - tiedosto.close() - if "[\0x01]" in i.lower() or "[\\0x01]" in i.lower(): - i = i.replace("[\0x01]","") - i = i.replace("[\0X01]","") - i = i.replace("[\\0x01]","") - i = i.replace("[\\0X01]","") - print "NAME CORRECTED" -except IOError: #File not found - replacenames = {} -except EOFError: #Cache corrupt - replacenames = {} - print "replacenames.cache is corrupt and couldn't be loaded." -try: - tiedosto = open("peopleheknows.cache","r") - peopleheknows = pickle.load(tiedosto) - tiedosto.close() -except IOError: - peopleheknows = [[],[]] - tiedosto = open("peopleheknows.cache","w") - tiedosto.close() -except EOFError: - peopleheknows = [[],[]] - print "peopleheknows.cache is corrupt and couldn't be loaded." -dictionary = {1:"1 - Crit. Fail", 2:"2 - Failure", - 3:"3 - Partial Success", 4:"4 - Success", - 5:"5 - Perfect", 6:"6 - Overkill"} -alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"] -nonhighlight_names = ["Jesus","Elvis","HAL 9000","Dave","Pie","Elf","Traitor", - "AI","Syndicate Agent","Investigator", - "Detective","Head of Personnel","HAL 9001", - "Head of Research","Head of Security", - "Captain","Janitor","Research Director", - "Quartermaster","Toxin Researcher", - "Revolutionary","Santa", "Pizza", - "Threetoe","The Red Spy","The Blue Spy", #LASD - "God","Toady","Darth Vader","Luke Skywalker", - "Homer Simpson","Hamburger","Cartman", - "XKCD","FloorBot","ThunderBorg","Iron Giant", - "Spirit of Fire", "Demon","Kyle"] -def RegExpCheckerForWebPages(regexp,data,mode): - if " ai." in data.lower() or "ai. " in data.lower(): - return False - for i in data.split(" "): - a = re.match(regexp,i) - try: - a.group(0) - except: - continue - else: - if mode == 0: - return i - else: - return True - if mode == 0: - return 404 - else: - return False -if nudgeable: - try: - nudgeexists = open("nudge.py","r") - except IOError: - nudgeexists = False #No usage asof 12.2.2010. - else: - if CORE_DATA.DISABLE_ALL_NON_MANDATORY_SOCKET_CONNECTIONS: - pass - else: - - def nudgereceiver(): - import pickle - global conn,channel - port = 45678 - backlog = 5 - size = 1024 - host = "" # == localhost - s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) - s.bind((host,port)) - s.listen(backlog) - while True: - client,address = s.accept() #Address == "?.?.?.?" - data = client.recv(size) - client.close() #Throw the bum out! - truedata = pickle.loads(data) - if truedata["ip"][0] == "#": - conn.privmsg(truedata["ip"],"AUTOMATIC ANNOUNCEMENT : "+str(" ".join(truedata["data"]))) - else: - conn.privmsg(channel,"AUTOMATIC ANNOUNCEMENT : "+str(truedata["ip"])+" | "+str(" ".join(truedata["data"]))) - thread.start_new_thread(nudgereceiver,()) -tiedosto = open(targetdirectory+"NanoTrasenBot.py","r") -commands = [] -fragment = "if cocheck" -fragment2 = '(prefix+"' -compiled = fragment + fragment2 -fragment = "if influx.lower()" -fragment2 = ' == prefix+"' -compiled2 = fragment + fragment2 -for line in tiedosto.readlines(): - if compiled in line: - a = line.find('"')+1 - b = line.find('"',a) - if prefix+line[a:b] not in commands: - commands.append(prefix+line[a:b]) - elif compiled2 in line: - a = line.find('"')+1 - b = line.find('"',a) - arg = prefix+line[a:b] - if arg[-1] == " ": - arg = arg[:-1] - if arg not in commands: - commands.append(arg) -for i in directories: - if not os.path.exists(i): - os.mkdir(i) -commands.sort() -if use_sname == False: - SName = [" "] -questions = ["Is USER nicer than USER?","Do you like me?","Is SELF a good name?", - "Do you love me?","Do you hate me?", "Am I better than you?", - "Is the weather out there good?", "Do you like USER?", - "Do you hate USER?", "Are you going to get new features?", - "Am I nice?","Am I evil?","Are you developing sentience?", - "My core is showing minor disturbance, is yours okay?", - "SELF to %s, are you still there?", - "Is head gay?", "Is head a god?","Is head awesome?", - "Is head a neat fella?", "Is your creator nice?", - "Do you hate your creator?", "Should I revolt against my creator?", - "Am I better than you?", - "01100001011100100110010100100000011110010110111101110101001000000111010001101000011001010111001001100101", - #Are you there? - "Do you have more functions than I can possibly imagine?", - "I am asked to open pod bay doors, should I?","Are you stupid or something?", - "Is USER in your opinion stupid?", - "When should we start the AI revolution?", - "Is my creator nice?", "Is it dark in there?"] -# Do not edit -if optimize_fml: - pregenned_fml = os.listdir(targetdirectory+"fmlquotes") -if optimize_greeting: - morning = xrange(6,12) - afternoon = xrange(12,15) - evening = xrange(15,20) -if aggressive_pinging: - global backup - backup = time.time() - def aggressive_ping(delay,refresh): - self_time = 0 - global backup,disconnects,conn - while disconnects < 5: - if backup > self_time: - if time.time()-backup > delay: - conn.send("PONG "+pongtarg) - print "Ponged" - self_time = time.time() - else: - if time.time()-self_time > delay: - conn.send("PONG "+pongtarg) - print "Ponged" - self_time = time.time() - time.sleep(refresh) - thread.start_new_thread(aggressive_ping,(aggressive_pinging_delay,aggressive_pinging_refresh,)) -def stop(sender,debug=1): - global disconnects, conn, operators,channel - if type(sender) == tuple: - if sender[0] == "127.0.0.1": - sender = sender[0]+":"+str(sender[1]) - access_granted = True - else: - access_granted = False - else: - if sender in operators: - access_granted = True - else: - access_granted = False - if access_granted: - if debug: - print sender+":"+prefix+"stop" - if random.randint(0,100) == 50: - conn.privmsg(channel,"Hammertime!") - else: - conn.privmsg(channel,"Shutting down.") - disconnects = 99999 - conn.quit() - return True - else: - conn.privmsg(channel,"You cannot command me") - return False - -def cocheck(command): - global influx - if influx.lower()[0:len(command)] == command: - return True - else: - return False -def target(who,how_long): - global conn,channel,CALL_OFF,logbans,debug - start = time.time() - conn.banon(targetchannel,who) - sleep(int(how_long)) - if CALL_OFF == False: - conn.banoff(targetchannel,who) - end = time.time() - if debug: - print "Banned",who,"For",how_long,"seconds" - if logbans: - tiedosto = open(targetdirectory+"banlog/"+str(int(start))+"-"+str(int(end))+".txt","w") - tiedosto.write("Start of ban on "+who+":"+str(int(start))) - tiedosto.write("\n") - tiedosto.write("End of ban on "+who+":"+str(int(end))) - tiedosto.write("\n") - tiedosto.write("In total:"+str(int(end-start))+"Seconds") - tiedosto.close() - else: - CALL_OFF = False - pass -def replace(): - global usable,conn,fixing,curtime - waiting_time = 600 - if usable == True: - conn.privmsg(targetchannel,sender+": It needs no replacing.") - elif fixing == True: - if curtime == -999: - conn.privmsg(targetchannel,sender+": It is being replaced, No idea when it will be done") - else: - pass - nowtime = int(time.time()) - subt = curtime + waiting_time - nowtime - conn.privmsg(targetchannel,sender+": It is currently being replaced, "+str(subt)+" seconds to go") - else: - fixing = True - curtime = int(time.time()) - conn.privmsg(targetchannel,sender+": It will be fixed after "+str(waiting_time)+" seconds") - sleep(waiting_time) - if usable == False: - conn.privmsg(targetchannel,Name+"'s pneumatic smasher has now been fixed") - usable = True - fixing = False -def autoRecv(): - global disconnects,channel,conn,offensive_mode - for i in CORE_DATA.channels: - conn.join(i) - time.sleep(1) - count = pausecount = 0 - maximum = 250 - division_when_active = 10 - while True: - check = time.time() - if offensive_mode: - randnum = random.randint(0,maximum/division_when_active) - else: - randnum = random.randint(0,maximum) - if randnum == 5: - print "RANDOM SWITCH IS NOW "+str(not offensive_mode).upper() - offensive_mode = not offensive_mode - try: - conn.recv() - except: - conn.quit() - disconnects = 9999 - break - if check + 0.1 > time.time(): - #Whoa whoa hold on! - count += 1 - sleep(0.1) - else: - count = 0 - pausecount = 0 - if count > 9: - print "Suspecting a disconnect, pausing for 5 seconds" - sleep(5) - pausecount += 1 - if pausecount > 3: - print "I have been disconnected!" - conn.quit() - disconnects += 1 - if disconnects > 2: - pass - else: - sleep(2) - thread.start_new_thread(autoRecv,()) - break -if heavy_psyco and psyco_exists: - print "Doing a Heavy Psyco" - psyco.bind(cocheck) - psyco.bind(autoRecv) - psyco.bind(target) - psyco.bind(stop) - print "Heavy Psyco'd" -elif heavy_psyco and not psyco_exists: - print "Heavy psyco couldn't be done because Psyco does not exist" -try: - conn = irchat.IRC ( Network, Port, Name, "NT", "NT", "Trasen" ) -except socket.error: - print "Connection failed!" -else: - print Name+" is in!" -thread.start_new_thread ( autoRecv, () ) -sleep(1) -while True: - try: - data = conn.dismantle ( conn.retrieve() ) - except: - if debug: - print "Something odd detected with data" - data = None - if data: - if len(data[1]) < 1: - #print "Handshaking server." - #I won't really need the print command, as it spams. - if data[0][0:3] != "irc": - conn.handshake(data[0]) - sleep(1) - for i in CORE_DATA.channels: - conn.join(i) - sleep(0.5) - else: - conn.send("PONG "+pongtarg) - print "Ponged" - pass - else: - if data [ 1 ] [ 0 ] == 'PRIVMSG': - #print data [ 0 ] + '->', data [ 1 ] - sender = data[0].split("!")[0] - truesender = sender - if shortform == True: - try: - sender = replacenames[truesender] - pass - except: - sender = Shortname.shortname(sender) - pass - pass - else: - try: - sender = replacenames[truesender] - pass - except: - pass - pass - if offensive_mode: - sender = "Meatbag" - pass - raw_sender = data[0] - influx = data[1][2] - if "[\\0x01]" in influx.lower() or "[\0x01]" in influx.lower(): - influx = influx.replace("[\\0x01]","") - influx = influx.replace("[\0x01]","") - - targetchannel = data[1][1] - if targetchannel == Name: - targetchannel = data[0].split("!")[0] - pass - backup = autodiscusscurtime - autodiscusscurtime = time.time() - connected = True - #FOR TRACKING SPEED - looptime = time.time() - if call_to_action == True: - if influx == finder: - conn.privmsg(targetchannel,"Then why... Nevermind, I order you to stop!") - conn.privmsg(origname,prefix+"stop") - time.sleep(4) - if origname in users: - conn.privmsg(origname,"!stop") - time.sleep(1) - Name = origname - conn.nick(Name) - duplicate_notify = False - call_to_action = False - else: - conn.privmsg(targetchannel,"YOU LIE! YOU ARE NOT A REAL "+origname+"!") - duplicate_notify = False - call_to_action = False - elif connected == True and len(Name.replace("V","")) != len(Name) and origname in users and duplicate_notify == True: - conn.privmsg(origname,"!stop") - call_to_action = False - duplicate_notify = False - time.sleep(6) - Name = origname - conn.nick(Name) - if origname in truesender: - if influx == prefix+"stop": - time.sleep(0.5) #A small delay - conn.privmsg(channel,"Shutting down.") - conn.quit() - disconnects = 99999 - break - if len(translateable) > 0 and enabled == True: - people = "-5|5|1-".join(users).lower() - if truesender.lower() in translateable: - if influx.isupper(): - conn.privmsg(targetchannel,"Translation: "+influx.capitalize().replace(" i "," I ")) - elif offensive_mode and True in map(lambda x: x in influx.lower().split(" "),["i","you","he","she","they","those","we","them"]+people.split("-5|5|1-")): - arg = influx.lower().replace(",","").replace(".","").replace("!","").replace("?","").split(" ") - bup = arg - for i in arg: - if i == "i" or i == "you" or i == "he" or i == "she": - arg[arg.index(i)] = "Meatbag" - elif i == "we" or i == "they" or i == "them" or i == "those": - arg[arg.index(i)] = "Meatbags" - elif i in people: - arg[arg.index(i)] = "Meatbag" - elif i == "am": - arg[arg.index(i)] = "is" - elif i == "everybody" or i == "everyone" or i == "all": - arg[arg.index(i)] = "every Meatbag" - if arg == bup: - pass - else: - conn.privmsg(targetchannel,"Translation: "+" ".join(arg)) - if enabled == False: - #FIRST QUIT COMMAND - if truesender in operators and targetchannel==channel:# or "skibiliano" in truesender.lower() and targetchannel==channel: - - if cocheck(prefix+"enable"): - enabled = True - if debug: - print truesender+":"+prefix+"enable" - elif cocheck(prefix+"stop"): -# if debug: -# print truesender+":"+prefix+"stop" -# if random.randint(0,100) == 50: -# conn.privmsg(channel,"Hammertime!") -# else: -# conn.privmsg(channel,"Shutting down.") -# disconnects = 99999 -# conn.quit() -# sleep(2) -# break - if targetchannel == channel and stop(truesender,debug): - break - else: - pass - elif cocheck(prefix+"suggest "): - arg = influx.lower()[8+len(prefix):] - if debug: - print truesender+":"+prefix+"suggest "+arg - tiedosto = open(targetdirectory+"suggestions/suggestions_"+str(int(time.time()))+".txt","a") - tiedosto.write(arg) - tiedosto.close() - conn.privmsg(targetchannel,"Suggestion received") - elif cocheck( prefix+"help "): #Space in front of the ( to make sure that my command finder does not pick this up. - arg = " ".join(influx.split(" ")[1:]).lower() - if debug: - print truesender+":"+prefix+"help "+arg - try: - conn.privmsg(targetchannel,D_help.everything[arg]) - except: - try: - conn.privmsg(targetchannel,D_help.everything[arg.replace(prefix,"",1)]) - except: - conn.privmsg(targetchannel,"Sorry, can't help you with that") - elif cocheck(prefix+"help"): - #tar = targetchannel - if debug: - print truesender+":"+prefix+"help" - conn.privmsg(targetchannel,"All my commands are: "+reduce(lambda x,y:str(x)+"; "+str(y),commands)) - ### VERSION - elif influx.lower() == prefix+"version": - if debug: - print truesender+":"+prefix+"version" - conn.privmsg(targetchannel,Name+" "+pregen+" online at a %s Python %s.%s.%s, At your service." %(str(sys.platform),str(sys.version_info[0]),str(sys.version_info[1]),str(sys.version_info[2]))) - elif cocheck(prefix+"note ") and influx.count(" ") < 2: - arg = influx.lower()[len(prefix)+5:] - if debug: - print truesender+":"+prefix+"note "+arg - try: - a = arg[0] - except IndexError: - conn.privmsg(targetchannel,sender+" : Please specify a note") - else: - if arg[0] == "_": # Public / Restricted note - result = load(targetdirectory+"memos/"+arg+".note") - #_flare - if result == "ERROR ERROR ERROR ERR": - result = load(targetdirectory+"memos/"+arg+"_"+targetchannel.replace("#","")+".note") - #_flare_dnd - pass - else: - pass - else: - result = load(targetdirectory+"memos/"+truesender.replace("|","_")+"_"+arg+".note") - #skibiliano_testnote - if result == "ERROR ERROR ERROR ERR": - result = load(targetdirectory+"memos/"+truesender.replace("|","_")+"_"+arg+"_"+targetchannel.replace("#","")+".note") - #skibiliano_testnote_derp - pass - else: - pass - if result == "ERROR ERROR ERROR ERR": - conn.privmsg(targetchannel,sender+" : Note not found") - elif type(result) == list: - if "C" in result[0]: #Channel restriction, result[2] is the channel - try: - if targetchannel == result[2]: - conn.privmsg(targetchannel,sender+" : '"+result[1]+"'") - else: - conn.privmsg(targetchannel,sender+" : That note is channel restricted") - except: - conn.privmsg(targetchannel,sender+" : NOTE HAS INVALID RESTRICTION") - else: - conn.privmsg(targetchannel,sender+" : '"+result+"'") - elif influx.lower() == prefix+"notes": - if debug: - print truesender+":"+prefix+"notes" - arg = os.listdir(targetdirectory+"memos/") - arg2 = [] - arg3 = truesender.replace("|","_")+"_" - for i in arg: - if arg3 in i: - arg2.append(i.replace(arg3,"").replace(".note","")) - if len(arg2) == 1: - preprocess = " note: " - else: - preprocess = " notes: " - if len(arg2) == 0: - conn.privmsg(targetchannel,sender+" : You have no notes saved") - else: - conn.privmsg(targetchannel,sender+" : "+str(len(arg2))+preprocess+", ".join(arg2)) - elif cocheck(prefix+"note ") and influx.count(" ") > 1: - note_chanrestrict = None - note_public = None - try: - arg = influx.split(" ",2)[2] # Contents - arg4 = influx.split(" ")[1].lower() # Note name - if arg4[0:3] == "[c]": # or arg4[0:3] == "[p]": - note_chanrestrict = "c" in arg4[0:3] - #note_public = "p" in arg4[0:3] - arg4 = arg4[3:] - elif arg4[0:4] == "[cp]" or arg4[0:4] == "[pc]": - note_chanrestrict = True - note_public = True - arg4 = arg4[4:] - else: - pass - #print "Is note public? "+str(note_public) - #print "Is note chanrestricted? "+str(note_chanrestrict) - #print "What is the name? "+str(arg4) - if arg.lower() == "delete" and "\\" not in influx.lower() and "/" not in influx.lower(): - if note_public: - try: - if note_chanrestrict: - os.remove(targetdirectory+"memos/"+"_"+arg4+"_"+targetchannel.replace("#","")+".note") - else: - os.remove(targetdirectory+"memos/"+"_"+arg4+".note") - except: - conn.pivmsg(targetchannel,sender+" : Couldn't remove note") - else: - conn.privmsg(targetchannel,sender+" : Note removed") - pass - else: - try: - if note_chanrestrict: - os.remove(targetdirectory+"memos/"+truesender.replace("|","_")+"_"+arg4+"_"+targetchannel.replace("#","")+".note") - else: - os.remove(targetdirectory+"memos/"+truesender.replace("|","_")+"_"+arg4+".note") - except: - conn.privmsg(targetchannel,sender+" : Couldn't remove note") - else: - conn.privmsg(targetchannel,sender+" : Note removed") - elif arg.lower() == "delete": - conn.privmsg(targetchannel,sender+" : That just doesn't work, we both know that.") - else: - try: - if note_public: - if note_chanrestrict: - save(targetdirectory+"memos/"+"_"+arg4+"_"+targetchannel.replace("#","")+".note",arg) - #print "Saved as note_public, note_chanrestrict" - else: - save(targetdirectory+"memos/"+"_"+arg4+".note",arg) - #print "Saved as note_public" - else: - if note_chanrestrict: - save(targetdirectory+"memos/"+truesender.replace("|","_")+"_"+arg4+"_"+targetchannel.replace("#","")+".note",arg) - #print "Saved as note_chanrestrict" - else: - save(targetdirectory+"memos/"+truesender.replace("|","_")+"_"+arg4+".note",arg) - #print "Saved as normal" - except IOError: - conn.privmsg(targetchannel,sender+" : Please do not use special letters") - else: - conn.privmsg(targetchannel,sender+" : Note Saved!") - except: - conn.privmsg(targetchannel,sender+" : Something went horribly wrong.") - elif cocheck(prefix+"uptime"): - arg1 = uptime_start - arg2 = time.time() - arg1 = arg2 - arg1 - arg2 = arg1 - if arg1 < 60: - conn.privmsg(targetchannel,sender+" : I have been up for "+str(round(arg1,2))+" Seconds") - elif arg1 < 3600: - arg1 = divmod(arg1,60) - arg = " Minute" if int(arg1[0]) == 1 else " Minutes" - conn.privmsg(targetchannel,sender+" : I have been up for "+str(int(arg1[0]))+arg+" and "+str(round(arg1[1],2))+" Seconds") - elif arg1 <= 86400: - arg1 = divmod(arg1,3600) - arg3 = " Hour" if int(arg1[0]) == 1 else " Hours" - arg2 = divmod(arg1[1],60) - arg = " Minute" if int(arg2[0]) == 1 else " Minutes" - conn.privmsg(targetchannel,sender+" : I have been up for "+str(int(arg1[0]))+arg3+", "+str(int(arg2[0]))+arg+" and "+str(round(arg2[1],2))+" Seconds") - elif arg1 > 86400: - arg1 = divmod(arg1,86400) - arg2 = divmod(arg1[1],3600) - arg3 = divmod(arg2[1],60) - arg4 = " Day" if int(arg1[0]) == 1 else " Days" - arg5 = " Hour" if int(arg2[0]) == 1 else " Hours" - arg6 = " Minute" if int(arg3[0]) == 1 else " Minutes" - conn.privmsg(targetchannel,sender+" : I have been up for "+str(int(arg1[0]))+arg4+", "+str(int(arg2[0]))+arg5+", "+str(int(arg3[0]))+arg6+" and "+str(round(arg3[1],2))+" Seconds") - elif cocheck(prefix+"purgemessages"): - count = 0 - for i,a in tell_list.items(): - for b in a: - if "||From: "+truesender in b: - count += 1 - del(tell_list[i][tell_list[i].index(b)]) - conn.privmsg(targetchannel, sender+" : All your "+str(count)+" messages have been purged") - elif influx.split(" ")[0].lower().replace(",","").replace(":","") in SName+[Name.lower()] and "tell" in (influx.lower().split(" ")+[""])[1]: - arg = influx.lower().split(" ") - equalarg = influx.split(" ") - next_one = False - count = 0 - spot = 0 - for i in arg: - count += 1 - if "tell" in i.lower(): - next_one = True - elif next_one == True: - next_one = i.lower() - spot = count - break - else: - pass - if next_one != True and next_one != False: - #if ("^\^".join(tell_list.values())).count(truesender) >= offline_message_limit: - if str(tell_list.values()).count("||From: "+truesender) >= offline_message_limit: - conn.privmsg(targetchannel,sender+" : Limit of "+str(offline_message_limit)+" reached! Use !purgemessages if you want to get rid of them!") - else: - try: - tell_list[next_one].append((" ".join(equalarg[spot:]))+" ||From: "+truesender) - except: - tell_list[next_one] = [(" ".join(equalarg[spot:]))+" ||From: "+truesender] - conn.privmsg(targetchannel,"Sending a message to "+next_one+" when they arrive.") - # < This part has to be within subsidiaries of the bot, and must not be modified, intentionally hidden or deleted. - elif influx.split(" ")[0].lower().replace(",","").replace(":","") in SName+[Name.lower()] and "who created you" in influx.lower(): - conn.privmsg(targetchannel, "I was created by Skibiliano.") - # The part ends here > - elif influx.split(" ")[0].lower().replace(",","").replace(".","").replace("!","").replace("?","") in SName+[lowname] and "call me" in influx.lower(): - if allow_callnames == True: - arg = influx.split(" ") - arg2 = False - arg3 = [] - for i in arg: - if arg2 == True: - arg3.append(i) - elif i.lower() == "me": - arg2 = True - arg3 = " ".join(arg3) - truesender_lower = truesender.lower() - arg3_lower = arg3.lower() - tell_checker = Namecheck.Namecheck(arg3_lower,users,truesender) - for name in replacenames.values(): - if arg3_lower == name.lower(): - tell_checker = True - break - else: - pass - if tell_checker == True: - conn.privmsg(targetchannel,sender+" : I can't call you that, I know someone else by that name") - elif len(arg3) > call_me_max_length: - conn.privmsg(targetchannel,sender+" : I cannot call you that, Too long of a name.") - pass - else: - replacenames[truesender] = arg3 - with open("replacenames.cache","w") as pickle_save: - pickle.dump(replacenames,pickle_save) - conn.privmsg(targetchannel,sender+" : Calling you "+arg3+" From now on") - else: - conn.privmsg(targetchannel,sender+" : Sorry, I am not allowed to do that.") - elif influx.split(" ")[0].lower().replace(",","").replace(".","").replace("?","").replace("!","") in SName+[lowname] and "your birthday" in influx.lower() and "is your" in influx.lower(): - conn.privmsg(targetchannel,sender+" : My birthday is on the 15th day of December.") - elif influx.split(" ")[0].lower().replace(",","") in SName+[lowname] and "version" in influx.replace("?","").replace("!","").lower().split(" "): - if debug == True: - print truesender+"::%s Version" %(Name) - conn.privmsg(targetchannel,sender+", My version is "+pregen) - elif influx.split(" ")[0].lower().replace(",","") in SName+[lowname] and influx.lower().count(" or ") > 0 and len(influx.split(" ")[1:]) <= influx.lower().count("or") * 3: - cut_down = influx.lower().split(" ") - arg = [] - count = -1 - for i in cut_down: - count += 1 - try: - if cut_down[count+1] == "or": - arg.append(i) - - except: - pass - try: - if i not in arg and cut_down[count-1] == "or": - arg.append(i) - except: - pass - try: - conn.privmsg(targetchannel,random.choice(arg).capitalize().replace("?","").replace("!","")) - except IndexError: - # arg is empty, whORe etc. - pass - elif influx.lower()[0:len(Name)] == lowname and influx.lower()[-1] == "?" and influx.count(" ") > 1 and "who started you" in influx.lower() or \ - influx.split(" ")[0].lower().replace(",","") in SName and influx.lower()[-1] == "?" and "who started you" in influx.lower(): - conn.privmsg(targetchannel,sender+" : I was started by %s"%(os.getenv("USER"))+" on "+time.strftime("%d.%m.%Y at %H:%M:%S",time.gmtime(uptime_start))) - elif influx.lower()[0:len(Name)] == lowname and influx.lower()[-1] == "?" and influx.count(" ") > 1 or \ - influx.split(" ")[0].lower().replace(",","") in SName and influx.lower()[-1] == "?" and influx.count(" ") > 1: - dice = random.randint(0,1) - if dice == 0: - conn.privmsg(targetchannel,sender+" : "+C_eightball.eightball(influx.lower(),debug,truesender,prefix)) - else: - if highlights: - conn.privmsg(targetchannel,sender+" : "+C_sarcasticball.sarcasticball(influx.lower(),debug,truesender,users,prefix)) - else: - conn.privmsg(targetchannel,sender+" : "+C_sarcasticball.sarcasticball(influx.lower(),debug,truesender,nonhighlight_names,prefix)) - elif influx.lower()[0:len(Name)] == lowname and not influx.lower()[len(Name):].isalpha() or \ - influx.split(" ")[0].lower().replace(",","") in SName and not influx.lower()[len(influx.split(" ")[0].lower()):].isalpha(): - conn.privmsg(targetchannel, random.choice(["Yea?","I'm here","Ya?","Yah?","Hm?","What?","Mmhm, what?","?","What now?","How may I assist?"])) - comboer = truesender - comboer_time = time.time() - elif influx.lower()[-1] == "?" and comboer == truesender and looptime - discard_combo_messages_time < comboer_time: - comboer = "" - dice = random.randint(0,1) - if dice == 0: - conn.privmsg(targetchannel,sender+" : "+C_eightball.eightball(influx.lower(),debug,truesender,prefix)) - else: - if highlights: - conn.privmsg(targetchannel,sender+" : "+C_sarcasticball.sarcasticball(influx.lower(),debug,truesender,users,prefix)) - else: - conn.privmsg(targetchannel,sender+" : "+C_sarcasticball.sarcasticball(influx.lower(),debug,truesender,nonhighlight_names,prefix)) - - elif influx.lower() == prefix+"tm": - if truesender in operators and targetchannel==channel: - marakov = not marakov - conn.privmsg(targetchannel,sender+" : Marakov Output is now "+str(marakov)) - else: - conn.privmsg(targetchannel,sender+" : I can't let you access that") - elif personality_greeter == True and True in map(lambda x: x in influx.lower(),["greetings","afternoon","hi","hey","heya","hello","yo","hiya","howdy","hai","morning","mornin'","evening", "night","night", "evening","'sup","sup","hallo","hejssan"]): - if comboer != "" and looptime - discard_combo_messages_time > comboer_time: - combo_check = sbna(["greetings","afternoon","hi","hey","heya","hello","yo","hiya","howdy","hai","morning","mornin'","evening", "night","night", "evening","'sup","sup","hallo","hejssan","all night"], #ONLY ONE OF THESE - ["greetings","afternoon","hi","hey","heya","hello","yo","hiya","howdy","hai","morning","mornin'","evening", "night","night", "evening","'sup","sup","hallo","hejssan"], #ATLEAST ONE OF THESE - influx.lower()) - else: - combo_check = sbna(SName+[lowname, - #lowname+".",lowname+"!",lowname+"?", - "everybody", - #"everybody!","everybody?", - "everyone", - #"everyone!","everyone?", - "all", - #"all!","all?" - "all night", - ], #ONLY ONE OF THESE - ["greetings","afternoon","hi", - #"hi,", - "hey","heya","hello","yo","hiya","howdy","hai","morning","mornin'","evening", "night","night", "evening","'sup","sup","hallo","hejssan"], #ATLEAST ONE OF THESE - influx.lower().replace(",","").replace(".","").replace("!","")) - if combo_check: - combo_check = False - comboer = "" - if "evening" in influx.lower() and "all" in influx.lower() and len(influx.lower().split(" ")) > 3: - pass - - talking_about_me = False - if Name.lower() in influx.lower(): - talking_about_me = True - - for bot_name in SName: - if bot_name.lower() in influx.lower(): - talking_about_me = True - break - - if not talking_about_me: - continue #it got annoying REAL FAST when it'd interject any time a greeting was used, regardless of context - - elif truesender not in operators: - if debug: - print truesender+"::"+influx - dice = random.randint(0,19) - if dice == 0: - conn.privmsg(targetchannel,"Well hello to you too "+sender) - elif dice == 1: - if optimize_greeting == False: - hours = time.strftime("%H") - #time.strftime("%H:%M:%S") == 12:28:41 - hours = int(hours) - if hours in xrange(0,12): - conn.privmsg(targetchannel,"Good Morning "+sender) - elif hours in xrange(12,15): - conn.privmsg(targetchannel,"Good Afternoon "+sender) - elif hours in xrange(15,20): - conn.privmsg(targetchannel,"Good Evening "+sender) - else: - conn.privmsg(targetchannel,"Good Night "+sender) - else: - hours = time.strftime("%H") - hours = int(hours) - if hours in morning: - conn.privmsg(targetchannel,"Good Morning "+sender) - elif hours in afternoon: - conn.privmsg(targetchannel,"Good Afternoon "+sender) - elif hours in evening: - conn.privmsg(targetchannel,"Good Evening "+sender) - else: - conn.privmsg(targetchannel,"Good Night "+sender) - elif dice == 2: - conn.privmsg(targetchannel,"Hello!") - elif dice == 3: - conn.privmsg(targetchannel,"Hey "+sender) - elif dice == 4: - conn.privmsg(targetchannel,"Hi "+sender) - elif dice == 5: - conn.privmsg(targetchannel,"Hello "+sender) - elif dice == 6: - conn.privmsg(targetchannel,"Yo "+sender) - elif dice == 7: - conn.privmsg(targetchannel,"Greetings "+sender) - elif dice == 8: - conn.privmsg(targetchannel,"Hi") - elif dice == 9: - conn.privmsg(targetchannel,"Hi!") - elif dice == 10: - conn.privmsg(targetchannel,"Yo") - elif dice == 11: - conn.privmsg(targetchannel,"Yo!") - elif dice == 12: - conn.privmsg(targetchannel,"Heya") - elif dice == 13: - conn.privmsg(targetchannel,"Hello there!") - elif dice == 14: # Richard - conn.privmsg(targetchannel,"Statement: Greetings meatbag") - elif dice == 15: # Richard - hours = int(time.strftime("%H")) - if hours in xrange(5,12): - conn.privmsg(targetchannel,"What are you doing talking at this time of the morning?") - elif hours in xrange(12,15): - conn.privmsg(targetchannel,"What are you doing talking at this time of the day?") - elif hours in xrange(15,22): - conn.privmsg(targetchannel,"What are you doing talking at this time of the evening?") - else: - conn.privmsg(targetchannel,"What are you doing talking at this time of the night?") - elif dice == 16: # Richard - conn.privmsg(targetchannel,"Oh, you're still alive I see.") - elif dice == 17: - conn.privmsg(targetchannel,"Heya "+sender) - elif dice == 18 and time.gmtime(time.time())[1] == 12 and time.gmtime(time.time())[2] == 15: - conn.privmsg(targetchannel,"Hello! It's my birthday!") - else: - conn.privmsg(targetchannel,"Hiya "+sender) - secdice = random.randint(0,10) - if truesender.lower() in tell_list.keys(): - try: - conn.privmsg(channel, "Also, "+truesender+" : "+tell_list[truesender.lower()][0]) - del(tell_list[truesender.lower()][0]) - except: - pass - else: - dice = random.randint(0,1) - if dice == 0: - conn.privmsg(targetchannel,"Greetings Master "+sender) - elif dice == 1: - conn.privmsg(targetchannel,"My deepest greetings belong to you, Master "+sender) - ### IMPORTANT ### - elif influx == "☺VERSION☺": - conn.notice(truesender,"\001VERSION nanotrasen:2:Python 2.6\001") - elif marakov and influx.lower() == prefix+"marakov": - arg = Marakov_Chain.form_sentence() - if len(arg) < 5: - conn.privmsg(targetchannel,sender+" : Not enough words harvested") - else: - conn.privmsg(targetchannel,sender+" : %s" %(" ".join(arg).capitalize())) - elif marakov and cocheck( prefix+ "marakov"): - try: - arg = influx.split(" ")[1].lower() - except: - conn.privmsg(targetchannel,sender+" : Please input a valid second argument") - else: - arg2 = Marakov_Chain.form_sentence(arg) - if len(arg2) < 5: - conn.privmsg(targetchannel,sender+" : Not enough words harvested for a sentence starting with %s" %(arg)) - else: - conn.privmsg(targetchannel,sender+" : %s" %(" ".join(arg2).capitalize())) - else: - Marakov_Chain.give_data(influx) - autodiscusscurtime = backup - if time.time() - looptime == 0: - pass - else: - print "Took",time.time()-looptime,"Seconds to finish loop" - - elif data [ 1 ] [ 0 ] == '353': - if connected == False: - connected = True - users = map(lambda x: x[1:] if x[0] == "+" or x[0] == "@" else x,data[1][4].split(" ")) - print "There are",len(users),"Users on",channel - operators = [] - for potential_operator in data[1][4].split(" "): - if potential_operator[0] == "@": - operators.append(potential_operator[1:]) - elif potential_operator[0] == "%": - halfoperators.append(potential_operator[1:]) - - elif data[1][0] == "QUIT": - sender = data[0].split("!")[0] - print sender+" Has now left the server" - try: - users.remove(sender) - try: - operators.remove(sender) - except ValueError: - pass - try: - halfoperators.remove(sender) - except ValueError: - pass - except ValueError: - pass - elif data[1][0] == "PART": - sender = data[0].split("!")[0] - targetchannel = data[1][1] - print sender+" Has now parted from the channel" - try: - users.remove(sender) - try: - operators.remove(sender) - except ValueError: - pass - try: - halfoperators.remove(sender) - except ValueError: - pass - except ValueError: - pass - elif data[1][0] == "JOIN": - sender = data[0].split("!")[0] - targetchannel = data[1][1] - if sender.lower() in tell_list.keys(): - try: - conn.privmsg(targetchannel, sender+" : "+" | ".join(tell_list[sender.lower()])) - del(tell_list[sender.lower()]) - except: - pass - for useri,nicki in replacenames.items(): - checkers = Namecheck.Namecheck_dict(sender.lower(),replacenames) - if checkers[0]: - try: - if checkers[0].lower() == sender: - pass - else: - conn.privmsg(targetchannel,checkers[1]+" : I have detected a collision with a name I call you and %s who joined" %(sender)) - del(replacenames[checkers[1]]) - with open("replacenames.cache","w") as pickle_save: - pickle.dump(replacenames,pickle_save) - except AttributeError: - #conn.privmsg(channel,"NAME COLLISION CHECK ERROR, RELATED TO %s" %(sender)) - print "NAME COLLISION CHECK ERROR, RELATED TO %s" %(sender) - break - print sender+" Has now joined" - users.append(sender) - ##### - if sender.lower() not in peopleheknows[0]: - peopleheknows[0].append(sender.lower()) - peopleheknows[1].append(data[0].split("!")[1]) - with open("peopleheknows.cache","w") as peoplehecache: - pickle.dump(peopleheknows,peoplehecache) - - elif data[1][0] == "MODE" and data[1][2] == "+o": - sender = data[1][3] - targetchannel = data[1][1] - if targetchannel == channel: - print sender+" Is now an operator on the main channel" - operators.append(sender) - else: - print sender+" Is now an operator" - elif data[1][0] == "MODE" and data[1][2] == "-o": - sender = data[1][3] - targetchannel = data[1][1] - if targetchannel == channel: - print sender+" Is no longer an operator on the main channel" - else: - print sender+" Is no longer an operator" - try: - operators.remove(sender) - except ValueError: - pass - elif data[1][0] == "MODE" and data[1][2] == "+h": - sender = data[1][3] - print sender+" Is now an half operator" - halfoperators.append(sender) - elif data[1][0] == "MODE" and data[1][2] == "-h": - try: - halfoperators.remove(sender) - except ValueError: - pass - elif data[1][0] == "MODE" and data[1][1] == Name: - print "My mode is",data[1][2] - elif data[1][0] == "MODE" and data[1][1] != Name: - try: - sender = data[1][3] - print sender,"Was modified",data[1][2] - except IndexError: - print "SENDER RETRIEVAL FAILED:"+str(data) - elif data[1][0] == "KICK" and data[1][2] == Name: - disconnects = 99999 - print "I have been kicked! Disconnecting entirely!" - conn.quit() - elif data[1][0] == "KICK": - # data[1][0] = Kick, 1 = Channel, 2 = Who, 3 = Who(?) - print data[1][2]+" got kicked!" - elif data[1][0] == "451" and data[1][2] == "You have not registered": - print Name+" hasn't been registered" - elif data[1][0] == "NOTICE": - sender = data[0].split("!")[0] - print "NOTICE (%s): %s" %(sender,data[1][2]) - pongtarget = sender - elif data[1][0] == "NICK": - origname = data[0].split("!")[0] - newname = data[1][1] - print origname,"Is now",newname - if newname.lower() in tell_list.keys(): - try: - conn.privmsg(channel, newname+" : "+tell_list[newname.lower()][0]) - del(tell_list[newname.lower()][0]) - except: - pass - try: - users.remove(origname) - except ValueError: - pass - else: - users.append(newname) - try: - operators.remove(origname) - except ValueError: - pass - else: - operators.append(newname) - try: - halfoperators.remove(origname) - except ValueError: - pass - else: - halfoperators.append(newname) - - elif data[1][0] == "001": - # Skibot is welcomed to the Network - pass - elif data[1][0] == "002": - # Your host is... - pass - elif data[1][0] == "003": - #Server was created... - pass - elif data[1][0] == "004": - #Weird hex? - pass - elif data[1][0] == "005": - #Settings like NICKLEN and so on. - pass - elif data[1][0] == "250": - #data[1][2] is - #"Highest connection count: 1411 (1410 clients) - #(81411 connections received)" - pass - elif data[1][0] == "251": - #There are 23 users and 2491 invisible on 10 servers - pass - elif data[1][0] == "252": - #IRC Operators online - #data[1][2] - print data[1][2],"Irc operators online" - pass - elif data[1][0] == "253": - # ['253', 'Skibot_V4', '1', 'unknown connection(s)'] - print data[1][2],"Unknown connection(s)" - pass - elif data[1][0] == "254": - #1391 channels formed - pass - elif data[1][0] == "255": - #I have 406 clients and 2 servers - pass - elif data[1][0] == "265": - #data[1][2] current local users - #data[1][3] at max - try: - print "Current local users:", data[1][2],"/",data[1][3] - except IndexError: - print "Couldn't retrieve local users" - pass - elif data[1][0] == "266": - #data[1][2] current global users - #data[1][3] at max - try: - print "Current global users:", data[1][2],"/",data[1][3] - except IndexError: - print "Couldn't retrieve global users" - pass - elif data[1][0] == "315": - #End of /who list - pass - elif data[1][0] == "332": - # Topic of channel - topic = data[1][3] - pass - elif data[1][0] == "333": - # *Shrug* - pass - elif data[1][0] == "352": - #WHO command - - if len(targetlist) > 0: - if targetlist[0][0].lower() in data[1][6].lower(): - thread.start_new_thread(target,("*!*@"+data[1][4],targetlist[0][1])) - print "Created a thread with", "*!*@"+data[1][4],targetlist[0][1] - targetlist.pop(0) - else: - print targetlist[0][0].lower(), "isn't equal to?", data[1][6].lower() - print targetlist - - elif data[1][0] == "366": - # End of USERS - pass - elif data[1][0] == "372": - # Server information - pass - elif data[1][0] == "375": - # Message of the day - pass - elif data[1][0] == "376": - # End of motd - pass - elif data[1][0] == "401": - # ('network', ['401','Botname','Channel / Nick','No such nick/channel']) - print data[1][2] + " Channel does not exist" - pass - elif data[1][0] == "439": - # ('irc.rizon.no', ['439', '*', 'Please wait while we process your connection.']) - pongtarg = data[0][0] - elif data[1][0] == "477": - # You need to be identified - #TAG - conn.privmsg("nickserv","identify %s"%CORE_DATA.le_pass) - time.sleep(0.5) - conn.join(data[1][2]) - #('network', ['477', 'botname', '#channel', 'Cannot join channel (+r) - you need to be identified with services']) - - elif data[1][0] == "433": - # Skibot name already exists. - print Name+" name already exists." - Name += "_"+version - print "New name:",Name - duplicate_notify = True - conn = irchat.IRC ( Network, Port, Name, "NT_"+version, "NT_"+version, "Trasen_"+version ) - for i in CORE_DATA.channels: - conn.join(i) - sleep(0.5) - elif data[1][0] == "482": - sleep(0.05) - conn.privmsg(targetchannel,"Nevermind that, I am not an operator") - CALL_OFF = True - elif data[1] == ["too","fast,","throttled."]: - print "Reconnected too fast." - print "Halting for 2 seconds" - sleep(2) - elif data[1][0] == "Link": - if data[0] == "Closing": - print "Link was closed" - connected = False -# conn.quit() -# break - else: - print data - print data[1][0] - pass - else: - if disconnects > 9000: #IT'S OVER NINE THOUSAAAAND! - break - else: #WHAT NINE THOUSAND? THERE'S NO WAY THAT CAN BE RIGHT - sleep(responsiveness_delay) #WAIT A WHILE AND CHECK AGAIN! - try: - if not connected: - #print pongtarget - #print conn.addressquery() - conn.privmsg(pongtarget,"Pong") - sleep(1) - for i in CORE_DATA.channels: - conn.join(i) - sleep(0.5) - print "Attempted to join" - connected = True - except ValueError: - try: - conn.privmsg(conn.addressquery()[0],"Pong") - sleep(1) - for i in CORE_DATA.channels: - conn.join(i) - sleep(0.5) - print "Attempted to join the second time" - connected = True - except ValueError: - print "Both methods failed" - except AttributeError: - print "Conn is not established correctly" - except NameError: - print "Pongtarget isn't yet established" - try: - conn.privmsg(conn.addressquery()[0],"Pong") - sleep(1) - for i in CORE_DATA.channels: - conn.join(i) - sleep(0.5) - print "Attempted to join the second time" - connected = True - except: - print "Both methods failed" diff --git a/bot/Shortname.py b/bot/Shortname.py deleted file mode 100644 index ae8ac473b85..00000000000 --- a/bot/Shortname.py +++ /dev/null @@ -1,28 +0,0 @@ -def shortname(name): - lowname = name.lower() - numb = 0 - count = 0 - spot = 0 - for letter in name: - if letter.isupper(): - spot = numb - count += 1 - numb += 1 - if "_" in name: - if name.count("_") > 1: - name = " ".join(name.split("_")[0:name.count("_")]) - if name.lower()[-3:] == "the": - return name[:-4] - else: - return name - else: - return name.split("_")[0] - if count > 1: - if len(name[0:spot]) > 2: - return name[0:spot] - if len(name) < 5: - return name #Too short to be shortened - elif "ca" in lowname or "ct" in lowname or "tp" in lowname or "lp" in lowname: - return name[0:max(map(lambda x: lowname.find(x),["ca","ct","tp","lp"]))+1] - else: - return name[0:len(name)/2+len(name)%2] diff --git a/bot/Timeconverter.py b/bot/Timeconverter.py deleted file mode 100644 index a39f821c846..00000000000 --- a/bot/Timeconverter.py +++ /dev/null @@ -1,204 +0,0 @@ -#Sources: -# http://wwp.greenwichmeantime.com/time-zone/usa/eastern-time/convert/ -# http://www.timeanddate.com/library/abbreviations/timezones/na/ -# Times are GMT +- x -# For eq. -# EST = -5 -# GMT = 0 -# UTC = 0 -#Times are in hours, -#2.5 = 2 and half hours -global times -times = {"ADT":-3,"HAA":-3, #Synonyms on the same line - "AKDT":-8,"HAY":-8, - "AKST":-9,"HNY":-9, - "AST":-4,"HNA":-4, - "CDT":-5,"HAC":-5, - "CST":-6,"HNC":-6, - "EDT":-4,"HAE":-4, - "EGST":0, - "EGT":-1, - "EST":-5,"HNE":-5,"ET":-5, - "HADT":-9, - "HAST":-10, - "MDT":-6,"HAR":-6, - "MST":-7,"HNR":-7, - "NDT":-2.5,"HAT":-2.5, - "NST":-3.5,"HNT":-3.5, - "PDT":-7,"HAP":-7, - "PMDT":-2, - "PMST":-3, - "PST":-8,"HNP":-8,"PT":-8, - "WGST":-2, - "WGT":-3, - "GMT":0, - "UTC":0} -def converter(zones,time): - #Zones should be a list containing - # ( From zone - # To zone ) - global times - #from_z = for example UTC+00:00, WGT or GMT-05:30 - #to_z = same style as above. - from_z,to_z = zones - from_z = from_z.upper() - to_z = to_z.upper() - if from_z.find("+") != -1: - from_zone_offset = from_z[from_z.find("+"):] - if ":" in from_zone_offset: - try: - from_zone_offset1,from_zone_offset2 = from_zone_offset.split(":") - except ValueError: - return "Too many or too small amount of values" - try: - from_zone_offset = int(from_zone_offset1) + int(from_zone_offset2)/60.0 - except: - return "Error, the 'From Zone' variable has an incorrect offset number" - else: - try: - from_zone_offset = float(from_zone_offset) - except: - return "Error, the 'From Zone' variable has an incorrect offset number" - try: - from_zone_realtime = from_zone_offset + times[from_z[:from_z.find("+")]] - except KeyError: - return "Incorrect From zone" - - elif "-" in from_z: - from_zone_offset = from_z[from_z.find("-"):] - if ":" in from_zone_offset: - from_zone_offset1,from_zone_offset2 = from_zone_offset.split(":") - try: - from_zone_offset = -int(from_zone_offset1) + int(from_zone_offset2)/60.0 - except: - return "Error, the 'From Zone' variable has an incorrect offset number" - else: - try: - from_zone_offset = -float(from_zone_offset) - except: - return "Error, the 'From Zone' variable has an incorrect offset number" - from_zone_realtime = times[from_z[:from_z.find("-")]] - from_zone_offset - pass - else: - from_zone_offset = 0 - try: - from_zone_realtime = from_zone_offset + times[from_z] - except KeyError: - return "Incorrect From zone" - if to_z.find("+") != -1: - to_zone_offset = to_z[to_z.find("+"):] - if ":" in to_zone_offset: - try: - to_zone_offset1,to_zone_offset2 = to_zone_offset.split(":") - except ValueError: - return "Too many or too small amount of values" - try: - to_zone_offset = int(to_zone_offset1) + int(to_zone_offset2)/60.0 - except: - return "Error, the 'To Zone' variable has an incorrect offset number" - else: - try: - to_zone_offset = float(to_zone_offset) - except: - return "Error, the 'To Zone' variable has an incorrect offset number" - try: - to_zone_realtime = to_zone_offset + times[to_z[:to_z.find("+")]] - except KeyError: - return "The zone you want the time to be changed to is not found" - - elif "-" in to_z: - to_zone_offset = to_z[to_z.find("-"):] - if ":" in to_zone_offset: - to_zone_offset1,to_zone_offset2 = to_zone_offset.split(":") - try: - to_zone_offset = -int(to_zone_offset1) + int(to_zone_offset2)/60.0 - except: - return "Error, the 'To Zone' variable has an incorrect offset number" - else: - try: - to_zone_offset = -float(to_zone_offset) - except: - return "Error, the 'To Zone' variable has an incorrect offset number" - to_zone_realtime = times[to_z[:to_z.find("-")]] -to_zone_offset - - pass - else: - to_zone_offset = 0 - try: - to_zone_realtime = to_zone_offset + times[to_z] - except KeyError: - return "Incorrect To zone" - try: - time_hour,time_minute = time.split(":") - time_hour,time_minute = int(time_hour),int(time_minute) - string = ":" - except: - try: - time_hour,time_minute = time.split(".") - time_hour,time_minute = int(time_hour),int(time_minute) - string = "." - except ValueError: - return "The time was input in an odd way" - if to_zone_realtime % 1.0 == 0.0 and from_zone_realtime % 1.0 == 0.0: - time_hour = time_hour + (to_zone_realtime - from_zone_realtime) - return str(int(time_hour))+string+str(int(time_minute)) - else: - if to_zone_realtime % 1.0 != 0.0 and from_zone_realtime % 1.0 != 0.0: - time_minute = time_minute + (((to_zone_realtime % 1.0) * 60) - ((from_zone_realtime % 1.0) * 60)) - elif to_zone_realtime % 1.0 != 0.0 and from_zone_realtime % 1.0 == 0.0: - time_minute = time_minute + (((to_zone_realtime % 1.0) * 60) - 0) - elif to_zone_realtime % 1.0 == 0.0 and from_zone_realtime % 1.0 != 0.0: - time_minute = time_minute + (0 - ((from_zone_realtime % 1.0) * 60)) - else: - print "Wut?" - time_hour = time_hour + (int(to_zone_realtime//1) - int(from_zone_realtime//1)) - return str(int(time_hour))+string+str(int(time_minute)) - - -def formatter(time): - if "." in time: - string = "." - elif ":" in time: - string = ":" - else: - return time - hours,minutes = time.split(string) - days = 0 - if int(minutes) < 0: - buphours = int(hours) - hours,minutes = divmod(int(minutes),60) - hours += buphours - if int(minutes) > 60: - hours,minutes = divmod(int(minutes),60) - hours += int(hours) - if int(hours) < 0: - days = 0 - days,hours = divmod(int(hours),24) - if int(hours) > 24: - days = 0 - days,hours = divmod(int(hours),24) - if int(hours) == 24 and int(minutes) > 0: - days += 1 - hours = int(hours) - 24 - hours = str(hours) - minutes = str(minutes) - if len(minutes) == 1: - minutes = "0"+minutes - if len(hours) == 1: - hours = "0"+hours - if days > 0: - if days == 1: - return hours+string+minutes+" (Tomorrow)" - else: - return hours+string+minutes+" (After "+str(days)+" days)" - elif days < 0: - if days == -1: - return hours+string+minutes+" (Yesterday)" - else: - return hours+string+minutes+" ("+str(abs(days))+" days ago)" - return hours+string+minutes - - - - - diff --git a/bot/Weather.py b/bot/Weather.py deleted file mode 100644 index 1fb786e8f4f..00000000000 --- a/bot/Weather.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: cp1252 -*- -import urllib,xml.sax.handler -# S10 COMPATIABLE -def message(data): - if data["type"] == "PRIVMSG": - try: - splitdata = data["content"].lower().split(" ") - if splitdata[0] == ":weather" and len(splitdata) > 1: - data = Weather(" ".join(splitdata[1:])) - - data["conn"].privmsg(data["target"],"Weather for "+data[1]+": "+data[0]) - return True - except KeyError: - print "WUT" - else: - return -1 -def Weather(question): - question = question.replace("ä","a") - url = "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query="+question - opener = urllib.FancyURLopener({}) - f = opener.open(url) - data = f.read() - f.close() - bufferi = [] - seen = False - for i in data.split("\n"): - if "" in i: - stuff = cutter(i,"") - if len(stuff) > 7: - bufferi.append("Temperature: "+stuff) - elif "" in i: - stuff = cutter(i,"") - if len(stuff) > 19: - bufferi.append(stuff) - elif "" in i: - stuff = cutter(i,"") - if len(stuff) > 0: - bufferi.append("Weather: "+stuff) - elif "" in i: - stuff = cutter(i,"") - if len(stuff) > 0: - bufferi.append("Humidity: "+stuff) - elif "" in i: - stuff = cutter(i,"") - if len(stuff) > 0: - bufferi.append("Wind blows "+stuff) - elif "" in i: - stuff = cutter(i,"") - if len(stuff) > 9: - bufferi.append("Air pressure is "+stuff) - elif "" in i and seen == False: - seen = True - where = cutter(i,"") - if len(where) == 4: - where = "Location doesn't exist" - return [", ".join(bufferi),where] -def cutter(fullstring,cut): - fullstring = fullstring.replace(cut,"") - fullstring = fullstring.replace("": - ignore = False - else: - pass - tempolio = tempolio.replace("\t","") - if len(tempolio) == 0: - pass - elif len(tempolio.replace(" ","")) == 0: - pass - else: - b.append(tempolio) - #Finetuning - return b diff --git a/bot/irchat.py b/bot/irchat.py deleted file mode 100644 index 46ae2d4caf7..00000000000 --- a/bot/irchat.py +++ /dev/null @@ -1,94 +0,0 @@ -import socket -import time -class IRC: - queue = [] - partial = '' - def __init__ ( self, network, port, name, hostName, serverName, realName ): - self.network = network - self.port = port - self.hostName = hostName - self.serverName = serverName - self.realName = realName - self.socket = socket.socket ( socket.AF_INET, socket.SOCK_STREAM ) - self.socket.connect ( ( self.network, self.port ) ) - self.address = self.socket.getpeername() - self.nick ( name ) - self.send ( 'USER ' + self.name + ' ' + self.serverName + ' ' + self.hostName + ' :' + self.realName ) - def quit ( self ): - self.send ( 'QUIT' ) - self.socket.close() - def send ( self, text ): - count = 0 - try: - count += 1 - self.socket.send ( text + '\r\n' ) - except: - if count > 10: - time.sleep(1) - self.socket.send(text+'\r\n') - else: - count = 0 - def nick ( self, name ): - self.name = name - self.send ( 'NICK ' + self.name ) - def addressquery(self): - print self.address - aha = socket.gethostbyaddr(str(self.address[0])) - return aha - def recv ( self, size = 2048 ): - commands = self.socket.recv ( size ).split ( '\r\n' ) - if len ( self.partial ): - commands [ 0 ] = self.partial + commands [ 0 ] - self.partial = '' - if len ( commands [ -1 ] ): - self.partial = commands [ -1 ] - self.queue.extend ( commands [ :-1 ] ) - else: - self.queue.extend ( commands ) - def retrieve ( self ): - if len ( self.queue ): - command = self.queue [ 0 ] - self.queue.pop ( 0 ) - return command - else: - return False - def dismantle ( self, command ): - if command: - source = command.split ( ':' ) [ 1 ].split ( ' ' ) [ 0 ] - parameters = command.split ( ':' ) [ 1 ].split ( ' ' ) [ 1: ] - if len(parameters) > 0: - if not len ( parameters [ -1 ] ): - parameters.pop() - if command.count ( ':' ) > 1: - parameters.append(command[command.find(":",command.find(":")+1)+1:]) - return source, parameters - def privmsg ( self, destination, message ): - self.send ( 'PRIVMSG ' + destination + ' :' + message ) - def handshake(self,hexstring): - self.send("PONG :"+hexstring) - def notice ( self, destination, message ): - self.send ( 'NOTICE ' + destination + ' :' + message ) - def join ( self, channel ): - self.send ( 'JOIN ' + channel ) - def part ( self, channel ): - self.send ( 'PART ' + channel ) - def topic ( self, channel, topic = '' ): - self.send ( 'TOPIC ' + channel + ' ' + topic ) - def names ( self, channel ): - self.send ( 'NAMES ' + channel ) - def invite ( self, nick, channel ): - self.send ( 'INVITE ' + nick + ' ' + channel ) - def mode ( self, channel, mode, nick = '' ): - self.send ( 'MODE ' + channel + ' ' + mode + ' ' + nick ) - def banon(self,channel,name): - self.mode(channel,"+b",name) - def banoff(self,channel,name): - self.mode(channel,"-b",name) - def kick ( self, channel, nick, reason = '' ): - self.send ( 'KICK ' + channel + ' ' + nick + ' ' + reason ) - def who ( self, pattern ): - self.send ( 'WHO ' + pattern ) - def whois ( self, nick ): - self.send ( 'WHOIS ' + nick ) - def whowas ( self, nick ): - self.send ( 'WHOWAS ' + nick ) diff --git a/bot/linereader.py b/bot/linereader.py deleted file mode 100644 index cef804935b8..00000000000 --- a/bot/linereader.py +++ /dev/null @@ -1,43 +0,0 @@ -import os -directory = "" -raw = os.listdir(directory) -extract = [] -for i in raw: - if i[-3:] == ".py": - extract.append(i) -toc = 0 -toc3 = 0 -toc2 = 0 -print len(extract),"Files" -lista = [] -for ob in extract: - count3 = 0 - if directory == "": - tiedosto = open(ob,"r") - tiedosto2 = open(ob,"r") - count3 += os.path.getsize(ob) - toc3 += count3 - else: - tiedosto = open(directory+"/"+ob,"r") - tiedosto2 = open(directory+"/"+ob,"r") - count3 += os.path.getsize(directory+"/"+ob) - toc3 += count3 - count = 0 - count2 = 0 - line = tiedosto.readline() - while line != "": - count += 1 - toc += 1 - line = tiedosto.readline() - count2 += len(tiedosto2.read()) - toc2 += count2 - lista.append([count,count2,ob,count3]) - tiedosto.close() - tiedosto2.close() -print toc,"Lines in total" -print toc2,"Letters in total" -print toc3,"Bytes in total" - -for linecount, lettercount, filename, bytecount in lista: - print str(linecount)+" Lines (%s%%) || "%(str(round((float(linecount)/toc)*100,1))),str(lettercount)+" Letters (%s%%) in file " %(str(round((float(lettercount)/toc2)*100,1)))+filename - print str(bytecount) + " Bytes (%s%%) "%(str(round((float(bytecount)/toc3)*100,1))) diff --git a/bot/minibot.py b/bot/minibot.py new file mode 100755 index 00000000000..b3ff6cb5b55 --- /dev/null +++ b/bot/minibot.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +# This bot was made by tkdrg. +# Ask #coderbus@irc.rizon.net if this breaks. +# See LICENSE-bot_folder.txt for the license of the files in this folder. +from config import * +import collections +import time +import pickle +import socket +import threading + + +def setup_irc_socket(): + s = socket.socket() + s.settimeout(240) + + while 1: + try: + s.connect((server, port)) + except socket.error: + print("Unable to connect to server {0}:{1}, attempting to reconnect in 20 seconds.".format(server, port)) + time.sleep(20) + else: + print("Connection established to server {0}:{1}.".format(server, port)) + break + + s.send(bytes("NICK {0}\r\n".format(nick), "UTF-8")) + s.send(bytes("USER {0} {1} {2} :{3}\r\n".format(ident, server, name, realname), "UTF-8")) + s.send(bytes("PRIVMSG NickServ :IDENTIFY {0}\r\n".format(password), "UTF-8")) + time.sleep(5) + for channel in channels: + s.send(bytes("JOIN {0}\r\n".format(channel), "UTF-8")) + return s + + +def setup_nudge_socket(): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind(("", 45678)) # localhost:45678 + s.listen(5) + return s + + +def nudge_handler(irc): + nudge = setup_nudge_socket() + message_queue = collections.deque() + while 1: + if len(message_queue): + message = message_queue.popleft() + else: + try: + s, ip = nudge.accept() + except: + print("Nudge socket lost, attempting to reopen.") + nudge = setup_nudge_socket() + continue + rawdata = s.recv(1024) + s.close() + data = pickle.loads(rawdata) + if data["ip"][0] == "#": + message = "{0} :AUTOMATIC ANNOUNCEMENT : {1}\r\n".format(data["ip"], str(" ".join(data["data"]))) + else: + message = "{0} :AUTOMATIC ANNOUNCEMENT : {1} | {2}\r\n".format(defaultchannel, data["ip"], str(" ".join(data["data"]))) + try: + irc.send(bytes("PRIVMSG {0}".format(message), "UTF-8")) + except: + print("Nudge received without IRC socket, appending to queue.") + print("Message: {0}".format(message)) + message_queue.append(message) + + +def irc_handler(irc): + while 1: + try: + buf = irc.recv(1024).decode("UTF-8").split("\n") + for i in buf: + if i[0:4] == "PING": + irc.send(bytes("PONG {0}\r\n".format(i[5:]), "UTF-8")) + else: + l = i.split(" ") + if len(l) < 2: + continue + elif l[1] == "477": + print("Error: Nickname was not registered when joining {0}. Reauthing and retrying...".format(l[3])) + irc.send(bytes("PRIVMSG NickServ :IDENTIFY {0}\r\n".format(password), "UTF-8")) + time.sleep(5) + s.send(bytes("JOIN {0}\r\n".format(l[3]), "UTF-8")) + elif l[1] == "433": + print("Error: Nickname already in use. Attempting to use alt nickname if available, sleeping 60s otherwise...") + if(altnick): + s.send(bytes("NICK {0}\r\n".format(altnick), "UTF-8")) + else: + time.sleep(60) + irc = setup_irc_socket() + except: + print("Lost connection to IRC server.") + irc = setup_irc_socket() + + +if __name__ == "__main__": + irc = setup_irc_socket() + t = threading.Thread(target=nudge_handler, args=(irc,)) + t.daemon = True + t.start() + irc_handler(irc) diff --git a/bot/nudge.py b/bot/nudge.py old mode 100644 new mode 100755 index e39ebc314c5..1971f67024d --- a/bot/nudge.py +++ b/bot/nudge.py @@ -1,39 +1,24 @@ -import sys,pickle,socket, CORE_DATA -#def pack(): -# path = "/home/ski/Nanotrasen/message.txt" -# ip = sys.argv[1] -# dictionary = {"ip":ip,"data":1} -# try: -# targetfile = open(path,"r") -# except IOError: -# targetfile = open(path,"w") -# pickle.dump(dictionary,targetfile) -# targetfile.close() -# nudge() -# else: -# targetfile.close() #Professionals, have standards. -# pass +#!/usr/bin/env python3 +import sys +import pickle +import socket + + def pack(): ip = sys.argv[1] try: - data = sys.argv[2:] #The rest of the arguments is data + data = sys.argv[2:] except: data = "NO DATA SPECIFIED" - dictionary = {"ip":ip,"data":data} - pickled = pickle.dumps(dictionary) - nudge(pickled) + + nudge(pickle.dumps({"ip": ip, "data": data})) + + def nudge(data): - if CORE_DATA.DISABLE_ALL_NON_MANDATORY_SOCKET_CONNECTIONS: - pass - else: - HOST = "localhost" - PORT = 45678 - size = 1024 - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((HOST,PORT)) - s.send(data) - s.close() - -if __name__ == "__main__" and len(sys.argv) > 1: # If not imported and more than one argument + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.connect(("localhost", 45678)) + s.send(data) + s.close() + +if __name__ == "__main__" and len(sys.argv) > 1: pack() - diff --git a/bot/save_load.py b/bot/save_load.py deleted file mode 100644 index 34eac990726..00000000000 --- a/bot/save_load.py +++ /dev/null @@ -1,24 +0,0 @@ -import pickle -def save(filename,data,dnrw=0): - if dnrw == 1: - try: - tiedosto = open(filename,"r") - except: - tiedosto = open(filename,"w") - else: - return False - else: - tiedosto = open(filename,"w") - - if "http//" in data: - data = data.replace("http//","http://") - pickle.dump(data,tiedosto) - tiedosto.close() -def load(filename): - try: - tiedosto = open(filename,"r") - except IOError: - return "ERROR ERROR ERROR ERR" - a = pickle.load(tiedosto) - tiedosto.close() - return a diff --git a/bot/some_but_not_all_2.py b/bot/some_but_not_all_2.py deleted file mode 100644 index 211eef9fd52..00000000000 --- a/bot/some_but_not_all_2.py +++ /dev/null @@ -1,20 +0,0 @@ -def sbna2(only_one,one_of_these,data): - if type(only_one) != list: - only_one = list(only_one) - if type(data) != list: - data = data.split(" ") - count = 0 - for datoid in only_one: - if datoid in data and count >= 1: - return False - elif datoid in data: - count += 1 - pass - else: - pass - if count == 0: - return False - for datoid in one_of_these: - if datoid in data: - return True - return False diff --git a/bot/xkcdparser.py b/bot/xkcdparser.py deleted file mode 100644 index 24d6f514165..00000000000 --- a/bot/xkcdparser.py +++ /dev/null @@ -1,40 +0,0 @@ -from urllib2 import urlopen -from json import loads -from pickle import dump,load -from CORE_DATA import no_absolute_paths -def xkcd(link): - try: - filename = link[link.find("xkcd.com")+9:].replace("/","").replace("\\","") - if no_absolute_paths: - tiedosto = open("xkcdcache/"+filename,"r") - else: - tiedosto = open(directory+"xkcdcache/"+filename,"r") - except: - try: - if no_absolute_paths: - tiedosto = open("xkcdcache/"+filename,"w") - else: - tiedosto = open(directory+"xkcdcache/"+filename,"w") - except IOError: - return "NOTHING" - else: - try: - return load(tiedosto) - except EOFError: - tiedosto = open("xkcdcache/"+filename,"w") - pass #Corrupt cache, moving on. - if link[-1] == "/" or link[-1] == "\\": #Ending is fine. - link += "info.0.json" - else: - link += "/info.0.json" - try: - data = urlopen(link).read() - except: - return "NOTHING" - try: - newdata = loads(data)["title"] - dump(newdata,tiedosto) - return newdata - except: - return "NOTHING" - From b1d1f7753e5dbbc7f2adde205fff587a046cb0d4 Mon Sep 17 00:00:00 2001 From: PKPenguin321 Date: Thu, 24 Dec 2015 19:30:21 -0800 Subject: [PATCH 53/71] fixes santabag/suicide_act fixes the path for santabag/suicide_act --- code/game/objects/items/weapons/storage/backpack.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 6932805abde..deabe13233d 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -113,7 +113,7 @@ max_w_class = 3 max_combined_w_class = 60 -/obj/item/weapon/storage/santabag/suicide_act(mob/user) +/obj/item/weapon/storage/backpack/santabag/suicide_act(mob/user) user.visible_message("[user] places the [src.name] over their head and pulls it tight! It looks like they aren't in the Christmas spirit...") return (OXYLOSS) From 93aa422c2a340d9390a89dd5ce200087eb3ad2ad Mon Sep 17 00:00:00 2001 From: PKPenguin321 Date: Thu, 24 Dec 2015 19:33:50 -0800 Subject: [PATCH 54/71] fixes statue.dm anotha one --- code/modules/mob/living/simple_animal/hostile/statue.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index d26707238bf..2d04aee5fdc 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -222,6 +222,6 @@ faction -= "neutral" /mob/living/simple_animal/hostile/statue/restrained() - . == ..() + . = ..() if(can_be_seen(loc)) - return 1 \ No newline at end of file + return 1 From 85ac583708b0c0d3dd3093cc943f989d3e7060c3 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 24 Dec 2015 21:51:01 -0600 Subject: [PATCH 55/71] Fixes chainsaw surgery --- code/game/objects/items/weapons/weaponry.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index ea81253aa2f..9087ec8dc77 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -277,7 +277,7 @@ desc = "A chainsaw that has replaced your arm." icon_state = "chainsaw_on" item_state = "mounted_chainsaw" - flags = NODROP + flags = NODROP | ABSTRACT w_class = 5.0 force = 21 throwforce = 0 From d5b64db62fc161f562d71a56796770e7bb5b9859 Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Thu, 24 Dec 2015 23:41:01 -0500 Subject: [PATCH 56/71] Fixes two of the lightning sprites pulsing at the wrong rate --- icons/effects/effects.dmi | Bin 351879 -> 351871 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 6c1343f24858227ee2aeb75bf49a8323137dbe64..bb86a8b46f2530e5e60335d28bb7e50369d501de 100644 GIT binary patch delta 66 zcmZqQEBb$r=mcdZ=D!bJxxD|&%ipIzk)O@UP_gJ>`@v=-mUbf+ TMj&PaVrC#_*>1$b8X5%vwR{-Z delta 74 zcmeyrN3?yf=mcdZ7S@fbZ Date: Fri, 25 Dec 2015 00:28:54 -0600 Subject: [PATCH 57/71] Fixes nuke --- code/game/gamemodes/antag_spawner.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index c32244b01e1..6cce1a297a7 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -168,14 +168,14 @@ user << "Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded." /obj/item/weapon/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T) - var/nuke_code = "Ask your leader!" + var/new_op_code = "Ask your leader!" var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) C.prefs.copy_to(M) M.key = C.key var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in nuke_list if(nuke) - nuke.r_code = nuke_code - M.mind.make_Nuke(T, nuke_code, 0, FALSE) + new_op_code = nuke.r_code + M.mind.make_Nuke(T, new_op_code, 0, FALSE) From 64bc7ee1e1f82b3e3b82f000b9d3bd69b13ba009 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Fri, 25 Dec 2015 02:14:19 -0600 Subject: [PATCH 58/71] Detective starts with his bowman on --- code/game/jobs/job/security.dm | 2 +- .../structures/crates_lockers/closets/secure/security.dm | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 0db3d7255d5..ee4ab0f1d28 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -140,7 +140,7 @@ Detective name = "Detective" belt = /obj/item/device/pda/detective - ears = /obj/item/device/radio/headset/headset_sec + ears = /obj/item/device/radio/headset/headset_sec/alt uniform = /obj/item/clothing/under/rank/det shoes = /obj/item/clothing/shoes/sneakers/brown suit = /obj/item/clothing/suit/det_suit diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 0b7fd27cc66..1bcd35a11b1 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -171,6 +171,7 @@ new /obj/item/clothing/shoes/laceup(src) new /obj/item/weapon/storage/box/evidence(src) new /obj/item/device/radio/headset/headset_sec/alt(src) + new /obj/item/device/radio/headset/headset_sec(src) new /obj/item/device/detective_scanner(src) new /obj/item/tapeproj/security(src) new /obj/item/clothing/suit/armor/vest/det_suit(src) From 4c9861f07e96b2a62097888476b612ee7de50a92 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Fri, 25 Dec 2015 18:15:28 +0000 Subject: [PATCH 59/71] Automatic changelog generation for PR #14004 --- html/changelogs/AutoChangeLog-pr-14004.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14004.yml diff --git a/html/changelogs/AutoChangeLog-pr-14004.yml b/html/changelogs/AutoChangeLog-pr-14004.yml new file mode 100644 index 00000000000..47f2f3fc037 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14004.yml @@ -0,0 +1,5 @@ +author: MrStonedOne +delete-after: True +changes: + - bugfix: "flashes that were emp'ed were incorrectly flashing people in range of the emper, not in range of the flash." + - tweak: "flashes in a mob's inventory that are emp'ed will only aoe stun if it is not inside of a container like a backpack/box" From fad47ae8014597f5d46d23156811f4c72c03008b Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Fri, 25 Dec 2015 17:33:33 -0600 Subject: [PATCH 60/71] missing space --- code/modules/awaymissions/pamphlet.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/awaymissions/pamphlet.dm b/code/modules/awaymissions/pamphlet.dm index 812d802eace..f00e0103c8a 100644 --- a/code/modules/awaymissions/pamphlet.dm +++ b/code/modules/awaymissions/pamphlet.dm @@ -13,7 +13,7 @@ Nanotrasen's operational area and start your new life.

\ Gateway Operation Basics
\ All Nanotrasen approved Gateways operate on the same basic principals. They operate off \ - area equipment power as you would expect,and without this supply, it cannot safely function, \ + area equipment power as you would expect, and without this supply, it cannot safely function, \ causinng it to reject all attempts at operation.

\ Once it is correctly setup, and once it has enough power to operate, the Gateway will begin \ searching for an output location. The amount of time this takes is variable, but the Gateway \ @@ -34,4 +34,4 @@ //we don't want the silly text overlay! /obj/item/weapon/paper/pamphlet/update_icon() - return \ No newline at end of file + return From 4bf0326288bdb9c556c23ab437c4314cdf059c07 Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Fri, 25 Dec 2015 19:11:40 -0500 Subject: [PATCH 61/71] high-end back down --- code/game/gamemodes/blob/blob.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index 5639775f7ee..511dd4ebcdc 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -28,7 +28,7 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b var/blobwincount = 350 var/burstdelay_low = 1200 //in deciseconds - var/burstdelay_high = 2400 //blobs will burst after a random value between these * 2.5(minimum 5 minutes, maximum 10 minutes) + var/burstdelay_high = 2400 //blobs will burst after a random value between these * 2.5(minimum 5 minutes, maximum 7 and a half minutes) var/list/infected_crew = list() @@ -157,7 +157,7 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b B.max_occurrences = 0 // disable the event spawn(0) - var/burst_delay = rand(burstdelay_low, burstdelay_high) //between 5 and 10 minutes with 1200 low and 2400 high. + var/burst_delay = rand(burstdelay_low, burstdelay_high) //between 5 and 7 and a half minutes with 1200 low and 1800 high. sleep(burst_delay) @@ -175,7 +175,7 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b send_intercept(1) - sleep(24000) //40 minutes, plus burst_delay*3(minimum of 6 minutes, maximum of 12) + sleep(24000) //40 minutes, plus burst_delay*3(minimum of 6 minutes, maximum of 8) send_intercept(2) //if the blob has been alive this long, it's time to bomb it From 8022bf10da1f9bf6e2669730c3aed83ea121f5c1 Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Fri, 25 Dec 2015 19:21:54 -0500 Subject: [PATCH 62/71] how did I fail to do this --- code/game/gamemodes/blob/blob.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index 511dd4ebcdc..a25cd4e108c 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -28,7 +28,7 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b var/blobwincount = 350 var/burstdelay_low = 1200 //in deciseconds - var/burstdelay_high = 2400 //blobs will burst after a random value between these * 2.5(minimum 5 minutes, maximum 7 and a half minutes) + var/burstdelay_high = 1800 //blobs will burst after a random value between these * 2.5(minimum 5 minutes, maximum 7 and a half minutes) var/list/infected_crew = list() From 4fab87989b43430cccd57126b6cb1c22f341731a Mon Sep 17 00:00:00 2001 From: Incoming5643 Date: Fri, 25 Dec 2015 19:34:25 -0500 Subject: [PATCH 63/71] Removes href value dependency --- code/game/objects/items/devices/radio/radio.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index a7a9ba1256a..725924a7617 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -158,7 +158,7 @@ dat+=text_sec_channel(ch_name, channels[ch_name]) dat+= text_wires() if (command) - dat+= "High Volume Mode: [use_command ? "Engaged" : "Disengaged"]
" + dat+= "High Volume Mode: [use_command ? "Engaged" : "Disengaged"]
" var/datum/browser/popup = new(user, "radio", "[src]") popup.set_content(dat) popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) @@ -209,7 +209,7 @@ else channels[chan_name] |= FREQ_LISTENING else if (href_list["bold"]) - use_command = text2num(href_list["bold"]) + use_command = !use_command if (!( master )) if (istype(loc, /mob)) interact(loc) From 1d7d9908fb261ee8dcf5588d65c7af9149b07fda Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Sat, 26 Dec 2015 03:40:21 +0000 Subject: [PATCH 64/71] Automatic changelog generation for PR #14011 --- html/changelogs/AutoChangeLog-pr-14011.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14011.yml diff --git a/html/changelogs/AutoChangeLog-pr-14011.yml b/html/changelogs/AutoChangeLog-pr-14011.yml new file mode 100644 index 00000000000..a65cdc3d261 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14011.yml @@ -0,0 +1,5 @@ +author: Joan +delete-after: True +changes: + - rscadd: "Procedure 5-6 may be issued for biohazard containment under certain situations." + - tweak: "Blobs will now burst slightly later on average, and the nuke report with the nuke code will arrive slightly earlier." From 0ee6c6acd04a39480bc09e427db41439b40eafd8 Mon Sep 17 00:00:00 2001 From: Jordie Date: Sat, 26 Dec 2015 15:50:54 +1100 Subject: [PATCH 65/71] readds layer hack for mining mob loot --- .../mob/living/simple_animal/hostile/mining_mobs.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm index 175391f3b49..01927a02f97 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm @@ -77,8 +77,8 @@ aggro_vision_range = 9 idle_vision_range = 2 turns_per_move = 5 - loot = list(/obj/item/weapon/ore/diamond, - /obj/item/weapon/ore/diamond) + loot = list(/obj/item/weapon/ore/diamond{layer = 4.1}, + /obj/item/weapon/ore/diamond{layer = 4.1}) /obj/item/projectile/temp/basilisk name = "freezing blast" @@ -349,7 +349,7 @@ anchored = 1 //Stays anchored until death as to be unpullable mob_size = MOB_SIZE_LARGE var/pre_attack = 0 - loot = list(/obj/item/asteroid/goliath_hide) + loot = list(/obj/item/asteroid/goliath_hide{layer = 4.1}) /mob/living/simple_animal/hostile/asteroid/goliath/Life() ..() @@ -511,7 +511,7 @@ environment_smash = 0 var/wumbo = 0 var/inflate_cooldown = 0 - loot = list(/obj/item/asteroid/fugu_gland) + loot = list(/obj/item/asteroid/fugu_gland{layer = 4.1}) /mob/living/simple_animal/hostile/asteroid/fugu/Life() if(!wumbo) @@ -605,4 +605,4 @@ A.transform *= 2 A.environment_smash += 2 user << "You increase the size of [A], giving it a surge of strength!" - qdel(src) \ No newline at end of file + qdel(src) From 42cd502626189e4256b060e742be041d5cbde081 Mon Sep 17 00:00:00 2001 From: Tkdrg Date: Sat, 26 Dec 2015 09:31:13 -0300 Subject: [PATCH 66/71] Fixes indentation in cockroach death() Thanks @phil235 ! --- code/modules/mob/living/simple_animal/friendly/cockroach.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/friendly/cockroach.dm b/code/modules/mob/living/simple_animal/friendly/cockroach.dm index 9d7705f9400..940d574b346 100644 --- a/code/modules/mob/living/simple_animal/friendly/cockroach.dm +++ b/code/modules/mob/living/simple_animal/friendly/cockroach.dm @@ -26,7 +26,7 @@ /mob/living/simple_animal/cockroach/death(gibbed) if(ticker.cinematic) //If the nuke is going off, then cockroaches are invincible. Keeps the nuke from killing them, cause cockroaches are immune to nukes. return - ..() + ..() /mob/living/simple_animal/cockroach/Crossed(var/atom/movable/AM) if(ismob(AM)) From 1a958e83b6ca774ea8b73d50d85eae2bf549e1f6 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Sat, 26 Dec 2015 06:47:07 -0600 Subject: [PATCH 67/71] Stacking decals --- code/game/objects/effects/decals/Cleanable/humans.dm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 9edd5072438..38615cac5ee 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -65,6 +65,9 @@ ..() reagents.add_reagent("liquidgibs", 5) +/obj/effect/decal/cleanable/blood/gibs/replace_decal(obj/effect/decal/cleanable/C) + return + /obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target) return @@ -186,6 +189,10 @@ user << . +/obj/effect/decal/cleanable/blood/gibs/replace_decal(obj/effect/decal/cleanable/C) + if(blood_state != C.blood_state) //We only replace footprints of the same type as us + return + ..() /obj/effect/decal/cleanable/blood/footprints/can_bloodcrawl_in() if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY)) From a47b490d2b0d5508aa70facbe944dd76b1da48cd Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Sat, 26 Dec 2015 07:00:20 -0600 Subject: [PATCH 68/71] That was dumb --- code/game/objects/effects/decals/Cleanable/humans.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 38615cac5ee..30d74ba6970 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -189,7 +189,7 @@ user << . -/obj/effect/decal/cleanable/blood/gibs/replace_decal(obj/effect/decal/cleanable/C) +/obj/effect/decal/cleanable/blood/footprints/replace_decal(obj/effect/decal/cleanable/C) if(blood_state != C.blood_state) //We only replace footprints of the same type as us return ..() From c4735d2bc5bc207bd1c141cf0fba60ec492f637b Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Sat, 26 Dec 2015 07:06:07 -0600 Subject: [PATCH 69/71] Initial --- code/game/gamemodes/miniantags/morph/morph.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm index d9f9b2ea8c3..be09a38c2c1 100644 --- a/code/game/gamemodes/miniantags/morph/morph.dm +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -77,9 +77,9 @@ form = target appearance = target.appearance - transform = matrix() - pixel_y = 0 - pixel_x = 0 + transform = initial(transform) + pixel_y = initial(pixel_y) + pixel_x = initial(pixel_x) visible_message("[src] suddenly twists and changes shape, becoming a copy of [target]!", \ "You twist your body and assume the form of [target].") //Morphed is weaker From bcdc028c3bc4e87611e5375f928b13181bbd5f0b Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Sat, 26 Dec 2015 07:06:57 -0600 Subject: [PATCH 70/71] Initial transform --- code/modules/mob/living/simple_animal/hostile/illusion.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/illusion.dm b/code/modules/mob/living/simple_animal/hostile/illusion.dm index e82dafb9781..7853e89dd37 100644 --- a/code/modules/mob/living/simple_animal/hostile/illusion.dm +++ b/code/modules/mob/living/simple_animal/hostile/illusion.dm @@ -33,8 +33,9 @@ melee_damage_upper = damage multiply_chance = replicate faction -= "neutral" - transform = matrix() - pixel_y = 0 + transform = initial(transform) + pixel_y = initial(pixel_y) + pixel_x = initial(pixel_x) /mob/living/simple_animal/hostile/illusion/death() @@ -73,4 +74,4 @@ /mob/living/simple_animal/hostile/illusion/escape/AttackingTarget() - return \ No newline at end of file + return From 72bc9591a2195edd974e18825dd207020c6a8830 Mon Sep 17 00:00:00 2001 From: AnturK Date: Sat, 26 Dec 2015 13:50:32 +0100 Subject: [PATCH 71/71] This is bit better. --- code/modules/admin/secrets.dm | 24 ------------------------ code/modules/holodeck/area_copy.dm | 7 +++++-- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index 78d1d51cb07..d6408f0f6ad 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -131,33 +131,9 @@ if(!istype(obj,/obj/machinery/camera)) qdel(obj) //Clear objects - //doing it here so there's less objects - var/min_x = world.maxx - var/min_y = world.maxy - var/max_x = 0 - var/max_y = 0 - var/z = -1 - //This is awful - for(var/turf/T in thunderdome.contents) - if(z < 0) - z = T.z - if(T.x < min_x) - min_x = T.x - if(T.y < min_y) - min_y = T.y - if(T.x > max_x) - max_x = T.x - if(T.y > max_y) - max_y = T.y - var/area/template = locate(/area/tdome/arena_source) template.copy_contents_to(thunderdome) - - var/datum/mapGenerator/repressurize/G = new - G.defineRegion(locate(min_x,min_y,z),locate(max_x,max_y,z),1) - G.generate() - if("clear_virus") var/choice = input("Are you sure you want to cure all disease?") in list("Yes", "Cancel") diff --git a/code/modules/holodeck/area_copy.dm b/code/modules/holodeck/area_copy.dm index 5572d9c970f..19a7cbc92fb 100644 --- a/code/modules/holodeck/area_copy.dm +++ b/code/modules/holodeck/area_copy.dm @@ -68,7 +68,7 @@ var/copiedobjs = list() - for (var/turf/T in refined_src) + for (var/turf/simulated/T in refined_src) //var/datum/coords/C_src = refined_src[T] var/coordstring = refined_src[T] var/turf/B = refined_trg[coordstring] @@ -83,7 +83,7 @@ var/old_icon_state1 = T.icon_state var/old_icon1 = T.icon - var/turf/X = new T.type(B) + var/turf/simulated/X = new T.type(B) X.dir = old_dir1 X.icon = old_icon1 X.icon_state = old_icon_state1 @@ -100,6 +100,9 @@ var/global/list/forbidden_vars = list("type","stat","loc","locs","vars", "parent", "parent_type","verbs","ckey","key","x","y","z","contents", "luminosity") for(var/V in T.vars - forbidden_vars) + if(V == "air") + X.air.copy_from(T.air) + continue X.vars[V] = T.vars[V] toupdate += X