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 @@ - - - - - - - - - + + + + + + + +