diff --git a/README.md b/README.md
index 824c02c942..51ae40c1fb 100644
--- a/README.md
+++ b/README.md
@@ -36,7 +36,7 @@ Use that link ONLY AS AN ORIENTATION on where here things start to become ambigu
Firstly, install all the general tools required to run the server:
* WampServer2.0i.exe -> recipient of the server.
* hamachi.msi -> used for establishing a tunnelling route for the server/client communication.
-* mysql-workbench-gpl-5.2.39-win32 -> MySQL server component, will store the server's DB.
+* mysql-query-browser-1.1.20-win.msi -> MySQL server component, will store the server's DB.
Now install the Java 7 Development Kit:
* jdk-7u79-windows-x64.exe
diff --git a/build/built-jar.properties b/build/built-jar.properties
index 318aaf3acf..06a37cbd0d 100644
--- a/build/built-jar.properties
+++ b/build/built-jar.properties
@@ -1,4 +1,4 @@
-#Fri, 27 Oct 2017 11:16:00 -0200
+#Sat, 28 Oct 2017 23:16:56 -0200
C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2=
diff --git a/build/classes/client/MapleCharacter$1.class b/build/classes/client/MapleCharacter$1.class
index cc01b808ea..da5ee830d5 100644
Binary files a/build/classes/client/MapleCharacter$1.class and b/build/classes/client/MapleCharacter$1.class differ
diff --git a/build/classes/client/MapleCharacter$10.class b/build/classes/client/MapleCharacter$10.class
index c863f275b4..57ae677db0 100644
Binary files a/build/classes/client/MapleCharacter$10.class and b/build/classes/client/MapleCharacter$10.class differ
diff --git a/build/classes/client/MapleCharacter$11.class b/build/classes/client/MapleCharacter$11.class
index cb1803173a..54555bacb8 100644
Binary files a/build/classes/client/MapleCharacter$11.class and b/build/classes/client/MapleCharacter$11.class differ
diff --git a/build/classes/client/MapleCharacter$12.class b/build/classes/client/MapleCharacter$12.class
index 6a62238b19..7463c88d0d 100644
Binary files a/build/classes/client/MapleCharacter$12.class and b/build/classes/client/MapleCharacter$12.class differ
diff --git a/build/classes/client/MapleCharacter$13.class b/build/classes/client/MapleCharacter$13.class
index e33ffc3829..256b4edd77 100644
Binary files a/build/classes/client/MapleCharacter$13.class and b/build/classes/client/MapleCharacter$13.class differ
diff --git a/build/classes/client/MapleCharacter$14.class b/build/classes/client/MapleCharacter$14.class
index c7aad56429..4f3f3c8552 100644
Binary files a/build/classes/client/MapleCharacter$14.class and b/build/classes/client/MapleCharacter$14.class differ
diff --git a/build/classes/client/MapleCharacter$15.class b/build/classes/client/MapleCharacter$15.class
index c61e5e40b8..b44992588b 100644
Binary files a/build/classes/client/MapleCharacter$15.class and b/build/classes/client/MapleCharacter$15.class differ
diff --git a/build/classes/client/MapleCharacter$16.class b/build/classes/client/MapleCharacter$16.class
index 21fe50eaf2..84b1eff0c0 100644
Binary files a/build/classes/client/MapleCharacter$16.class and b/build/classes/client/MapleCharacter$16.class differ
diff --git a/build/classes/client/MapleCharacter$17.class b/build/classes/client/MapleCharacter$17.class
index 7cd4db1cea..84375f2f2f 100644
Binary files a/build/classes/client/MapleCharacter$17.class and b/build/classes/client/MapleCharacter$17.class differ
diff --git a/build/classes/client/MapleCharacter$18.class b/build/classes/client/MapleCharacter$18.class
index ec75f29df2..ff901e8fbc 100644
Binary files a/build/classes/client/MapleCharacter$18.class and b/build/classes/client/MapleCharacter$18.class differ
diff --git a/build/classes/client/MapleCharacter$19.class b/build/classes/client/MapleCharacter$19.class
index 12093f3624..4fc9d400f8 100644
Binary files a/build/classes/client/MapleCharacter$19.class and b/build/classes/client/MapleCharacter$19.class differ
diff --git a/build/classes/client/MapleCharacter$2.class b/build/classes/client/MapleCharacter$2.class
index 7e60a68ab3..73f924764d 100644
Binary files a/build/classes/client/MapleCharacter$2.class and b/build/classes/client/MapleCharacter$2.class differ
diff --git a/build/classes/client/MapleCharacter$3.class b/build/classes/client/MapleCharacter$3.class
index 3088112bcf..6e085c17af 100644
Binary files a/build/classes/client/MapleCharacter$3.class and b/build/classes/client/MapleCharacter$3.class differ
diff --git a/build/classes/client/MapleCharacter$4.class b/build/classes/client/MapleCharacter$4.class
index 509f602118..2d5be9fd72 100644
Binary files a/build/classes/client/MapleCharacter$4.class and b/build/classes/client/MapleCharacter$4.class differ
diff --git a/build/classes/client/MapleCharacter$5.class b/build/classes/client/MapleCharacter$5.class
index 3df962e462..d81759f696 100644
Binary files a/build/classes/client/MapleCharacter$5.class and b/build/classes/client/MapleCharacter$5.class differ
diff --git a/build/classes/client/MapleCharacter$6.class b/build/classes/client/MapleCharacter$6.class
index 9200095191..e094e91f35 100644
Binary files a/build/classes/client/MapleCharacter$6.class and b/build/classes/client/MapleCharacter$6.class differ
diff --git a/build/classes/client/MapleCharacter$7.class b/build/classes/client/MapleCharacter$7.class
index 3e3a6ae310..04993b21e7 100644
Binary files a/build/classes/client/MapleCharacter$7.class and b/build/classes/client/MapleCharacter$7.class differ
diff --git a/build/classes/client/MapleCharacter$8.class b/build/classes/client/MapleCharacter$8.class
index 821f360489..5b6bbb77a0 100644
Binary files a/build/classes/client/MapleCharacter$8.class and b/build/classes/client/MapleCharacter$8.class differ
diff --git a/build/classes/client/MapleCharacter$9.class b/build/classes/client/MapleCharacter$9.class
index daf352190e..14db0f1ff4 100644
Binary files a/build/classes/client/MapleCharacter$9.class and b/build/classes/client/MapleCharacter$9.class differ
diff --git a/build/classes/client/MapleCharacter$FameStatus.class b/build/classes/client/MapleCharacter$FameStatus.class
index f4cc6ebd1a..a8cc4a25f2 100644
Binary files a/build/classes/client/MapleCharacter$FameStatus.class and b/build/classes/client/MapleCharacter$FameStatus.class differ
diff --git a/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class b/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class
index a09cb2c936..1b6503f9b6 100644
Binary files a/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class and b/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class differ
diff --git a/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class b/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class
index d93fb450c2..ad1d0550fa 100644
Binary files a/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class and b/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class differ
diff --git a/build/classes/client/MapleCharacter$SkillEntry.class b/build/classes/client/MapleCharacter$SkillEntry.class
index 58d3283a9a..934a9752f1 100644
Binary files a/build/classes/client/MapleCharacter$SkillEntry.class and b/build/classes/client/MapleCharacter$SkillEntry.class differ
diff --git a/build/classes/client/MapleCharacter.class b/build/classes/client/MapleCharacter.class
index b9423ca39b..1a9d6c42f6 100644
Binary files a/build/classes/client/MapleCharacter.class and b/build/classes/client/MapleCharacter.class differ
diff --git a/build/classes/client/MapleClient$CharNameAndId.class b/build/classes/client/MapleClient$CharNameAndId.class
index b40fec8e7f..e81fcddf99 100644
Binary files a/build/classes/client/MapleClient$CharNameAndId.class and b/build/classes/client/MapleClient$CharNameAndId.class differ
diff --git a/build/classes/client/MapleClient.class b/build/classes/client/MapleClient.class
index 9497412bdd..f236964ec1 100644
Binary files a/build/classes/client/MapleClient.class and b/build/classes/client/MapleClient.class differ
diff --git a/build/classes/client/inventory/MapleInventory.class b/build/classes/client/inventory/MapleInventory.class
index 32e09704ad..0a3c10cd0c 100644
Binary files a/build/classes/client/inventory/MapleInventory.class and b/build/classes/client/inventory/MapleInventory.class differ
diff --git a/build/classes/net/PacketProcessor.class b/build/classes/net/PacketProcessor.class
index c10f5ec8c8..a71a51be8d 100644
Binary files a/build/classes/net/PacketProcessor.class and b/build/classes/net/PacketProcessor.class differ
diff --git a/build/classes/net/mina/MaplePacketEncoder.class b/build/classes/net/mina/MaplePacketEncoder.class
index bb60a586b7..49acdd9cc3 100644
Binary files a/build/classes/net/mina/MaplePacketEncoder.class and b/build/classes/net/mina/MaplePacketEncoder.class differ
diff --git a/build/classes/net/server/PlayerBuffStorage.class b/build/classes/net/server/PlayerBuffStorage.class
index 5fce7cb3b1..0f3e92831a 100644
Binary files a/build/classes/net/server/PlayerBuffStorage.class and b/build/classes/net/server/PlayerBuffStorage.class differ
diff --git a/build/classes/net/server/channel/Channel.class b/build/classes/net/server/channel/Channel.class
index 24a8b37ba6..0c96c96b18 100644
Binary files a/build/classes/net/server/channel/Channel.class and b/build/classes/net/server/channel/Channel.class differ
diff --git a/build/classes/net/server/channel/handlers/ChangeMapHandler.class b/build/classes/net/server/channel/handlers/ChangeMapHandler.class
index 6504079bfc..7b030ddd7f 100644
Binary files a/build/classes/net/server/channel/handlers/ChangeMapHandler.class and b/build/classes/net/server/channel/handlers/ChangeMapHandler.class differ
diff --git a/build/classes/net/server/channel/handlers/ChangeMapSpecialHandler.class b/build/classes/net/server/channel/handlers/ChangeMapSpecialHandler.class
index d56428d5c0..6d00d2a0bf 100644
Binary files a/build/classes/net/server/channel/handlers/ChangeMapSpecialHandler.class and b/build/classes/net/server/channel/handlers/ChangeMapSpecialHandler.class differ
diff --git a/build/classes/net/server/channel/handlers/PlayerInteractionHandler.class b/build/classes/net/server/channel/handlers/PlayerInteractionHandler.class
index cf9e1443fd..215b628667 100644
Binary files a/build/classes/net/server/channel/handlers/PlayerInteractionHandler.class and b/build/classes/net/server/channel/handlers/PlayerInteractionHandler.class differ
diff --git a/build/classes/net/server/channel/handlers/StorageHandler.class b/build/classes/net/server/channel/handlers/StorageHandler.class
index 1bac9da359..d509bf2e86 100644
Binary files a/build/classes/net/server/channel/handlers/StorageHandler.class and b/build/classes/net/server/channel/handlers/StorageHandler.class differ
diff --git a/build/classes/net/server/world/MapleParty.class b/build/classes/net/server/world/MapleParty.class
index 6b8ee38c0d..830ae1e1ea 100644
Binary files a/build/classes/net/server/world/MapleParty.class and b/build/classes/net/server/world/MapleParty.class differ
diff --git a/build/classes/net/server/world/World$1.class b/build/classes/net/server/world/World$1.class
index 8fb6c46f5b..6608afc102 100644
Binary files a/build/classes/net/server/world/World$1.class and b/build/classes/net/server/world/World$1.class differ
diff --git a/build/classes/net/server/world/World.class b/build/classes/net/server/world/World.class
index d2bf7bd67d..277c1203fa 100644
Binary files a/build/classes/net/server/world/World.class and b/build/classes/net/server/world/World.class differ
diff --git a/build/classes/scripting/event/EventInstanceManager$1.class b/build/classes/scripting/event/EventInstanceManager$1.class
index b58abca907..13a5b0a21e 100644
Binary files a/build/classes/scripting/event/EventInstanceManager$1.class and b/build/classes/scripting/event/EventInstanceManager$1.class differ
diff --git a/build/classes/scripting/event/EventInstanceManager$2.class b/build/classes/scripting/event/EventInstanceManager$2.class
index 378130a188..83c24e623e 100644
Binary files a/build/classes/scripting/event/EventInstanceManager$2.class and b/build/classes/scripting/event/EventInstanceManager$2.class differ
diff --git a/build/classes/scripting/event/EventInstanceManager$3.class b/build/classes/scripting/event/EventInstanceManager$3.class
index 9004e14ac8..8fbd0a5d0e 100644
Binary files a/build/classes/scripting/event/EventInstanceManager$3.class and b/build/classes/scripting/event/EventInstanceManager$3.class differ
diff --git a/build/classes/scripting/event/EventInstanceManager.class b/build/classes/scripting/event/EventInstanceManager.class
index 3527871339..5890396b50 100644
Binary files a/build/classes/scripting/event/EventInstanceManager.class and b/build/classes/scripting/event/EventInstanceManager.class differ
diff --git a/build/classes/scripting/event/EventManager$EventManagerWorker.class b/build/classes/scripting/event/EventManager$EventManagerWorker.class
index 26068b494d..6151673105 100644
Binary files a/build/classes/scripting/event/EventManager$EventManagerWorker.class and b/build/classes/scripting/event/EventManager$EventManagerWorker.class differ
diff --git a/build/classes/scripting/event/EventManager.class b/build/classes/scripting/event/EventManager.class
index 845ac25c2f..c1d54a992d 100644
Binary files a/build/classes/scripting/event/EventManager.class and b/build/classes/scripting/event/EventManager.class differ
diff --git a/build/classes/server/MaplePlayerShop.class b/build/classes/server/MaplePlayerShop.class
index fa5eb45d6e..4617a9106d 100644
Binary files a/build/classes/server/MaplePlayerShop.class and b/build/classes/server/MaplePlayerShop.class differ
diff --git a/build/classes/server/MapleStatEffect.class b/build/classes/server/MapleStatEffect.class
index 15a08a5385..7fe5b72591 100644
Binary files a/build/classes/server/MapleStatEffect.class and b/build/classes/server/MapleStatEffect.class differ
diff --git a/build/classes/server/MapleStorage$1.class b/build/classes/server/MapleStorage$1.class
index b5893bcb37..ecce5c2a42 100644
Binary files a/build/classes/server/MapleStorage$1.class and b/build/classes/server/MapleStorage$1.class differ
diff --git a/build/classes/server/MapleStorage.class b/build/classes/server/MapleStorage.class
index 195885c3b7..3883c2abe7 100644
Binary files a/build/classes/server/MapleStorage.class and b/build/classes/server/MapleStorage.class differ
diff --git a/build/classes/server/events/BalrogPQ$1.class b/build/classes/server/events/BalrogPQ$1.class
index 6206972d48..3eeca272bf 100644
Binary files a/build/classes/server/events/BalrogPQ$1.class and b/build/classes/server/events/BalrogPQ$1.class differ
diff --git a/build/classes/server/events/BalrogPQ$2.class b/build/classes/server/events/BalrogPQ$2.class
index 7e042e1514..1c46a8e771 100644
Binary files a/build/classes/server/events/BalrogPQ$2.class and b/build/classes/server/events/BalrogPQ$2.class differ
diff --git a/build/classes/server/events/BalrogPQ.class b/build/classes/server/events/BalrogPQ.class
index c6170c67f9..792ede3ea6 100644
Binary files a/build/classes/server/events/BalrogPQ.class and b/build/classes/server/events/BalrogPQ.class differ
diff --git a/build/classes/server/life/MapleMonster.class b/build/classes/server/life/MapleMonster.class
index eae7027ff4..d792d511ca 100644
Binary files a/build/classes/server/life/MapleMonster.class and b/build/classes/server/life/MapleMonster.class differ
diff --git a/build/classes/server/maps/MapleMap$ActivateItemReactor.class b/build/classes/server/maps/MapleMap$ActivateItemReactor.class
index aeb2759346..db9a70d0af 100644
Binary files a/build/classes/server/maps/MapleMap$ActivateItemReactor.class and b/build/classes/server/maps/MapleMap$ActivateItemReactor.class differ
diff --git a/build/classes/server/maps/MapleMiniDungeon.class b/build/classes/server/maps/MapleMiniDungeon.class
index 5bd0a17edf..c1dc94bfc6 100644
Binary files a/build/classes/server/maps/MapleMiniDungeon.class and b/build/classes/server/maps/MapleMiniDungeon.class differ
diff --git a/build/classes/tools/DatabaseConnection.class b/build/classes/tools/DatabaseConnection.class
index b5d376309d..8e28546511 100644
Binary files a/build/classes/tools/DatabaseConnection.class and b/build/classes/tools/DatabaseConnection.class differ
diff --git a/dist/MapleSolaxia.jar b/dist/MapleSolaxia.jar
index 7a59496cbf..5f125551bb 100644
Binary files a/dist/MapleSolaxia.jar and b/dist/MapleSolaxia.jar differ
diff --git a/docs/mychanges_ptbr.txt b/docs/mychanges_ptbr.txt
index d9e57f10a5..2b4d1e3111 100644
--- a/docs/mychanges_ptbr.txt
+++ b/docs/mychanges_ptbr.txt
@@ -614,4 +614,13 @@ Corrigido alguns problemas com as configs de inicializa
Corrigido bug com inicialização de NPC scripts podendo desconectar o jogador se instaciado múltiplas vezes.
26 Outubro 2017,
-Adicionado feature de randomização dos stats ganhos de HP e MP. Stat ganho de MP leva na contabilização INT do jogador.
\ No newline at end of file
+Adicionado feature de randomização dos stats ganhos de HP e MP. Stat ganho de MP leva na contabilização INT do jogador.
+
+27 - 28 Outubro 2017,
+Alterado fairness de alguns locks do server para atender em fila requisições de acesso ao código atômico.
+Corrigido jogadores "pulando mapas" se estiverem jogando com Internet lenta e tentarem usar portais múltiplas vezes.
+Corrigido storage não liberando devidamente o jogador em casos onde o mesmo não possa executar uma transação por falta de nível 15.
+Corrigido sistema de buffs não computando buffs com valor zero não sendo apropriadamente ativados no jogador.
+
+29 Outubro 2017,
+Adicionado drop data para diversas versões de Fairy, Yetis e Pepes.
\ No newline at end of file
diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml
index 3287222d26..e01a05efb0 100644
--- a/nbproject/private/private.xml
+++ b/nbproject/private/private.xml
@@ -2,6 +2,8 @@
-
+
+ file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/quest/21001.js
+
diff --git a/scripts/npc/1202009.js b/scripts/npc/1202009.js
new file mode 100644
index 0000000000..f910d2f8e1
--- /dev/null
+++ b/scripts/npc/1202009.js
@@ -0,0 +1,11 @@
+var status = 0;
+
+function start() {
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection) {
+ cm.sendOk("Up ahead is the #rMirror Cave#k. Only the chosen ones have permission to access that place.");
+ cm.dispose();
+}
\ No newline at end of file
diff --git a/scripts/npc/1202010.js b/scripts/npc/1202010.js
new file mode 100644
index 0000000000..7045f6685c
--- /dev/null
+++ b/scripts/npc/1202010.js
@@ -0,0 +1,11 @@
+var status = 0;
+
+function start() {
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection) {
+ cm.sendOk("Behold, the distinguished brave heroes of Rien! Those stout hearts are who have been protecting our people since long ago, our valiant comrades.");
+ cm.dispose();
+}
\ No newline at end of file
diff --git a/scripts/npc/1204001.js b/scripts/npc/1204001.js
index d41d9b8507..461de680e3 100644
--- a/scripts/npc/1204001.js
+++ b/scripts/npc/1204001.js
@@ -12,7 +12,7 @@ function action(mode, type, selection) {
status--;
}
if (status == 0) {
- cm.sendNext("I'm Francis, the Puppeteer of the Black Wings. How dare you disturb my puppets... It really upsets me, but I''ll let it slide this time. If I catch you doing it again though, I swear in the name of the Black Mage, I will make you pay for it.", 9);
+ cm.sendNext("I'm Francis, the Puppeteer of the Black Wings. How dare you disturb my puppets... It really upsets me, but I'll let it slide this time. If I catch you doing it again though, I swear in the name of the Black Mage, I will make you pay for it.", 9);
} else if (status == 1) {
cm.sendNextPrev("#b(The Black Wings? Huh? Who are they? And how is all this related to the Black Mage? Hm, maybe you should report this info to Tru.)#k", 3);
} else if (status == 2) {
diff --git a/scripts/npc/1209001.js b/scripts/npc/1209001.js
new file mode 100644
index 0000000000..11522ad66c
--- /dev/null
+++ b/scripts/npc/1209001.js
@@ -0,0 +1,11 @@
+var status = 0;
+
+function start() {
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection) {
+ cm.sendOk("The #rBlack Mage#k's forces approaches here in an unstoppable pace... We have no other way than to flee this area now, leaving our home behind. Oh, the tragedy!");
+ cm.dispose();
+}
\ No newline at end of file
diff --git a/scripts/npc/1209002.js b/scripts/npc/1209002.js
new file mode 100644
index 0000000000..c3c8af2b31
--- /dev/null
+++ b/scripts/npc/1209002.js
@@ -0,0 +1,11 @@
+var status = 0;
+
+function start() {
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection) {
+ cm.sendOk("Please calm down, uncle. We are embarking to #bVictoria Island#k, we will be safe once we reach there. So, come on!");
+ cm.dispose();
+}
\ No newline at end of file
diff --git a/scripts/npc/1209003.js b/scripts/npc/1209003.js
new file mode 100644
index 0000000000..4ff1742bc9
--- /dev/null
+++ b/scripts/npc/1209003.js
@@ -0,0 +1,11 @@
+var status = 0;
+
+function start() {
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection) {
+ cm.sendOk("We are departing to #bVictoria Island#k briefly. I've heard the #rBlack Mage#k himself cannot take that place on his grasp yet, thanks to #bthe seal that has been casted on that area#k. We pray for their safety, but if fortune does not favor the Heroes, at least we will be safe once we reach the continent.");
+ cm.dispose();
+}
\ No newline at end of file
diff --git a/scripts/npc/1209004.js b/scripts/npc/1209004.js
new file mode 100644
index 0000000000..bdf41dbc34
--- /dev/null
+++ b/scripts/npc/1209004.js
@@ -0,0 +1,11 @@
+var status = 0;
+
+function start() {
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection) {
+ cm.sendOk("I hope for this travel to be a safe one, and that we get to live on a more peaceful place there... Hey, darling, let's go.");
+ cm.dispose();
+}
\ No newline at end of file
diff --git a/scripts/npc/1209005.js b/scripts/npc/1209005.js
new file mode 100644
index 0000000000..21e90a69e6
--- /dev/null
+++ b/scripts/npc/1209005.js
@@ -0,0 +1,11 @@
+var status = 0;
+
+function start() {
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection) {
+ cm.sendOk("Alright, embarking in...");
+ cm.dispose();
+}
\ No newline at end of file
diff --git a/scripts/portal/enterGym.js b/scripts/portal/enterGym.js
index 2ed8834665..9fb1036066 100644
--- a/scripts/portal/enterGym.js
+++ b/scripts/portal/enterGym.js
@@ -1,15 +1,19 @@
function enter(pi) {
if (pi.isQuestStarted(21701)) {
- pi.playPortalSound();
- pi.warp(914010000, 1);
+ pi.playPortalSound();
+ pi.warp(914010000, 1);
+ return true;
} else if (pi.isQuestStarted(21702)) {
- pi.playPortalSound();
- pi.warp(914010100, 1);
+ pi.playPortalSound();
+ pi.warp(914010100, 1);
+ return true;
} else if (pi.isQuestStarted(21703)) {
pi.playPortalSound();
pi.warp(914010200, 1);
+ return true;
} else {
- pi.playerMessage(5, "Only if you are recieving a lesson from Puo, you will be allowed to enter the Pengiun Training Ground.");
+ pi.playerMessage(5, "You will be allowed to enter the Penguin Training Ground only if you are receiving a lesson from Puo.");
+ return false;
}
}
\ No newline at end of file
diff --git a/scripts/quest/20011.js b/scripts/quest/20011.js
index d2badd1bec..1153de5c31 100644
--- a/scripts/quest/20011.js
+++ b/scripts/quest/20011.js
@@ -6,6 +6,11 @@
var status = -1;
function start(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -30,6 +35,11 @@ function start(mode, type, selection) {
}
function end(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -38,13 +48,13 @@ function end(mode, type, selection) {
if (status == 0) {
qm.sendNext("Ah, it seems like you've successfully hunted a #o100120#. Pretty simple, right? Regular Attacks may be easy to use, but they are pretty weak. Don't worry, though. #p1102006# will teach you how to use more powerful skills. Wait, let me give you a well-deserved quest reward before you go.");
} else if (status == 1) {
- qm.sendNextPrev("This equipment is for Noblesses. It's much cooler than what you're wearing right now, isn''t it? Follow the arrows to your left to meet my younger brother #b#p1102006##k. How about you change into your new Noblesse outfit before you go? \r\n\r\n#fUI/UIWindow.img/QuestIcon/4/0# \r\n#i1002869# #t1002869# - 1 \r\n#i1052177# #t1052177# - 1 \r\n\r\n#fUI/UIWindow.img/QuestIcon/8/0# 30 exp");
+ qm.sendNextPrev("This equipment is for Noblesses. It's much cooler than what you're wearing right now, isn't it? Follow the arrows to your left to meet my younger brother #b#p1102006##k. How about you change into your new Noblesse outfit before you go? \r\n\r\n#fUI/UIWindow.img/QuestIcon/4/0# \r\n#i1002869# #t1002869# - 1 \r\n#i1052177# #t1052177# - 1 \r\n\r\n#fUI/UIWindow.img/QuestIcon/8/0# 30 exp");
} else if (status == 2) {
- qm.gainItem(1002869, 1);
- qm.gainItem(1052177, 1);
- qm.forceCompleteQuest();
- qm.gainExp(30);
- qm.guideHint(6);
- qm.dispose();
+ qm.gainItem(1002869, 1);
+ qm.gainItem(1052177, 1);
+ qm.forceCompleteQuest();
+ qm.gainExp(30);
+ qm.guideHint(6);
+ qm.dispose();
}
}
\ No newline at end of file
diff --git a/scripts/quest/20012.js b/scripts/quest/20012.js
index eb12ce63b2..4fd2db2067 100644
--- a/scripts/quest/20012.js
+++ b/scripts/quest/20012.js
@@ -6,6 +6,11 @@
var status = -1;
function start(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -14,7 +19,7 @@ function start(mode, type, selection) {
qm.dispose();
return;
}
- status--;
+ status--;
}
if (status == 0) {
qm.sendNext("I've been waiting for you, #h0#. My name is #p1102006# and I'm the third brother you are going to meet. So, you've learned about using Regular Attacks, correct? Well, next you'll be learning about your #bSkills#k, which you will find very helpful in Maple World.");
@@ -30,17 +35,22 @@ function start(mode, type, selection) {
}
function end(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
status--;
}
if (status == 0) {
- qm.sendNext("You've successfully defeated the #o100121#s and brought me a #t4000483#. That's very impressive! #bYou earn 3 Skill Points every time you level up, after you officially become a knight, that is. Keep following the arrow to the left, and you''ll meet #b#p1102007##k, who will guide you through the next step.\r\n\r\n#fUI/UIWindow.img/QuestIcon/4/0# \r\n#fUI/UIWindow.img/QuestIcon/8/0# 40 exp");
+ qm.sendNext("You've successfully defeated the #o100121#s and brought me a #t4000483#. That's very impressive! #bYou earn 3 Skill Points every time you level up, after you officially become a knight, that is. Keep following the arrow to the left, and you'll meet #b#p1102007##k, who will guide you through the next step.\r\n\r\n#fUI/UIWindow.img/QuestIcon/4/0# \r\n#fUI/UIWindow.img/QuestIcon/8/0# 40 exp");
} else if (status == 1) {
- qm.gainItem(4000483, -1);
- qm.forceCompleteQuest();
- qm.gainExp(40);
- qm.dispose();
+ qm.gainItem(4000483, -1);
+ qm.forceCompleteQuest();
+ qm.gainExp(40);
+ qm.dispose();
}
}
\ No newline at end of file
diff --git a/scripts/quest/20013.js b/scripts/quest/20013.js
index 9c07a2da36..6efdb7a762 100644
--- a/scripts/quest/20013.js
+++ b/scripts/quest/20013.js
@@ -6,34 +6,44 @@
var status = -1;
function start(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
if (status == 2) {
- qm.sendNext("Hmm, was that too much to ask? Is it because you don''t know how to break Boxes? I'll tell you how if you accept my Quest. Let me know if you change your mind.");
+ qm.sendNext("Hmm, was that too much to ask? Is it because you don't know how to break Boxes? I'll tell you how if you accept my Quest. Let me know if you change your mind.");
qm.dispose();
return;
}
- status--;
+ status--;
}
if (status == 0) {
qm.sendNext("#b(*clang clang*)#k");
} else if (status == 1) {
- qm.sendNextPrev("Whoa! Hey! You scared me. I didn't know I had a visitor. You must be the Noblesse #p1102006# was talking about. Welcome! I''m #p1102007#, and my hobby is making #bChairs#k. I'm thinking about making you one as a welcome present.");
+ qm.sendNextPrev("Whoa! Hey! You scared me. I didn't know I had a visitor. You must be the Noblesse #p1102006# was talking about. Welcome! I'm #p1102007#, and my hobby is making #bChairs#k. I'm thinking about making you one as a welcome present.");
} else if (status == 2) {
- qm.sendNextPrev("But wait, I can't make you one because I don''t have enough materials. Could you find me the materials I need? Around this area, you will find a lot of Boxes with items inside. Could you bring me back a #t4032267# and a #t4032268# found inside those Boxes?");
+ qm.sendNextPrev("But wait, I can't make you one because I don't have enough materials. Could you find me the materials I need? Around this area, you will find a lot of Boxes with items inside. Could you bring me back a #t4032267# and a #t4032268# found inside those Boxes?");
} else if (status == 3) {
qm.sendNextPrev("Do you know how to get items from boxes? All you have to do is break the Boxes like you're attacking a monster. The difference is that you can attack monsters using your Skills, but you can #bonly use Regular Attacks to break Boxes#k.");
} else if (status == 4) {
qm.sendAcceptDecline("Please bring me 1 #b#t4032267##k and 1 #b#t4032268##k found inside those Boxes. I'll make you an awesome Chair as soon as I have what I need. I'll wait here!");
} else if (status == 5) {
- qm.forceStartQuest();
- qm.guideHint(9);
- qm.dispose();
+ qm.forceStartQuest();
+ qm.guideHint(9);
+ qm.dispose();
}
}
function end(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -44,16 +54,16 @@ function end(mode, type, selection) {
} else if (status == 1) {
qm.sendNextPrev("Here it is, a #t3010060#. What do you think? Nifty, huh? You can #bquickly recover your HP by sitting in this Chair#k. It will be stored in the #bSet-up#k window in your Inventory, so confirm that you've received the chair and head over to #b#p1102008##k. You'll see him if you keep following the arrow to the left. \r\n\r\n#fUI/UIWindow.img/QuestIcon/4/0# \r\n#i3010060# 1 #t3010060# \r\n#fUI/UIWindow.img/QuestIcon/8/0# 95 exp");
} else if (status == 2) {
- qm.gainItem(4032267, -1);
- qm.gainItem(4032268, -1);
- qm.gainItem(3010060, 1);
- qm.forceCompleteQuest();
- qm.forceCompleteQuest(20000);
- qm.forceCompleteQuest(20001);
- qm.forceCompleteQuest(20002);
- qm.forceCompleteQuest(20015);
- qm.gainExp(95);
- qm.guideHint(10);
- qm.dispose();
+ qm.gainItem(4032267, -1);
+ qm.gainItem(4032268, -1);
+ qm.gainItem(3010060, 1);
+ qm.forceCompleteQuest();
+ qm.forceCompleteQuest(20000);
+ qm.forceCompleteQuest(20001);
+ qm.forceCompleteQuest(20002);
+ qm.forceCompleteQuest(20015);
+ qm.gainExp(95);
+ qm.guideHint(10);
+ qm.dispose();
}
}
\ No newline at end of file
diff --git a/scripts/quest/20016.js b/scripts/quest/20016.js
index 8388d72410..770529ce08 100644
--- a/scripts/quest/20016.js
+++ b/scripts/quest/20016.js
@@ -6,6 +6,11 @@
var status = -1;
function start(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -14,7 +19,7 @@ function start(mode, type, selection) {
qm.dispose();
return;
}
- status--;
+ status--;
}
if (status == 0) {
qm.sendNext("Hello, #h0#. Welcome to #p1101000# Knights. My name is #p1101002# and I am currently serving as the young Empress's Tactician. We'd better get acquainted since we'll be seeing a lot of each other. Haha!");
@@ -29,23 +34,23 @@ function start(mode, type, selection) {
} else if (status == 5) {
qm.sendNextPrev("But that was ages ago and people today don't realize how scary the Black Mage is. We've all become spoiled by the peaceful Maple World we enjoy today and forgotten how chaotic and frightening Maple World once was. If we don't do something, the Black Mage will once again rule Maple World!");
} else if (status == 6) {
- qm.sendNextPrev("This is why the young Empress has decided to take matters into her own hands. She's forming a knighthood of brave Maplers to defeat the Black Mage once and for all. You know what you need to do, right? I''m sure you have an idea since you, yourself, signed up to be a Knight.");
+ qm.sendNextPrev("This is why the young Empress has decided to take matters into her own hands. She's forming a knighthood of brave Maplers to defeat the Black Mage once and for all. You know what you need to do, right? I'm sure you have an idea since you, yourself, signed up to be a Knight.");
} else if (status == 7) {
qm.sendNextPrev("We have to get stronger so we can defeat the Black Mage if he revives. Our primary goal is to prevent him from destroying Maple World, and you will play a prominent role in that.");
} else if (status == 8) {
qm.sendAcceptDecline("That concludes my explanation. Have I answered all your questions? \r\n\r\n#fUI/UIWindow.img/QuestIcon/4/0# \r\n#fUI/UIWindow.img/QuestIcon/8/0# 380 exp");
} else if (status == 9) {
- if (!qm.isQuestStarted(20016)) {
- qm.forceStartQuest();
- qm.gainExp(380);
- }
- qm.sendNext("I'm glad you're clear about our current situation, but you know, at your current level, you're not even strong enough to face the Black Mage's minions, let alone the Black Mage himself. Not even his minions' minions, as a matter of fact. How will you protect Maple World at your current level?");
+ if (!qm.isQuestStarted(20016)) {
+ qm.forceStartQuest();
+ qm.gainExp(380);
+ }
+ qm.sendNext("I'm glad you're clear about our current situation, but you know, at your current level, you're not even strong enough to face the Black Mage's minions, let alone the Black Mage himself. Not even his minions' minions, as a matter of fact. How will you protect Maple World at your current level?");
} else if (status == 10) {
qm.sendNextPrev("Although you've been accepted into the knighthood, you cannot be recognized as a knight yet. You are not an Official Knight because you're not even a Knight-in-Training. If you remain at your current level, you'll be nothing more than the handyman of #p1101000# Knights.");
} else if (status == 11) {
- qm.sendNextPrev("But no one starts as a strong Knight on day one. The Empress didn''t want someone strong. She wanted someone with courage whom she could develop into a strong Knight through rigorous training. So, you should first become a Knight-in-Training. We'll talk about your missions when you get to that point.");
+ qm.sendNextPrev("But no one starts as a strong Knight on day one. The Empress didn't want someone strong. She wanted someone with courage whom she could develop into a strong Knight through rigorous training. So, you should first become a Knight-in-Training. We'll talk about your missions when you get to that point.");
} else if (status == 12) {
- qm.sendPrev("Take the portal on the left to reach the Training Forest. There, you will find #p1102000#, the Training Instructor, who will teach you how to become stronger. I don''t want to find you wandering around aimlessly until you reach Lv. 10, you hear?");
+ qm.sendPrev("Take the portal on the left to reach the Training Forest. There, you will find #p1102000#, the Training Instructor, who will teach you how to become stronger. I don't want to find you wandering around aimlessly until you reach Lv. 10, you hear?");
qm.forceCompleteQuest();
qm.dispose();
}
diff --git a/scripts/quest/20017.js b/scripts/quest/20017.js
index cb5fafa9f8..5edd3a7b3e 100644
--- a/scripts/quest/20017.js
+++ b/scripts/quest/20017.js
@@ -6,6 +6,11 @@
var status = -1;
function start(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -14,12 +19,12 @@ function start(mode, type, selection) {
qm.dispose();
return;
}
- status--;
+ status--;
}
if (status == 0) {
- qm.sendNext("Hmm? #p1101002# sent you, huh? You must be the newbie that recently joined Cygnus Knights. Welcome, and nice to meet you! My name is #p1102000#. I''m the Training Instructor who trains all Noblesses like yourself. Of course, I'm not a human as you can tell.");
+ qm.sendNext("Hmm? #p1101002# sent you, huh? You must be the newbie that recently joined Cygnus Knights. Welcome, and nice to meet you! My name is #p1102000#. I'm the Training Instructor who trains all Noblesses like yourself. Of course, I'm not a human as you can tell.");
} else if (status == 1) {
- qm.sendNextPrev("We are called Piyos. You''ve seen #p1101001# who is at the Empress''s side all the time, haven't you? Piyos are of the same family as #p1101001#, but we belong to different types. Of course, you haven't seen any of us since we only live in Ereve. You'll get used to Piyos in no time.");
+ qm.sendNextPrev("We are called Piyos. You've seen #p1101001# who is at the Empress's side all the time, haven't you? Piyos are of the same family as #p1101001#, but we belong to different types. Of course, you haven't seen any of us since we only live in Ereve. You'll get used to Piyos in no time.");
} else if (status == 2) {
qm.sendNextPrev("Oh, and did you know that there are no monsters in Ereve? Not even a smidgeon of evil dare enter Ereve. But don't you worry. You'll be able to train with illusory monsters created by #p1101001# called Mimis.");
} else if (status == 3) {
diff --git a/scripts/quest/20700.js b/scripts/quest/20700.js
index e813374bec..b17bad420b 100644
--- a/scripts/quest/20700.js
+++ b/scripts/quest/20700.js
@@ -6,12 +6,17 @@
var status = -1;
function start(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
if (status == 1) {
qm.sendNext("When will you realize how weak you are... When you get yourself in trouble in Victoria Island?");
- qm.safeDispose();
+ qm.dispose();
return;
}
status--;
@@ -19,7 +24,7 @@ function start(mode, type, selection) {
if (status == 0) {
qm.sendNext("You have finally become a Knight-in-Training. I'd like to give you a mission right away, but you still look miles away from even being able to handle a task on your own. Are you sure you can even go to Victoria Island like this?");
} else if (status == 1) {
- qm.askAcceptDecline("It's up to you to head over to Victoria Island, but a Knight-in-Training that can't take care of one''s self in battles is likely to cause harm to the Empress''s impeccable reputation. As the Head Tactician of this island, I can't let that happen, period. I want you to keep training until the right time comes.");
+ qm.askAcceptDecline("It's up to you to head over to Victoria Island, but a Knight-in-Training that can't take care of one's self in battles is likely to cause harm to the Empress's impeccable reputation. As the Head Tactician of this island, I can't let that happen, period. I want you to keep training until the right time comes.");
} else if (status == 2) {
qm.forceCompleteQuest();
qm.sendNext("#p1102000#, the Training Instructor, will help you train into a serviceable knight. Once you reach Level 13, I'll assign you a mission or two. So until then, keep training.");
diff --git a/scripts/quest/21001.js b/scripts/quest/21001.js
index 6c1c632a82..e2f84504d6 100644
--- a/scripts/quest/21001.js
+++ b/scripts/quest/21001.js
@@ -48,36 +48,38 @@ function start(mode, type, selection) {
}
function end(mode, type, selection) {
- status++;
- if (mode != 1) {
- if (type == 1 && mode == 0) {
- qm.sendNext("What about the child? Please give me the child!");
- }
- qm.dispose();
- return;
- }
- if (status == 0)
- qm.sendYesNo("You made it back safely! What about the child?! Did you bring the child with you?!");
- else if (status == 1) {
- qm.gainItem(4001271, -1);
- qm.removeEquipFromSlot(-11);
- qm.forceCompleteQuest();
- qm.sendNext("Oh, what a relief. I'm so glad...", 9);
- } else if (status == 2)
- qm.sendNextPrev("Hurry and board the ship! We don't have much time!", 3);
- else if (status == 3)
- qm.sendNextPrev("We don't have any time to waste. The Black Mage's forces are getting closer and closer! We're doomed if we don't leave right right this moment!", 9);
- else if (status == 4)
- qm.sendNextPrev("Leave, now!", 3);
- else if (status == 5)
- qm.sendNextPrev("Aran, please! I know you want to stay and fight the Black Mage, but it's too late! Leave it to the others and come to Victoria Island with us!", 9);
- else if (status == 6)
- qm.sendNextPrev("No, I can't!", 3);
- else if (status == 7) {
- qm.sendNextPrev("Athena Pierce, why don't you leave for Victoria Island first? I promise I'll come for you later. I'll be alright. I must fight the Black Mage with the other heroes!", 3);
- } else if (status == 8) {
- qm.forceCompleteQuest();
- qm.warp(914090010); // Initialize Aran Tutorial Scenes
- qm.dispose();
- }
- }
\ No newline at end of file
+ status++;
+ if (mode != 1) {
+ if (type == 1 && mode == 0) {
+ qm.sendNext("What about the child? Please give me the child!");
+ }
+
+ qm.dispose();
+ return;
+ }
+
+ if (status == 0)
+ qm.sendYesNo("You made it back safely! What about the child?! Did you bring the child with you?!");
+ else if (status == 1) {
+ qm.sendNext("Oh, what a relief. I'm so glad...", 9);
+ } else if (status == 2)
+ qm.sendNextPrev("Hurry and board the ship! We don't have much time!", 3);
+ else if (status == 3)
+ qm.sendNextPrev("We don't have any time to waste. The Black Mage's forces are getting closer and closer! We're doomed if we don't leave right right this moment!", 9);
+ else if (status == 4)
+ qm.sendNextPrev("Leave, now!", 3);
+ else if (status == 5)
+ qm.sendNextPrev("Aran, please! I know you want to stay and fight the Black Mage, but it's too late! Leave it to the others and come to Victoria Island with us!", 9);
+ else if (status == 6)
+ qm.sendNextPrev("No, I can't!", 3);
+ else if (status == 7) {
+ qm.sendNextPrev("Athena Pierce, why don't you leave for Victoria Island first? I promise I'll come for you later. I'll be alright. I must fight the Black Mage with the other heroes!", 3);
+ } else if (status == 8) {
+ qm.gainItem(4001271, -1);
+ qm.removeEquipFromSlot(-11);
+ qm.forceCompleteQuest();
+
+ qm.warp(914090010); // Initialize Aran Tutorial Scenes
+ qm.dispose();
+ }
+}
\ No newline at end of file
diff --git a/scripts/quest/21013.js b/scripts/quest/21013.js
index bfe81c8a50..700a6d6afc 100644
--- a/scripts/quest/21013.js
+++ b/scripts/quest/21013.js
@@ -75,7 +75,7 @@ function end(mode, type, selection) {
qm.gainItem(3010062, 1);
qm.sendNextPrev("Here, a fully-assembled chair, just for you! I've always wanted to give you a chair as a gift, because I know a hero can occasionally use some good rest. Tee hee.", 9);
} else if (status == 2) {
- qm.sendNext("A hero is not invincible. A hero is human. I'm sure you will face challenges and even fatter at times. But you are a hero because you have what it takes to overcome any obstacles you may encounter.", 9);
+ qm.sendNext("A hero is not invincible. A hero is human. I'm sure you will face challenges and even falter at times. But you are a hero because you have what it takes to overcome any obstacles you may encounter.", 9);
} else if (status == 3) {
qm.guideHint(19);
qm.dispose();
diff --git a/scripts/quest/21100.js b/scripts/quest/21100.js
index e176ba666e..483bc4f160 100644
--- a/scripts/quest/21100.js
+++ b/scripts/quest/21100.js
@@ -10,7 +10,7 @@ function start(mode, type, selection) {
status++;
}
if (status == 0) {
- qm.sendNext("There isn't much record left of the heores that fought against the Black Mage. Even in the Book of Prophecy, the only information available is that there were five of them. There is nothing about who they were or what they looked like. Is there anything you remember? Anything at all?", 8);
+ qm.sendNext("There isn't much record left of the heroes that fought against the Black Mage. Even in the Book of Prophecy, the only information available is that there were five of them. There is nothing about who they were or what they looked like. Is there anything you remember? Anything at all?", 8);
} else if (status == 1) {
qm.sendNextPrev("I don't remember a thing...", 2);
} else if (status == 2) {
diff --git a/scripts/quest/21101.js b/scripts/quest/21101.js
index f533215526..c535686ce3 100644
--- a/scripts/quest/21101.js
+++ b/scripts/quest/21101.js
@@ -37,12 +37,12 @@ function start(mode, type, selection) {
qm.sendYesNo("#b(Are you certain that you were the hero that wielded the #p1201001#? Yes, you're sure. You better grab the #p1201001# really tightly. Surely it will react to you.)#k");
} else if (status == 1) {
if (qm.getPlayer().getJob().getId() == 2000) {
- if(!qm.canHold(1142129)) {
- cm.sendOk("Wow, your #bequip#k inventory is full. I need you to make at least 1 empty slot to complete this quest.");
- qm.dispose();
- return;
- }
- qm.gainItem(1142129, true);
+ if(!qm.canHold(1142129)) {
+ cm.sendOk("Wow, your #bequip#k inventory is full. I need you to make at least 1 empty slot to complete this quest.");
+ qm.dispose();
+ return;
+ }
+ qm.gainItem(1142129, true);
qm.completeQuest();
qm.changeJobById(2100);
qm.getPlayer().setStr(35);
@@ -51,8 +51,10 @@ function start(mode, type, selection) {
qm.getPlayer().setRemainingSp((qm.getPlayer().getLevel() - 10) * 3 + 1);
qm.getPlayer().setMaxHp(qm.getPlayer().getMaxHp() + 275);
qm.getPlayer().setMaxMp(qm.getPlayer().getMaxMp() + 15);
- qm.teachSkill(21000000, 0, 10, -1);
- qm.teachSkill(21001003, 0, 20, -1);
+
+ //qm.teachSkill(21000000, 0, 10, -1); //learned later...
+ //qm.teachSkill(21001003, 0, 20, -1); //learned later...
+
//qm.getPlayer().changeSkillLevel(SkillFactory.getSkill(20009000), 0, -1);
//qm.getPlayer().changeSkillLevel(SkillFactory.getSkill(20009000), 1, 0);
//qm.showInfo("You have acquired the Pig's Weakness skill.");
diff --git a/scripts/quest/21700.js b/scripts/quest/21700.js
index 259778c77d..4e4b8c233b 100644
--- a/scripts/quest/21700.js
+++ b/scripts/quest/21700.js
@@ -1,6 +1,11 @@
var status = -1;
function start(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -28,7 +33,7 @@ function start(mode, type, selection) {
qm.forceStartQuest();
}
} else if (status == 6) {
- qm.sendPrev("You'll find a Training Center if you exit to the #bleft#k. There, you''ll meet #b#p1202006##k. I'm a bit worried because I think he may be struggling with bouts of Alzheimer's, but he spent a long time researching skills to help you. I'm sure you'll learn a thing or two from him.");
+ qm.sendPrev("You'll find a Training Center if you exit to the #bleft#k. There, you'll meet #b#p1202006##k. I'm a bit worried because I think he may be struggling with bouts of Alzheimer's, but he spent a long time researching skills to help you. I'm sure you'll learn a thing or two from him.");
qm.dispose();
}
}
diff --git a/scripts/quest/21703.js b/scripts/quest/21703.js
index 732a46e0d0..f700d0c139 100644
--- a/scripts/quest/21703.js
+++ b/scripts/quest/21703.js
@@ -2,9 +2,12 @@
importPackage(Packages.client);
var status = -1;
-
-
function start(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -16,27 +19,32 @@ function start(mode, type, selection) {
status--;
}
if (status == 0) {
- qm.sendNext("Your abilities are really beginning to take shape. I am surprised that an old man like me was able to help you. I''m tearing up just thinking about how happy it makes me to have been of assistance to you. *Sniff sniff*");
+ qm.sendNext("Your abilities are really beginning to take shape. I am surprised that an old man like me was able to help you. I'm tearing up just thinking about how happy it makes me to have been of assistance to you. *Sniff sniff*");
} else if (status == 1) {
qm.sendNextPrev("#b(You didn't even train that long with him... Why is he crying?)#k", 2);
} else if (status == 2) {
- qm.sendNextPrev("Alright, here''s the third and the final stage of training. Your last opponent is... #r#o9300343#s#k! Do you know anything about #o1210100#s?");
+ qm.sendNextPrev("Alright, here's the third and the final stage of training. Your last opponent is... #r#o9300343#s#k! Do you know anything about #o1210100#s?");
} else if (status == 3) {
qm.sendNextPrev('Well, a little bit...', 2);
} else if (status == 4) {
- qm.sendNextPrev("They are natural warriors! They''re born with a voracious appetite for food. They devour any food that''s visible the moment they sweep by. Terrifying, isn''t it?");
+ qm.sendNextPrev("They are natural warriors! They're born with a voracious appetite for food. They devour any food that's visible the moment they sweep by. Terrifying, isn't it?");
} else if (status == 5) {
qm.sendNextPrev("#b(Is that really true?)#k", 2);
} else if (status == 6) {
qm.sendAcceptDecline("Okay, now... #bEnter the Training Center again#k, defeat #r30#k #o9300343#s, and show me what you're made of! You'll have to exert all your energy to defeat them! Go, go, go! Rise above me!");
} else if (status == 7) {
- qm.forceStartQuest();
- qm.sendOk("Now go and take on those monstrous #o9300343#s!");
- qm.dispose();
+ qm.forceStartQuest();
+ qm.sendOk("Now go and take on those monstrous #o9300343#s!");
+ qm.dispose();
}
}
function end(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -45,7 +53,7 @@ function end(mode, type, selection) {
qm.dispose();
return;
}
- status--;
+ status--;
}
if (status == 0) {
qm.sendNext("Ah, you've come back after defeating all 30 #o9300343#s. I knew you had it in you... Even though you have no memories and few abilities, I could see that you were different! How? Because you're carrying around a Polearm, obviously!");
diff --git a/scripts/quest/21704.js b/scripts/quest/21704.js
index 1a35cb86b4..5b2e09399f 100644
--- a/scripts/quest/21704.js
+++ b/scripts/quest/21704.js
@@ -1,6 +1,11 @@
var status = -1;
function start(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -8,7 +13,7 @@ function start(mode, type, selection) {
qm.dispose();
return;
}
- status--;
+ status--;
}
if (status == 0) {
qm.sendNext("How did the training go? The Penguin Teacher #p1202006# likes to exaggerate and it worried me knowing that he has bouts of Alzheimer's, but I'm sure he helped you. He's been studying the skills of heroes for a very long time.");
@@ -17,9 +22,9 @@ function start(mode, type, selection) {
} else if (status == 2) {
qm.sendAcceptDecline("That's great! Honestly, though, I think it has less to do with the method of #p1202006#'s training and more to do with your body remembering its old abilities. #bI'm sure your body will remember more skills as you continue to train#k! \r\n\r\n#fUI/UIWindow.img/QuestIcon/8/0# 500 exp");
} else if (status == 3) {
- qm.forceCompleteQuest();
- qm.gainExp(500);
- qm.dispose();
+ qm.forceCompleteQuest();
+ qm.gainExp(500);
+ qm.dispose();
}
}
diff --git a/scripts/quest/21712.js b/scripts/quest/21712.js
index 9402e9f2e7..28f43a1f02 100644
--- a/scripts/quest/21712.js
+++ b/scripts/quest/21712.js
@@ -1,6 +1,11 @@
var status = -1;
function start(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -19,7 +24,7 @@ function start(mode, type, selection) {
qm.forceStartQuest();
qm.sendNext("I wonder what triggered this in the first place. There is no way this puppet was naturally created, which means someone planned this. I should keep an eye on the #o1210102#s.", 9);
} else if (status == 3) {
- qm.sendPrev("#b(You were able to find out what caused the changes in the #o1210102#s. You should report to #p1002104# and deliver the information you''ve gathered.)#k", 2);
+ qm.sendPrev("#b(You were able to find out what caused the changes in the #o1210102#s. You should report to #p1002104# and deliver the information you've gathered.)#k", 2);
qm.dispose();
}
}
diff --git a/scripts/quest/21716.js b/scripts/quest/21716.js
index f764ed8b8b..c0b01f605e 100644
--- a/scripts/quest/21716.js
+++ b/scripts/quest/21716.js
@@ -1,11 +1,16 @@
var status = -1;
function start(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
if (status == 2) {
- qm.sendNext("What? I don''t think there are any suspects besides that kid. Please think again.");
+ qm.sendNext("What? I don't think there are any suspects besides that kid. Please think again.");
qm.dispose();
return;
}
@@ -19,9 +24,9 @@ function start(mode, type, selection) {
qm.sendAcceptDecline("A kid with a puppet? That seems very suspicious. I am sure that kid is the reason the Green Mushrooms have suddenly turned violent.");
} else if (status == 3) {
qm.forceStartQuest();
- qm.sendNext("How dare this kid wreak havoc in the South Forest. Who knows how long it will take to restore the forest... I''ll have to devote most of my time cleaning up the mess.", 2);
+ qm.sendNext("How dare this kid wreak havoc in the South Forest. Who knows how long it will take to restore the forest... I'll have to devote most of my time cleaning up the mess.", 2);
} else if (status == 4) {
- qm.sendPrev("#b(You were able to find out what caused the changes in the Green Mushrooms. You should report #p1002104# and deliver the information you''ve collected.)#k", 2);
+ qm.sendPrev("#b(You were able to find out what caused the changes in the Green Mushrooms. You should report #p1002104# and deliver the information you've collected.)#k", 2);
} else if (status == 5) {
qm.dispose();
}
diff --git a/scripts/quest/21719.js b/scripts/quest/21719.js
index dcd3074386..ae21781a97 100644
--- a/scripts/quest/21719.js
+++ b/scripts/quest/21719.js
@@ -1,6 +1,11 @@
var status = -1;
function start(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -11,15 +16,15 @@ function start(mode, type, selection) {
status--;
}
if (status == 0) {
- qm.sendNext("Aren''t you the one that used to be in #m101000000# until not too long ago? I finally found you! Do you know how long it took for me to finally find you?", 8);
+ qm.sendNext("Aren't you the one that used to be in #m101000000# until not too long ago? I finally found you! Do you know how long it took for me to finally find you?", 8);
} else if (status == 1) {
qm.sendNextPrev("Who are you?", 2);
} else if (status == 2) {
qm.sendAcceptDecline("Me? If you want to know, stop by my cave. I'll even send you an invitation. You'll be directly sent to my cave as soon as you accept. Look forward to seeing you there.");
} else if (status == 3) {
- qm.forceCompleteQuest();
- qm.warp(910510200, 0);
- qm.dispose();
+ qm.forceCompleteQuest();
+ qm.warp(910510200, 0);
+ qm.dispose();
}
}
diff --git a/scripts/quest/21720.js b/scripts/quest/21720.js
index 629d39d94d..fb183c5cf1 100644
--- a/scripts/quest/21720.js
+++ b/scripts/quest/21720.js
@@ -5,6 +5,11 @@ function start(mode, type, selection) {
}
function end(mode, type, selection) {
+ if(mode == -1 || mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -19,11 +24,11 @@ function end(mode, type, selection) {
} else if (status == 1) {
qm.sendNextPrev("#b(You tell her about the Puppeteer and the Black Wings, and about their mission.)#k", 2);
} else if (status == 2) {
- qm.sendNextPrev("I see... I didn''t know there was a group called the Black Wings... They must be fools if they''re trying to revive the Black Mage, knowing how dangerous he is.", 8);
+ qm.sendNextPrev("I see... I didn't know there was a group called the Black Wings... They must be fools if they're trying to revive the Black Mage, knowing how dangerous he is.", 8);
} else if (status == 3) {
- qm.sendNextPrev("That...that''s true...\r\r#b(She''s definitely not afraid to speak her mind.)#k", 2);
+ qm.sendNextPrev("That...that's true...\r\r#b(She's definitely not afraid to speak her mind.)#k", 2);
} else if (status == 4) {
- qm.sendNextPrev("The Book of Prophecy states that the hero will revive and fight against the Black Mage. I wasn''t sure if that was true, but this confirms that the Black Mage is still around.", 8);
+ qm.sendNextPrev("The Book of Prophecy states that the hero will revive and fight against the Black Mage. I wasn't sure if that was true, but this confirms that the Black Mage is still around.", 8);
} else if (status == 5) {
qm.sendNextPrev("Aren't you scared?", 2);
} else if (status == 6) {
@@ -34,14 +39,14 @@ function end(mode, type, selection) {
qm.teachSkill(21001003, qm.getPlayer().getSkillLevel(21001003), 20, -1);
qm.gainExp(3900 * qm.getPlayer().getExpRate());
}
- qm.showIntro("Effect/BasicEff.img/AranGetSkill");
- qm.sendNext('#b(You remembered the Polearm Booster skill!)#k', 2);
+ qm.showIntro("Effect/BasicEff.img/AranGetSkill");
+ qm.sendNext('#b(You remembered the Polearm Booster skill!)#k', 2);
} else if (status == 8) {
qm.sendNextPrev("This skill was found in an ancient incomprehensible script. I had a hunch it might be a skill you used in the past, and I think I was right. You're not as strong as you used to be, but you'll get there, in time.", 8);
} else if (status == 9) {
- qm.sendNextPrev("You are steadily becoming more powerful, and I''ll be here to keep motivating you. You have nothing to be afraid of. You will not lose the battle. You didn''t emerge from ice only to lose to the Black Mage, did you? This time, you''ll finish him, once and for all!", 8);
+ qm.sendNextPrev("You are steadily becoming more powerful, and I'll be here to keep motivating you. You have nothing to be afraid of. You will not lose the battle. You didn't emerge from ice only to lose to the Black Mage, did you? This time, you'll finish him, once and for all!", 8);
} else if (status == 10) {
- qm.sendPrev("To do so, there''s only one thing you can do. Train, train, train. Head to Victoria Island and continue training. Let''s make sure you become so powerful that the Black Mage doesn''t stand a chance!", 8);
+ qm.sendPrev("To do so, there's only one thing you can do. Train, train, train. Head to Victoria Island and continue training. Let's make sure you become so powerful that the Black Mage doesn't stand a chance!", 8);
} else if (status == 11) {
qm.dispose();
}
diff --git a/scripts/quest/3360.js b/scripts/quest/3360.js
index b967ba6a21..78a8943ba1 100644
--- a/scripts/quest/3360.js
+++ b/scripts/quest/3360.js
@@ -29,6 +29,11 @@ function start(mode, type, selection) {
if (mode == -1) {
qm.dispose();
} else {
+ if(mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
if (mode == 1) {
status++;
} else {
@@ -43,7 +48,7 @@ function start(mode, type, selection) {
qm.sendAcceptDecline("All right, now, this key is very long and complex. I need you to memorize it very well. I won't say again, so you'd better write it down somewhere. Are you ready?");
} else if (status == 2) {
var pass = generateString();
- qm.sendOk("The key code is #b"+pass+"#k. Got that? Put the key into the door of the secret passage, and you will be able to walk around the passage freely.");
+ qm.sendOk("The key code is #b" + pass + "#k. Got that? Put the key into the door of the secret passage, and you will be able to walk around the passage freely.");
qm.forceStartQuest(pass);
qm.dispose();
}
diff --git a/sql/db_database.sql b/sql/db_database.sql
index 1872af372b..dac79e818d 100644
--- a/sql/db_database.sql
+++ b/sql/db_database.sql
@@ -16581,8 +16581,8 @@ INSERT INTO `reactordrops` (`reactordropid`, `reactorid`, `itemid`, `chance`, `q
(120, 1022000, 4031452, 1, -1),
(121, 2202003, 4001022, 1, -1),
(122, 2201001, 4001022, 1, -1),
-(123, 1402000, 4032309, 1, -1),
-(124, 1402000, 4032310, 1, -1),
+(123, 1402000, 4032309, 1, 21013),
+(124, 1402000, 4032310, 1, 21013),
(125, 1022001, 4032319, 7, -1),
(126, 1022002, 4001340, 1, 28167),
(127, 1202000, 4001366, 1, 28194),
diff --git a/sql/db_drops.sql b/sql/db_drops.sql
index 60adc497c2..2fa31ed7fe 100644
--- a/sql/db_drops.sql
+++ b/sql/db_drops.sql
@@ -19228,6 +19228,7 @@ USE `maplesolaxia`;
#insert things that should be present by now, but aren't yet.
INSERT IGNORE INTO temp_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`) VALUES
+(3000001, 0, 80, 120, 0, 400000),
(2386010, 8143000, 1, 1, 0, 10000),
(3230100, 4001004, 1, 1, 0, 5000),
(3000002, 4000068, 1, 1, 0, 40000),
@@ -20562,6 +20563,138 @@ USE `maplesolaxia`;
(9400533, 4031597, 1, 1, 0, 999999),
(9400534, 4031597, 1, 1, 0, 999999);
+ INSERT IGNORE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`) VALUES
+(9300341, 0, 12, 18, 0, 400000),
+(9300341, 1002019, 1, 1, 0, 1500),
+(9300341, 1060002, 1, 1, 0, 700),
+(9300341, 1072008, 1, 1, 0, 700),
+(9300341, 1072023, 1, 1, 0, 800),
+(9300341, 1082019, 1, 1, 0, 1000),
+(9300341, 1322007, 1, 1, 0, 700),
+(9300341, 1412001, 1, 1, 0, 700),
+(9300341, 1412002, 1, 1, 0, 700),
+(9300341, 1412012, 1, 1, 0, 700),
+(9300341, 1432000, 1, 1, 0, 700),
+(9300341, 1432001, 1, 1, 0, 500),
+(9300341, 1442029, 1, 1, 0, 700),
+(9300341, 1482000, 1, 1, 0, 500),
+(9300341, 2000000, 1, 1, 0, 20000),
+(9300341, 2010009, 1, 1, 0, 20000),
+(9300341, 2040505, 1, 1, 0, 750),
+(9300341, 2040600, 1, 1, 0, 750),
+(9300341, 2040602, 1, 1, 0, 300),
+(9300341, 2041018, 1, 1, 0, 300),
+(9300341, 2041043, 1, 1, 0, 750),
+(9300341, 2060000, 1, 1, 0, 30000),
+(9300341, 2061000, 1, 1, 0, 30000),
+(9300341, 2380005, 1, 1, 0, 8000),
+(9300341, 4000004, 1, 1, 0, 600000),
+(9300341, 4000010, 1, 1, 0, 600000),
+(9300341, 4010005, 1, 1, 0, 9000),
+(9300341, 4020005, 1, 1, 0, 9000),
+(9300341, 4030000, 1, 1, 0, 10000),
+(9300341, 4031273, 1, 1, 2104, 500000),
+(9300342, 4000012, 1, 1, 0, 600000),
+(9300342, 2000000, 1, 1, 0, 20000),
+(9300342, 2043102, 1, 1, 0, 300),
+(9300342, 2000003, 1, 1, 0, 20000),
+(9300342, 4020003, 1, 1, 0, 9000),
+(9300342, 1322000, 1, 1, 0, 700),
+(9300342, 2060000, 1, 1, 0, 30000),
+(9300342, 1041044, 1, 1, 0, 800),
+(9300342, 1061037, 1, 1, 0, 800),
+(9300342, 4010004, 1, 1, 0, 9000),
+(9300342, 1092008, 1, 1, 0, 700),
+(9300342, 1041017, 1, 1, 0, 800),
+(9300342, 1061012, 1, 1, 0, 800),
+(9300342, 1462002, 1, 1, 0, 500),
+(9300342, 2061000, 1, 1, 0, 30000),
+(9300342, 1041063, 1, 1, 0, 800),
+(9300342, 1061059, 1, 1, 0, 800),
+(9300342, 1452003, 1, 1, 0, 500),
+(9300342, 2048000, 1, 1, 0, 300),
+(9300342, 1002033, 1, 1, 0, 1500),
+(9300342, 1302007, 1, 1, 0, 700),
+(9300342, 4020002, 1, 1, 0, 9000),
+(9300342, 1032001, 1, 1, 0, 1000),
+(9300342, 1002010, 1, 1, 0, 1500),
+(9300342, 2000001, 1, 1, 0, 20000),
+(9300342, 1002143, 1, 1, 0, 1500),
+(9300342, 1432005, 1, 1, 0, 500),
+(9300342, 1412012, 1, 1, 0, 700),
+(9300342, 1072285, 1, 1, 0, 800),
+(9300342, 1482001, 1, 1, 0, 500),
+(9300342, 2380011, 1, 1, 0, 8000),
+(9300342, 0, 28, 42, 0, 400000),
+(9300342, 4031146, 1, 1, 2065, 1000000),
+(9300342, 2040902, 1, 1, 0, 750),
+(9300342, 2041020, 1, 1, 0, 750),
+(9300342, 2048001, 1, 1, 0, 750),
+(9300342, 2048003, 1, 1, 0, 750),
+(9300342, 2044701, 1, 1, 0, 750),
+(9300342, 4010005, 1, 1, 0, 7000),
+(9300342, 1302020, 1, 1, 0, 700),
+(9300342, 1302030, 1, 1, 0, 700),
+(9300342, 1442013, 1, 1, 0, 700),
+(9300342, 1412002, 1, 1, 0, 700),
+(9300342, 1382012, 1, 1, 0, 700),
+(9300342, 1041018, 1, 1, 0, 700),
+(9300342, 1452022, 1, 1, 0, 700),
+(9300342, 1060031, 1, 1, 0, 700),
+(9300342, 4001369, 1, 1, 28259, 10000),
+(9300343, 0, 14, 21, 0, 400000),
+(9300343, 1002008, 1, 1, 0, 1500),
+(9300343, 1002610, 1, 1, 0, 1500),
+(9300343, 1040034, 1, 1, 0, 800),
+(9300343, 1041012, 1, 1, 0, 700),
+(9300343, 1041014, 1, 1, 0, 800),
+(9300343, 1061028, 1, 1, 0, 800),
+(9300343, 1062002, 1, 1, 0, 800),
+(9300343, 1402018, 1, 1, 0, 700),
+(9300343, 1422000, 1, 1, 0, 700),
+(9300343, 1472000, 1, 1, 0, 500),
+(9300343, 2000000, 1, 1, 0, 20000),
+(9300343, 2010009, 1, 1, 0, 20000),
+(9300343, 2040702, 1, 1, 0, 300),
+(9300343, 2041021, 1, 1, 0, 300),
+(9300343, 2060000, 1, 1, 0, 30000),
+(9300343, 2061000, 1, 1, 0, 30000),
+(9300343, 2380006, 1, 1, 0, 8000),
+(9300343, 4000017, 1, 1, 0, 40000),
+(9300343, 4000021, 1, 1, 0, 50000),
+(9300343, 4010006, 1, 1, 0, 9000),
+(9300343, 4020006, 1, 1, 0, 9000),
+(9300343, 4030011, 1, 1, 0, 10000),
+(9300343, 4030012, 1, 1, 0, 10000),
+(9300343, 4031846, 1, 1, 2173, 50000),
+(9300343, 4032130, 1, 1, 20707, 10000),
+(9300343, 4032340, 1, 1, 21710, 200000);
+
+ -- Copying drops from some mobs to other versions of them
+ INSERT IGNORE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`)
+ SELECT 6300001, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance` FROM drop_data WHERE dropperid = 6300000;
+
+ INSERT IGNORE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`)
+ SELECT 6300002, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance` FROM drop_data WHERE dropperid = 6300000;
+
+ INSERT IGNORE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`)
+ SELECT 6400001, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance` FROM drop_data WHERE dropperid = 6400000;
+
+ INSERT IGNORE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`)
+ SELECT 6130102, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance` FROM drop_data WHERE dropperid = 6130103;
+
+ INSERT IGNORE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`)
+ SELECT 6230201, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance` FROM drop_data WHERE dropperid = 6230200;
+
+ INSERT IGNORE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`)
+ SELECT 3000002, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance` FROM drop_data WHERE dropperid = 3000001;
+
+ INSERT IGNORE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`)
+ SELECT 3000003, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance` FROM drop_data WHERE dropperid = 3000001;
+
+ INSERT IGNORE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`)
+ SELECT 3000004, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance` FROM drop_data WHERE dropperid = 3000001;
+
-- Thanks to DietStory dev team
-- There are two Jr. Boogies mob ids for some unknown reason. 3230301 had no drops, but 3230300 had all the correct drops.
-- Just copying the drops from the one with the correct drop data.
diff --git a/src/client/MapleCharacter.java b/src/client/MapleCharacter.java
index 5aff74185d..1b5ce9d560 100644
--- a/src/client/MapleCharacter.java
+++ b/src/client/MapleCharacter.java
@@ -208,6 +208,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
private String chalktext;
private String dataString;
private String search = null;
+ private AtomicBoolean mapTransitioning = new AtomicBoolean(true); // player client is currently trying to change maps or log in the game map
private AtomicBoolean awayFromWorld = new AtomicBoolean(true); // player is online, but on cash shop or mts
private AtomicInteger exp = new AtomicInteger();
private AtomicInteger gachaexp = new AtomicInteger();
@@ -268,9 +269,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
private ScheduledFuture> chairRecoveryTask = null;
private ScheduledFuture> pendantOfSpirit = null; //1122017
private List> timers = new ArrayList<>();
- private Lock chrLock = new ReentrantLock();
- private Lock effLock = new ReentrantLock();
- private Lock petLock = new ReentrantLock();
+ private Lock chrLock = new ReentrantLock(true);
+ private Lock effLock = new ReentrantLock(true);
+ private Lock petLock = new ReentrantLock(true);
private Lock prtLock = new ReentrantLock();
private Map> excluded = new LinkedHashMap<>();
private Set excludedItems = new LinkedHashSet<>();
@@ -1251,6 +1252,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
private void changeMapInternal(final MapleMap to, final Point pos, final byte[] warpPacket) {
if(!canWarpMap) return;
+ this.mapTransitioning.set(true);
+
this.unregisterChairBuff();
this.clearBanishPlayerData();
this.closePlayerInteractions();
@@ -1288,18 +1291,26 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
int temp = newWarpMap;
newWarpMap = -1;
changeMap(temp);
+ } else {
+ // if this event map has a gate already opened, render it
+ EventInstanceManager eim = getEventInstance();
+ if(eim != null) {
+ eim.recoverOpenedGate(this, map.getId());
+ }
+
+ // if this map has obstacle components moving, make it do so for this client
+ for(Entry e: map.getEnvironment().entrySet()) {
+ announce(MaplePacketCreator.environmentMove(e.getKey(), e.getValue()));
+ }
}
-
- // if this event map has a gate already opened, render it
- EventInstanceManager eim = getEventInstance();
- if(eim != null) {
- eim.recoverOpenedGate(this, map.getId());
- }
-
- // if this map has obstacle components moving, make it do so for this client
- for(Entry e: map.getEnvironment().entrySet()) {
- announce(MaplePacketCreator.environmentMove(e.getKey(), e.getValue()));
- }
+ }
+
+ public boolean isChangingMaps() {
+ return this.mapTransitioning.get();
+ }
+
+ public void setMapTransitionComplete() {
+ this.mapTransitioning.set(false);
}
public void changePage(int page) {
@@ -3322,7 +3333,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
addItemEffectHolder(sourceid, expirationtime, appliedStatups);
for (Entry statup : toDeploy.entrySet()) {
- if(statup.getValue().value != 0) effects.put(statup.getKey(), statup.getValue());
+ effects.put(statup.getKey(), statup.getValue());
}
} finally {
chrLock.unlock();
diff --git a/src/client/MapleClient.java b/src/client/MapleClient.java
index 4619404980..d7d1c4863e 100644
--- a/src/client/MapleClient.java
+++ b/src/client/MapleClient.java
@@ -111,7 +111,7 @@ public class MapleClient {
private int picattempt = 0;
private byte gender = -1;
private boolean disconnecting = false;
- private final Lock mutex = new ReentrantLock(true);
+ private final Lock lock = new ReentrantLock(true);
private int votePoints;
private int voteTime = -1;
private long lastNpcClick;
@@ -1150,8 +1150,12 @@ public class MapleClient {
}
}
- public final Lock getLock() {
- return mutex;
+ public void lockClient() {
+ lock.lock();
+ }
+
+ public void unlockClient() {
+ lock.unlock();
}
private static class CharNameAndId {
diff --git a/src/client/inventory/MapleInventory.java b/src/client/inventory/MapleInventory.java
index 2e106ce84a..cf0a925d24 100644
--- a/src/client/inventory/MapleInventory.java
+++ b/src/client/inventory/MapleInventory.java
@@ -50,7 +50,7 @@ public class MapleInventory implements Iterable- {
private byte slotLimit;
private MapleInventoryType type;
private boolean checked = false;
- private Lock lock = new ReentrantLock();
+ private Lock lock = new ReentrantLock(true);
public MapleInventory(MapleCharacter mc, MapleInventoryType type, byte slotLimit) {
this.owner = mc;
diff --git a/src/constants/ServerConstants.java b/src/constants/ServerConstants.java
index 5e32b4c608..125eda455e 100644
--- a/src/constants/ServerConstants.java
+++ b/src/constants/ServerConstants.java
@@ -71,7 +71,7 @@ public class ServerConstants {
public static final int PARTY_EXPERIENCE_MOD = 1; //Change for event stuff.
- //Miscellaneous COnfiguration
+ //Miscellaneous Configuration
public static final byte MIN_UNDERLEVEL_FOR_EXP_GAIN = 5; //Characters are unable to get EXP from a mob if their level are under this threshold, only if "USE_UNDERLEVELED_EXP_BLOCK" is enabled.
public static final byte MAX_MONITORED_BUFFSTATS = 5; //Limits accounting for "dormant" buff effects, that should take place when stronger stat buffs expires.
public static final int MAX_AP = 32767; //Max AP allotted on the auto-assigner.
diff --git a/src/net/PacketProcessor.java b/src/net/PacketProcessor.java
index d088e3cbd3..ace217ff1d 100644
--- a/src/net/PacketProcessor.java
+++ b/src/net/PacketProcessor.java
@@ -231,7 +231,7 @@ 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());don't use unused stuff
+ registerHandler(RecvOpcode.PLAYER_UPDATE, new PlayerUpdateHandler());
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/mina/MaplePacketEncoder.java b/src/net/mina/MaplePacketEncoder.java
index c14106b10c..e8c30a96e1 100644
--- a/src/net/mina/MaplePacketEncoder.java
+++ b/src/net/mina/MaplePacketEncoder.java
@@ -44,15 +44,14 @@ public class MaplePacketEncoder implements ProtocolEncoder {
final byte[] header = send_crypto.getPacketHeader(unencrypted.length);
MapleCustomEncryption.encryptData(unencrypted);
- final Lock mutex = client.getLock();
- mutex.lock();
+ client.lockClient();
try {
send_crypto.crypt(unencrypted);
System.arraycopy(header, 0, ret, 0, 4);
System.arraycopy(unencrypted, 0, ret, 4, unencrypted.length);
out.write(IoBuffer.wrap(ret));
} finally {
- mutex.unlock();
+ client.unlockClient();
}
// System.arraycopy(unencrypted, 0, ret, 4, unencrypted.length);
// out.write(ByteBuffer.wrap(ret));
diff --git a/src/net/server/PlayerBuffStorage.java b/src/net/server/PlayerBuffStorage.java
index 25d1a88230..1de55ec044 100644
--- a/src/net/server/PlayerBuffStorage.java
+++ b/src/net/server/PlayerBuffStorage.java
@@ -33,24 +33,24 @@ import java.util.concurrent.locks.ReentrantLock;
*/
public class PlayerBuffStorage {
private int id = (int) (Math.random() * 100);
- private final Lock mutex = new ReentrantLock();
- private Map> buffs = new HashMap>();
+ private final Lock lock = new ReentrantLock(true);
+ private Map> buffs = new HashMap<>();
public void addBuffsToStorage(int chrid, List toStore) {
- mutex.lock();
+ lock.lock();
try {
buffs.put(chrid, toStore);//Old one will be replaced if it's in here.
} finally {
- mutex.unlock();
+ lock.unlock();
}
}
public List getBuffsFromStorage(int chrid) {
- mutex.lock();
+ lock.lock();
try {
return buffs.remove(chrid);
} finally {
- mutex.unlock();
+ lock.unlock();
}
}
diff --git a/src/net/server/channel/Channel.java b/src/net/server/channel/Channel.java
index ed4a698baf..9b30d86820 100644
--- a/src/net/server/channel/Channel.java
+++ b/src/net/server/channel/Channel.java
@@ -90,11 +90,11 @@ public final class Channel {
private Map dojoParty = new HashMap<>();
private Map dungeons = new HashMap<>();
- private ReentrantReadWriteLock merchant_lock = new ReentrantReadWriteLock(true);
- private ReadLock merchRlock = merchant_lock.readLock();
- private WriteLock merchWlock = merchant_lock.writeLock();
+ private ReentrantReadWriteLock merchantLock = new ReentrantReadWriteLock(true);
+ private ReadLock merchRlock = merchantLock.readLock();
+ private WriteLock merchWlock = merchantLock.writeLock();
- private Lock lock = new ReentrantLock();
+ private Lock lock = new ReentrantLock(true);
public Channel(final int world, final int channel) {
this.world = world;
diff --git a/src/net/server/channel/handlers/ChangeMapHandler.java b/src/net/server/channel/handlers/ChangeMapHandler.java
index fd6ad8df39..576cbc573d 100644
--- a/src/net/server/channel/handlers/ChangeMapHandler.java
+++ b/src/net/server/channel/handlers/ChangeMapHandler.java
@@ -41,7 +41,8 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler {
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
MapleCharacter chr = c.getPlayer();
- if (chr.isBanned()) {
+ if (chr.isChangingMaps() || chr.isBanned()) {
+ c.announce(MaplePacketCreator.enableActions());
return;
}
if (chr.getTrade() != null) {
diff --git a/src/net/server/channel/handlers/ChangeMapSpecialHandler.java b/src/net/server/channel/handlers/ChangeMapSpecialHandler.java
index 15f1716255..292a6dd1b9 100644
--- a/src/net/server/channel/handlers/ChangeMapSpecialHandler.java
+++ b/src/net/server/channel/handlers/ChangeMapSpecialHandler.java
@@ -31,20 +31,21 @@ import tools.data.input.SeekableLittleEndianAccessor;
public final class ChangeMapSpecialHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
- slea.readByte();
- String startwp = slea.readMapleAsciiString();
- slea.readShort();
- MaplePortal portal = c.getPlayer().getMap().getPortal(startwp);
- if (portal == null || c.getPlayer().portalDelay() > System.currentTimeMillis() || c.getPlayer().getBlockedPortals().contains(portal.getScriptName())) {
- c.announce(MaplePacketCreator.enableActions());
- return;
- }
- if (c.getPlayer().isBanned()) {
- return;
- }
- if (c.getPlayer().getTrade() != null) {
- MapleTrade.cancelTrade(c.getPlayer());
- }
- portal.enterPortal(c);
+ slea.readByte();
+ String startwp = slea.readMapleAsciiString();
+ slea.readShort();
+ MaplePortal portal = c.getPlayer().getMap().getPortal(startwp);
+ if (portal == null || c.getPlayer().portalDelay() > System.currentTimeMillis() || c.getPlayer().getBlockedPortals().contains(portal.getScriptName())) {
+ c.announce(MaplePacketCreator.enableActions());
+ return;
+ }
+ if (c.getPlayer().isChangingMaps() || c.getPlayer().isBanned()) {
+ c.announce(MaplePacketCreator.enableActions());
+ return;
+ }
+ if (c.getPlayer().getTrade() != null) {
+ MapleTrade.cancelTrade(c.getPlayer());
+ }
+ portal.enterPortal(c);
}
}
diff --git a/src/net/server/channel/handlers/PlayerInteractionHandler.java b/src/net/server/channel/handlers/PlayerInteractionHandler.java
index d448b3e52f..c74da3eeae 100644
--- a/src/net/server/channel/handlers/PlayerInteractionHandler.java
+++ b/src/net/server/channel/handlers/PlayerInteractionHandler.java
@@ -229,11 +229,10 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
} else if (!merchant.isOpen()) {
c.announce(MaplePacketCreator.hiredMerchantMaintenanceMessage());
return;
- } else if (merchant.getFreeSlotThreadsafe() == -1) {
+ } else if (!merchant.addVisitor(c.getPlayer())) {
chr.dropMessage(1, "This shop has reached it's maximum capacity, please come by later.");
return;
} else {
- merchant.addVisitor(c.getPlayer());
c.announce(MaplePacketCreator.getHiredMerchant(c.getPlayer(), merchant, false));
}
chr.setHiredMerchant(merchant);
diff --git a/src/net/server/channel/handlers/PlayerUpdateHandler.java b/src/net/server/channel/handlers/PlayerUpdateHandler.java
new file mode 100644
index 0000000000..100dfb3352
--- /dev/null
+++ b/src/net/server/channel/handlers/PlayerUpdateHandler.java
@@ -0,0 +1,34 @@
+/*
+ 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.channel.handlers;
+
+import client.MapleClient;
+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();
+ }
+}
\ No newline at end of file
diff --git a/src/net/server/channel/handlers/StorageHandler.java b/src/net/server/channel/handlers/StorageHandler.java
index 3004392491..323ad9be8f 100644
--- a/src/net/server/channel/handlers/StorageHandler.java
+++ b/src/net/server/channel/handlers/StorageHandler.java
@@ -51,6 +51,7 @@ public final class StorageHandler extends AbstractMaplePacketHandler {
if (chr.getLevel() < 15){
chr.message("You may only use the storage once you have reached level 15.");
+ c.announce(MaplePacketCreator.enableActions());
return;
}
if (mode == 4) { // take out
@@ -103,6 +104,7 @@ public final class StorageHandler extends AbstractMaplePacketHandler {
return;
}
if (quantity < 1 || chr.getItemQuantity(itemId, false) < quantity) {
+ c.announce(MaplePacketCreator.enableActions());
return;
}
if (storage.isFull()) {
@@ -139,11 +141,13 @@ public final class StorageHandler extends AbstractMaplePacketHandler {
if (meso < 0 && (storageMesos - meso) < 0) {
meso = -2147483648 + storageMesos;
if (meso < playerMesos) {
+ c.announce(MaplePacketCreator.enableActions());
return;
}
} else if (meso > 0 && (playerMesos + meso) < 0) {
meso = 2147483647 - playerMesos;
if (meso > storageMesos) {
+ c.announce(MaplePacketCreator.enableActions());
return;
}
}
@@ -151,6 +155,7 @@ public final class StorageHandler extends AbstractMaplePacketHandler {
chr.gainMeso(meso, false, true, false);
FilePrinter.print(FilePrinter.STORAGE + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + (meso > 0 ? " took out " : " stored ") + Math.abs(meso) + " mesos\r\n");
} else {
+ c.announce(MaplePacketCreator.enableActions());
return;
}
storage.sendMeso(c);
diff --git a/src/net/server/world/MapleParty.java b/src/net/server/world/MapleParty.java
index d1ea4041a6..7af35b31dc 100644
--- a/src/net/server/world/MapleParty.java
+++ b/src/net/server/world/MapleParty.java
@@ -43,7 +43,7 @@ public class MapleParty {
private Map histMembers = new HashMap<>();
private int nextEntry = 0;
- private Lock lock = new ReentrantLock();
+ private Lock lock = new ReentrantLock(true);
public MapleParty(int id, MaplePartyCharacter chrfor) {
this.leaderId = chrfor.getId();
diff --git a/src/net/server/world/World.java b/src/net/server/world/World.java
index ab980bb9bf..bd809eb63f 100644
--- a/src/net/server/world/World.java
+++ b/src/net/server/world/World.java
@@ -79,31 +79,38 @@ public class World {
private int id, flag, exprate, droprate, mesorate, bossdroprate;
private String eventmsg;
private List channels = new ArrayList<>();
- private Map parties = new HashMap<>();
- private AtomicInteger runningPartyId = new AtomicInteger();
private Map messengers = new HashMap<>();
private AtomicInteger runningMessengerId = new AtomicInteger();
private Map families = new LinkedHashMap<>();
private Map gsStore = new HashMap<>();
private PlayerStorage players = new PlayerStorage();
+
private Set queuedGuilds = new HashSet<>();
+ private Map parties = new HashMap<>();
+ private AtomicInteger runningPartyId = new AtomicInteger();
+ private Lock partyLock = new ReentrantLock(true);
+
private Map owlSearched = new LinkedHashMap<>();
private Lock owlLock = new ReentrantLock();
+ private Lock activePetsLock = new ReentrantLock(true);
private Map activePets = new LinkedHashMap<>();
private ScheduledFuture> petsSchedule;
private long petUpdate;
+ private Lock activeMountsLock = new ReentrantLock(true);
private Map activeMounts = new LinkedHashMap<>();
private ScheduledFuture> mountsSchedule;
private long mountUpdate;
+ private Lock activePlayerShopsLock = new ReentrantLock(true);
+ private Map activePlayerShops = new LinkedHashMap<>();
+
+ private Lock activeMerchantsLock = new ReentrantLock(true);
private Map> activeMerchants = new LinkedHashMap<>();
private long merchantUpdate;
- private Map activePlayerShops = new LinkedHashMap<>();
-
private ScheduledFuture> charactersSchedule;
public World(int world, int flag, String eventmsg, int exprate, int droprate, int mesorate, int bossdroprate) {
@@ -366,21 +373,32 @@ public class World {
public MapleParty createParty(MaplePartyCharacter chrfor) {
int partyid = runningPartyId.getAndIncrement();
MapleParty party = new MapleParty(partyid, chrfor);
- synchronized(parties) {
+
+ partyLock.lock();
+ try {
parties.put(party.getId(), party);
+ } finally {
+ partyLock.unlock();
}
+
return party;
}
public MapleParty getParty(int partyid) {
- synchronized(parties) {
+ partyLock.lock();
+ try {
return parties.get(partyid);
+ } finally {
+ partyLock.unlock();
}
}
public MapleParty disbandParty(int partyid) {
- synchronized(parties) {
+ partyLock.lock();
+ try {
return parties.remove(partyid);
+ } finally {
+ partyLock.unlock();
}
}
@@ -766,27 +784,39 @@ public class World {
}
Integer key = getPetKey(chr, petSlot);
- synchronized(activePets) {
+
+ activePetsLock.lock();
+ try {
byte initProc;
if(System.currentTimeMillis() - petUpdate > 55000) initProc = ServerConstants.PET_EXHAUST_COUNT - 2;
else initProc = ServerConstants.PET_EXHAUST_COUNT - 1;
activePets.put(key, initProc);
+ } finally {
+ activePetsLock.unlock();
}
}
public void unregisterPetHunger(MapleCharacter chr, byte petSlot) {
Integer key = getPetKey(chr, petSlot);
- synchronized(activePets) {
+
+ activePetsLock.lock();
+ try {
activePets.remove(key);
+ } finally {
+ activePetsLock.unlock();
}
}
public void runPetSchedule() {
Map deployedPets;
- synchronized(activePets) {
+
+ activePetsLock.lock();
+ try {
petUpdate = System.currentTimeMillis();
deployedPets = Collections.unmodifiableMap(activePets);
+ } finally {
+ activePetsLock.unlock();
}
for(Map.Entry dp: deployedPets.entrySet()) {
@@ -799,8 +829,11 @@ public class World {
dpVal = 0;
}
- synchronized(activePets) {
+ activePetsLock.lock();
+ try {
activePets.put(dp.getKey(), dpVal);
+ } finally {
+ activePetsLock.unlock();
}
}
}
@@ -811,27 +844,37 @@ public class World {
}
Integer key = chr.getId();
- synchronized(activeMounts) {
+ activeMountsLock.lock();
+ try {
byte initProc;
if(System.currentTimeMillis() - mountUpdate > 45000) initProc = ServerConstants.MOUNT_EXHAUST_COUNT - 2;
else initProc = ServerConstants.MOUNT_EXHAUST_COUNT - 1;
activeMounts.put(key, initProc);
+ } finally {
+ activeMountsLock.unlock();
}
}
public void unregisterMountHunger(MapleCharacter chr) {
Integer key = chr.getId();
- synchronized(activeMounts) {
+
+ activeMountsLock.lock();
+ try {
activeMounts.remove(key);
+ } finally {
+ activeMountsLock.unlock();
}
}
public void runMountSchedule() {
Map deployedMounts;
- synchronized(activeMounts) {
+ activeMountsLock.lock();
+ try {
mountUpdate = System.currentTimeMillis();
deployedMounts = Collections.unmodifiableMap(activeMounts);
+ } finally {
+ activeMountsLock.unlock();
}
for(Map.Entry dp: deployedMounts.entrySet()) {
@@ -844,60 +887,82 @@ public class World {
dpVal = 0;
}
- synchronized(activeMounts) {
+ activeMountsLock.lock();
+ try {
activeMounts.put(dp.getKey(), dpVal);
+ } finally {
+ activeMountsLock.unlock();
}
}
}
public void registerPlayerShop(MaplePlayerShop ps) {
- synchronized(activePlayerShops) {
+ activePlayerShopsLock.lock();
+ try {
activePlayerShops.put(ps.getOwner().getId(), ps);
+ } finally {
+ activePlayerShopsLock.unlock();
}
}
public void unregisterPlayerShop(MaplePlayerShop ps) {
- synchronized(activePlayerShops) {
+ activePlayerShopsLock.lock();
+ try {
activePlayerShops.remove(ps.getOwner().getId());
+ } finally {
+ activePlayerShopsLock.unlock();
}
}
public List getActivePlayerShops() {
List psList = new ArrayList<>();
- synchronized(activePlayerShops) {
+ activePlayerShopsLock.lock();
+ try {
for(MaplePlayerShop mps : activePlayerShops.values()) {
psList.add(mps);
}
return psList;
+ } finally {
+ activePlayerShopsLock.unlock();
}
}
public MaplePlayerShop getPlayerShop(int ownerid) {
- synchronized(activePlayerShops) {
+ activePlayerShopsLock.lock();
+ try {
return activePlayerShops.get(ownerid);
+ } finally {
+ activePlayerShopsLock.unlock();
}
}
public void registerHiredMerchant(MapleHiredMerchant hm) {
- synchronized(activeMerchants) {
+ activeMerchantsLock.lock();
+ try {
byte initProc;
if(System.currentTimeMillis() - merchantUpdate > 5 * 60 * 1000) initProc = 1;
else initProc = 0;
activeMerchants.put(hm.getOwnerId(), new Pair<>(hm, initProc));
+ } finally {
+ activeMerchantsLock.unlock();
}
}
public void unregisterHiredMerchant(MapleHiredMerchant hm) {
- synchronized(activeMerchants) {
+ activeMerchantsLock.lock();
+ try {
activeMerchants.remove(hm.getOwnerId());
+ } finally {
+ activeMerchantsLock.unlock();
}
}
public void runHiredMerchantSchedule() {
Map> deployedMerchants;
- synchronized(activeMerchants) {
+ activeMerchantsLock.lock();
+ try {
merchantUpdate = System.currentTimeMillis();
deployedMerchants = new LinkedHashMap<>(activeMerchants);
@@ -914,12 +979,15 @@ public class World {
activeMerchants.remove(dm.getKey());
}
}
+ } finally {
+ activeMerchantsLock.unlock();
}
}
public List getActiveMerchants() {
List hmList = new ArrayList<>();
- synchronized(activeMerchants) {
+ activeMerchantsLock.lock();
+ try {
for(Pair hmp : activeMerchants.values()) {
MapleHiredMerchant hm = hmp.getLeft();
if(hm.isOpen()) {
@@ -928,16 +996,21 @@ public class World {
}
return hmList;
+ } finally {
+ activeMerchantsLock.unlock();
}
}
public MapleHiredMerchant getHiredMerchant(int ownerid) {
- synchronized(activeMerchants) {
+ activeMerchantsLock.lock();
+ try {
if(activeMerchants.containsKey(ownerid)) {
return activeMerchants.get(ownerid).getLeft();
}
return null;
+ } finally {
+ activeMerchantsLock.unlock();
}
}
diff --git a/src/scripting/event/EventInstanceManager.java b/src/scripting/event/EventInstanceManager.java
index a8b846027f..e3cfefee0d 100644
--- a/src/scripting/event/EventInstanceManager.java
+++ b/src/scripting/event/EventInstanceManager.java
@@ -87,13 +87,16 @@ public class EventInstanceManager {
private long timeStarted = 0;
private long eventTime = 0;
private MapleExpedition expedition = null;
- private List mapIds = new LinkedList();
- private List isInstanced = new LinkedList();
- private final ReentrantReadWriteLock mutex = new ReentrantReadWriteLock();
- private final Lock pL = new ReentrantLock();
+ private List mapIds = new LinkedList<>();
+ private List isInstanced = new LinkedList<>();
+
+ private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+ private final ReadLock rL = lock.readLock();
+ private final WriteLock wL = lock.writeLock();
+
+ private final Lock pL = new ReentrantLock(true);
private final Lock sL = new ReentrantLock();
- private final ReadLock rL = mutex.readLock();
- private final WriteLock wL = mutex.writeLock();
+
private ScheduledFuture> event_schedule = null;
private boolean disposed = false;
private boolean eventCleared = false;
diff --git a/src/scripting/event/EventManager.java b/src/scripting/event/EventManager.java
index f499f069aa..cb38e3de74 100644
--- a/src/scripting/event/EventManager.java
+++ b/src/scripting/event/EventManager.java
@@ -214,15 +214,6 @@ public class EventManager {
return Integer.parseInt(props.getProperty(key));
}
- private boolean getLockLobby(int lobbyId) {
- lobbyLock.lock();
- try {
- return openedLobbys.get(lobbyId);
- } finally {
- lobbyLock.unlock();
- }
- }
-
private void setLockLobby(int lobbyId, boolean lock) {
lobbyLock.lock();
try {
@@ -239,11 +230,11 @@ public class EventManager {
openedLobbys.set(lobbyId, true);
return true;
}
+
+ return false;
} finally {
lobbyLock.unlock();
}
-
- return false;
}
private void freeLobbyInstance(String lobbyName) {
@@ -292,8 +283,7 @@ public class EventManager {
if(lobbyId == -1) return false;
}
else {
- if(getLockLobby(lobbyId)) return false;
- startLobbyInstance(lobbyId);
+ if(!startLobbyInstance(lobbyId)) return false;
}
EventInstanceManager eim = (EventInstanceManager) (iv.invokeFunction("setup", leader.getClient().getChannel()));
@@ -331,8 +321,7 @@ public class EventManager {
if(lobbyId == -1) return false;
}
else {
- if(getLockLobby(lobbyId)) return false;
- startLobbyInstance(lobbyId);
+ if(!startLobbyInstance(lobbyId)) return false;
}
EventInstanceManager eim = (EventInstanceManager) (iv.invokeFunction("setup", difficulty, (lobbyId > -1) ? lobbyId : leader.getId()));
@@ -368,8 +357,7 @@ public class EventManager {
if(lobbyId == -1) return false;
}
else {
- if(getLockLobby(lobbyId)) return false;
- startLobbyInstance(lobbyId);
+ if(!startLobbyInstance(lobbyId)) return false;
}
EventInstanceManager eim = (EventInstanceManager) (iv.invokeFunction("setup", (Object) null));
@@ -406,8 +394,7 @@ public class EventManager {
if(lobbyId == -1) return false;
}
else {
- if(getLockLobby(lobbyId)) return false;
- startLobbyInstance(lobbyId);
+ if(!startLobbyInstance(lobbyId)) return false;
}
EventInstanceManager eim = (EventInstanceManager) (iv.invokeFunction("setup", difficulty, (lobbyId > -1) ? lobbyId : party.getLeaderId()));
@@ -448,8 +435,7 @@ public class EventManager {
if(lobbyId == -1) return false;
}
else {
- if(getLockLobby(lobbyId)) return false;
- startLobbyInstance(lobbyId);
+ if(!startLobbyInstance(lobbyId)) return false;
}
if(eim == null) {
diff --git a/src/server/MaplePlayerShop.java b/src/server/MaplePlayerShop.java
index 985a25f305..41ae11ae74 100644
--- a/src/server/MaplePlayerShop.java
+++ b/src/server/MaplePlayerShop.java
@@ -31,6 +31,8 @@ import java.util.List;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import net.SendOpcode;
import server.maps.AbstractMapleMapObject;
import server.maps.MapleMapObjectType;
@@ -53,6 +55,7 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
private List bannedList = new ArrayList<>();
private List> chatLog = new LinkedList<>();
private Map chatSlot = new LinkedHashMap<>();
+ private Lock visitorLock = new ReentrantLock(true);
public MaplePlayerShop(MapleCharacter owner, String description) {
this.setPosition(owner.getPosition());
@@ -322,8 +325,11 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
}
public void sendShop(MapleClient c) {
- synchronized(visitors) {
+ visitorLock.lock();
+ try {
c.announce(MaplePacketCreator.getPlayerShop(this, isOwner(c.getPlayer())));
+ } finally {
+ visitorLock.unlock();
}
}
@@ -332,11 +338,14 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
}
public MapleCharacter[] getVisitors() {
- synchronized(visitors) {
+ visitorLock.lock();
+ try {
MapleCharacter[] copy = new MapleCharacter[3];
for(int i = 0; i < visitors.length; i++) copy[i] = visitors[i];
return copy;
+ } finally {
+ visitorLock.unlock();
}
}
@@ -370,13 +379,16 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
}
MapleCharacter target = null;
- synchronized(visitors) {
+ visitorLock.lock();
+ try {
for (int i = 0; i < 3; i++) {
if (visitors[i] != null && visitors[i].getName().equals(name)) {
target = visitors[i];
break;
}
}
+ } finally {
+ visitorLock.unlock();
}
if(target != null) {
@@ -400,15 +412,17 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
return false;
}
- if (this.hasFreeSlot() && !this.isVisitor(chr)) {
- this.addVisitor(chr);
- chr.setPlayerShop(this);
- this.sendShop(chr.getClient());
+ synchronized (visitors) {
+ if (this.hasFreeSlot() && !this.isVisitor(chr)) {
+ this.addVisitor(chr);
+ chr.setPlayerShop(this);
+ this.sendShop(chr.getClient());
- return true;
+ return true;
+ }
+
+ return false;
}
-
- return false;
}
public List sendAvailableBundles(int itemid) {
diff --git a/src/server/MapleStatEffect.java b/src/server/MapleStatEffect.java
index a43aebe7e0..0b32d8eab1 100644
--- a/src/server/MapleStatEffect.java
+++ b/src/server/MapleStatEffect.java
@@ -191,6 +191,7 @@ public class MapleStatEffect {
ret.duration *= 1000; // items have their times stored in ms, of course
ret.overTime = overTime;
}
+
ArrayList> statups = new ArrayList<>();
ret.watk = (short) MapleDataTool.getInt("pad", source, 0);
ret.wdef = (short) MapleDataTool.getInt("pdd", source, 0);
@@ -206,15 +207,6 @@ public class MapleStatEffect {
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MAP_PROTECTION, Integer.valueOf(ret.mapProtection));
if (ret.overTime && ret.getSummonMovementType() == null) {
- addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WATK, Integer.valueOf(ret.watk));
- addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WDEF, Integer.valueOf(ret.wdef));
- addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MATK, Integer.valueOf(ret.matk));
- addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MDEF, Integer.valueOf(ret.mdef));
- addBuffStatPairToListIfNotZero(statups, MapleBuffStat.ACC, Integer.valueOf(ret.acc));
- addBuffStatPairToListIfNotZero(statups, MapleBuffStat.AVOID, Integer.valueOf(ret.avoid));
- addBuffStatPairToListIfNotZero(statups, MapleBuffStat.SPEED, Integer.valueOf(ret.speed));
- addBuffStatPairToListIfNotZero(statups, MapleBuffStat.JUMP, Integer.valueOf(ret.jump));
-
if(!skill) {
if(isPyramidBuff(sourceid)) {
ret.berserk = MapleDataTool.getInt("berserk", source, 0);
@@ -273,7 +265,17 @@ public class MapleStatEffect {
ret.speed *= 15;
}
}
+
+ addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WATK, Integer.valueOf(ret.watk));
+ addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WDEF, Integer.valueOf(ret.wdef));
+ addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MATK, Integer.valueOf(ret.matk));
+ addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MDEF, Integer.valueOf(ret.mdef));
+ addBuffStatPairToListIfNotZero(statups, MapleBuffStat.ACC, Integer.valueOf(ret.acc));
+ addBuffStatPairToListIfNotZero(statups, MapleBuffStat.AVOID, Integer.valueOf(ret.avoid));
+ addBuffStatPairToListIfNotZero(statups, MapleBuffStat.SPEED, Integer.valueOf(ret.speed));
+ addBuffStatPairToListIfNotZero(statups, MapleBuffStat.JUMP, Integer.valueOf(ret.jump));
}
+
MapleData ltd = source.getChildByPath("lt");
if (ltd != null) {
ret.lt = (Point) ltd.getData();
@@ -730,6 +732,7 @@ public class MapleStatEffect {
applyto.toggleHide(false);
return true;
}
+
int hpchange = calcHPChange(applyfrom, primary);
int mpchange = calcMPChange(applyfrom, primary);
diff --git a/src/server/MapleStorage.java b/src/server/MapleStorage.java
index 2acee93c47..78f73049a0 100644
--- a/src/server/MapleStorage.java
+++ b/src/server/MapleStorage.java
@@ -27,7 +27,6 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -51,7 +50,7 @@ public class MapleStorage {
private byte slots;
private Map> typeItems = new HashMap<>();
private List
- items;
- private Lock lock = new ReentrantLock();
+ private Lock lock = new ReentrantLock(true);
private MapleStorage(int id, byte slots, int meso) {
this.id = id;
@@ -224,6 +223,14 @@ public class MapleStorage {
}
public void sendStorage(MapleClient c, int npcId) {
+ /*
+ if (c.getPlayer().getLevel() < 15){
+ c.getPlayer().message("You may only use the storage once you have reached level 15.");
+ c.announce(MaplePacketCreator.enableActions());
+ return;
+ }
+ */
+
final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
lock.lock();
diff --git a/src/server/events/BalrogPQ.java b/src/server/events/BalrogPQ.java
index 731e3da958..3776582afd 100644
--- a/src/server/events/BalrogPQ.java
+++ b/src/server/events/BalrogPQ.java
@@ -14,7 +14,7 @@ import server.TimerManager;
public class BalrogPQ {
public static final int[] EasyBalrogParts = {8830002, 8830003, 8830000};
public static final int[] HardBalrogParts = {8830000, 8830001, 8830002};
- public static List candidates = new ArrayList();
+ public static List candidates = new ArrayList<>();
public static boolean hasStarted = false;
public static String partyLeader = "undefined";
public static boolean balrogSpawned = false;
@@ -28,8 +28,10 @@ public class BalrogPQ {
}
public static void warpAllCandidates(){
- for(MapleCharacter c : candidates){
- c.changeMap(105100300);
+ synchronized(candidates){
+ for(MapleCharacter c : candidates){
+ c.changeMap(105100300);
+ }
}
}
@@ -48,7 +50,7 @@ public class BalrogPQ {
TimerManager tMan = TimerManager.getInstance();
tMan.schedule(new Runnable(){
@Override
- public void run(){
+ public void run(){
for(MapleCharacter chrs : fmap.getCharacters()){
chrs.changeMap(105100100);
chrs.message("You did not defeat the balrog in time..");
@@ -57,9 +59,9 @@ public class BalrogPQ {
}
} , 60 * 60 * 1000);
- tMan.schedule(new Runnable(){
+ tMan.schedule(new Runnable(){
@Override
- public void run(){
+ public void run(){
if(fmap.getCharacters().size() <= 3){
if(fmap.getCharacters().size() > 0){
for(MapleCharacter chrs : fmap.getCharacters()){
@@ -92,7 +94,9 @@ public class BalrogPQ {
hasStarted = false;
balrogSpawned = false;
partyLeader = "undefined";
- candidates.clear();
+ synchronized(candidates){
+ candidates.clear();
+ }
timeStamp = 0;
}
public static void spawnBalrog(int mode, MapleCharacter chr){
diff --git a/src/server/life/MapleMonster.java b/src/server/life/MapleMonster.java
index 6a04b9344b..c7fe418db6 100644
--- a/src/server/life/MapleMonster.java
+++ b/src/server/life/MapleMonster.java
@@ -85,7 +85,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
private final HashMap takenDamage = new HashMap<>();
private ReentrantLock externalLock = new ReentrantLock();
- private ReentrantLock monsterLock = new ReentrantLock();
+ private ReentrantLock monsterLock = new ReentrantLock(true);
private ReentrantLock statiLock = new ReentrantLock();
public MapleMonster(int id, MapleMonsterStats stats) {
diff --git a/src/server/maps/MapleHiredMerchant.java b/src/server/maps/MapleHiredMerchant.java
index a6563bd599..44c265b1eb 100644
--- a/src/server/maps/MapleHiredMerchant.java
+++ b/src/server/maps/MapleHiredMerchant.java
@@ -36,6 +36,8 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import net.server.Server;
import server.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
@@ -50,7 +52,6 @@ import tools.Pair;
* @author Ronan (concurrency protection)
*/
public class MapleHiredMerchant extends AbstractMapleMapObject {
-
private int ownerId, itemId, mesos = 0;
private int channel, world;
private long start;
@@ -62,6 +63,7 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
private List sold = new LinkedList<>();
private AtomicBoolean open = new AtomicBoolean();
private MapleMap map;
+ private Lock visitorLock = new ReentrantLock(true);
public MapleHiredMerchant(final MapleCharacter owner, int itemId, String desc) {
this.setPosition(owner.getPosition());
@@ -76,8 +78,11 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
public void broadcastToVisitorsThreadsafe(final byte[] packet) {
- synchronized(visitors) {
+ visitorLock.lock();
+ try {
broadcastToVisitors(packet);
+ } finally {
+ visitorLock.unlock();
}
}
@@ -90,7 +95,8 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
public boolean addVisitor(MapleCharacter visitor) {
- synchronized(visitors) {
+ visitorLock.lock();
+ try {
int i = this.getFreeSlot();
if (i > -1) {
visitors[i] = visitor;
@@ -100,25 +106,33 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
return false;
+ } finally {
+ visitorLock.unlock();
}
}
public void removeVisitor(MapleCharacter visitor) {
- synchronized(visitors) {
+ visitorLock.lock();
+ try {
int slot = getVisitorSlot(visitor);
- if (slot < 0){ //Not found
- return;
+ if (slot < 0) { //Not found
+ return;
}
if (visitors[slot] != null && visitors[slot].getId() == visitor.getId()) {
visitors[slot] = null;
broadcastToVisitors(MaplePacketCreator.hiredMerchantVisitorLeave(slot + 1));
}
+ } finally {
+ visitorLock.unlock();
}
}
public int getVisitorSlotThreadsafe(MapleCharacter visitor) {
- synchronized(visitors) {
+ visitorLock.lock();
+ try {
return getVisitorSlot(visitor);
+ } finally {
+ visitorLock.unlock();
}
}
@@ -132,7 +146,8 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
public void removeAllVisitors() {
- synchronized(visitors) {
+ visitorLock.lock();
+ try {
for (int i = 0; i < 3; i++) {
if (visitors[i] != null) {
visitors[i].setHiredMerchant(null);
@@ -143,6 +158,8 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
visitors[i] = null;
}
}
+ } finally {
+ visitorLock.unlock();
}
}
@@ -314,11 +331,14 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
public MapleCharacter[] getVisitors() {
- synchronized(visitors) {
+ visitorLock.lock();
+ try {
MapleCharacter[] copy = new MapleCharacter[3];
for(int i = 0; i < visitors.length; i++) copy[i] = visitors[i];
return copy;
+ } finally {
+ visitorLock.unlock();
}
}
@@ -362,12 +382,6 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
}
- public int getFreeSlotThreadsafe() {
- synchronized(visitors) {
- return getFreeSlot();
- }
- }
-
private int getFreeSlot() {
for (int i = 0; i < 3; i++) {
if (visitors[i] == null) {
diff --git a/src/server/maps/MapleMap.java b/src/server/maps/MapleMap.java
index db59f5f074..e823d37987 100644
--- a/src/server/maps/MapleMap.java
+++ b/src/server/maps/MapleMap.java
@@ -2724,7 +2724,6 @@ public class MapleMap {
if (reactor.getShouldCollect() == true && mapitem != null && mapitem == getMapObject(mapitem.getObjectId())) {
mapitem.lockItem();
try {
- TimerManager tMan = TimerManager.getInstance();
if (mapitem.isPickedUp()) {
return;
}
@@ -2735,6 +2734,7 @@ public class MapleMap {
reactor.hitReactor(c);
if (reactor.getDelay() > 0) {
+ TimerManager tMan = TimerManager.getInstance();
tMan.schedule(new Runnable() {
@Override
public void run() {
diff --git a/src/server/maps/MapleMiniDungeon.java b/src/server/maps/MapleMiniDungeon.java
index 5d39376c65..00a54738a0 100644
--- a/src/server/maps/MapleMiniDungeon.java
+++ b/src/server/maps/MapleMiniDungeon.java
@@ -22,7 +22,7 @@ import tools.MaplePacketCreator;
public class MapleMiniDungeon {
List players = new ArrayList<>();
ScheduledFuture> timeoutTask = null;
- Lock lock = new ReentrantLock();
+ Lock lock = new ReentrantLock(true);
int baseMap;
long expireTime;
diff --git a/src/server/maps/MapleReactor.java b/src/server/maps/MapleReactor.java
index dbd7aa5d27..6db3be3769 100644
--- a/src/server/maps/MapleReactor.java
+++ b/src/server/maps/MapleReactor.java
@@ -59,7 +59,7 @@ public class MapleReactor extends AbstractMapleMapObject {
this.evstate = (byte)0;
this.stats = stats;
this.rid = rid;
- alive = true;
+ this.alive = true;
}
public void setShouldCollect(boolean collect) {
diff --git a/src/tools/DatabaseConnection.java b/src/tools/DatabaseConnection.java
index 21c7fac711..e4c640c174 100644
--- a/src/tools/DatabaseConnection.java
+++ b/src/tools/DatabaseConnection.java
@@ -84,7 +84,7 @@ public class DatabaseConnection {
config.setMaximumPoolSize(poolSize);
config.addDataSourceProperty("cachePrepStmts", true);
- config.addDataSourceProperty("prepStmtCacheSize", 250);
+ config.addDataSourceProperty("prepStmtCacheSize", 25);
config.addDataSourceProperty("prepStmtCacheSqlLimit", 2048);
ds = new HikariDataSource(config);
diff --git a/wz/Map.wz/Map/Map9/914000200.img.xml b/wz/Map.wz/Map/Map9/914000200.img.xml
index f2a2cd3913..25df13e9ca 100644
--- a/wz/Map.wz/Map/Map9/914000200.img.xml
+++ b/wz/Map.wz/Map/Map9/914000200.img.xml
@@ -1,1686 +1 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/wz/String.wz/Map.img.xml b/wz/String.wz/Map.img.xml
index 713e5b758a..b6bcbf4fa8 100644
--- a/wz/String.wz/Map.img.xml
+++ b/wz/String.wz/Map.img.xml
@@ -1,17704 +1 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/wz/String.wz/Skill.img.xml b/wz/String.wz/Skill.img.xml
index 62db55c0bc..1c971d2b04 100644
--- a/wz/String.wz/Skill.img.xml
+++ b/wz/String.wz/Skill.img.xml
@@ -1,12727 +1 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file