From ad812de0012d48c28a8493d6205c62122bb2933a Mon Sep 17 00:00:00 2001 From: ronancpl Date: Sat, 14 Jul 2018 13:10:40 -0300 Subject: [PATCH] Improved login phase + C. scheduler & EXP share & MoveLifeHandler fix Refactored login system, caching account data, merging some queries and using way less DB queries on login. Server now uses associative tables for character-account and character-world, lowering considerably usage of some DB queries. Fixed getPartyMembersOnSameMap method trying to access disconnected members, promptly throwing nulls. Improved EXP distribution system, now crediting damage-contributing EXP to the party when the player is not present on the map. Improved the "View-all-chars" feature mechanics, not so often disconnecting players for server response timeout anymore. Improved Mystic Doors mechanics, now correctly spawning party players at actual door location on the off-town map. Fixed "fly" command not working properly. All characters of that account are able to use this mechanic (client session limitation). Fixed a critical deadlock issue on the new channel scheduler system. Fixed some mobs not using skills, issue brought on the latest MoveLifeHandler update. Improved slightly skill/movement synergy on the MoveLifeHandler responses. GMs no longer creates Hall-of-fame PlayerNPCs when reaching max class level. Fixed monsterValue script method being triggered multiple times for party members. Fixed pinkbean not dropping items inside expedition. Moved "recharge" command from Donator to JrGM. --- docs/issues.txt | 2 +- docs/mychanges_ptbr.txt | 26 +- scripts/event/PinkBeanBattle.js | 6 + scripts/map/onUserEnter/677000012.js | 17 + scripts/npc/1032001.js | 2 +- scripts/npc/2071012.js | 47 + scripts/npc/9201000.js | 2 +- scripts/npc/9201001.js | 2 +- scripts/npc/9201002.js | 2 +- scripts/npc/9201004.js | 2 +- scripts/npc/9201005.js | 2 +- scripts/npc/9201008.js | 2 +- scripts/npc/9201011.js | 2 +- scripts/npc/9201012.js | 2 +- scripts/npc/9201023.js | 2 +- scripts/npc/9201024.js | 2 +- scripts/npc/9201025.js | 2 +- scripts/npc/9201026.js | 2 +- scripts/npc/9201027.js | 2 +- scripts/npc/9201049.js | 2 +- scripts/npc/9201133.js | 45 + scripts/npc/9977777.js | 2 + scripts/npc/commands.js | 2 +- scripts/portal/foxLaidy_map.js | 8 +- sql/db_drops.sql | 16 +- src/client/MapleCharacter.java | 148 +- src/client/MapleClient.java | 6 +- src/client/command/Commands.java | 46 +- src/client/creator/CharacterFactory.java | 2 +- src/client/inventory/ItemFactory.java | 124 +- src/client/newyear/NewYearCardRecord.java | 23 +- src/constants/ServerConstants.java | 3 +- src/net/PacketProcessor.java | 16 +- src/net/{ => opcodes}/RecvOpcode.java | 4 +- src/net/{ => opcodes}/SendOpcode.java | 2 +- src/net/server/Server.java | 339 +- .../channel/handlers/AdminCommandHandler.java | 2 +- .../handlers/AllianceOperationHandler.java | 2 +- .../channel/handlers/ChangeMapHandler.java | 25 +- .../server/channel/handlers/DoorHandler.java | 24 +- .../handlers/EnterCashShopHandler.java | 2 +- .../channel/handlers/EnterMTSHandler.java | 2 +- .../channel/handlers/FamilyUseHandler.java | 2 +- .../channel/handlers/MoveLifeHandler.java | 60 +- .../channel/handlers/NPCAnimationHandler.java | 2 +- .../handlers/PlayerMapTransitionHandler.java | 37 + .../channel/handlers/PlayerUpdateHandler.java | 6 +- .../channel/handlers/TransferNameHandler.java | 2 +- .../handlers/TransferNameResultHandler.java | 2 +- .../handlers/TransferWorldHandler.java | 2 +- .../channel/handlers/WeddingTalkHandler.java | 2 +- .../handlers/WeddingTalkMoreHandler.java | 2 +- .../server/channel/worker/BaseScheduler.java | 24 +- .../channel/worker/MobAnimationScheduler.java | 4 +- .../handlers/login/AfterLoginHandler.java | 1 - .../handlers/login/CharSelectedHandler.java | 2 +- .../login/CharSelectedWithPicHandler.java | 2 +- .../handlers/login/LoginPasswordHandler.java | 1 + .../handlers/login/RegisterPicHandler.java | 2 +- .../login/ServerStatusRequestHandler.java | 11 +- .../handlers/login/ViewAllCharHandler.java | 80 + ...ava => ViewAllCharRegisterPicHandler.java} | 6 +- ...r.java => ViewAllCharSelectedHandler.java} | 7 +- .../ViewAllCharSelectedWithPicHandler.java | 4 +- .../handlers/login/ViewCharHandler.java | 92 - .../worker/CharacterAutosaverWorker.java | 2 +- .../server/worker/CharacterDiseaseWorker.java | 5 +- .../worker/WeddingReservationWorker.java | 2 +- src/net/server/world/World.java | 160 +- src/scripting/AbstractPlayerInteraction.java | 1 - src/scripting/event/EventInstanceManager.java | 15 +- src/scripting/npc/NPCConversationManager.java | 2 +- src/server/TimerManager.java | 3 + src/server/life/MapleMonster.java | 68 +- src/server/life/MaplePlayerNPC.java | 37 +- src/server/life/MobSkill.java | 8 +- src/server/maps/MapleDoorObject.java | 10 +- src/server/maps/MaplePlayerShop.java | 2 +- src/tools/FilePrinter.java | 1 + src/tools/MapleLogger.java | 2 +- src/tools/MaplePacketCreator.java | 36 +- src/tools/locks/MonitoredLockType.java | 1 + .../lib/MonsterBook_updated.img.xml | 283 +- .../MapleQuestItemFetcher.java | 6 +- .../MapleQuestlineFetcher.java | 2 +- wz/Map.wz/Map/Map6/677000010.img.xml | 1045 +- wz/Map.wz/Map/Map6/677000011.img.xml | 3983 +- wz/Map.wz/Map/Map6/677000012.img.xml | 1493 +- wz/Quest.wz/Act.img.xml | 56027 +--------------- wz/Quest.wz/QuestInfo.img.xml | 23765 +------ wz/String.wz/MonsterBook.img.xml | 283 +- 91 files changed, 1902 insertions(+), 86664 deletions(-) create mode 100644 scripts/map/onUserEnter/677000012.js create mode 100644 scripts/npc/2071012.js create mode 100644 scripts/npc/9201133.js rename src/net/{ => opcodes}/RecvOpcode.java (99%) rename src/net/{ => opcodes}/SendOpcode.java (99%) create mode 100644 src/net/server/channel/handlers/PlayerMapTransitionHandler.java create mode 100644 src/net/server/handlers/login/ViewAllCharHandler.java rename src/net/server/handlers/login/{ViewAllPicRegisterHandler.java => ViewAllCharRegisterPicHandler.java} (88%) rename src/net/server/handlers/login/{PickCharHandler.java => ViewAllCharSelectedHandler.java} (90%) delete mode 100644 src/net/server/handlers/login/ViewCharHandler.java diff --git a/docs/issues.txt b/docs/issues.txt index d28e49a516..7b1be7e003 100644 --- a/docs/issues.txt +++ b/docs/issues.txt @@ -21,7 +21,6 @@ Missing features list: - Miniroom tooltips (such as number of players in store/host awaiting game) not showing up properly. - Change name/World transfer. - Some pirate skills doesn't work for 3rd parties. -- Medal quests. - Cache frequently used SQL data. --------------------------- @@ -35,6 +34,7 @@ Missing features list: --------------------------- ** Quest ** +- Family & Medal quests. --------------------------- diff --git a/docs/mychanges_ptbr.txt b/docs/mychanges_ptbr.txt index 73a827c003..2f2affb4f8 100644 --- a/docs/mychanges_ptbr.txt +++ b/docs/mychanges_ptbr.txt @@ -6,7 +6,7 @@ Abdula -> 9209000 CUSTOM NPC SHOPS: - Spindle -> 9201082 + Asia -> 2082014 T-1337 -> 9201101 LOGS: @@ -1107,4 +1107,26 @@ Melhorado liberação de recursos ao finalizar objeto MapleMonster. 03 - 04 Julho 2018, Adicionado server flag que permite usar clean slates mesmo em equipamentos sem slots vazios (onde falhou o scroll). Corrigido um possível ponto crítico de deadlock com MapleServerHandler. -Adicionado portal SFX para vários portais scriptados que ainda faltavam o efeito. \ No newline at end of file +Adicionado portal SFX para vários portais scriptados que ainda faltavam o efeito. + +08 - 10 Julho 2018, +Refatorado sistema de login, agora utilizando caches para manter dados recorrentes, diminuindo consideravelmente consultas a DB. +Server agora usa registros associativos de conta, personagem e mundo em seus objetos, diminuindo bastante o uso da DB e, por consequência, uma melhor fluidez em demais processos, mais notáveis aqueles referentes a fase de login. +Corrigido metodo que localiza membros de party no mesmo mapa tentando acessar possível campo "map", que fica nulo para jogadores desconectados. + +11 - 12 Julho 2018, +Otimizado chamadas a DB na fase de login, agora utilizando uma mesma query para recuperar dados de todos os personagens de uma dada conta (diminuindo drasticamente a quantidade de consultas a DB). +Melhorado sistema de distribuicao de EXP, agora creditando EXP aos membros de party presentes no mapa mesmo quando o jogador que contribuiu com a ação nao se encontra presente no mesmo. +Corrigido jogadores nao podendo usar portais apos logarem via "view-all-chars". +Corrigido cash shop inventory de Cygnus e Aran nao propagando itens de cash comprado para outros personagens de mesma classe base da mesma conta. +Melhorado mecânica de Magic Doors, permitindo jogadores serem spawnados corretamente ao atravessar portais quando em party. +Corrigido comando "fly" nao atuando corretamente. Todos os personagens da conta poderao usar desta mecânica. +Corrigido deadlock crítico introduzido no sistema abstrato de temporizadores em channels. +Corrigido alguns mobs nao lançando skills, problema introduzido na última atualização do MoveLifeHandler. +Ajustado MoveLifeHandler para melhor aplicar as skills/movimentações dos mobs. +GMs nao mais geram playernpcs ao atingir level 200 (agora somente via comando). +Corrigido função monsterValue dos scripts de eventos sendo processado múltiplas vezes no cenário onde jogadores estao em party. +Corrigido pinkbean nao dropando itens dentro da expedição. + +14 Julho 2018, +Movido "recharge" de Donator para JrGM. \ No newline at end of file diff --git a/scripts/event/PinkBeanBattle.js b/scripts/event/PinkBeanBattle.js index ee61b5f6d5..e4ee83165d 100644 --- a/scripts/event/PinkBeanBattle.js +++ b/scripts/event/PinkBeanBattle.js @@ -162,6 +162,12 @@ function playerRevive(eim, player) { return true; } +function monsterRevive(eim, mob) { + if(isPinkBean(mob)) { + mob.enableDrops(); + } +} + function playerDisconnected(eim, player) { if (eim.isEventTeamLackingNow(true, minPlayers, player)) { eim.dropMessage(5, "[Expedition] Either the leader has quit the expedition or there is no longer the minimum number of members required to continue it."); diff --git a/scripts/map/onUserEnter/677000012.js b/scripts/map/onUserEnter/677000012.js new file mode 100644 index 0000000000..06180624c9 --- /dev/null +++ b/scripts/map/onUserEnter/677000012.js @@ -0,0 +1,17 @@ +importPackage(Packages.server.life); + +function start(ms) { + var pos = new java.awt.Point(842, 0); + var mobId = 9400633; + var mobName = "Astaroth"; + + var player = ms.getPlayer(); + var map = player.getMap(); + + if(map.getMonsterById(mobId) != null){ + return; + } + + map.spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(mobId), pos); + player.message(mobName + " has appeared!"); +} \ No newline at end of file diff --git a/scripts/npc/1032001.js b/scripts/npc/1032001.js index 993eb304fc..1d501ebf8c 100644 --- a/scripts/npc/1032001.js +++ b/scripts/npc/1032001.js @@ -50,7 +50,7 @@ function start() { if (cm.getLevel() >= 8 && cm.canGetFirstJob(jobType)) cm.sendNext("Want to be a magician? There are some standards to meet. because we can't just accept EVERYONE in... #bYour level should be at least 8#k, with getting INT as your top priority. Let's see."); else { - cm.sendOk("Train a bit more until you reach #blevel 10, " + cm.getFirstJobStatRequirement(jobType) + "#k and I can show you the way of the #rMagician#k."); + cm.sendOk("Train a bit more until you reach #blevel 8, " + cm.getFirstJobStatRequirement(jobType) + "#k and I can show you the way of the #rMagician#k."); cm.dispose(); } } else if (cm.getLevel() >= 30 && cm.getJobId() == 200) { diff --git a/scripts/npc/2071012.js b/scripts/npc/2071012.js new file mode 100644 index 0000000000..c50775950a --- /dev/null +++ b/scripts/npc/2071012.js @@ -0,0 +1,47 @@ +/* A Familiar Lady + Hidden Street : Gloomy Forest (922220000) + */ + +var status; + +function start() { + status = -1; + action(1, 0, 0); +} + +function action(mode, type, selection) { + if (mode == -1) { + cm.dispose(); + } else { + if (mode == 0 && type > 0) { + cm.dispose(); + return; + } + if (mode == 1) + status++; + else + status--; + + if(status == 0) { + if(cm.getQuestProgress(23647, 0) != 0) { + cm.dispose(); + return; + } + + if(!cm.haveItem(4031793, 1)) { + cm.sendOk("Umm... Hey... Would you help me find a #bsoft and shiny silver fur#k that I lost on the woods? I need it, I need it, I need it sooooo much!"); + cm.dispose(); + return; + } + + cm.sendYesNo("Hey... Umm... Would you help me find a #bsoft and shiny silver fur#k that I lost on the woods? I need it, I need it, I need it sooooo much! ... Oh you found it!!! Will you give it to me?"); + } else if(status == 1) { + cm.sendNext("Teehehee~ That's your reward for taking it from me, serves you well."); + cm.gainItem(4031793, -1); + cm.gainFame(-5); + cm.setQuestProgress(23647, 0, 1); + + cm.dispose(); + } + } +} \ No newline at end of file diff --git a/scripts/npc/9201000.js b/scripts/npc/9201000.js index d7c5c871ce..fe125a47b7 100644 --- a/scripts/npc/9201000.js +++ b/scripts/npc/9201000.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201001.js b/scripts/npc/9201001.js index e03ad10988..d654fed771 100644 --- a/scripts/npc/9201001.js +++ b/scripts/npc/9201001.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201002.js b/scripts/npc/9201002.js index 307746521e..6f9345bd26 100644 --- a/scripts/npc/9201002.js +++ b/scripts/npc/9201002.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201004.js b/scripts/npc/9201004.js index ccc11ca078..6447f313c8 100644 --- a/scripts/npc/9201004.js +++ b/scripts/npc/9201004.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201005.js b/scripts/npc/9201005.js index 4ec9b478d1..762645ecf0 100644 --- a/scripts/npc/9201005.js +++ b/scripts/npc/9201005.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201008.js b/scripts/npc/9201008.js index 48448b3da9..e9d6d410ca 100644 --- a/scripts/npc/9201008.js +++ b/scripts/npc/9201008.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201011.js b/scripts/npc/9201011.js index aaff283231..01fbba44d1 100644 --- a/scripts/npc/9201011.js +++ b/scripts/npc/9201011.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201012.js b/scripts/npc/9201012.js index 6447b09832..0028013dca 100644 --- a/scripts/npc/9201012.js +++ b/scripts/npc/9201012.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201023.js b/scripts/npc/9201023.js index e03ad10988..d654fed771 100644 --- a/scripts/npc/9201023.js +++ b/scripts/npc/9201023.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201024.js b/scripts/npc/9201024.js index e03ad10988..d654fed771 100644 --- a/scripts/npc/9201024.js +++ b/scripts/npc/9201024.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201025.js b/scripts/npc/9201025.js index e03ad10988..d654fed771 100644 --- a/scripts/npc/9201025.js +++ b/scripts/npc/9201025.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201026.js b/scripts/npc/9201026.js index e03ad10988..d654fed771 100644 --- a/scripts/npc/9201026.js +++ b/scripts/npc/9201026.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201027.js b/scripts/npc/9201027.js index e03ad10988..d654fed771 100644 --- a/scripts/npc/9201027.js +++ b/scripts/npc/9201027.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201049.js b/scripts/npc/9201049.js index f054f065ec..2066d213af 100644 --- a/scripts/npc/9201049.js +++ b/scripts/npc/9201049.js @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/scripts/npc/9201133.js b/scripts/npc/9201133.js new file mode 100644 index 0000000000..8f6f9c8e6e --- /dev/null +++ b/scripts/npc/9201133.js @@ -0,0 +1,45 @@ +var map = 677000010; +var quest = 28283; +var status = -1; +var inHuntingGround; + +function start(mode, type, selection) { + inHuntingGround = (cm.getMapId() >= 677000010 && cm.getMapId() <= 677000012); + action(1, 0, 0); +} + +function action(mode, type, selection) { + if (mode == 1) { + status++; + } else { + cm.dispose(); + return; + } + if (status == 0) { + if(!inHuntingGround) { + if (cm.isQuestStarted(quest)) { + if(!cm.getPlayer().haveItemEquipped(1003036)) { + cm.sendOk("The path ahead has a weird stench... Equip the #rgas mask#k before entering."); + cm.dispose(); + return; + } + + cm.sendYesNo("Would you like to move to #b#m" + map + "##k?"); + } else { + cm.sendOk("The entrance is blocked by a strange force."); + cm.dispose(); + } + } else { + if(cm.getMapId() == 677000011) { + map = 677000012; + cm.sendYesNo("Would you like to move to #b#m" + map + "##k?"); + } else { + map = 105050400; + cm.sendYesNo("Would you like to #bexit this place#k?"); + } + } + } else { + cm.warp(map, 0); + cm.dispose(); + } +} \ No newline at end of file diff --git a/scripts/npc/9977777.js b/scripts/npc/9977777.js index f7baa36cbd..6d30fe0578 100644 --- a/scripts/npc/9977777.js +++ b/scripts/npc/9977777.js @@ -156,6 +156,7 @@ function writeFeatureTab_Serverpotentials() { addFeature("Custom jail system."); addFeature("Custom buyback system, uses mesos / NX, via MTS."); addFeature("Delete Character."); + addFeature("Smooth view-all-char, now showing all account chars."); addFeature("Autosaver (periodically saves player's data on DB)."); addFeature("Fixed and randomized HP/MP growth rate available."); addFeature("Prevented 'NPC gone after some uptime' issue."); @@ -199,6 +200,7 @@ function writeFeatureTab_Project() { addFeature("Uncovered many opcodes throughout the source."); addFeature("Reviewed many Java aspects that needed attention."); addFeature("Reviewed SQL data, eliminating duplicated entries."); + addFeature("Improved login phase, using cache over DB queries."); addFeature("Protected many flaws with login management system."); addFeature("Developed many survey tools for content profiling."); addFeature("ThreadTracker: runtime tool for deadlock detection."); diff --git a/scripts/npc/commands.js b/scripts/npc/commands.js index 84cccd1567..e0ad2d6ace 100644 --- a/scripts/npc/commands.js +++ b/scripts/npc/commands.js @@ -162,6 +162,7 @@ function writeHeavenMSCommandsLv2() { //JrGM comm_cursor = comm_lv2; desc_cursor = desc_lv2; + addCommand("recharge", ""); addCommand("whereami", ""); addCommand("hide", ""); addCommand("unhide", ""); @@ -205,7 +206,6 @@ function writeHeavenMSCommandsLv1() { //Donator addCommand("whodrops", ""); addCommand("buffme", ""); addCommand("goto", ""); - addCommand("recharge", ""); } function writeHeavenMSCommandsLv0() { //Common diff --git a/scripts/portal/foxLaidy_map.js b/scripts/portal/foxLaidy_map.js index 882a5759f0..c9532a08d5 100644 --- a/scripts/portal/foxLaidy_map.js +++ b/scripts/portal/foxLaidy_map.js @@ -1,4 +1,10 @@ function enter(pi) { - pi.playPortalSound(); pi.warp(222010200, "east00"); + if(!(pi.isQuestStarted(3647) && pi.haveItem(4031793, 1))) { + pi.playPortalSound(); pi.warp(222010200, "east00"); + } else { + if(!pi.isQuestStarted(23647)) pi.forceStartQuest(23647); + pi.playPortalSound(); pi.warp(922220000, "east00"); + } + return true; } diff --git a/sql/db_drops.sql b/sql/db_drops.sql index a7cb0be4db..4998b029af 100644 --- a/sql/db_drops.sql +++ b/sql/db_drops.sql @@ -19288,8 +19288,7 @@ USE `heavenms`; (4230117, 2382055, 1, 1, 0, 10000), (4230118, 2382067, 1, 1, 0, 10000), (4240000, 2383011, 1, 1, 0, 10000), -(1210102, 4001354, 1, 1, 28209, 10000), -(2110200, 4001368, 1, 1, 28258, 10000), +(1210102, 4001354, 1, 1, 28209, 80000), (1110101, 4031773, 1, 1, 2145, 80000), (1130100, 4031773, 1, 1, 2145, 80000), (1140100, 4031773, 1, 1, 2145, 80000), @@ -19811,13 +19810,14 @@ USE `heavenms`; (9400120, 2290109, 1, 1, 0, 10000), (3210100, 4001000, 1, 1, 2017, 20000), (4300013, 4000538, 1, 1, 2288, 400000), -(2130100, 4001367, 1, 1, 28257, 10000), -(1110100, 4001369, 1, 1, 28259, 10000), -(1210101, 4001370, 1, 1, 28260, 10000), -(1110101, 4001371, 1, 1, 28261, 10000), +(2130100, 4001367, 1, 1, 28257, 40000), +(2110200, 4001368, 1, 1, 28258, 40000), +(1110100, 4001369, 1, 1, 28259, 40000), +(1210101, 4001370, 1, 1, 28260, 40000), +(1110101, 4001371, 1, 1, 28261, 40000), (3300003, 4001317, 1, 1, 2326, 20000), -(1210102, 4001364, 1, 1, 28192, 10000), -(1120100, 4001365, 1, 1, 28192, 10000), +(1210102, 4001364, 1, 1, 28192, 80000), +(1120100, 4001365, 1, 1, 28192, 80000), (1210103, 4032137, 1, 1, 20711, 40000), (1210103, 4032139, 1, 1, 20713, 40000), (1210101, 4001357, 1, 1, 28244, 70000), diff --git a/src/client/MapleCharacter.java b/src/client/MapleCharacter.java index 60ba02f2b1..38b1600f35 100644 --- a/src/client/MapleCharacter.java +++ b/src/client/MapleCharacter.java @@ -1350,7 +1350,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { eventChangedMap(target.getId()); MapleMap to = getWarpMap(target.getId()); - changeMapInternal(to, pos, MaplePacketCreator.getWarpToMap(to, 0x80, this));//Position :O (LEFT) + changeMapInternal(to, pos, MaplePacketCreator.getWarpToMap(to, 0x80, pos, this)); canWarpMap = false; canWarpCounter--; @@ -1394,6 +1394,25 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { return false; } + public List getLastVisitedMapids() { + List lastVisited = new ArrayList<>(5); + + petLock.lock(); + try { + for(WeakReference lv : lastVisitedMaps) { + MapleMap lvm = lv.get(); + + if(lvm != null) { + lastVisited.add(lvm.getId()); + } + } + } finally { + petLock.unlock(); + } + + return lastVisited; + } + public void updateMapDropsUponPartyOperation(List exPartyMembers) { List> mapids; @@ -1890,7 +1909,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { public static boolean deleteCharFromDB(MapleCharacter player, int senderAccId) { int cid = player.getId(); - if(!Server.getInstance().haveCharacterid(senderAccId, cid)) { + if(!Server.getInstance().haveCharacterEntry(senderAccId, cid)) { return false; } @@ -2050,7 +2069,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } con.close(); - Server.getInstance().deleteCharacterid(accId, cid); + Server.getInstance().deleteCharacterEntry(accId, cid); return true; } catch (SQLException e) { e.printStackTrace(); @@ -4583,7 +4602,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { if(party != null) { for(MaplePartyCharacter partyMembers: party.getMembers()) { MapleCharacter chr = partyMembers.getPlayer(); - if(chr.getMap().hashCode() == thisMapHash && chr.isLoggedinWorld()) list.add(chr); + MapleMap chrMap = chr.getMap(); + if(chrMap != null && chrMap.hashCode() == thisMapHash && chr.isLoggedinWorld()) list.add(chr); } } } finally { @@ -5284,15 +5304,15 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { effLock.unlock(); } } - - public boolean isCygnus() { - return getJobType() == 1; - } public boolean isGmJob() { int jn = job.getJobNiche(); return jn >= 8 && jn <= 9; } + + public boolean isCygnus() { + return getJobType() == 1; + } public boolean isAran() { return job.getId() >= 2000 && job.getId() <= 2112; @@ -5423,7 +5443,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { maxmp = Math.min(30000, maxmp); if (level == 200) { exp.set(0); - if(ServerConstants.PLAYERNPC_AUTODEPLOY) MaplePlayerNPC.spawnPlayerNPC(GameConstants.getHallOfFameMapid(job), this); + if(ServerConstants.PLAYERNPC_AUTODEPLOY && !this.isGM()) MaplePlayerNPC.spawnPlayerNPC(GameConstants.getHallOfFameMapid(job), this); } recalcLocalStats(); hp = localmaxhp; @@ -5787,6 +5807,104 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } } + public static MapleCharacter loadCharacterEntryFromDB(ResultSet rs, List equipped) { + MapleCharacter ret = new MapleCharacter(); + + try { + ret.accountid = rs.getInt("accountid"); + ret.id = rs.getInt("id"); + ret.name = rs.getString("name"); + ret.gender = rs.getInt("gender"); + ret.skinColor = MapleSkinColor.getById(rs.getInt("skincolor")); + ret.face = rs.getInt("face"); + ret.hair = rs.getInt("hair"); + + // skipping pets, probably unneeded here + + ret.level = rs.getInt("level"); + ret.job = MapleJob.getById(rs.getInt("job")); + ret.str = rs.getInt("str"); + ret.dex = rs.getInt("dex"); + ret.int_ = rs.getInt("int"); + ret.luk = rs.getInt("luk"); + ret.hp = rs.getInt("hp"); + ret.maxhp = rs.getInt("maxhp"); + ret.mp = rs.getInt("mp"); + ret.maxmp = rs.getInt("maxmp"); + + ret.remainingAp = rs.getInt("ap"); + String[] skillPoints = rs.getString("sp").split(","); + for (int i = 0; i < ret.remainingSp.length; i++) { + ret.remainingSp[i] = Integer.parseInt(skillPoints[i]); + } + + ret.exp.set(rs.getInt("exp")); + ret.fame = rs.getInt("fame"); + ret.gachaexp.set(rs.getInt("gachaexp")); + ret.mapid = rs.getInt("map"); + ret.initialSpawnPoint = rs.getInt("spawnpoint"); + + ret.gmLevel = rs.getInt("gm"); + ret.world = rs.getByte("world"); + ret.rank = rs.getInt("rank"); + ret.rankMove = rs.getInt("rankMove"); + ret.jobRank = rs.getInt("jobRank"); + ret.jobRankMove = rs.getInt("jobRankMove"); + + MapleInventory inv = ret.inventory[MapleInventoryType.EQUIPPED.ordinal()]; + for (Item item : equipped) { + inv.addItemFromDB(item); + } + } catch (SQLException sqle) { + sqle.printStackTrace(); + } + + return ret; + } + + public MapleCharacter generateCharacterEntry() { + MapleCharacter ret = new MapleCharacter(); + + ret.accountid = this.getAccountID(); + ret.id = this.getId(); + ret.name = this.getName(); + ret.gender = this.getGender(); + ret.skinColor = this.getSkinColor(); + ret.face = this.getFace(); + ret.hair = this.getHair(); + + // skipping pets, probably unneeded here + + ret.level = this.getLevel(); + ret.job = this.getJob(); + ret.str = this.getStr(); + ret.dex = this.getDex(); + ret.int_ = this.getInt(); + ret.luk = this.getLuk(); + ret.hp = this.getHp(); + ret.maxhp = this.getMaxHp(); + ret.mp = this.getMp(); + ret.maxmp = this.getMaxMp(); + ret.remainingAp = this.getRemainingAp(); + ret.remainingSp = this.getRemainingSps(); + ret.exp.set(this.getExp()); + ret.fame = this.getFame(); + ret.gachaexp.set(this.getGachaExp()); + ret.mapid = this.getMapId(); + ret.initialSpawnPoint = this.getInitialSpawnpoint(); + + ret.inventory[MapleInventoryType.EQUIPPED.ordinal()] = this.getInventory(MapleInventoryType.EQUIPPED); + + ret.gmLevel = this.gmLevel(); + ret.world = this.getWorld(); + ret.rank = this.getRank(); + ret.rankMove = this.getRankMove(); + ret.jobRank = this.getJobRank(); + ret.jobRankMove = this.getJobRankMove(); + + return ret; + } + public static MapleCharacter loadCharFromDB(int charid, MapleClient client, boolean channelserver) throws SQLException { try { MapleCharacter ret = new MapleCharacter(); @@ -6845,24 +6963,24 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } } - public void saveToDB() { + public void saveCharToDB() { if(ServerConstants.USE_AUTOSAVE) { Runnable r = new Runnable() { @Override public void run() { - saveToDB(true); + saveCharToDB(true); } }; Thread t = new Thread(r); //spawns a new thread to deal with this t.start(); } else { - saveToDB(true); + saveCharToDB(true); } } //ItemFactory saveItems and monsterbook.saveCards are the most time consuming here. - public synchronized void saveToDB(boolean notAutosave) { + public synchronized void saveCharToDB(boolean notAutosave) { if(!loggedIn) return; Calendar c = Calendar.getInstance(); @@ -6870,6 +6988,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { if(notAutosave) FilePrinter.print(FilePrinter.SAVING_CHARACTER, "Attempting to save " + name + " at " + c.getTime().toString()); else FilePrinter.print(FilePrinter.AUTOSAVING_CHARACTER, "Attempting to autosave " + name + " at " + c.getTime().toString()); + Server.getInstance().updateCharacterEntry(this); + Connection con = null; try { con = DatabaseConnection.getConnection(); @@ -7693,7 +7813,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { if (slots <= 96) { inventory[type].setSlotLimit(slots); - this.saveToDB(); + this.saveCharToDB(); if (update) { client.announce(MaplePacketCreator.updateInventorySlotLimit(type, slots)); } diff --git a/src/client/MapleClient.java b/src/client/MapleClient.java index 9b51e6e694..f8181b6b65 100644 --- a/src/client/MapleClient.java +++ b/src/client/MapleClient.java @@ -841,7 +841,7 @@ public class MapleClient { removePlayer(); player.saveCooldowns(); - player.saveToDB(true); + player.saveCharToDB(true); clear(); return; @@ -924,7 +924,7 @@ public class MapleClient { //getChannelServer().removePlayer(player); already being done player.saveCooldowns(); - player.saveToDB(true); + player.saveCharToDB(true); if (player != null) {//no idea, occur :( player.empty(false); } @@ -933,7 +933,7 @@ public class MapleClient { getChannelServer().removePlayer(player); player.saveCooldowns(); - player.saveToDB(); + player.saveCharToDB(); } } } diff --git a/src/client/command/Commands.java b/src/client/command/Commands.java index 9420259fa7..37c93969db 100644 --- a/src/client/command/Commands.java +++ b/src/client/command/Commands.java @@ -784,26 +784,6 @@ public class Commands { player.dropMessage(5, "That map does not exist."); } break; - - case "recharge": - MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); - for (Item torecharge : c.getPlayer().getInventory(MapleInventoryType.USE).list()) { - if (ItemConstants.isThrowingStar(torecharge.getItemId())){ - torecharge.setQuantity(ii.getSlotMax(c, torecharge.getItemId())); - c.getPlayer().forceUpdateItem(torecharge); - } else if (ItemConstants.isArrow(torecharge.getItemId())){ - torecharge.setQuantity(ii.getSlotMax(c, torecharge.getItemId())); - c.getPlayer().forceUpdateItem(torecharge); - } else if (ItemConstants.isBullet(torecharge.getItemId())){ - torecharge.setQuantity(ii.getSlotMax(c, torecharge.getItemId())); - c.getPlayer().forceUpdateItem(torecharge); - } else if (ItemConstants.isConsumable(torecharge.getItemId())){ - torecharge.setQuantity(ii.getSlotMax(c, torecharge.getItemId())); - c.getPlayer().forceUpdateItem(torecharge); - } - } - player.dropMessage(5, "USE Recharged."); - break; default: return false; @@ -818,6 +798,26 @@ public class Commands { Skill skill; switch(sub[0]) { + case "recharge": + MapleItemInformationProvider mii = MapleItemInformationProvider.getInstance(); + for (Item torecharge : c.getPlayer().getInventory(MapleInventoryType.USE).list()) { + if (ItemConstants.isThrowingStar(torecharge.getItemId())){ + torecharge.setQuantity(mii.getSlotMax(c, torecharge.getItemId())); + c.getPlayer().forceUpdateItem(torecharge); + } else if (ItemConstants.isArrow(torecharge.getItemId())){ + torecharge.setQuantity(mii.getSlotMax(c, torecharge.getItemId())); + c.getPlayer().forceUpdateItem(torecharge); + } else if (ItemConstants.isBullet(torecharge.getItemId())){ + torecharge.setQuantity(mii.getSlotMax(c, torecharge.getItemId())); + c.getPlayer().forceUpdateItem(torecharge); + } else if (ItemConstants.isConsumable(torecharge.getItemId())){ + torecharge.setQuantity(mii.getSlotMax(c, torecharge.getItemId())); + c.getPlayer().forceUpdateItem(torecharge); + } + } + player.dropMessage(5, "USE Recharged."); + break; + case "whereami": player.yellowMessage("Map ID: " + player.getMap().getId()); player.yellowMessage("Players on this map:"); @@ -1653,7 +1653,7 @@ public class Commands { } break; - case "fly": + case "fly": // fly option will become available for any character of that account if (sub.length < 2) { player.yellowMessage("Syntax: !fly "); break; @@ -2776,7 +2776,7 @@ public class Commands { player.getMap().removePlayer(player);//LOL FORGOT THIS >< c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION); player.setWorld(worldb); - player.saveToDB();//To set the new world :O (true because else 2 player instances are created, one in both worlds) + player.saveCharToDB();//To set the new world :O (true because else 2 player instances are created, one in both worlds) c.announce(MaplePacketCreator.getChannelChange(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1]))); } catch (UnknownHostException | NumberFormatException ex) { ex.printStackTrace(); @@ -2791,7 +2791,7 @@ public class Commands { case "saveall": for (World world : Server.getInstance().getWorlds()) { for (MapleCharacter chr : world.getPlayerStorage().getAllCharacters()) { - chr.saveToDB(); + chr.saveCharToDB(); } } String message = player.getName() + " used !saveall."; diff --git a/src/client/creator/CharacterFactory.java b/src/client/creator/CharacterFactory.java index 1aa6198f06..ba84b0e296 100644 --- a/src/client/creator/CharacterFactory.java +++ b/src/client/creator/CharacterFactory.java @@ -86,7 +86,7 @@ public abstract class CharacterFactory { } c.announce(MaplePacketCreator.addNewCharEntry(newchar)); - Server.getInstance().createCharacterid(newchar.getAccountID(), newchar.getId(), newchar.getWorld()); + Server.getInstance().createCharacterEntry(newchar); Server.getInstance().broadcastGMMessage(c.getWorld(), MaplePacketCreator.sendYellowTip("[NEW CHAR]: " + c.getAccountName() + " has created a new character with IGN " + name)); return 0; diff --git a/src/client/inventory/ItemFactory.java b/src/client/inventory/ItemFactory.java index 18d3efedf1..f802ae021a 100644 --- a/src/client/inventory/ItemFactory.java +++ b/src/client/inventory/ItemFactory.java @@ -42,8 +42,8 @@ public enum ItemFactory { INVENTORY(1, false), STORAGE(2, true), CASH_EXPLORER(3, true), - CASH_CYGNUS(4, false), - CASH_ARAN(5, false), + CASH_CYGNUS(4, true), + CASH_ARAN(5, true), MERCHANT(6, false); private final int value; private final boolean account; @@ -72,6 +72,68 @@ public enum ItemFactory { else saveItemsMerchant(items, bundlesList, id, con); } + private static Equip loadEquipFromResultSet(ResultSet rs) throws SQLException { + Equip equip = new Equip(rs.getInt("itemid"), (short) rs.getInt("position")); + equip.setOwner(rs.getString("owner")); + equip.setQuantity((short) rs.getInt("quantity")); + equip.setAcc((short) rs.getInt("acc")); + equip.setAvoid((short) rs.getInt("avoid")); + equip.setDex((short) rs.getInt("dex")); + equip.setHands((short) rs.getInt("hands")); + equip.setHp((short) rs.getInt("hp")); + equip.setInt((short) rs.getInt("int")); + equip.setJump((short) rs.getInt("jump")); + equip.setVicious((short) rs.getInt("vicious")); + equip.setFlag((byte) rs.getInt("flag")); + equip.setLuk((short) rs.getInt("luk")); + equip.setMatk((short) rs.getInt("matk")); + equip.setMdef((short) rs.getInt("mdef")); + equip.setMp((short) rs.getInt("mp")); + equip.setSpeed((short) rs.getInt("speed")); + equip.setStr((short) rs.getInt("str")); + equip.setWatk((short) rs.getInt("watk")); + equip.setWdef((short) rs.getInt("wdef")); + equip.setUpgradeSlots((byte) rs.getInt("upgradeslots")); + equip.setLevel((byte) rs.getByte("level")); + equip.setItemExp(rs.getInt("itemexp")); + equip.setItemLevel(rs.getByte("itemlevel")); + equip.setExpiration(rs.getLong("expiration")); + equip.setGiftFrom(rs.getString("giftFrom")); + equip.setRingId(rs.getInt("ringid")); + + return equip; + } + + public static List> loadEquippedItems(int id, boolean isAccount, boolean login) throws SQLException { + List> items = new ArrayList<>(); + + StringBuilder query = new StringBuilder(); + query.append("SELECT * FROM "); + query.append("(SELECT id, accountid FROM characters) AS accountterm "); + query.append("RIGHT JOIN "); + query.append("(SELECT * FROM (`inventoryitems` LEFT JOIN `inventoryequipment` USING(`inventoryitemid`))) AS equipterm"); + query.append(" ON accountterm.id=equipterm.characterid "); + query.append("WHERE accountterm.`"); + query.append(isAccount ? "accountid" : "characterid"); + query.append("` = ?"); + query.append(login ? " AND `inventorytype` = " + MapleInventoryType.EQUIPPED.getType() : ""); + + try (Connection con = DatabaseConnection.getConnection()) { + try (PreparedStatement ps = con.prepareStatement(query.toString())) { + ps.setInt(1, id); + + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + Integer cid = rs.getInt("characterid"); + items.add(new Pair(loadEquipFromResultSet(rs), cid)); + } + } + } + } + + return items; + } + private List> loadItemsCommon(int id, boolean login) throws SQLException { List> items = new ArrayList<>(); @@ -96,34 +158,7 @@ public enum ItemFactory { MapleInventoryType mit = MapleInventoryType.getByType(rs.getByte("inventorytype")); if (mit.equals(MapleInventoryType.EQUIP) || mit.equals(MapleInventoryType.EQUIPPED)) { - Equip equip = new Equip(rs.getInt("itemid"), (short) rs.getInt("position")); - equip.setOwner(rs.getString("owner")); - equip.setQuantity((short) rs.getInt("quantity")); - equip.setAcc((short) rs.getInt("acc")); - equip.setAvoid((short) rs.getInt("avoid")); - equip.setDex((short) rs.getInt("dex")); - equip.setHands((short) rs.getInt("hands")); - equip.setHp((short) rs.getInt("hp")); - equip.setInt((short) rs.getInt("int")); - equip.setJump((short) rs.getInt("jump")); - equip.setVicious((short) rs.getInt("vicious")); - equip.setFlag((byte) rs.getInt("flag")); - equip.setLuk((short) rs.getInt("luk")); - equip.setMatk((short) rs.getInt("matk")); - equip.setMdef((short) rs.getInt("mdef")); - equip.setMp((short) rs.getInt("mp")); - equip.setSpeed((short) rs.getInt("speed")); - equip.setStr((short) rs.getInt("str")); - equip.setWatk((short) rs.getInt("watk")); - equip.setWdef((short) rs.getInt("wdef")); - equip.setUpgradeSlots((byte) rs.getInt("upgradeslots")); - equip.setLevel((byte) rs.getByte("level")); - equip.setItemExp(rs.getInt("itemexp")); - equip.setItemLevel(rs.getByte("itemlevel")); - equip.setExpiration(rs.getLong("expiration")); - equip.setGiftFrom(rs.getString("giftFrom")); - equip.setRingId(rs.getInt("ringid")); - items.add(new Pair(equip, mit)); + items.add(new Pair(loadEquipFromResultSet(rs), mit)); } else { Item item = new Item(rs.getInt("itemid"), (byte) rs.getInt("position"), (short) rs.getInt("quantity"), rs.getInt("petid")); item.setOwner(rs.getString("owner")); @@ -277,34 +312,7 @@ public enum ItemFactory { MapleInventoryType mit = MapleInventoryType.getByType(rs.getByte("inventorytype")); if (mit.equals(MapleInventoryType.EQUIP) || mit.equals(MapleInventoryType.EQUIPPED)) { - Equip equip = new Equip(rs.getInt("itemid"), (short) rs.getInt("position")); - equip.setOwner(rs.getString("owner")); - equip.setQuantity((short) rs.getInt("quantity")); - equip.setAcc((short) rs.getInt("acc")); - equip.setAvoid((short) rs.getInt("avoid")); - equip.setDex((short) rs.getInt("dex")); - equip.setHands((short) rs.getInt("hands")); - equip.setHp((short) rs.getInt("hp")); - equip.setInt((short) rs.getInt("int")); - equip.setJump((short) rs.getInt("jump")); - equip.setVicious((short) rs.getInt("vicious")); - equip.setFlag((byte) rs.getInt("flag")); - equip.setLuk((short) rs.getInt("luk")); - equip.setMatk((short) rs.getInt("matk")); - equip.setMdef((short) rs.getInt("mdef")); - equip.setMp((short) rs.getInt("mp")); - equip.setSpeed((short) rs.getInt("speed")); - equip.setStr((short) rs.getInt("str")); - equip.setWatk((short) rs.getInt("watk")); - equip.setWdef((short) rs.getInt("wdef")); - equip.setUpgradeSlots((byte) rs.getInt("upgradeslots")); - equip.setLevel((byte) rs.getByte("level")); - equip.setItemExp(rs.getInt("itemexp")); - equip.setItemLevel(rs.getByte("itemlevel")); - equip.setExpiration(rs.getLong("expiration")); - equip.setGiftFrom(rs.getString("giftFrom")); - equip.setRingId(rs.getInt("ringid")); - items.add(new Pair(equip, mit)); + items.add(new Pair(loadEquipFromResultSet(rs), mit)); } else { if(bundles > 0) { Item item = new Item(rs.getInt("itemid"), (byte) rs.getInt("position"), (short)(bundles * rs.getInt("quantity")), rs.getInt("petid")); diff --git a/src/client/newyear/NewYearCardRecord.java b/src/client/newyear/NewYearCardRecord.java index 532044a746..987c5ceb78 100644 --- a/src/client/newyear/NewYearCardRecord.java +++ b/src/client/newyear/NewYearCardRecord.java @@ -241,30 +241,15 @@ public class NewYearCardRecord { } } - private static int getCharacterWorld(int receiverid) { - try (Connection con = DatabaseConnection.getConnection()) { - try (PreparedStatement ps = con.prepareStatement("SELECT world FROM characters WHERE id = ?")) { - ps.setInt(1, receiverid); - try (ResultSet rs = ps.executeQuery()) { - if (rs.next()) { - return rs.getInt("world"); - } - } - } - } catch(SQLException sqle) { - sqle.printStackTrace(); - } - - return -1; - } - public void startNewYearCardTask() { if(sendTask != null) return; sendTask = TimerManager.getInstance().register(new Runnable() { @Override public void run() { - int world = getCharacterWorld(receiverId); + Server server = Server.getInstance(); + + int world = server.getCharacterWorld(receiverId); if(world == -1) { sendTask.cancel(false); sendTask = null; @@ -272,7 +257,7 @@ public class NewYearCardRecord { return; } - MapleCharacter target = Server.getInstance().getWorld(world).getPlayerStorage().getCharacterById(receiverId); + MapleCharacter target = server.getWorld(world).getPlayerStorage().getCharacterById(receiverId); if(target != null && target.isLoggedinWorld()) { target.announce(MaplePacketCreator.onNewYearCardRes(target, NewYearCardRecord.this, 0xC, 0)); } diff --git a/src/constants/ServerConstants.java b/src/constants/ServerConstants.java index c3cbd70cda..0f366cc88c 100644 --- a/src/constants/ServerConstants.java +++ b/src/constants/ServerConstants.java @@ -23,6 +23,7 @@ public class ServerConstants { public static final long PURGING_INTERVAL = 5 * 60 * 1000; public static final long RANKING_INTERVAL = 60 * 60 * 1000; //60 minutes, 3600000. public static final long COUPON_INTERVAL = 60 * 60 * 1000; //60 minutes, 3600000. + public static final long UPDATE_INTERVAL = 777; public static final boolean ENABLE_PIC = false; //Pick true/false to enable or disable Pic. Delete character needs this feature ENABLED. public static final boolean ENABLE_PIN = false; //Pick true/false to enable or disable Pin. @@ -66,7 +67,7 @@ public class ServerConstants { public static final boolean USE_ENFORCE_JOB_LEVEL_RANGE = false;//Caps the player level on the minimum required to advance their current jobs. public static final boolean USE_ENFORCE_OWL_SUGGESTIONS = false;//Forces the Owl of Minerva to always display the defined item array on GameConstants.OWL_DATA instead of those featured by the players. public static final boolean USE_ENFORCE_UNMERCHABLE_PET = true; //Forces players to not sell pets via merchants. (since non-named pets gets dirty name and other possible DB-related issues) - public static final boolean USE_ENFORCE_MDOOR_POSITION = true; //Forces mystic door to be spawned near spawnpoints. (since things bugs out other way, and this helps players to locate the door faster) + public static final boolean USE_ENFORCE_MDOOR_POSITION = false; //Forces mystic door to be spawned near spawnpoints. public static final boolean USE_ERASE_PERMIT_ON_OPENSHOP = true;//Forces "shop permit" item to be consumed when player deploy his/her player shop. public static final boolean USE_ERASE_UNTRADEABLE_DROP = true; //Forces flagged untradeable items to disappear when dropped. public static final boolean USE_ERASE_PET_ON_EXPIRATION = false;//Forces pets to be removed from inventory when expire time comes, rather than converting it to a doll. diff --git a/src/net/PacketProcessor.java b/src/net/PacketProcessor.java index 8ed1a6a01a..e43cebd324 100644 --- a/src/net/PacketProcessor.java +++ b/src/net/PacketProcessor.java @@ -24,6 +24,7 @@ package net; import java.util.LinkedHashMap; import java.util.Map; +import net.opcodes.RecvOpcode; import net.server.channel.handlers.*; import net.server.handlers.CustomPacketHandler; import net.server.handlers.KeepAliveHandler; @@ -38,16 +39,16 @@ import net.server.handlers.login.CreateCharHandler; import net.server.handlers.login.DeleteCharHandler; import net.server.handlers.login.GuestLoginHandler; import net.server.handlers.login.LoginPasswordHandler; -import net.server.handlers.login.PickCharHandler; import net.server.handlers.login.RegisterPicHandler; import net.server.handlers.login.RegisterPinHandler; import net.server.handlers.login.RelogRequestHandler; import net.server.handlers.login.ServerStatusRequestHandler; import net.server.handlers.login.ServerlistRequestHandler; import net.server.handlers.login.SetGenderHandler; +import net.server.handlers.login.ViewAllCharHandler; +import net.server.handlers.login.ViewAllCharRegisterPicHandler; +import net.server.handlers.login.ViewAllCharSelectedHandler; import net.server.handlers.login.ViewAllCharSelectedWithPicHandler; -import net.server.handlers.login.ViewAllPicRegisterHandler; -import net.server.handlers.login.ViewCharHandler; public final class PacketProcessor { @@ -114,15 +115,15 @@ public final class PacketProcessor { registerHandler(RecvOpcode.CHECK_CHAR_NAME, new CheckCharNameHandler()); registerHandler(RecvOpcode.CREATE_CHAR, new CreateCharHandler()); registerHandler(RecvOpcode.DELETE_CHAR, new DeleteCharHandler()); - registerHandler(RecvOpcode.VIEW_ALL_CHAR, new ViewCharHandler()); - registerHandler(RecvOpcode.PICK_ALL_CHAR, new PickCharHandler()); + registerHandler(RecvOpcode.VIEW_ALL_CHAR, new ViewAllCharHandler()); + registerHandler(RecvOpcode.PICK_ALL_CHAR, new ViewAllCharSelectedHandler()); registerHandler(RecvOpcode.REGISTER_PIN, new RegisterPinHandler()); registerHandler(RecvOpcode.GUEST_LOGIN, new GuestLoginHandler()); registerHandler(RecvOpcode.REGISTER_PIC, new RegisterPicHandler()); registerHandler(RecvOpcode.CHAR_SELECT_WITH_PIC, new CharSelectedWithPicHandler()); registerHandler(RecvOpcode.SET_GENDER, new SetGenderHandler()); registerHandler(RecvOpcode.VIEW_ALL_WITH_PIC, new ViewAllCharSelectedWithPicHandler()); - registerHandler(RecvOpcode.VIEW_ALL_PIC_REGISTER, new ViewAllPicRegisterHandler()); + registerHandler(RecvOpcode.VIEW_ALL_PIC_REGISTER, new ViewAllCharRegisterPicHandler()); } else { //CHANNEL HANDLERS registerHandler(RecvOpcode.NAME_TRANSFER, new TransferNameHandler()); @@ -237,7 +238,8 @@ public final class PacketProcessor { registerHandler(RecvOpcode.ACCEPT_FAMILY, new AcceptFamilyHandler()); registerHandler(RecvOpcode.DUEY_ACTION, new DueyHandler()); registerHandler(RecvOpcode.USE_DEATHITEM, new UseDeathItemHandler()); - registerHandler(RecvOpcode.PLAYER_UPDATE, new PlayerUpdateHandler()); + //registerHandler(RecvOpcode.PLAYER_UPDATE, new PlayerUpdateHandler()); unused + registerHandler(RecvOpcode.PLAYER_MAP_TRANSFER, new PlayerMapTransitionHandler()); registerHandler(RecvOpcode.USE_MAPLELIFE, new UseMapleLifeHandler()); registerHandler(RecvOpcode.USE_CATCH_ITEM, new UseCatchItemHandler()); registerHandler(RecvOpcode.MOB_DAMAGE_MOB_FRIENDLY, new MobDamageMobFriendlyHandler()); diff --git a/src/net/RecvOpcode.java b/src/net/opcodes/RecvOpcode.java similarity index 99% rename from src/net/RecvOpcode.java rename to src/net/opcodes/RecvOpcode.java index 1b72921b8f..8b8c6e3e09 100644 --- a/src/net/RecvOpcode.java +++ b/src/net/opcodes/RecvOpcode.java @@ -19,7 +19,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package net; +package net.opcodes; public enum RecvOpcode { CUSTOM_PACKET(0x3713),//13 37 lol @@ -174,7 +174,7 @@ public enum RecvOpcode { ITEM_PICKUP(0xCA), DAMAGE_REACTOR(0xCD), TOUCHING_REACTOR(0xCE), - TEMP_SKILL(0xCF), + PLAYER_MAP_TRANSFER(0xCF), MAPLETV(0xFFFE),//Don't know SNOWBALL(0xD3), LEFT_KNOCKBACK(0xD4), diff --git a/src/net/SendOpcode.java b/src/net/opcodes/SendOpcode.java similarity index 99% rename from src/net/SendOpcode.java rename to src/net/opcodes/SendOpcode.java index 049467bf0d..193c761d92 100644 --- a/src/net/SendOpcode.java +++ b/src/net/opcodes/SendOpcode.java @@ -19,7 +19,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package net; +package net.opcodes; public enum SendOpcode { diff --git a/src/net/server/Server.java b/src/net/server/Server.java index c7c70e273c..d87b65d383 100644 --- a/src/net/server/Server.java +++ b/src/net/server/Server.java @@ -21,9 +21,6 @@ */ package net.server; -import net.server.worker.CharacterDiseaseWorker; -import net.server.worker.CouponWorker; -import net.server.worker.RankingWorker; import java.io.FileInputStream; import java.io.IOException; import java.net.InetSocketAddress; @@ -43,14 +40,22 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; import tools.locks.MonitoredReentrantLock; +import tools.locks.MonitoredReentrantReadWriteLock; import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; +import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; import net.MapleServerHandler; import net.mina.MapleCodecFactory; import net.server.channel.Channel; import net.server.guild.MapleAlliance; import net.server.guild.MapleGuild; import net.server.guild.MapleGuildCharacter; +import net.server.worker.CharacterDiseaseWorker; +import net.server.worker.CouponWorker; +import net.server.worker.RankingWorker; import net.server.world.World; import org.apache.mina.core.buffer.IoBuffer; @@ -64,6 +69,8 @@ import org.apache.mina.transport.socket.nio.NioSocketAcceptor; import client.MapleClient; import client.MapleCharacter; import client.SkillFactory; +import client.inventory.Item; +import client.inventory.ItemFactory; import client.newyear.NewYearCardRecord; import constants.ItemConstants; import constants.GameConstants; @@ -96,14 +103,18 @@ public class Server { private final Map guilds = new HashMap<>(100); private final Map inLoginState = new HashMap<>(100); private final Lock srvLock = new MonitoredReentrantLock(MonitoredLockType.SERVER); - private final Lock lgnLock = new MonitoredReentrantLock(MonitoredLockType.SERVER_LOGIN); private final Lock disLock = new MonitoredReentrantLock(MonitoredLockType.SERVER_DISEASES); + private final ReentrantReadWriteLock lgnLock = new MonitoredReentrantReadWriteLock(MonitoredLockType.SERVER_LOGIN, true); + private final ReadLock lgnRLock = lgnLock.readLock(); + private final WriteLock lgnWLock = lgnLock.writeLock(); private final PlayerBuffStorage buffStorage = new PlayerBuffStorage(); private final Map alliances = new HashMap<>(100); private final Map newyears = new HashMap<>(); private final List processDiseaseAnnouncePlayers = new LinkedList<>(); private final List registeredDiseaseAnnouncePlayers = new LinkedList<>(); + private final AtomicLong currentTime = new AtomicLong(0); + private boolean availableDeveloperRoom = false; private boolean online = false; public static long uptime = System.currentTimeMillis(); @@ -115,6 +126,20 @@ public class Server { return instance; } + public void updateCurrentTime() { + currentTime.addAndGet(ServerConstants.UPDATE_INTERVAL); + } + + public long forceUpdateCurrentTime() { + long timeNow = System.currentTimeMillis(); + currentTime.set(timeNow); + return timeNow; + } + + public long getCurrentTime() { // returns a slightly delayed time value + return currentTime.get(); + } + public boolean isOnline() { return online; } @@ -372,7 +397,7 @@ public class Server { disconnectIdlesOnLoginTask(); long timeLeft = getTimeLeftForNextHour(); - tMan.register(new CharacterDiseaseWorker(), 777, 777); + tMan.register(new CharacterDiseaseWorker(), ServerConstants.UPDATE_INTERVAL, ServerConstants.UPDATE_INTERVAL); tMan.register(new CouponWorker(), ServerConstants.COUPON_INTERVAL, timeLeft); tMan.register(new RankingWorker(), ServerConstants.RANKING_INTERVAL, timeLeft); @@ -822,123 +847,223 @@ public class Server { public List getWorlds() { return worlds; } - - private static void loadCharacteridsFromDb(Integer accountid, Set accChars) { - try { - try (Connection con = DatabaseConnection.getConnection()) { - try (PreparedStatement ps = con.prepareStatement("SELECT id FROM characters WHERE accountid = ?")) { - ps.setInt(1, accountid); - - try (ResultSet rs = ps.executeQuery()) { - while(rs.next()) { - accChars.add(rs.getInt("id")); - } - } - } - } - } catch (SQLException sqle) { - sqle.printStackTrace(); - } - } - - public boolean haveCharacterid(Integer accountid, Integer chrid) { - lgnLock.lock(); - try { - Set accChars = accountChars.get(accountid); - if(accChars == null) { - accChars = new HashSet<>(5); - loadCharacteridsFromDb(accountid, accChars); - - accountChars.put(accountid, accChars); - } - - return accChars.contains(chrid); - } finally { - lgnLock.unlock(); - } - } - - public void createCharacterid(Integer accountid, Integer chrid, Integer world) { - lgnLock.lock(); - try { - Set accChars = accountChars.get(accountid); - if(accChars == null) { - accChars = new HashSet<>(5); - accountChars.put(accountid, accChars); - } - - accChars.add(chrid); - worldChars.put(chrid, world); - } finally { - lgnLock.unlock(); - } - } - - public void deleteCharacterid(Integer accountid, Integer chrid) { - lgnLock.lock(); - try { - Set accChars = accountChars.get(accountid); - if(accChars != null) { - accChars.remove(chrid); - } - - worldChars.remove(chrid); - } finally { - lgnLock.unlock(); - } - } - - private static int getCharacterWorldFromDB(int chrid) { - int world = -1; - - try { - Connection con = DatabaseConnection.getConnection(); - - try (PreparedStatement ps = con.prepareStatement("SELECT world FROM characters WHERE id = ?")) { - ps.setInt(1, chrid); - - try (ResultSet rs = ps.executeQuery()) { - if(rs.next()) { - world = rs.getInt("world"); - } - } - } - - con.close(); - } catch (SQLException sqle) { - sqle.printStackTrace(); - } - - return world; - } public int getCharacterWorld(Integer chrid) { - lgnLock.lock(); + lgnRLock.lock(); try { Integer worldid = worldChars.get(chrid); + return worldid != null ? worldid : -1; + } finally { + lgnRLock.unlock(); + } + } + + public boolean haveCharacterEntry(Integer accountid, Integer chrid) { + lgnRLock.lock(); + try { + Set accChars = accountChars.get(accountid); + return accChars.contains(chrid); + } finally { + lgnRLock.unlock(); + } + } + + private Set getAccountCharacterEntries(Integer accountid) { + lgnRLock.lock(); + try { + return new HashSet<>(accountChars.get(accountid)); + } finally { + lgnRLock.unlock(); + } + } + + public void updateCharacterEntry(MapleCharacter chr) { + MapleCharacter chrView = chr.generateCharacterEntry(); + World wserv = worlds.get(chrView.getWorld()); + + lgnWLock.lock(); + try { + wserv.registerAccountCharacterView(chrView.getAccountID(), chrView); + } finally { + lgnWLock.unlock(); + } + } + + public void createCharacterEntry(MapleCharacter chr) { + Integer accountid = chr.getAccountID(), chrid = chr.getId(), world = chr.getWorld(); + + lgnWLock.lock(); + try { + Set accChars = accountChars.get(accountid); + accChars.add(chrid); - if(worldid == null) { - worldid = getCharacterWorldFromDB(chrid); - worldChars.put(chrid, worldid); + worldChars.put(chrid, world); + + MapleCharacter chrView = chr.generateCharacterEntry(); + World wserv = worlds.get(chrView.getWorld()); + wserv.registerAccountCharacterView(chrView.getAccountID(), chrView); + } finally { + lgnWLock.unlock(); + } + } + + public void deleteCharacterEntry(Integer accountid, Integer chrid) { + lgnWLock.lock(); + try { + Set accChars = accountChars.get(accountid); + accChars.remove(chrid); + + Integer world = worldChars.remove(chrid); + if(world != null) { + World wserv = worlds.get(world); + wserv.unregisterAccountCharacterView(accountid, chrid); + } + } finally { + lgnWLock.unlock(); + } + } + + public void transferWorldCharacterEntry(MapleCharacter chr, Integer toWorld) { // used before setting the new worldid on the character object + lgnWLock.lock(); + try { + Integer chrid = chr.getId(), accountid = chr.getAccountID(), world = worldChars.get(chr.getId()); + if(world != null) { + World wserv = worlds.get(world); + wserv.unregisterAccountCharacterView(accountid, chrid); } - return worldid; + worldChars.put(chrid, toWorld); + + MapleCharacter chrView = chr.generateCharacterEntry(); + World wserv = worlds.get(toWorld); + wserv.registerAccountCharacterView(chrView.getAccountID(), chrView); } finally { - lgnLock.unlock(); + lgnWLock.unlock(); } } /* - public void deleteAccount(Integer accountid) { is this even a thing? - lgnLock.lock(); + public void deleteAccountEntry(Integer accountid) { is this even a thing? + lgnWLock.lock(); try { accountChars.remove(accountid); } finally { - lgnLock.unlock(); + lgnWLock.unlock(); } } */ + private static List> loadAccountCharactersViewFromDb(MapleClient c, int wlen) { + List> wchars = new ArrayList<>(wlen); + for(int i = 0; i < wlen; i++) wchars.add(i, new LinkedList()); + + List chars = new LinkedList<>(); + int curWorld = 0; + try { + List> accEquips = ItemFactory.loadEquippedItems(c.getAccID(), true, true); + Map> accPlayerEquips = new HashMap<>(); + + for(Pair ae : accEquips) { + List playerEquips = accPlayerEquips.get(ae.getRight()); + if(playerEquips == null) { + playerEquips = new LinkedList<>(); + accPlayerEquips.put(ae.getRight(), playerEquips); + } + + playerEquips.add(ae.getLeft()); + } + + Connection con = DatabaseConnection.getConnection(); + try (PreparedStatement ps = con.prepareStatement("SELECT * FROM characters WHERE accountid = ? ORDER BY world, id")) { + ps.setInt(1, c.getAccID()); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + int cworld = rs.getByte("world"); + if(cworld >= wlen) break; + + if(cworld > curWorld) { + wchars.add(curWorld, chars); + + curWorld = cworld; + chars = new LinkedList<>(); + } + + Integer cid = rs.getInt("id"); + chars.add(MapleCharacter.loadCharacterEntryFromDB(rs, accPlayerEquips.get(cid))); + } + } + } + con.close(); + + wchars.add(curWorld, chars); + } catch (SQLException sqle) { + sqle.printStackTrace(); + } + + return wchars; + } + + public void loadAccountCharactersView(MapleClient c) { + int accId = c.getAccID(); + int gmLevel = 0; + boolean firstAccountLogin; + + lgnRLock.lock(); + try { + firstAccountLogin = !accountChars.containsKey(accId); + } finally { + lgnRLock.unlock(); + } + + if(!firstAccountLogin) { + Set accWorlds = new HashSet<>(); + + lgnRLock.lock(); + try { + for(Integer chrid : getAccountCharacterEntries(accId)) { + accWorlds.add(worldChars.get(chrid)); + } + } finally { + lgnRLock.unlock(); + } + + for(Integer aw : accWorlds) { + for(MapleCharacter chr : worlds.get(aw).getAllCharactersView()) { + if(gmLevel < chr.gmLevel()) gmLevel = chr.gmLevel(); + } + } + + c.setGMLevel(gmLevel); + return; + } + + List> accChars = loadAccountCharactersViewFromDb(c, worlds.size()); + + lgnWLock.lock(); + try { + Set chars = new HashSet<>(5); + for(int wid = 0; wid < worlds.size(); wid++) { + World w = worlds.get(wid); + List wchars = accChars.get(wid); + w.loadAccountCharactersView(accId, wchars); + + for(MapleCharacter chr : wchars) { + int cid = chr.getId(); + if(gmLevel < chr.gmLevel()) gmLevel = chr.gmLevel(); + + chars.add(cid); + worldChars.put(cid, wid); + } + } + + accountChars.put(accId, chars); + } finally { + lgnWLock.unlock(); + } + + c.setGMLevel(gmLevel); + } + private static String getRemoteIp(InetSocketAddress isa) { return isa.getAddress().getHostAddress(); } @@ -946,23 +1071,23 @@ public class Server { public void setCharacteridInTransition(InetSocketAddress isa, int charId) { String remoteIp = getRemoteIp(isa); - lgnLock.lock(); + lgnWLock.lock(); try { transitioningChars.put(remoteIp, charId); } finally { - lgnLock.unlock(); + lgnWLock.unlock(); } } public boolean validateCharacteridInTransition(InetSocketAddress isa, int charId) { String remoteIp = getRemoteIp(isa); - lgnLock.lock(); + lgnWLock.lock(); try { Integer cid = transitioningChars.remove(remoteIp); return cid != null && cid.equals(charId); } finally { - lgnLock.unlock(); + lgnWLock.unlock(); } } diff --git a/src/net/server/channel/handlers/AdminCommandHandler.java b/src/net/server/channel/handlers/AdminCommandHandler.java index e52b814754..01de5ce5fe 100644 --- a/src/net/server/channel/handlers/AdminCommandHandler.java +++ b/src/net/server/channel/handlers/AdminCommandHandler.java @@ -132,7 +132,7 @@ public final class AdminCommandHandler extends AbstractMaplePacketHandler { MapleMonster monster = (MapleMonster) monsterx.get(x); if (monster.getId() == mobToKill) { c.getPlayer().getMap().killMonster(monster, c.getPlayer(), true); - monster.giveExpToCharacter(c.getPlayer(), monster.getExp(), true, 1); + //monster.giveExpToCharacter(c.getPlayer(), monster.getExp(), true, 1); already being done } } break; diff --git a/src/net/server/channel/handlers/AllianceOperationHandler.java b/src/net/server/channel/handlers/AllianceOperationHandler.java index d884d3d237..f03f59b945 100644 --- a/src/net/server/channel/handlers/AllianceOperationHandler.java +++ b/src/net/server/channel/handlers/AllianceOperationHandler.java @@ -24,7 +24,7 @@ package net.server.channel.handlers; import client.MapleCharacter; import client.MapleClient; import net.AbstractMaplePacketHandler; -import net.SendOpcode; +import net.opcodes.SendOpcode; import net.server.Server; import net.server.guild.MapleGuild; import net.server.guild.MapleGuildCharacter; diff --git a/src/net/server/channel/handlers/ChangeMapHandler.java b/src/net/server/channel/handlers/ChangeMapHandler.java index 795163a639..56e99e1898 100644 --- a/src/net/server/channel/handlers/ChangeMapHandler.java +++ b/src/net/server/channel/handlers/ChangeMapHandler.java @@ -23,17 +23,19 @@ package net.server.channel.handlers; import java.net.InetAddress; import java.net.UnknownHostException; +import java.util.Calendar; import net.AbstractMaplePacketHandler; +import client.MapleCharacter; +import client.MapleClient; +import client.inventory.MapleInventoryType; import client.inventory.manipulator.MapleInventoryManipulator; import server.MaplePortal; import server.MapleTrade; import server.maps.MapleMap; +import tools.FilePrinter; import tools.MaplePacketCreator; import tools.data.input.SeekableLittleEndianAccessor; -import client.MapleCharacter; -import client.MapleClient; -import client.inventory.MapleInventoryType; public final class ChangeMapHandler extends AbstractMaplePacketHandler { @@ -42,6 +44,10 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler { MapleCharacter chr = c.getPlayer(); if (chr.isChangingMaps() || chr.isBanned()) { + if(chr.isChangingMaps()) { + FilePrinter.printError(FilePrinter.PORTAL_STUCK + chr.getName() + ".txt", "Player " + chr.getName() + " got stuck when changing maps. Timestamp: " + Calendar.getInstance().getTime().toString() + " Last visited mapids: " + chr.getLastVisitedMapids()); + } + c.announce(MaplePacketCreator.enableActions()); return; } @@ -49,7 +55,7 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler { MapleTrade.cancelTrade(chr); } if (slea.available() == 0) { //Cash Shop :) - if(!chr.getCashShop().isOpened()) { + if(!chr.getCashShop().isOpened()) { c.disconnect(false, false); return; } @@ -62,7 +68,7 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler { ex.printStackTrace(); } } else { - if(chr.getCashShop().isOpened()) { + if(chr.getCashShop().isOpened()) { c.disconnect(false, false); return; } @@ -138,21 +144,22 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler { c.announce(MaplePacketCreator.enableActions()); return; } + if (chr.getMapId() == 109040004) { chr.getFitness().resetTimes(); - } - if (chr.getMapId() == 109030003 || chr.getMapId() == 109030103) { + } else if (chr.getMapId() == 109030003 || chr.getMapId() == 109030103) { chr.getOla().resetTimes(); } + if (portal != null) { if(portal.getPosition().distanceSq(chr.getPosition()) > 400000) { - c.announce(MaplePacketCreator.enableActions()); + c.announce(MaplePacketCreator.enableActions()); return; } portal.enterPortal(c); } else { - c.announce(MaplePacketCreator.enableActions()); + c.announce(MaplePacketCreator.enableActions()); } } catch (Exception e) { e.printStackTrace(); diff --git a/src/net/server/channel/handlers/DoorHandler.java b/src/net/server/channel/handlers/DoorHandler.java index c72907d663..ee3d97dfec 100644 --- a/src/net/server/channel/handlers/DoorHandler.java +++ b/src/net/server/channel/handlers/DoorHandler.java @@ -21,10 +21,14 @@ */ package net.server.channel.handlers; +import java.util.Calendar; +import client.MapleCharacter; import client.MapleClient; import net.AbstractMaplePacketHandler; import server.maps.MapleDoorObject; import server.maps.MapleMapObject; +import tools.FilePrinter; +import tools.MaplePacketCreator; import tools.data.input.SeekableLittleEndianAccessor; /** @@ -35,15 +39,29 @@ public final class DoorHandler extends AbstractMaplePacketHandler { @Override public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { int ownerid = slea.readInt(); - boolean mode = (slea.readByte() == 0); // specifies if backwarp or not, 1 town to target, 0 target to town - for (MapleMapObject obj : c.getPlayer().getMap().getMapObjects()) { + slea.readByte(); // specifies if backwarp or not, 1 town to target, 0 target to town + + MapleCharacter chr = c.getPlayer(); + if (chr.isChangingMaps() || chr.isBanned()) { + if(chr.isChangingMaps()) { + FilePrinter.printError(FilePrinter.PORTAL_STUCK + chr.getName() + ".txt", "Player " + chr.getName() + " got stuck when changing maps (using Mystic Door). Timestamp: " + Calendar.getInstance().getTime().toString() + " Last visited mapids: " + chr.getLastVisitedMapids()); + } + + c.announce(MaplePacketCreator.enableActions()); + return; + } + + for (MapleMapObject obj : chr.getMap().getMapObjects()) { if (obj instanceof MapleDoorObject) { MapleDoorObject door = (MapleDoorObject) obj; if (door.getOwnerId() == ownerid) { - door.warp(c.getPlayer(), mode); + door.warp(chr); return; } } } + + c.announce(MaplePacketCreator.blockedMessage(6)); + c.announce(MaplePacketCreator.enableActions()); } } diff --git a/src/net/server/channel/handlers/EnterCashShopHandler.java b/src/net/server/channel/handlers/EnterCashShopHandler.java index fb0d4724e2..3becadcb9b 100644 --- a/src/net/server/channel/handlers/EnterCashShopHandler.java +++ b/src/net/server/channel/handlers/EnterCashShopHandler.java @@ -81,7 +81,7 @@ public class EnterCashShopHandler extends AbstractMaplePacketHandler { c.getChannelServer().removePlayer(mc); mc.getMap().removePlayer(mc); mc.getCashShop().open(true); - mc.saveToDB(); + mc.saveCharToDB(); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/net/server/channel/handlers/EnterMTSHandler.java b/src/net/server/channel/handlers/EnterMTSHandler.java index 30da949350..d6bf850f16 100644 --- a/src/net/server/channel/handlers/EnterMTSHandler.java +++ b/src/net/server/channel/handlers/EnterMTSHandler.java @@ -95,7 +95,7 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler { chr.forfeitExpirableQuests(); chr.cancelQuestExpirationTask(); - chr.saveToDB(); + chr.saveCharToDB(); chr.getMap().removePlayer(c.getPlayer()); try { c.announce(MaplePacketCreator.openCashShop(c, true)); diff --git a/src/net/server/channel/handlers/FamilyUseHandler.java b/src/net/server/channel/handlers/FamilyUseHandler.java index 81d267bb9a..38af1f49da 100644 --- a/src/net/server/channel/handlers/FamilyUseHandler.java +++ b/src/net/server/channel/handlers/FamilyUseHandler.java @@ -25,7 +25,7 @@ import constants.ServerConstants; import client.MapleCharacter; import client.MapleClient; import net.AbstractMaplePacketHandler; -import net.SendOpcode; +import net.opcodes.SendOpcode; import tools.data.input.SeekableLittleEndianAccessor; import tools.data.output.MaplePacketLittleEndianWriter; diff --git a/src/net/server/channel/handlers/MoveLifeHandler.java b/src/net/server/channel/handlers/MoveLifeHandler.java index 8173258691..905bdd21a5 100644 --- a/src/net/server/channel/handlers/MoveLifeHandler.java +++ b/src/net/server/channel/handlers/MoveLifeHandler.java @@ -26,12 +26,14 @@ import client.MapleClient; import java.awt.Point; import java.util.ArrayList; import java.util.List; +import net.server.Server; import server.life.MapleMonster; import server.life.MapleMonsterInformationProvider; //import server.life.MobAttackInfo; //import server.life.MobAttackInfoFactory; import server.life.MobSkill; import server.life.MobSkillFactory; +import server.maps.MapleMap; import server.maps.MapleMapObject; import server.maps.MapleMapObjectType; import server.movement.LifeMovementFragment; @@ -48,9 +50,12 @@ import tools.data.input.SeekableLittleEndianAccessor; public final class MoveLifeHandler extends AbstractMovementPacketHandler { @Override public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { + MapleCharacter player = c.getPlayer(); + MapleMap map = player.getMap(); + int objectid = slea.readInt(); short moveid = slea.readShort(); - MapleMapObject mmo = c.getPlayer().getMap().getMapObject(objectid); + MapleMapObject mmo = map.getMapObject(objectid); if (mmo == null || mmo.getType() != MapleMapObjectType.MONSTER) { return; } @@ -95,8 +100,18 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler { nextCastSkill = skillToUse.getLeft(); nextCastSkillLevel = skillToUse.getRight(); toUse = MobSkillFactory.getMobSkill(nextCastSkill, nextCastSkillLevel); + + if (!isSkill && !isAttack) { + long curtime = Server.getInstance().getCurrentTime(); + if(curtime >= monster.getNextBasicSkillTime()) { // dont use the special attack too often, chase the player f3 + //MobAttackInfo mobAttack = MobAttackInfoFactory.getMobAttackInfo(monster, attackId); + monster.setNextBasicSkillTime(curtime); + } else { + toUse = null; // paliative measure for suspicious mob movement + } + } - if (isSkill || isAttack) { + if (toUse != null) { int percHpLeft = (int) (((float) monster.getHp() / monster.getMaxHp()) * 100); if (nextCastSkill != toUse.getSkillId() || nextCastSkillLevel != toUse.getSkillLevel()) { //toUse.resetAnticipatedSkill(); @@ -106,25 +121,13 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler { } else if (monster.canUseSkill(toUse)) { int animationTime = MapleMonsterInformationProvider.getInstance().getMobSkillAnimationTime(monster.getId(), rndSkill); if(animationTime > 0) { - toUse.applyDelayedEffect(c.getPlayer(), monster, true, banishPlayers, animationTime); + toUse.applyDelayedEffect(player, monster, true, banishPlayers, animationTime); } else { - toUse.applyEffect(c.getPlayer(), monster, true, banishPlayers); + toUse.applyEffect(player, monster, true, banishPlayers); } } else { toUse = null; } - } else { - toUse = null; // paliative measure for suspicious mob movement - - /* - long curtime = System.currentTimeMillis(); - if(curtime >= monster.getNextBasicSkillTime()) { // dont use the special attack too often, chase the player f3 - MobAttackInfo mobAttack = MobAttackInfoFactory.getMobAttackInfo(monster, attackId); - monster.setNextBasicSkillTime(curtime); - } else { - toUse = null; - } - */ } } } else { @@ -133,35 +136,44 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler { } } + if(toUse == null) { + useSkillId = 0; + useSkillLevel = 0; + rawActivity = -1; + pOption = 0; + } + slea.readByte(); slea.readInt(); // whatever short start_x = slea.readShort(); // hmm.. startpos? short start_y = slea.readShort(); // hmm... Point startPos = new Point(start_x, start_y); res = parseMovement(slea); - if (monster.getController() != c.getPlayer()) { - if (monster.isAttackedBy(c.getPlayer())) { - monster.switchController(c.getPlayer(), true); + if (monster.getController() != player) { + if (monster.isAttackedBy(player)) { + monster.switchController(player, true); } else { return; } } else if (rawActivity == -1 && monster.isControllerKnowsAboutAggro() && !monster.isMobile() && !monster.isFirstAttack()) { - monster.setControllerHasAggro(false); + monster.setControllerHasAggro(false); monster.setControllerKnowsAboutAggro(false); } boolean aggro = monster.isControllerHasAggro(); - if (toUse != null) { - c.announce(MaplePacketCreator.moveMonsterResponse(objectid, moveid, monster.getMp(), aggro, toUse.getSkillId(), toUse.getSkillLevel())); + + if (toUse != null) { + c.announce(MaplePacketCreator.moveMonsterResponse(objectid, moveid, monster.getMp(), aggro, toUse.getSkillId(), toUse.getSkillLevel())); } else { c.announce(MaplePacketCreator.moveMonsterResponse(objectid, moveid, monster.getMp(), aggro)); } + if (aggro) { monster.setControllerKnowsAboutAggro(true); } if (res != null) { - c.getPlayer().getMap().broadcastMessage(c.getPlayer(), MaplePacketCreator.moveMonster(objectid, nextMovementCouldBeSkill, rawActivity, useSkillId, useSkillLevel, pOption, startPos, res), monster.getPosition()); + map.broadcastMessage(player, MaplePacketCreator.moveMonster(objectid, nextMovementCouldBeSkill, rawActivity, useSkillId, useSkillLevel, pOption, startPos, res), monster.getPosition()); updatePosition(res, monster, -1); - c.getPlayer().getMap().moveMonster(monster, monster.getPosition()); + map.moveMonster(monster, monster.getPosition()); } for (MapleCharacter chr : banishPlayers) { diff --git a/src/net/server/channel/handlers/NPCAnimationHandler.java b/src/net/server/channel/handlers/NPCAnimationHandler.java index 30d569709c..8acec78469 100644 --- a/src/net/server/channel/handlers/NPCAnimationHandler.java +++ b/src/net/server/channel/handlers/NPCAnimationHandler.java @@ -23,7 +23,7 @@ package net.server.channel.handlers; import client.MapleClient; import net.AbstractMaplePacketHandler; -import net.SendOpcode; +import net.opcodes.SendOpcode; import tools.data.input.SeekableLittleEndianAccessor; import tools.data.output.MaplePacketLittleEndianWriter; diff --git a/src/net/server/channel/handlers/PlayerMapTransitionHandler.java b/src/net/server/channel/handlers/PlayerMapTransitionHandler.java new file mode 100644 index 0000000000..da797948ed --- /dev/null +++ b/src/net/server/channel/handlers/PlayerMapTransitionHandler.java @@ -0,0 +1,37 @@ +/* + This file is part of the HeavenMS MapleStory Server + Copyleft (L) 2016 - 2018 RonanLana + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation version 3 as published by + the Free Software Foundation. You may not use, modify or distribute + this program under any other version of the GNU Affero General Public + License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +package net.server.channel.handlers; + +import client.MapleClient; +import net.AbstractMaplePacketHandler; +import tools.data.input.SeekableLittleEndianAccessor; + +/** + * + * @author Ronan + */ +public final class PlayerMapTransitionHandler extends AbstractMaplePacketHandler { + + @Override + public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { + c.getPlayer().setMapTransitionComplete(); + } +} \ No newline at end of file diff --git a/src/net/server/channel/handlers/PlayerUpdateHandler.java b/src/net/server/channel/handlers/PlayerUpdateHandler.java index 100dfb3352..672c2af3a6 100644 --- a/src/net/server/channel/handlers/PlayerUpdateHandler.java +++ b/src/net/server/channel/handlers/PlayerUpdateHandler.java @@ -26,9 +26,7 @@ import net.AbstractMaplePacketHandler; import tools.data.input.SeekableLittleEndianAccessor; public final class PlayerUpdateHandler extends AbstractMaplePacketHandler { - + @Override - public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { - c.getPlayer().setMapTransitionComplete(); - } + public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {} } \ No newline at end of file diff --git a/src/net/server/channel/handlers/TransferNameHandler.java b/src/net/server/channel/handlers/TransferNameHandler.java index dafd5c7972..373c101cea 100644 --- a/src/net/server/channel/handlers/TransferNameHandler.java +++ b/src/net/server/channel/handlers/TransferNameHandler.java @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2016 - 2018 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/src/net/server/channel/handlers/TransferNameResultHandler.java b/src/net/server/channel/handlers/TransferNameResultHandler.java index 35e4c18e26..b12999a384 100644 --- a/src/net/server/channel/handlers/TransferNameResultHandler.java +++ b/src/net/server/channel/handlers/TransferNameResultHandler.java @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2016 - 2018 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/src/net/server/channel/handlers/TransferWorldHandler.java b/src/net/server/channel/handlers/TransferWorldHandler.java index 806a336804..79657dfca1 100644 --- a/src/net/server/channel/handlers/TransferWorldHandler.java +++ b/src/net/server/channel/handlers/TransferWorldHandler.java @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2016 - 2018 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/src/net/server/channel/handlers/WeddingTalkHandler.java b/src/net/server/channel/handlers/WeddingTalkHandler.java index 40bee34039..0a8f0aec84 100644 --- a/src/net/server/channel/handlers/WeddingTalkHandler.java +++ b/src/net/server/channel/handlers/WeddingTalkHandler.java @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2016 - 2018 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/src/net/server/channel/handlers/WeddingTalkMoreHandler.java b/src/net/server/channel/handlers/WeddingTalkMoreHandler.java index 8165d3c01f..ded6c80bf0 100644 --- a/src/net/server/channel/handlers/WeddingTalkMoreHandler.java +++ b/src/net/server/channel/handlers/WeddingTalkMoreHandler.java @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2016 - 2018 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/src/net/server/channel/worker/BaseScheduler.java b/src/net/server/channel/worker/BaseScheduler.java index 9a1f88ba5b..e643e4a8ce 100644 --- a/src/net/server/channel/worker/BaseScheduler.java +++ b/src/net/server/channel/worker/BaseScheduler.java @@ -60,6 +60,8 @@ public abstract class BaseScheduler { } private void runBaseSchedule() { + List toRemove; + schedulerLock.lock(); try { if(registeredEntries.isEmpty()) { @@ -77,7 +79,7 @@ public abstract class BaseScheduler { idleProcs = 0; long timeNow = System.currentTimeMillis(); - List toRemove = new LinkedList<>(); + toRemove = new LinkedList<>(); for(Entry> rmd : registeredEntries.entrySet()) { Pair r = rmd.getValue(); @@ -90,17 +92,11 @@ public abstract class BaseScheduler { for(Object mse : toRemove) { registeredEntries.remove(mse); } - - dispatchRemovedEntries(toRemove, true); } finally { schedulerLock.unlock(); } - } - - private void dispatchRemovedEntries(List toRemove, boolean fromUpdate) { - for (SchedulerListener listener : listeners.toArray(new SchedulerListener[listeners.size()])) { - listener.removedScheduledEntries(toRemove, fromUpdate); - } + + dispatchRemovedEntries(toRemove, true); } protected void registerEntry(Object key, Runnable removalAction, long duration) { @@ -122,10 +118,16 @@ public abstract class BaseScheduler { try { Pair rm = registeredEntries.remove(key); if(rm != null) rm.getLeft().run(); - - dispatchRemovedEntries(Collections.singletonList(key), false); } finally { schedulerLock.unlock(); } + + dispatchRemovedEntries(Collections.singletonList(key), false); + } + + private void dispatchRemovedEntries(List toRemove, boolean fromUpdate) { + for (SchedulerListener listener : listeners.toArray(new SchedulerListener[listeners.size()])) { + listener.removedScheduledEntries(toRemove, fromUpdate); + } } } diff --git a/src/net/server/channel/worker/MobAnimationScheduler.java b/src/net/server/channel/worker/MobAnimationScheduler.java index 887d71d9e6..fdf6875430 100644 --- a/src/net/server/channel/worker/MobAnimationScheduler.java +++ b/src/net/server/channel/worker/MobAnimationScheduler.java @@ -62,7 +62,9 @@ public class MobAnimationScheduler extends BaseScheduler { public boolean registerAnimationMode(Integer mobHash, long animationTime) { animationLock.lock(); try { - if(onAnimationMobs.contains(mobHash)) return false; + if(onAnimationMobs.contains(mobHash)) { + return false; + } registerEntry(mobHash, r, animationTime); onAnimationMobs.add(mobHash); diff --git a/src/net/server/handlers/login/AfterLoginHandler.java b/src/net/server/handlers/login/AfterLoginHandler.java index 420635b485..f48d8876a6 100644 --- a/src/net/server/handlers/login/AfterLoginHandler.java +++ b/src/net/server/handlers/login/AfterLoginHandler.java @@ -30,7 +30,6 @@ public final class AfterLoginHandler extends AbstractMaplePacketHandler { @Override public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { - byte c2 = slea.readByte(); byte c3 = 5; if (slea.available() > 0) { diff --git a/src/net/server/handlers/login/CharSelectedHandler.java b/src/net/server/handlers/login/CharSelectedHandler.java index 86590a893f..b25c637301 100644 --- a/src/net/server/handlers/login/CharSelectedHandler.java +++ b/src/net/server/handlers/login/CharSelectedHandler.java @@ -46,7 +46,7 @@ public final class CharSelectedHandler extends AbstractMaplePacketHandler { } Server server = Server.getInstance(); - if(!server.haveCharacterid(c.getAccID(), charId)) { + if(!server.haveCharacterEntry(c.getAccID(), charId)) { c.getSession().close(true); return; } diff --git a/src/net/server/handlers/login/CharSelectedWithPicHandler.java b/src/net/server/handlers/login/CharSelectedWithPicHandler.java index 2034fa4442..55fa741b56 100644 --- a/src/net/server/handlers/login/CharSelectedWithPicHandler.java +++ b/src/net/server/handlers/login/CharSelectedWithPicHandler.java @@ -27,7 +27,7 @@ public class CharSelectedWithPicHandler extends AbstractMaplePacketHandler { } Server server = Server.getInstance(); - if(!server.haveCharacterid(c.getAccID(), charId)) { + if(!server.haveCharacterEntry(c.getAccID(), charId)) { c.getSession().close(true); return; } diff --git a/src/net/server/handlers/login/LoginPasswordHandler.java b/src/net/server/handlers/login/LoginPasswordHandler.java index cf7ec97793..5cfea94e4e 100644 --- a/src/net/server/handlers/login/LoginPasswordHandler.java +++ b/src/net/server/handlers/login/LoginPasswordHandler.java @@ -113,6 +113,7 @@ public final class LoginPasswordHandler implements MaplePacketHandler { } private static void login(MapleClient c){ + Server.getInstance().loadAccountCharactersView(c); // locks the login session until data is recovered from the cache or the DB. c.announce(MaplePacketCreator.getAuthSuccess(c));//why the fk did I do c.getAccountName()? Server.getInstance().registerLoginState(c); diff --git a/src/net/server/handlers/login/RegisterPicHandler.java b/src/net/server/handlers/login/RegisterPicHandler.java index bdef20bf52..bc0d6e67f7 100644 --- a/src/net/server/handlers/login/RegisterPicHandler.java +++ b/src/net/server/handlers/login/RegisterPicHandler.java @@ -27,7 +27,7 @@ public final class RegisterPicHandler extends AbstractMaplePacketHandler { } Server server = Server.getInstance(); - if(!server.haveCharacterid(c.getAccID(), charId)) { + if(!server.haveCharacterEntry(c.getAccID(), charId)) { c.getSession().close(true); return; } diff --git a/src/net/server/handlers/login/ServerStatusRequestHandler.java b/src/net/server/handlers/login/ServerStatusRequestHandler.java index 91dd1a2c31..b2c37b302a 100644 --- a/src/net/server/handlers/login/ServerStatusRequestHandler.java +++ b/src/net/server/handlers/login/ServerStatusRequestHandler.java @@ -32,10 +32,13 @@ public final class ServerStatusRequestHandler extends AbstractMaplePacketHandler @Override public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { - byte world = (byte) slea.readShort();//Wuuu? ): + byte world = (byte) slea.readShort(); World wserv = Server.getInstance().getWorld(world); - int status = wserv.getWorldCapacityStatus(); - - c.announce(MaplePacketCreator.getServerStatus(status)); + if(wserv != null) { + int status = wserv.getWorldCapacityStatus(); + c.announce(MaplePacketCreator.getServerStatus(status)); + } else { + c.announce(MaplePacketCreator.getServerStatus(2)); + } } } diff --git a/src/net/server/handlers/login/ViewAllCharHandler.java b/src/net/server/handlers/login/ViewAllCharHandler.java new file mode 100644 index 0000000000..5808224def --- /dev/null +++ b/src/net/server/handlers/login/ViewAllCharHandler.java @@ -0,0 +1,80 @@ +/* + This file is part of the OdinMS Maple Story Server + Copyright (C) 2008 Patrick Huy + Matthias Butz + Jan Christian Meyer + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation version 3 as published by + the Free Software Foundation. You may not use, modify or distribute + this program under any other version of the GNU Affero General Public + License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +package net.server.handlers.login; + +import client.MapleCharacter; +import client.MapleClient; +import constants.ServerConstants; +import java.util.ArrayList; +import java.util.List; +import net.AbstractMaplePacketHandler; +import net.server.Server; +import net.server.world.World; +import tools.MaplePacketCreator; +import tools.data.input.SeekableLittleEndianAccessor; +import tools.Pair; + +public final class ViewAllCharHandler extends AbstractMaplePacketHandler { + @Override + public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { + try { + List wlist = Server.getInstance().getWorlds(); + List>> worldChars = new ArrayList<>(wlist.size() + 1); + + int chrTotal = 0; + int accountId = c.getAccID(); + List lastwchars = null; + for(World w : wlist) { + List wchars = w.getAccountCharactersView(accountId); + + if(!wchars.isEmpty()) { + lastwchars = wchars; + + worldChars.add(new Pair<>(w.getId(), wchars)); + chrTotal += wchars.size(); + } + } + + if (chrTotal > 9) { + int padRight = chrTotal % 3; + if (padRight > 0 && lastwchars != null) { + MapleCharacter chr = lastwchars.get(lastwchars.size() - 1); + + for(int i = padRight; i < 3; i++) { // filling the remaining slots with the last character loaded + chrTotal++; + lastwchars.add(chr); + } + } + } + + int charsSize = chrTotal; + int unk = charsSize + (3 - charsSize % 3); //rowSize? + c.announce(MaplePacketCreator.showAllCharacter(charsSize, unk)); + + for (Pair> wchars : worldChars) { + c.announce(MaplePacketCreator.showAllCharacterInfo(wchars.getLeft(), wchars.getRight(), ServerConstants.ENABLE_PIC)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/net/server/handlers/login/ViewAllPicRegisterHandler.java b/src/net/server/handlers/login/ViewAllCharRegisterPicHandler.java similarity index 88% rename from src/net/server/handlers/login/ViewAllPicRegisterHandler.java rename to src/net/server/handlers/login/ViewAllCharRegisterPicHandler.java index 23e3df91df..6a9f063d8f 100644 --- a/src/net/server/handlers/login/ViewAllPicRegisterHandler.java +++ b/src/net/server/handlers/login/ViewAllCharRegisterPicHandler.java @@ -10,7 +10,7 @@ import tools.MaplePacketCreator; import tools.Randomizer; import tools.data.input.SeekableLittleEndianAccessor; -public final class ViewAllPicRegisterHandler extends AbstractMaplePacketHandler { //Gey class name lol +public final class ViewAllCharRegisterPicHandler extends AbstractMaplePacketHandler { //Gey class name lol @Override @@ -20,7 +20,7 @@ public final class ViewAllPicRegisterHandler extends AbstractMaplePacketHandler slea.readInt(); // please don't let the client choose which world they should login Server server = Server.getInstance(); - if(!server.haveCharacterid(c.getAccID(), charId)) { + if(!server.haveCharacterEntry(c.getAccID(), charId)) { c.getSession().close(true); return; } @@ -31,7 +31,7 @@ public final class ViewAllPicRegisterHandler extends AbstractMaplePacketHandler return; } - int channel = Randomizer.rand(0, server.getWorld(c.getWorld()).getChannels().size()); + int channel = Randomizer.rand(1, server.getWorld(c.getWorld()).getChannels().size()); c.setChannel(channel); String mac = slea.readMapleAsciiString(); diff --git a/src/net/server/handlers/login/PickCharHandler.java b/src/net/server/handlers/login/ViewAllCharSelectedHandler.java similarity index 90% rename from src/net/server/handlers/login/PickCharHandler.java rename to src/net/server/handlers/login/ViewAllCharSelectedHandler.java index 98a76aff19..bf8cf2c1d0 100644 --- a/src/net/server/handlers/login/PickCharHandler.java +++ b/src/net/server/handlers/login/ViewAllCharSelectedHandler.java @@ -31,7 +31,7 @@ import tools.MaplePacketCreator; import tools.Randomizer; import tools.data.input.SeekableLittleEndianAccessor; -public final class PickCharHandler extends AbstractMaplePacketHandler { +public final class ViewAllCharSelectedHandler extends AbstractMaplePacketHandler { @Override public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { @@ -39,7 +39,7 @@ public final class PickCharHandler extends AbstractMaplePacketHandler { slea.readInt(); // please don't let the client choose which world they should login Server server = Server.getInstance(); - if(!server.haveCharacterid(c.getAccID(), charId)) { + if(!server.haveCharacterEntry(c.getAccID(), charId)) { c.getSession().close(true); return; } @@ -58,7 +58,8 @@ public final class PickCharHandler extends AbstractMaplePacketHandler { } try { - c.setChannel(Randomizer.nextInt(c.getWorldServer().getChannels().size())); + int channel = Randomizer.rand(1, c.getWorldServer().getChannels().size()); + c.setChannel(channel); } catch (Exception e) { e.printStackTrace(); c.setChannel(1); diff --git a/src/net/server/handlers/login/ViewAllCharSelectedWithPicHandler.java b/src/net/server/handlers/login/ViewAllCharSelectedWithPicHandler.java index 6a62a3260e..0865a4bc70 100644 --- a/src/net/server/handlers/login/ViewAllCharSelectedWithPicHandler.java +++ b/src/net/server/handlers/login/ViewAllCharSelectedWithPicHandler.java @@ -21,13 +21,13 @@ public class ViewAllCharSelectedWithPicHandler extends AbstractMaplePacketHandle slea.readInt(); // please don't let the client choose which world they should login Server server = Server.getInstance(); - if(!server.haveCharacterid(c.getAccID(), charId)) { + if(!server.haveCharacterEntry(c.getAccID(), charId)) { c.getSession().close(true); return; } c.setWorld(server.getCharacterWorld(charId)); - int channel = Randomizer.rand(0, c.getWorldServer().getChannels().size()); + int channel = Randomizer.rand(1, c.getWorldServer().getChannels().size()); c.setChannel(channel); String macs = slea.readMapleAsciiString(); diff --git a/src/net/server/handlers/login/ViewCharHandler.java b/src/net/server/handlers/login/ViewCharHandler.java deleted file mode 100644 index 3014c606b6..0000000000 --- a/src/net/server/handlers/login/ViewCharHandler.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - This file is part of the OdinMS Maple Story Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation version 3 as published by - the Free Software Foundation. You may not use, modify or distribute - this program under any other version of the GNU Affero General Public - License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ -package net.server.handlers.login; - -import client.MapleCharacter; -import client.MapleClient; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import net.AbstractMaplePacketHandler; -import net.server.Server; -import tools.DatabaseConnection; -import tools.MaplePacketCreator; -import tools.data.input.SeekableLittleEndianAccessor; - -public final class ViewCharHandler extends AbstractMaplePacketHandler { - @Override - public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { - try { - short charsNum; - List worlds; - List chars; - - int wlen = Server.getInstance().getWorlds().size(); - - Connection con = DatabaseConnection.getConnection(); - try (PreparedStatement ps = con.prepareStatement("SELECT world, id FROM characters WHERE accountid = ?")) { - ps.setInt(1, c.getAccID()); - charsNum = 0; - worlds = new ArrayList<>(); - chars = new ArrayList<>(); - try (ResultSet rs = ps.executeQuery()) { - while (rs.next()) { - int cworld = rs.getByte("world"); - if(cworld >= wlen) continue; - - boolean inside = false; - for (int w : worlds) { - if (w == cworld) { - inside = true; - } - } - if (!inside) { - worlds.add(cworld); - } - MapleCharacter chr = MapleCharacter.loadCharFromDB(rs.getInt("id"), c, false); - chars.add(chr); - charsNum++; - } - } - } - int unk = charsNum + 3 - charsNum % 3; - c.announce(MaplePacketCreator.showAllCharacter(charsNum, unk)); - for (Iterator it = worlds.iterator(); it.hasNext();) { - int w = it.next(); - List chrsinworld = new ArrayList<>(); - for (MapleCharacter chr : chars) { - if (chr.getWorld() == w) { - chrsinworld.add(chr); - } - } - c.announce(MaplePacketCreator.showAllCharacterInfo(w, chrsinworld)); - } - - con.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/src/net/server/worker/CharacterAutosaverWorker.java b/src/net/server/worker/CharacterAutosaverWorker.java index 7f582d963e..a10934d4e8 100644 --- a/src/net/server/worker/CharacterAutosaverWorker.java +++ b/src/net/server/worker/CharacterAutosaverWorker.java @@ -36,7 +36,7 @@ public class CharacterAutosaverWorker extends BaseWorker implements Runnable { PlayerStorage ps = wserv.getPlayerStorage(); for(MapleCharacter chr: ps.getAllCharacters()) { if(chr != null && chr.isLoggedin()) { - chr.saveToDB(false); + chr.saveCharToDB(false); } } } diff --git a/src/net/server/worker/CharacterDiseaseWorker.java b/src/net/server/worker/CharacterDiseaseWorker.java index 8d222f639a..c9c5c2f7de 100644 --- a/src/net/server/worker/CharacterDiseaseWorker.java +++ b/src/net/server/worker/CharacterDiseaseWorker.java @@ -28,6 +28,9 @@ import net.server.Server; public class CharacterDiseaseWorker implements Runnable { @Override public void run() { - Server.getInstance().runAnnouncePlayerDiseasesSchedule(); + Server serv = Server.getInstance(); + + serv.updateCurrentTime(); + serv.runAnnouncePlayerDiseasesSchedule(); } } diff --git a/src/net/server/worker/WeddingReservationWorker.java b/src/net/server/worker/WeddingReservationWorker.java index cfa93fa193..8ee90890c4 100644 --- a/src/net/server/worker/WeddingReservationWorker.java +++ b/src/net/server/worker/WeddingReservationWorker.java @@ -1,5 +1,5 @@ /* - This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server + This file is part of the HeavenMS MapleStory Server Copyleft (L) 2017 RonanLana This program is free software: you can redistribute it and/or modify diff --git a/src/net/server/world/World.java b/src/net/server/world/World.java index 155f2366f7..35ba8dc474 100644 --- a/src/net/server/world/World.java +++ b/src/net/server/world/World.java @@ -35,6 +35,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; @@ -43,6 +44,8 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.SortedMap; +import java.util.TreeMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; import tools.locks.MonitoredReentrantLock; @@ -77,7 +80,7 @@ import tools.locks.MonitoredLockType; /** * * @author kevintjuh93 - * @author Ronan (thread-oriented world schedules) + * @author Ronan (thread-oriented world schedules, guild queue, marriages & party chars) */ public class World { @@ -94,10 +97,14 @@ public class World { private Map gsStore = new HashMap<>(); private PlayerStorage players = new PlayerStorage(); + private Map> accountChars = new HashMap<>(); + private Lock accountCharsLock = new MonitoredReentrantLock(MonitoredLockType.WORLD_CHARS, true); + private Set queuedGuilds = new HashSet<>(); private Map, Pair>> queuedMarriages = new HashMap<>(); private Map> marriageGuests = new HashMap<>(); + private Map partyChars = new HashMap<>(); private Map parties = new HashMap<>(); private AtomicInteger runningPartyId = new AtomicInteger(); private Lock partyLock = new MonitoredReentrantLock(MonitoredLockType.WORLD_PARTY, true); @@ -242,6 +249,87 @@ public class World { this.questrate = quest; } + public void loadAccountCharactersView(Integer accountId, List chars) { + SortedMap charsMap = new TreeMap<>(); + for(MapleCharacter chr : chars) { + charsMap.put(chr.getId(), chr); + } + + accountCharsLock.lock(); // accountCharsLock should be used after server's lgnWLock for compliance + try { + accountChars.put(accountId, charsMap); + } finally { + accountCharsLock.unlock(); + } + } + + public void registerAccountCharacterView(Integer accountId, MapleCharacter chr) { + accountCharsLock.lock(); + try { + accountChars.get(accountId).put(chr.getId(), chr); + } finally { + accountCharsLock.unlock(); + } + } + + public void unregisterAccountCharacterView(Integer accountId, Integer chrId) { + accountCharsLock.lock(); + try { + accountChars.get(accountId).remove(chrId); + } finally { + accountCharsLock.unlock(); + } + } + + private static List>> getSortedAccountCharacterView(Map> map) { + List>> list = new ArrayList<>(map.size()); + for(Entry> e : map.entrySet()) { + list.add(e); + } + + Collections.sort(list, new Comparator>>() { + @Override + public int compare(Entry> o1, Entry> o2) { + return o1.getKey() - o2.getKey(); + } + }); + + return list; + } + + public List getAllCharactersView() { // sorted by accountid, charid + List chrList = new LinkedList<>(); + Map> accChars; + + accountCharsLock.lock(); + try { + accChars = new HashMap<>(accountChars); + } finally { + accountCharsLock.unlock(); + } + + for (Entry> e : getSortedAccountCharacterView(accChars)) { + for (MapleCharacter chr : e.getValue().values()) { + chrList.add(chr); + } + } + + return chrList; + } + + public List getAccountCharactersView(Integer accountId) { + List chrList; + + accountCharsLock.lock(); + try { + chrList = new LinkedList<>(accountChars.get(accountId).values()); + } finally { + accountCharsLock.unlock(); + } + + return chrList; + } + public PlayerStorage getPlayerStorage() { return players; } @@ -511,6 +599,37 @@ public class World { System.out.println("Guest list: " + marriageGuests); } + private void registerCharacterParty(Integer chrid, Integer partyid) { + partyLock.lock(); + try { + partyChars.put(chrid, partyid); + } finally { + partyLock.unlock(); + } + } + + private void unregisterCharacterPartyInternal(Integer chrid) { + partyChars.remove(chrid); + } + + private void unregisterCharacterParty(Integer chrid) { + partyLock.lock(); + try { + unregisterCharacterPartyInternal(chrid); + } finally { + partyLock.unlock(); + } + } + + public Integer getCharacterPartyid(Integer chrid) { + partyLock.lock(); + try { + return partyChars.get(chrid); + } finally { + partyLock.unlock(); + } + } + public MapleParty createParty(MaplePartyCharacter chrfor) { int partyid = runningPartyId.getAndIncrement(); MapleParty party = new MapleParty(partyid, chrfor); @@ -518,6 +637,7 @@ public class World { partyLock.lock(); try { parties.put(party.getId(), party); + registerCharacterParty(chrfor.getId(), partyid); } finally { partyLock.unlock(); } @@ -534,7 +654,7 @@ public class World { } } - public MapleParty disbandParty(int partyid) { + private MapleParty disbandParty(int partyid) { partyLock.lock(); try { return parties.remove(partyid); @@ -542,9 +662,39 @@ public class World { partyLock.unlock(); } } - - public void updateParty(MapleParty party, PartyOperation operation, MaplePartyCharacter target) { - for (MaplePartyCharacter partychar : party.getMembers()) { + + private void updateCharacterParty(MapleParty party, PartyOperation operation, MaplePartyCharacter target, Collection partyMembers) { + switch (operation) { + case JOIN: + registerCharacterParty(target.getId(), party.getId()); + break; + + case LEAVE: + case EXPEL: + unregisterCharacterParty(target.getId()); + break; + + case DISBAND: + partyLock.lock(); + try { + for (MaplePartyCharacter partychar : partyMembers) { + unregisterCharacterPartyInternal(partychar.getId()); + } + } finally { + partyLock.unlock(); + } + break; + + default: + break; + } + } + + private void updateParty(MapleParty party, PartyOperation operation, MaplePartyCharacter target) { + Collection partyMembers = party.getMembers(); + updateCharacterParty(party, operation, target, partyMembers); + + for (MaplePartyCharacter partychar : partyMembers) { MapleCharacter chr = getPlayerStorage().getCharacterByName(partychar.getName()); if (chr != null) { if (operation == PartyOperation.DISBAND) { diff --git a/src/scripting/AbstractPlayerInteraction.java b/src/scripting/AbstractPlayerInteraction.java index 1f5e5e8358..3f2451c138 100644 --- a/src/scripting/AbstractPlayerInteraction.java +++ b/src/scripting/AbstractPlayerInteraction.java @@ -495,7 +495,6 @@ public class AbstractPlayerInteraction { } if (ItemConstants.getInventoryType(id) == MapleInventoryType.EQUIP) { if (randomStats) { - item = ii.randomizeStats((Equip) item); MapleInventoryManipulator.addFromDrop(c, ii.randomizeStats((Equip) item), false, petId); } else { MapleInventoryManipulator.addFromDrop(c, (Equip) item, false, petId); diff --git a/src/scripting/event/EventInstanceManager.java b/src/scripting/event/EventInstanceManager.java index 7350052c56..5847d3c1f6 100644 --- a/src/scripting/event/EventInstanceManager.java +++ b/src/scripting/event/EventInstanceManager.java @@ -558,6 +558,19 @@ public class EventInstanceManager { } } + public void reviveMonster(MapleMonster mob) { + try { + sL.lock(); + try { + em.getIv().invokeFunction("monsterRevive", this, mob); + } finally { + sL.unlock(); + } + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + } + public boolean revivePlayer(MapleCharacter chr) { try { Object b; @@ -577,7 +590,7 @@ public class EventInstanceManager { } return true; } - + public void playerDisconnected(MapleCharacter chr) { try { sL.lock(); diff --git a/src/scripting/npc/NPCConversationManager.java b/src/scripting/npc/NPCConversationManager.java index 96decc56e3..721a59c0fb 100644 --- a/src/scripting/npc/NPCConversationManager.java +++ b/src/scripting/npc/NPCConversationManager.java @@ -317,7 +317,7 @@ public class NPCConversationManager extends AbstractPlayerInteraction { public boolean canSpawnPlayerNpc(int mapid) { MapleCharacter chr = getPlayer(); - return !ServerConstants.PLAYERNPC_AUTODEPLOY && chr.getLevel() >= chr.getMaxClassLevel() && MaplePlayerNPC.canSpawnPlayerNpc(chr.getName(), mapid); + return !ServerConstants.PLAYERNPC_AUTODEPLOY && chr.getLevel() >= chr.getMaxClassLevel() && !chr.isGM() && MaplePlayerNPC.canSpawnPlayerNpc(chr.getName(), mapid); } public MaplePlayerNPC getPlayerNPCByScriptid(int scriptId) { diff --git a/src/server/TimerManager.java b/src/server/TimerManager.java index 825a7f22d7..3723da4d8f 100644 --- a/src/server/TimerManager.java +++ b/src/server/TimerManager.java @@ -27,6 +27,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import net.server.Server; import javax.management.MBeanServer; import javax.management.ObjectName; import tools.FilePrinter; @@ -78,7 +79,9 @@ public class TimerManager implements TimerManagerMBean { public Runnable purge() {//Yay? return new Runnable() { + @Override public void run() { + Server.getInstance().forceUpdateCurrentTime(); ses.purge(); } }; diff --git a/src/server/life/MapleMonster.java b/src/server/life/MapleMonster.java index 0898a15026..ffe783a6c7 100644 --- a/src/server/life/MapleMonster.java +++ b/src/server/life/MapleMonster.java @@ -56,9 +56,12 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Lock; import tools.locks.MonitoredReentrantLock; +import net.server.Server; import net.server.channel.Channel; +import net.server.world.World; import net.server.world.MapleParty; import net.server.world.MaplePartyCharacter; +import scripting.event.EventInstanceManager; import server.TimerManager; import server.life.MapleLifeFactory.BanishInfo; import server.maps.MapleMap; @@ -128,6 +131,10 @@ public class MapleMonster extends AbstractLoadedMapleLife { this.dropsDisabled = true; } + public void enableDrops() { + this.dropsDisabled = false; + } + public boolean dropsDisabled() { return dropsDisabled; } @@ -233,7 +240,7 @@ public class MapleMonster extends AbstractLoadedMapleLife { public boolean applyAnimationIfRoaming(int attackPos, int skillPos) { // roam: not casting attack or skill animations if(!animationLock.tryLock()) return false; - + try { long animationTime; @@ -394,12 +401,13 @@ public class MapleMonster extends AbstractLoadedMapleLife { } } - public void distributeExperience(int killerId) { + private void distributeExperience(int killerId) { if (isAlive()) { return; } - int minThresholdLevel = calcThresholdLevel(this.getMap().getEventInstance() != null); + EventInstanceManager eim = getMap().getEventInstance(); + int minThresholdLevel = calcThresholdLevel(eim != null); int exp = getExp(); long totalHealth = maxHpPlusHeal.get(); Map expDist = new HashMap<>(); @@ -412,12 +420,19 @@ public class MapleMonster extends AbstractLoadedMapleLife { expDist.put(damage.getKey(), exp8perHp * damage.getValue().get()); } - Collection chrs = map.getCharacters(); Set underleveled = new HashSet<>(); - for (MapleCharacter mc : chrs) { - if (expDist.containsKey(mc.getId())) { + Collection mapChrs = map.getCharacters(); + for (MapleCharacter mc : mapChrs) { + Float mcExp = expDist.remove(mc.getId()); + if (mcExp != null) { boolean isKiller = (mc.getId() == killerId); - float xp = expDist.get(mc.getId()); + if (isKiller) { + if (eim != null) { + eim.monsterKilled(mc, this); + } + } + + float xp = mcExp; if (isKiller) { xp += exp2; } @@ -438,6 +453,24 @@ public class MapleMonster extends AbstractLoadedMapleLife { } } + if(!expDist.isEmpty()) { // locate on world server the partyid of the missing characters + World wserv = Server.getInstance().getWorld(map.getWorld()); + + for (Entry ed : expDist.entrySet()) { + boolean isKiller = (ed.getKey() == killerId); + float xp = ed.getValue(); + if (isKiller) { + xp += exp2; + } + + Integer pID = wserv.getCharacterPartyid(ed.getKey()); + if (pID != null) { + float pXP = xp + (partyExp.containsKey(pID) ? partyExp.get(pID) : 0); + partyExp.put(pID, pXP); + } + } + } + for (Entry party : partyExp.entrySet()) { distributeExperienceToParty(party.getKey(), party.getValue(), killerId, underleveled, minThresholdLevel); } @@ -447,13 +480,7 @@ public class MapleMonster extends AbstractLoadedMapleLife { } } - public void giveExpToCharacter(MapleCharacter attacker, float exp, boolean isKiller, int numExpSharers) { - if (isKiller) { - if (getMap().getEventInstance() != null) { - getMap().getEventInstance().monsterKilled(attacker, this); - } - } - + private void giveExpToCharacter(MapleCharacter attacker, float exp, boolean isKiller, int numExpSharers) { //PARTY BONUS: 2p -> +2% , 3p -> +4% , 4p -> +6% , 5p -> +8% , 6p -> +10% final float partyModifier = numExpSharers <= 1 ? 0.0f : 0.02f * (numExpSharers - 1); @@ -528,6 +555,8 @@ public class MapleMonster extends AbstractLoadedMapleLife { } if(toSpawn.size() > 0) { + final EventInstanceManager eim = this.getMap().getEventInstance(); + TimerManager.getInstance().schedule(new Runnable() { @Override public void run() { @@ -564,6 +593,10 @@ public class MapleMonster extends AbstractLoadedMapleLife { for(int i = 8810017; i >= 8810010; i--) reviveMap.killMonster(reviveMap.getMonsterById(i), killer, true); } + + if(eim != null) { + eim.reviveMonster(mob); + } } } }, getAnimationTime("die1")); @@ -599,11 +632,12 @@ public class MapleMonster extends AbstractLoadedMapleLife { dispatchUpdateQuestMobCount(); } - if (getMap().getEventInstance() != null) { + EventInstanceManager eim = getMap().getEventInstance(); + if (eim != null) { if (!this.getStats().isFriendly()) { - getMap().getEventInstance().monsterKilled(this, hasKiller); + eim.monsterKilled(this, hasKiller); } else { - getMap().getEventInstance().friendlyKilled(this, hasKiller); + eim.friendlyKilled(this, hasKiller); } } diff --git a/src/server/life/MaplePlayerNPC.java b/src/server/life/MaplePlayerNPC.java index e32e71ba7a..45c654eda8 100644 --- a/src/server/life/MaplePlayerNPC.java +++ b/src/server/life/MaplePlayerNPC.java @@ -403,11 +403,9 @@ public class MaplePlayerNPC extends AbstractMapleMapObject { private static MaplePlayerNPC createPlayerNPCInternal(MapleMap map, Point pos, MapleCharacter chr) { int mapId = map.getId(); - /* if(!canSpawnPlayerNpc(chr.getName(), mapId)) { return null; } - */ byte branch = GameConstants.getHallOfFameBranch(chr.getJob(), mapId); @@ -613,39 +611,10 @@ public class MaplePlayerNPC extends AbstractMapleMapObject { } } - private static List loadCharacteridsFromDB(int world) { - List list = new LinkedList<>(); - - try { - Connection con = DatabaseConnection.getConnection(); - PreparedStatement ps = con.prepareStatement("SELECT id FROM characters WHERE world = ?"); - ps.setInt(1, world); - - ResultSet rs = ps.executeQuery(); - while(rs.next()) { - list.add(rs.getInt(1)); - } - - rs.close(); - ps.close(); - con.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - return list; - } - public static void multicastSpawnPlayerNPC(int mapid, int world) { - MapleClient mockClient = new MapleClient(null, null, null); - - for(Integer cid : loadCharacteridsFromDB(world)) { - try { - MapleCharacter mc = MapleCharacter.loadCharFromDB(cid, mockClient, false); - spawnPlayerNPC(mapid, mc); - } catch (SQLException sqle) { - sqle.printStackTrace(); - } + World wserv = Server.getInstance().getWorld(world); + for(MapleCharacter mc : wserv.getAllCharactersView()) { + spawnPlayerNPC(mapid, mc); } } diff --git a/src/server/life/MobSkill.java b/src/server/life/MobSkill.java index 91ef97293c..650f209416 100644 --- a/src/server/life/MobSkill.java +++ b/src/server/life/MobSkill.java @@ -154,7 +154,7 @@ public class MobSkill { } break; case 120: - disease = MapleDisease.SEAL; + disease = MapleDisease.SEAL; break; case 121: disease = MapleDisease.DARKNESS; @@ -309,7 +309,7 @@ public class MobSkill { if (lt != null && rb != null && skill) { int i = 0; for (MapleCharacter character : getPlayersInRange(monster, player)) { - if (!character.isActiveBuffedValue(2321005)) { + if (!character.isActiveBuffedValue(2321005)) { // holy shield if (disease.equals(MapleDisease.SEDUCE)) { if (i < 10) { character.giveDebuff(MapleDisease.SEDUCE, this); @@ -329,9 +329,7 @@ public class MobSkill { } private List getPlayersInRange(MapleMonster monster, MapleCharacter player) { - List players = new ArrayList(); - players.add(player); - return monster.getMap().getPlayersInRange(calculateBoundingBox(monster.getPosition(), monster.isFacingLeft()), players); + return monster.getMap().getPlayersInRange(calculateBoundingBox(monster.getPosition(), monster.isFacingLeft()), Collections.singletonList(player)); } public int getSkillId() { diff --git a/src/server/maps/MapleDoorObject.java b/src/server/maps/MapleDoorObject.java index 99fa6f0c62..750d60c0e4 100644 --- a/src/server/maps/MapleDoorObject.java +++ b/src/server/maps/MapleDoorObject.java @@ -19,11 +19,10 @@ */ package server.maps; -import client.MapleCharacter; import java.awt.Point; - -import tools.MaplePacketCreator; +import client.MapleCharacter; import client.MapleClient; +import tools.MaplePacketCreator; /** * @@ -49,10 +48,9 @@ public class MapleDoorObject extends AbstractMapleMapObject { toPos = toPosition; } - public void warp(final MapleCharacter chr, boolean toTown) { + public void warp(final MapleCharacter chr) { if (chr.getId() == ownerId || (chr.getParty() != null && chr.getParty().getMemberById(ownerId) != null)) { - if(chr.getParty() == null && (to.isLastDoorOwner(chr.getId()) || toTown)) chr.changeMap(to, toPos); - else chr.changeMap(to, to.findClosestPlayerSpawnpoint(toPos)); // weird issues happens with party, relocating players elsewhere.... + chr.changeMap(to, toPos); } else { chr.getClient().announce(MaplePacketCreator.blockedMessage(6)); chr.getClient().announce(MaplePacketCreator.enableActions()); diff --git a/src/server/maps/MaplePlayerShop.java b/src/server/maps/MaplePlayerShop.java index 8fd9c688d2..7ce092931b 100644 --- a/src/server/maps/MaplePlayerShop.java +++ b/src/server/maps/MaplePlayerShop.java @@ -38,7 +38,7 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; import tools.locks.MonitoredReentrantLock; -import net.SendOpcode; +import net.opcodes.SendOpcode; import server.MapleItemInformationProvider; import tools.MaplePacketCreator; import tools.Pair; diff --git a/src/tools/FilePrinter.java b/src/tools/FilePrinter.java index df0195d24d..e5d9e3875e 100644 --- a/src/tools/FilePrinter.java +++ b/src/tools/FilePrinter.java @@ -22,6 +22,7 @@ public class FilePrinter { SQL_EXCEPTION = "sqlexceptions.txt", PACKET_HANDLER = "PacketHandler/", PORTAL = "portals/", + PORTAL_STUCK = "portalblocks/", NPC = "npcs/", INVOCABLE = "invocable/", REACTOR = "reactors/", diff --git a/src/tools/MapleLogger.java b/src/tools/MapleLogger.java index d3cb594e92..d7f457ba72 100644 --- a/src/tools/MapleLogger.java +++ b/src/tools/MapleLogger.java @@ -23,7 +23,7 @@ package tools; import java.util.ArrayList; import java.util.List; -import net.RecvOpcode; +import net.opcodes.RecvOpcode; import client.MapleClient; /** diff --git a/src/tools/MaplePacketCreator.java b/src/tools/MaplePacketCreator.java index ca12f0e55b..11148ab768 100644 --- a/src/tools/MaplePacketCreator.java +++ b/src/tools/MaplePacketCreator.java @@ -35,7 +35,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import net.SendOpcode; +import net.opcodes.SendOpcode; import net.server.PlayerCoolDownValueHolder; import net.server.Server; import net.server.channel.Channel; @@ -152,9 +152,10 @@ public class MaplePacketCreator { mplew.writeInt(chr.getHair()); // hair for (int i = 0; i < 3; i++) { - if (chr.getPet(i) != null) //Checked GMS.. and your pets stay when going into the cash shop. + MaplePet pet = chr.getPet(i); + if (pet != null) //Checked GMS.. and your pets stay when going into the cash shop. { - mplew.writeLong(chr.getPet(i).getUniqueId()); + mplew.writeLong(pet.getUniqueId()); } else { mplew.writeLong(0); } @@ -328,7 +329,7 @@ public class MaplePacketCreator { mplew.writeInt(chr.getJobRank()); // job rank mplew.writeInt(chr.getJobRankMove()); // move (negative is downwards) } - + private static void addQuestInfo(final MaplePacketLittleEndianWriter mplew, MapleCharacter chr) { mplew.writeShort(chr.getStartedQuestsSize()); for (MapleQuestStatus q : chr.getStartedQuests()) { @@ -1035,11 +1036,29 @@ public class MaplePacketCreator { mplew.writeInt(to.getId()); mplew.write(spawnPoint); mplew.writeShort(chr.getHp()); - mplew.write(0); + mplew.writeBool(false); mplew.writeLong(getTime(System.currentTimeMillis())); + mplew.writeShort(0); return mplew.getPacket(); } - + + public static byte[] getWarpToMap(MapleMap to, int spawnPoint, Point spawnPosition, MapleCharacter chr) { + final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); + mplew.writeShort(SendOpcode.SET_FIELD.getValue()); + mplew.writeInt(chr.getClient().getChannel() - 1); + mplew.writeInt(0);//updated + mplew.write(0);//updated + mplew.writeInt(to.getId()); + mplew.write(spawnPoint); + mplew.writeShort(chr.getHp()); + mplew.writeBool(true); + mplew.writeInt(spawnPosition.x); // spawn position placement thanks to Arnah (Vertisy) + mplew.writeInt(spawnPosition.y); + mplew.writeLong(getTime(System.currentTimeMillis())); + mplew.writeShort(0); + return mplew.getPacket(); + } + /** * Gets a packet to spawn a portal. * @@ -4873,13 +4892,13 @@ public class MaplePacketCreator { public static byte[] showAllCharacter(int chars, int unk) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(11); mplew.writeShort(SendOpcode.VIEW_ALL_CHAR.getValue()); - mplew.write(1); + mplew.write(chars > 0 ? 1 : 5); // 2: already connected to server, 3 : unk error (view-all-characters), 5 : cannot find any mplew.writeInt(chars); mplew.writeInt(unk); return mplew.getPacket(); } - public static byte[] showAllCharacterInfo(int worldid, List chars) { + public static byte[] showAllCharacterInfo(int worldid, List chars, boolean usePic) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendOpcode.VIEW_ALL_CHAR.getValue()); mplew.write(0); @@ -4888,6 +4907,7 @@ public class MaplePacketCreator { for (MapleCharacter chr : chars) { addCharEntry(mplew, chr, true); } + mplew.write(usePic ? 1 : 2); return mplew.getPacket(); } diff --git a/src/tools/locks/MonitoredLockType.java b/src/tools/locks/MonitoredLockType.java index 78fa594622..6a7b8b980a 100644 --- a/src/tools/locks/MonitoredLockType.java +++ b/src/tools/locks/MonitoredLockType.java @@ -55,6 +55,7 @@ public enum MonitoredLockType { WORLD_PARTY, WORLD_OWL, WORLD_PETS, + WORLD_CHARS, WORLD_MOUNTS, WORLD_PSHOPS, WORLD_MERCHS, diff --git a/tools/MapleMobBookUpdate/lib/MonsterBook_updated.img.xml b/tools/MapleMobBookUpdate/lib/MonsterBook_updated.img.xml index dff7aa8e37..e81f16c253 100644 --- a/tools/MapleMobBookUpdate/lib/MonsterBook_updated.img.xml +++ b/tools/MapleMobBookUpdate/lib/MonsterBook_updated.img.xml @@ -2489,23 +2489,22 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -2856,19 +2855,18 @@ - - - - - - - - - - - - - + + + + + + + + + + + + @@ -2996,21 +2994,20 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + @@ -11913,14 +11910,13 @@ - - - - - - - - + + + + + + + @@ -11953,26 +11949,25 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + @@ -12743,9 +12738,8 @@ - - - + + @@ -12782,33 +12776,32 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -13044,19 +13037,18 @@ - - - - - - - - - - - - - + + + + + + + + + + + + @@ -13297,24 +13289,23 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -13752,10 +13743,9 @@ - - - - + + + @@ -14234,15 +14224,14 @@ - - - - - - - - - + + + + + + + + diff --git a/tools/MapleQuestItemFetcher/src/maplequestitemfetcher/MapleQuestItemFetcher.java b/tools/MapleQuestItemFetcher/src/maplequestitemfetcher/MapleQuestItemFetcher.java index 8302ee5a39..9b69103142 100644 --- a/tools/MapleQuestItemFetcher/src/maplequestitemfetcher/MapleQuestItemFetcher.java +++ b/tools/MapleQuestItemFetcher/src/maplequestitemfetcher/MapleQuestItemFetcher.java @@ -429,7 +429,7 @@ public class MapleQuestItemFetcher { printWriter.println(); } - static private List> getSortedMapEntries0(Map map) { + private static List> getSortedMapEntries0(Map map) { List> list = new ArrayList<>(map.size()); for(Entry e : map.entrySet()) { list.add(e); @@ -445,7 +445,7 @@ public class MapleQuestItemFetcher { return list; } - static private List> getSortedMapEntries1(Map map) { + private static List> getSortedMapEntries1(Map map) { List> list = new ArrayList<>(map.size()); for(Entry e : map.entrySet()) { list.add(e); @@ -461,7 +461,7 @@ public class MapleQuestItemFetcher { return list; } - static private List>> getSortedMapEntries2(Map> map) { + private static List>> getSortedMapEntries2(Map> map) { List>> list = new ArrayList<>(map.size()); for(Entry> e : map.entrySet()) { List il = new ArrayList<>(2); diff --git a/tools/MapleQuestlineFetcher/src/maplequestlinefetcher/MapleQuestlineFetcher.java b/tools/MapleQuestlineFetcher/src/maplequestlinefetcher/MapleQuestlineFetcher.java index 928d2a2b91..572a726350 100644 --- a/tools/MapleQuestlineFetcher/src/maplequestlinefetcher/MapleQuestlineFetcher.java +++ b/tools/MapleQuestlineFetcher/src/maplequestlinefetcher/MapleQuestlineFetcher.java @@ -380,7 +380,7 @@ public class MapleQuestlineFetcher { } /* - static private List>> getSortedMapEntries(Map> map) { + private static List>> getSortedMapEntries(Map> map) { List>> list = new ArrayList<>(map.size()); for(Map.Entry> e : map.entrySet()) { List il = new ArrayList<>(2); diff --git a/wz/Map.wz/Map/Map6/677000010.img.xml b/wz/Map.wz/Map/Map6/677000010.img.xml index f801de0394..57eda21771 100644 --- a/wz/Map.wz/Map/Map6/677000010.img.xml +++ b/wz/Map.wz/Map/Map6/677000010.img.xml @@ -1,1044 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/wz/Map.wz/Map/Map6/677000011.img.xml b/wz/Map.wz/Map/Map6/677000011.img.xml index 40508fb098..57d6e53403 100644 --- a/wz/Map.wz/Map/Map6/677000011.img.xml +++ b/wz/Map.wz/Map/Map6/677000011.img.xml @@ -1,3982 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/wz/Map.wz/Map/Map6/677000012.img.xml b/wz/Map.wz/Map/Map6/677000012.img.xml index feebe3cc8e..5c90d004b8 100644 --- a/wz/Map.wz/Map/Map6/677000012.img.xml +++ b/wz/Map.wz/Map/Map6/677000012.img.xml @@ -1,1492 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/wz/Quest.wz/Act.img.xml b/wz/Quest.wz/Act.img.xml index fd93b2cc11..0914bce47f 100644 --- a/wz/Quest.wz/Act.img.xml +++ b/wz/Quest.wz/Act.img.xml @@ -1,56026 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/wz/Quest.wz/QuestInfo.img.xml b/wz/Quest.wz/QuestInfo.img.xml index a6c91d3fef..a5cacbd618 100644 --- a/wz/Quest.wz/QuestInfo.img.xml +++ b/wz/Quest.wz/QuestInfo.img.xml @@ -1,2640 +1,254 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +"/> \ No newline at end of file diff --git a/wz/String.wz/MonsterBook.img.xml b/wz/String.wz/MonsterBook.img.xml index dff7aa8e37..e81f16c253 100644 --- a/wz/String.wz/MonsterBook.img.xml +++ b/wz/String.wz/MonsterBook.img.xml @@ -2489,23 +2489,22 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -2856,19 +2855,18 @@ - - - - - - - - - - - - - + + + + + + + + + + + + @@ -2996,21 +2994,20 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + @@ -11913,14 +11910,13 @@ - - - - - - - - + + + + + + + @@ -11953,26 +11949,25 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + @@ -12743,9 +12738,8 @@ - - - + + @@ -12782,33 +12776,32 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -13044,19 +13037,18 @@ - - - - - - - - - - - - - + + + + + + + + + + + + @@ -13297,24 +13289,23 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -13752,10 +13743,9 @@ - - - - + + + @@ -14234,15 +14224,14 @@ - - - - - - - - - + + + + + + + +