stan пре 2 дана
родитељ
комит
2966b19955
100 измењених фајлова са 10495 додато и 3522 уклоњено
  1. 9 1
      CMakeLists.txt
  2. 22 0
      README.md
  3. 37 16
      Sunrise/Sunrise.vcxproj
  4. 66 0
      Sunrise/resources/database/account_settings_defaults.sql
  5. 79 0
      Sunrise/resources/database/account_settings_schema.sql
  6. 7203 0
      Sunrise/resources/database/investment_defaults.sql
  7. 119 0
      Sunrise/resources/database/investment_schema.sql
  8. 2 31
      Sunrise/resources/default_settings.json
  9. 9 0
      Sunrise/resources/resource.h
  10. 7 0
      Sunrise/resources/sunrise.rc
  11. 4 2
      Sunrise/src/client/hooks/network/content_config/request/content_config_get_replacement.cpp
  12. 7 9
      Sunrise/src/core/runtime/core_runtime.cpp
  13. 3 80
      Sunrise/src/core/settings/parser.h
  14. 0 2
      Sunrise/src/core/settings/server/definition.h
  15. 0 98
      Sunrise/src/core/settings/server/entitlement_settings_parser.cpp
  16. 2 9
      Sunrise/src/core/settings/server/server_settings_parser.cpp
  17. 1 8
      Sunrise/src/core/settings/settings.h
  18. 40 1
      Sunrise/src/core/settings/settings_parser.cpp
  19. 22 76
      Sunrise/src/core/settings/settings_runtime.cpp
  20. 0 407
      Sunrise/src/core/settings/settings_upgrade.cpp
  21. 0 30
      Sunrise/src/core/settings/settings_upgrade.h
  22. 0 336
      Sunrise/src/core/settings/state/account_rows_parser.cpp
  23. 0 100
      Sunrise/src/core/settings/state/account_settings_parser.cpp
  24. 0 91
      Sunrise/src/core/settings/state/audio_parser.cpp
  25. 0 126
      Sunrise/src/core/settings/state/controls_parser.cpp
  26. 0 91
      Sunrise/src/core/settings/state/display_parser.cpp
  27. 0 119
      Sunrise/src/core/settings/state/family5_override_parser.cpp
  28. 0 116
      Sunrise/src/core/settings/state/interface_parser.cpp
  29. 0 234
      Sunrise/src/core/settings/state/inventory_parser.cpp
  30. 0 426
      Sunrise/src/core/settings/state/key_bindings_parser.cpp
  31. 0 101
      Sunrise/src/core/settings/state/social_parser.cpp
  32. 4 281
      Sunrise/src/core/settings/state_settings.cpp
  33. 19 5
      Sunrise/src/middleware/datagen/family4/account/account_encoder.cpp
  34. 9 3
      Sunrise/src/middleware/datagen/family4/account/layout.h
  35. 9 5
      Sunrise/src/middleware/datagen/family4/character/character_encoder.cpp
  36. 1 1
      Sunrise/src/middleware/datagen/family4/character/layout.h
  37. 1 8
      Sunrise/src/middleware/datagen/family4/instance/instance_encoder.cpp
  38. 1 0
      Sunrise/src/middleware/datagen/family4/loadout/definition.h
  39. 1 0
      Sunrise/src/middleware/datagen/family4/loadout/loadout_item_resolver.cpp
  40. 7 13
      Sunrise/src/middleware/datagen/family4/progression/progression_bank_keys.cpp
  41. 29 10
      Sunrise/src/middleware/web_service/messages/opcode701/opcode701_codec.cpp
  42. 3 0
      Sunrise/src/middleware/web_service/messages/opcode701/opcode701_codec.h
  43. 9 7
      Sunrise/src/middleware/web_service/messages/opcode702.h
  44. 154 44
      Sunrise/src/middleware/web_service/messages/opcode702_codec.cpp
  45. 56 88
      Sunrise/src/server/bap/bap_world_reward_queue.cpp
  46. 17 3
      Sunrise/src/server/bap/encrypted/activity_message/receipts/activity_incident_grants.cpp
  47. 10 3
      Sunrise/src/server/bap/encrypted/body/bap_service_body.cpp
  48. 20 3
      Sunrise/src/server/bap/encrypted/encrypted_runtime.cpp
  49. 393 9
      Sunrise/src/server/bap/encrypted/internal.h
  50. 4 2
      Sunrise/src/server/bap/encrypted/push/snapshot/family4_selection_move.cpp
  51. 25 12
      Sunrise/src/server/bap/encrypted/queuez/queuez_deferred_push.cpp
  52. 2 8
      Sunrise/src/server/bap/internal.h
  53. 9 7
      Sunrise/src/server/http/server_http.cpp
  54. 16 0
      Sunrise/src/server/web_service/web_service_actions.cpp
  55. 13 4
      Sunrise/src/server/web_service/web_service_runtime.cpp
  56. 7 4
      Sunrise/src/server/web_service/web_service_runtime.h
  57. 3 7
      Sunrise/src/state/account/account_state.h
  58. 88 0
      Sunrise/src/state/account/inventory/inventory_seen_runtime.cpp
  59. 4 0
      Sunrise/src/state/account/inventory/inventory_state.h
  60. 31 0
      Sunrise/src/state/account/inventory/seen_state.h
  61. 1 1
      Sunrise/src/state/account/settings/key_bindings.h
  62. 2 0
      Sunrise/src/state/account/settings/settings_delta.cpp
  63. 2 0
      Sunrise/src/state/account/settings/settings_delta.h
  64. 2 2
      Sunrise/src/state/account/settings/settings_state.h
  65. 4 1
      Sunrise/src/state/activity/membership/transactions/activity_membership_authoritative_prepare.cpp
  66. 4 1
      Sunrise/src/state/activity/membership/transactions/activity_membership_commit.cpp
  67. 13 4
      Sunrise/src/state/activity/membership/transactions/activity_membership_prepare.cpp
  68. 0 48
      Sunrise/src/state/entitlements/entitlement_defaults.cpp
  69. 9 20
      Sunrise/src/state/entitlements/entitlement_runtime.cpp
  70. 3 12
      Sunrise/src/state/entitlements/entitlement_runtime.h
  71. 0 3
      Sunrise/src/state/entitlements/validation.h
  72. 162 0
      Sunrise/src/state/investment/investment_account_store.cpp
  73. 155 0
      Sunrise/src/state/investment/investment_database.cpp
  74. 219 0
      Sunrise/src/state/investment/investment_inventory_store.cpp
  75. 49 0
      Sunrise/src/state/investment/investment_reward_store.cpp
  76. 248 0
      Sunrise/src/state/investment/investment_settings_store.cpp
  77. 81 0
      Sunrise/src/state/investment/investment_store_boot.cpp
  78. 38 0
      Sunrise/src/state/investment/investment_store_validation.cpp
  79. 321 0
      Sunrise/src/state/investment/investment_unlock_store.cpp
  80. 61 0
      Sunrise/src/state/investment/store.h
  81. 142 0
      Sunrise/src/state/investment/store_internal.h
  82. 2 7
      Sunrise/src/state/runtime/runtime.h
  83. 0 2
      Sunrise/src/state/runtime/state.h
  84. 27 15
      Sunrise/src/state/runtime/state_account_acquisition_runtime.cpp
  85. 8 4
      Sunrise/src/state/runtime/state_account_dismantle_runtime.cpp
  86. 2 1
      Sunrise/src/state/runtime/state_account_equipment_runtime.cpp
  87. 32 22
      Sunrise/src/state/runtime/state_account_item_action_runtime.cpp
  88. 2 1
      Sunrise/src/state/runtime/state_account_profile_runtime.cpp
  89. 23 19
      Sunrise/src/state/runtime/state_account_reward_grant_runtime.cpp
  90. 63 43
      Sunrise/src/state/runtime/state_account_runtime.cpp
  91. 5 5
      Sunrise/src/state/runtime/state_account_settings_runtime.cpp
  92. 90 49
      Sunrise/src/state/runtime/state_progression_runtime.cpp
  93. 37 111
      Sunrise/src/state/runtime/state_runtime.cpp
  94. 1 1
      Sunrise/src/state/runtime/storage/internal.h
  95. 1 4
      Sunrise/src/state/unlocks/definition.h
  96. 16 17
      Sunrise/src/state/unlocks/unlocks_records.cpp
  97. 79 89
      Sunrise/src/state/unlocks/unlocks_runtime.cpp
  98. 3 2
      Sunrise/src/state/unlocks/unlocks_runtime.h
  99. 1 1
      Sunrise/src/steam/interfaces/methods/apps_dlc.cpp
  100. 10 0
      Sunrise/vendor/sqlite/NOTICE.txt

+ 9 - 1
CMakeLists.txt

@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 3.31)
-project(Sunrise CXX)
+project(Sunrise C CXX)
 
 set(CMAKE_CXX_STANDARD 20)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -17,6 +17,8 @@ file(GLOB_RECURSE VENDOR_SOURCES CONFIGURE_DEPENDS
     "Sunrise/vendor/imgui/*.h"
     "Sunrise/vendor/lua/*.c"
     "Sunrise/vendor/lua/*.h"
+    "Sunrise/vendor/sqlite/*.c"
+    "Sunrise/vendor/sqlite/*.h"
 )
 # Lua builds as C++ here, matching the MSVC project's CompileAsCpp setting.
 file(GLOB_RECURSE LUA_SOURCES CONFIGURE_DEPENDS
@@ -27,6 +29,7 @@ file(GLOB_RECURSE RESOURCE_FILES CONFIGURE_DEPENDS
     "Sunrise/resources/*.rc"
     "Sunrise/resources/*.h"
     "Sunrise/resources/*.json"
+    "Sunrise/resources/*.sql"
 )
 
 add_library(steam_api64 SHARED
@@ -60,6 +63,7 @@ target_include_directories(steam_api64 SYSTEM PRIVATE
     "${CMAKE_CURRENT_SOURCE_DIR}/Sunrise/vendor/imgui"
     "${CMAKE_CURRENT_SOURCE_DIR}/Sunrise/vendor/imgui/backends"
     "${CMAKE_CURRENT_SOURCE_DIR}/Sunrise/vendor/lua"
+    "${CMAKE_CURRENT_SOURCE_DIR}/Sunrise/vendor/sqlite"
 )
 
 if(DEFINED XWIN_DIR)
@@ -129,3 +133,7 @@ set_target_properties(steam_api64 PROPERTIES
     LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/x64/$<CONFIG>"
     ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/x64/$<CONFIG>"
 )
+
+set_source_files_properties(Sunrise/vendor/sqlite/sqlite3.c PROPERTIES
+    COMPILE_DEFINITIONS "SQLITE_OMIT_LOAD_EXTENSION;SQLITE_THREADSAFE=1"
+)

+ 22 - 0
README.md

@@ -83,6 +83,27 @@ $ cmake -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=$(pwd)/linux-to-win-toolchain.c
 $ cmake --build build
 ```
 
+## Saved progression
+
+Sunrise stores account and character progression in `Sunrise/data/investment.sqlite3`, relative
+to the DLL. Inventory, currencies, sockets, subclass choices, titles, unlocks, objectives,
+seasonal progress, claims, and ownership survive restarts. Character unlock banks are separate.
+Earned world rewards also survive while waiting for their inventory grant and pickup notification.
+In-game account preferences, account keybindings, and each item's seen marker are also saved.
+Client-mod options and local server policy remain in `Sunrise/settings.json`. Selection, current
+activity, and sign-in time last only for the current run.
+
+The DLL embeds `Sunrise/resources/database/investment_schema.sql`, `investment_defaults.sql`,
+`account_settings_schema.sql`, and `account_settings_defaults.sql`. New databases use these
+defaults. Version-1 saves upgrade to version 2 without replacing their inventory or progression;
+the added account preferences start with the bundled defaults.
+Settings files with an older or missing version are deleted and replaced with bundled defaults.
+There is no settings migration or progression import. Existing SQLite saves are kept.
+
+Close the game before copying or editing the database. Back up the whole `Sunrise/data` folder.
+Removing that database starts a new save from the bundled defaults. A database with a newer
+schema is refused rather than replaced.
+
 ## Contributing
 
 Pull Requests are welcome. Please follow these rules:
@@ -107,6 +128,7 @@ Pull Requests are welcome. Please follow these rules:
 - https://github.com/ocornut/imgui
 - https://github.com/microsoft/detours
 - https://lua.org/
+- [SQLite](https://www.sqlite.org/)
 
 ### Artwork:
 

+ 37 - 16
Sunrise/Sunrise.vcxproj

@@ -35,7 +35,7 @@
     <TargetName>steam_api64</TargetName>
     <OutDir>$(ProjectDir)..\build\$(Platform)\$(Configuration)\</OutDir>
     <IntDir>$(ProjectDir)..\build\obj\$(Platform)\$(Configuration)\</IntDir>
-    <ExternalIncludePath>$(ExternalIncludePath);$(ProjectDir)vendor\detours;$(ProjectDir)vendor\imgui;$(ProjectDir)vendor\imgui\backends;$(ProjectDir)vendor\lua</ExternalIncludePath>
+    <ExternalIncludePath>$(ExternalIncludePath);$(ProjectDir)vendor\detours;$(ProjectDir)vendor\imgui;$(ProjectDir)vendor\imgui\backends;$(ProjectDir)vendor\lua;$(ProjectDir)vendor\sqlite</ExternalIncludePath>
     <VcpkgApplocalDeps>false</VcpkgApplocalDeps>
     <!-- clang rejects the UCRT offsetof macro in a constant expression, so point it at the
          builtin. MSVC refuses the same define as a reserved name, so it stays on this pass. -->
@@ -49,7 +49,7 @@
       <ConformanceMode>true</ConformanceMode>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
       <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
-      <AdditionalIncludeDirectories>$(ProjectDir)src;$(ProjectDir)vendor\detours;$(ProjectDir)vendor\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;$(ProjectDir)vendor\detours;$(ProjectDir)vendor\lua;$(ProjectDir)vendor\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <TreatAngleIncludeAsExternal>true</TreatAngleIncludeAsExternal>
       <ExternalWarningLevel>TurnOffAllWarnings</ExternalWarningLevel>
       <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;WIN32_LEAN_AND_MEAN;NOMINMAX;IMGUI_USER_CONFIG=&quot;core/ui/imgui_user_config.h&quot;;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -100,6 +100,17 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\state\gameplay\external\entity_object_types.cpp" />
+    <ClCompile Include="src\state\investment\investment_account_store.cpp" />
+    <ClCompile Include="src\state\investment\investment_database.cpp" />
+    <ClCompile Include="src\state\investment\investment_inventory_store.cpp" />
+    <ClCompile Include="src\state\investment\investment_store_boot.cpp" />
+    <ClCompile Include="src\state\investment\investment_unlock_store.cpp" />
+    <ClCompile Include="vendor\sqlite\sqlite3.c">
+      <CompileAs>CompileAsC</CompileAs>
+      <WarningLevel>TurnOffAllWarnings</WarningLevel>
+      <TreatWarningAsError>false</TreatWarningAsError>
+      <PreprocessorDefinitions>SQLITE_OMIT_LOAD_EXTENSION;SQLITE_THREADSAFE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
     <ClCompile Include="src\dllmain.cpp" />
     <ClCompile Include="src\core\logging\log.cpp" />
     <ClCompile Include="src\core\logging\snapshot\log_snapshot_ring.cpp" />
@@ -111,22 +122,11 @@
     <ClCompile Include="src\core\settings\json_scalar.cpp" />
     <ClCompile Include="src\core\settings\json_structure.cpp" />
     <ClCompile Include="src\core\settings\settings_runtime.cpp" />
-    <ClCompile Include="src\core\settings\settings_upgrade.cpp" />
     <ClCompile Include="src\core\settings\client\client_settings_parser.cpp" />
     <ClCompile Include="src\core\settings\client\client_ui_settings_parser.cpp" />
     <ClCompile Include="src\core\settings\server\server_settings_parser.cpp" />
-    <ClCompile Include="src\core\settings\server\entitlement_settings_parser.cpp" />
     <ClCompile Include="src\core\settings\steam\steam_settings_parser.cpp" />
-    <ClCompile Include="src\core\settings\state\account_settings_parser.cpp" />
-    <ClCompile Include="src\core\settings\state\family5_override_parser.cpp" />
     <ClCompile Include="src\core\settings\state\activity_default_destination_parser.cpp" />
-    <ClCompile Include="src\core\settings\state\inventory_parser.cpp" />
-    <ClCompile Include="src\core\settings\state\audio_parser.cpp" />
-    <ClCompile Include="src\core\settings\state\controls_parser.cpp" />
-    <ClCompile Include="src\core\settings\state\display_parser.cpp" />
-    <ClCompile Include="src\core\settings\state\interface_parser.cpp" />
-    <ClCompile Include="src\core\settings\state\key_bindings_parser.cpp" />
-    <ClCompile Include="src\core\settings\state\social_parser.cpp" />
     <ClCompile Include="src\core\runtime\core_runtime.cpp" />
     <ClCompile Include="src\core\runtime\host_environment.cpp" />
     <ClCompile Include="src\core\ui\modules\ui_module_descriptor.cpp" />
@@ -587,7 +587,6 @@
     <ClCompile Include="src\state\activity\membership\activity_membership_query.cpp" />
     <ClCompile Include="src\state\unlocks\unlocks_runtime.cpp" />
     <ClCompile Include="src\state\unlocks\unlocks_records.cpp" />
-    <ClCompile Include="src\state\entitlements\entitlement_defaults.cpp" />
     <ClCompile Include="src\state\entitlements\entitlement_runtime.cpp" />
     <ClCompile Include="src\state\entitlements\entitlement_validation.cpp" />
     <ClCompile Include="src\state\activity\defaults\activity_defaults_snapshot.cpp" />
@@ -1095,7 +1094,6 @@
     <ClCompile Include="src\state\build_data\runtime\build_data_routing_catalogs.cpp" />
     <ClCompile Include="src\state\build_data\cache\records\cache_investment_records.cpp" />
     <ClCompile Include="src\server\bap\encrypted\push\snapshot\family4_object_staging.cpp" />
-    <ClCompile Include="src\core\settings\state\account_rows_parser.cpp" />
     <ClCompile Include="src\server\bap\encrypted\push\queuez\queuez_banner_push.cpp" />
     <ClCompile Include="src\server\bap\encrypted\push\queuez\queuez_push_reporting.cpp" />
     <ClCompile Include="src\server\bap\encrypted\push\queuez\queuez_family5_push.cpp" />
@@ -1197,6 +1195,7 @@
     <ClCompile Include="src\state\build_data\sobjects\sobject_catalog.cpp" />
   </ItemGroup>
   <ItemGroup Condition="'$(SunriseRunClangTidy)'=='true'">
+    <ClCompile Remove="vendor\sqlite\sqlite3.c" />
     <ClCompile Remove="vendor\detours\detours.cpp" />
     <ClCompile Remove="vendor\detours\disasm.cpp" />
     <ClCompile Remove="vendor\detours\modules.cpp" />
@@ -2039,7 +2038,6 @@
     <ClInclude Include="src\state\activity\receipts\definition.h" />
     <ClInclude Include="src\state\activity\receipts\activity_receipts.h" />
     <ClInclude Include="src\core\settings\server\activation\definition.h" />
-    <ClInclude Include="src\core\settings\settings_upgrade.h" />
     <ClInclude Include="src\middleware\gameplay\group\migration_messages.h" />
     <ClInclude Include="src\middleware\gameplay\group\notice_messages.h" />
     <ClInclude Include="src\server\gameplay\group\group_migration_receipts.h" />
@@ -2130,5 +2128,28 @@
     <ClInclude Include="src\client\hooks\network\investment\lore_visibility_patch.h" />
     <ClCompile Include="src\client\hooks\network\investment\investment_lore_visibility.cpp" />
   </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\state\investment\investment_store_validation.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\state\investment\investment_reward_store.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="vendor\sqlite\sqlite3.h" />
+    <ClInclude Include="src\state\investment\store.h" />
+    <ClInclude Include="src\state\investment\store_internal.h" />
+    <None Include="vendor\sqlite\NOTICE.txt" />
+    <None Include="resources\database\investment_schema.sql" />
+    <None Include="resources\database\investment_defaults.sql" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\state\investment\investment_settings_store.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\state\account\inventory\inventory_seen_runtime.cpp" />
+    <ClInclude Include="src\state\account\inventory\seen_state.h" />
+    <None Include="resources\database\account_settings_schema.sql" />
+    <None Include="resources\database\account_settings_defaults.sql" />
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
 </Project>

+ 66 - 0
Sunrise/resources/database/account_settings_defaults.sql

@@ -0,0 +1,66 @@
+INSERT INTO account_preferences VALUES (1,1);
+INSERT INTO account_controls VALUES (1,0,0,2,0,0,1,0,0,15,0,0,0,0,1,0);
+INSERT INTO account_audio VALUES (1,1,0,0,8,2,0,3,2,2);
+INSERT INTO account_display VALUES (1,3,0,0,0,85,10000,0);
+INSERT INTO account_interface VALUES (1,0,0,1,3,1,2,0,0,0,0,0,0,0,0);
+INSERT INTO account_social VALUES (1,0,3,1,1,0,1,0,0,0,1,1);
+INSERT INTO account_key_bindings VALUES (0,109,-1);
+INSERT INTO account_key_bindings VALUES (1,-1,-1);
+INSERT INTO account_key_bindings VALUES (2,111,-1);
+INSERT INTO account_key_bindings VALUES (3,60,-1);
+INSERT INTO account_key_bindings VALUES (4,31,-1);
+INSERT INTO account_key_bindings VALUES (5,48,-1);
+INSERT INTO account_key_bindings VALUES (6,34,-1);
+INSERT INTO account_key_bindings VALUES (7,109,-1);
+INSERT INTO account_key_bindings VALUES (8,111,-1);
+INSERT INTO account_key_bindings VALUES (9,60,-1);
+INSERT INTO account_key_bindings VALUES (10,16,-1);
+INSERT INTO account_key_bindings VALUES (11,114,-1);
+INSERT INTO account_key_bindings VALUES (12,115,-1);
+INSERT INTO account_key_bindings VALUES (13,17,-1);
+INSERT INTO account_key_bindings VALUES (14,18,-1);
+INSERT INTO account_key_bindings VALUES (15,19,-1);
+INSERT INTO account_key_bindings VALUES (16,32,-1);
+INSERT INTO account_key_bindings VALUES (17,46,-1);
+INSERT INTO account_key_bindings VALUES (18,45,-1);
+INSERT INTO account_key_bindings VALUES (19,47,-1);
+INSERT INTO account_key_bindings VALUES (20,72,-1);
+INSERT INTO account_key_bindings VALUES (21,106,-1);
+INSERT INTO account_key_bindings VALUES (22,-1,-1);
+INSERT INTO account_key_bindings VALUES (23,105,-1);
+INSERT INTO account_key_bindings VALUES (24,-1,-1);
+INSERT INTO account_key_bindings VALUES (25,111,-1);
+INSERT INTO account_key_bindings VALUES (26,105,-1);
+INSERT INTO account_key_bindings VALUES (27,111,-1);
+INSERT INTO account_key_bindings VALUES (28,109,-1);
+INSERT INTO account_key_bindings VALUES (29,33,-1);
+INSERT INTO account_key_bindings VALUES (30,72,-1);
+INSERT INTO account_key_bindings VALUES (31,33,-1);
+INSERT INTO account_key_bindings VALUES (32,49,-1);
+INSERT INTO account_key_bindings VALUES (33,77,-1);
+INSERT INTO account_key_bindings VALUES (34,78,-1);
+INSERT INTO account_key_bindings VALUES (35,79,-1);
+INSERT INTO account_key_bindings VALUES (36,80,-1);
+INSERT INTO account_key_bindings VALUES (37,59,-1);
+INSERT INTO account_key_bindings VALUES (38,61,-1);
+INSERT INTO account_key_bindings VALUES (39,114,-1);
+INSERT INTO account_key_bindings VALUES (40,115,-1);
+INSERT INTO account_key_bindings VALUES (41,35,-1);
+INSERT INTO account_key_bindings VALUES (42,30,-1);
+INSERT INTO account_key_bindings VALUES (43,64,-1);
+INSERT INTO account_key_bindings VALUES (44,-1,-1);
+INSERT INTO account_key_bindings VALUES (45,-1,-1);
+INSERT INTO account_key_bindings VALUES (46,-1,-1);
+INSERT INTO account_key_bindings VALUES (47,-1,-1);
+INSERT INTO account_key_bindings VALUES (48,37,-1);
+INSERT INTO account_key_bindings VALUES (49,-1,-1);
+INSERT INTO account_key_bindings VALUES (50,38,-1);
+INSERT INTO account_key_bindings VALUES (51,-1,-1);
+INSERT INTO account_key_bindings VALUES (52,-1,-1);
+INSERT INTO account_key_bindings VALUES (53,-1,-1);
+INSERT INTO account_key_bindings VALUES (54,-1,-1);
+INSERT INTO account_key_bindings VALUES (55,-1,-1);
+INSERT INTO account_key_bindings VALUES (56,1024,-1);
+INSERT INTO account_key_bindings VALUES (57,39,-1);
+INSERT INTO account_key_bindings VALUES (58,53,-1);
+INSERT INTO account_key_bindings VALUES (59,13,-1);

+ 79 - 0
Sunrise/resources/database/account_settings_schema.sql

@@ -0,0 +1,79 @@
+CREATE TABLE account_preferences (id INTEGER PRIMARY KEY CHECK(id=1), key_binding_source INTEGER NOT NULL CHECK(key_binding_source IN(0,1))) STRICT;
+
+CREATE TABLE account_controls (
+    id INTEGER PRIMARY KEY CHECK(id=1),
+    button_layout INTEGER NOT NULL,
+    movement_mode INTEGER NOT NULL,
+    controller_look_sensitivity INTEGER NOT NULL,
+    controller_invert_vertical INTEGER NOT NULL CHECK(controller_invert_vertical IN(0,1)),
+    controller_auto_look_centering INTEGER NOT NULL CHECK(controller_auto_look_centering IN(0,1)),
+    controller_vibration INTEGER NOT NULL CHECK(controller_vibration IN(0,1)),
+    controller_swap_shoulders INTEGER NOT NULL CHECK(controller_swap_shoulders IN(0,1)),
+    controller_invert_horizontal INTEGER NOT NULL CHECK(controller_invert_horizontal IN(0,1)),
+    mouse_look_sensitivity INTEGER NOT NULL,
+    mouse_invert_vertical INTEGER NOT NULL CHECK(mouse_invert_vertical IN(0,1)),
+    mouse_invert_horizontal INTEGER NOT NULL CHECK(mouse_invert_horizontal IN(0,1)),
+    unidentified_toggle INTEGER NOT NULL CHECK(unidentified_toggle IN(0,1)),
+    mouse_aim_smoothing INTEGER NOT NULL CHECK(mouse_aim_smoothing IN(0,1)),
+    ads_sensitivity_modifier REAL NOT NULL,
+    double_press_delay INTEGER NOT NULL
+) STRICT;
+
+CREATE TABLE account_audio (
+    id INTEGER PRIMARY KEY CHECK(id=1),
+    voice_output_mode INTEGER NOT NULL,
+    team_voice_channel INTEGER NOT NULL,
+    reserved_mode INTEGER NOT NULL,
+    migration_version INTEGER NOT NULL,
+    chat_volume INTEGER NOT NULL,
+    mute_when_unfocused INTEGER NOT NULL CHECK(mute_when_unfocused IN(0,1)),
+    sound_effects_volume INTEGER NOT NULL,
+    dialogue_volume INTEGER NOT NULL,
+    music_volume INTEGER NOT NULL
+) STRICT;
+
+CREATE TABLE account_display (
+    id INTEGER PRIMARY KEY CHECK(id=1),
+    brightness INTEGER NOT NULL,
+    show_fps INTEGER NOT NULL CHECK(show_fps IN(0,1)),
+    hdr_mode INTEGER NOT NULL,
+    vertical_sync_interval INTEGER NOT NULL,
+    field_of_view INTEGER NOT NULL,
+    calibration_primary REAL NOT NULL,
+    calibration_alpha REAL NOT NULL
+) STRICT;
+
+CREATE TABLE account_interface (
+    id INTEGER PRIMARY KEY CHECK(id=1),
+    subtitles_mode INTEGER NOT NULL,
+    colorblind_mode INTEGER NOT NULL,
+    helmet_mode INTEGER NOT NULL,
+    hud_opacity INTEGER NOT NULL,
+    display_hints INTEGER NOT NULL CHECK(display_hints IN(0,1)),
+    background_opacity INTEGER NOT NULL,
+    reticle_location INTEGER NOT NULL,
+    reticle_color INTEGER NOT NULL,
+    text_size INTEGER NOT NULL,
+    text_color INTEGER NOT NULL,
+    text_background_style INTEGER NOT NULL,
+    text_background_opacity INTEGER NOT NULL,
+    reserved_text_mode INTEGER NOT NULL,
+    subtitle_options_entry INTEGER NOT NULL
+) STRICT;
+
+CREATE TABLE account_social (
+    id INTEGER PRIMARY KEY CHECK(id=1),
+    prefer_good_connection INTEGER NOT NULL CHECK(prefer_good_connection IN(0,1)),
+    text_chat_mode INTEGER NOT NULL,
+    show_real_names INTEGER NOT NULL CHECK(show_real_names IN(0,1)),
+    clan_invite_notifications INTEGER NOT NULL CHECK(clan_invite_notifications IN(0,1)),
+    profanity_filter INTEGER NOT NULL CHECK(profanity_filter IN(0,1)),
+    voice_chat_enabled INTEGER NOT NULL CHECK(voice_chat_enabled IN(0,1)),
+    whisper_chat_mode INTEGER NOT NULL,
+    team_chat_join_mode INTEGER NOT NULL,
+    local_chat_join_mode INTEGER NOT NULL,
+    clan_chat_join_mode INTEGER NOT NULL,
+    chat_auto_hide_mode INTEGER NOT NULL
+) STRICT;
+
+CREATE TABLE account_key_bindings (action INTEGER PRIMARY KEY CHECK(action BETWEEN 0 AND 59), primary_code INTEGER NOT NULL CHECK(primary_code BETWEEN -1 AND 65535), secondary_code INTEGER NOT NULL CHECK(secondary_code BETWEEN -1 AND 65535)) STRICT;

+ 7203 - 0
Sunrise/resources/database/investment_defaults.sql

@@ -0,0 +1,7203 @@
+INSERT INTO account VALUES (1, -7013740688821976832, 1);
+INSERT INTO characters VALUES (0, -7013740688821976831, 0, 0, 1, 50, 1, 1.0, 308080871, 1, 65535, -1, 57);
+INSERT INTO items VALUES (0, 0, 0, 4611686018427387905, 3843477312, 106, 1, 0, 0, 1, 12, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427387905, 0, 2874284214);
+INSERT INTO sockets VALUES (4611686018427387905, 1, 3433396027);
+INSERT INTO sockets VALUES (4611686018427387905, 2, 106909392);
+INSERT INTO sockets VALUES (4611686018427387905, 3, 1168162263);
+INSERT INTO sockets VALUES (4611686018427387905, 4, 460017080);
+INSERT INTO sockets VALUES (4611686018427387905, 5, 4248210736);
+INSERT INTO sockets VALUES (4611686018427387905, 6, 2323986101);
+INSERT INTO sockets VALUES (4611686018427387905, 7, 2357520979);
+INSERT INTO sockets VALUES (4611686018427387905, 9, 2285418970);
+INSERT INTO sockets VALUES (4611686018427387905, 11, 3876796314);
+INSERT INTO items VALUES (0, 0, 1, 4611686018427387906, 1096206669, 106, 1, 1, 0, 1, 10, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427387906, 0, 996573084);
+INSERT INTO sockets VALUES (4611686018427387906, 1, 1332244541);
+INSERT INTO sockets VALUES (4611686018427387906, 2, 106909392);
+INSERT INTO sockets VALUES (4611686018427387906, 3, 4071163871);
+INSERT INTO sockets VALUES (4611686018427387906, 4, 2360754333);
+INSERT INTO sockets VALUES (4611686018427387906, 5, 4248210736);
+INSERT INTO sockets VALUES (4611686018427387906, 6, 2323986101);
+INSERT INTO sockets VALUES (4611686018427387906, 9, 2285418970);
+INSERT INTO items VALUES (0, 0, 2, 4611686018427387907, 1864563948, 106, 1, 2, 0, 1, 8, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427387907, 0, 3642491337);
+INSERT INTO sockets VALUES (4611686018427387907, 1, 938542991);
+INSERT INTO sockets VALUES (4611686018427387907, 2, 2363751990);
+INSERT INTO sockets VALUES (4611686018427387907, 3, 354401740);
+INSERT INTO sockets VALUES (4611686018427387907, 4, 2590710093);
+INSERT INTO sockets VALUES (4611686018427387907, 6, 2931483505);
+INSERT INTO sockets VALUES (4611686018427387907, 7, 2603105938);
+INSERT INTO items VALUES (0, 0, 3, 4611686018427387908, 4070132608, 106, 1, 3, 0, 1, 11, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427387908, 0, 3961599962);
+INSERT INTO sockets VALUES (4611686018427387908, 1, 807186981);
+INSERT INTO sockets VALUES (4611686018427387908, 2, 807186981);
+INSERT INTO sockets VALUES (4611686018427387908, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427387908, 5, 2765543780);
+INSERT INTO sockets VALUES (4611686018427387908, 6, 969663972);
+INSERT INTO sockets VALUES (4611686018427387908, 7, 2236091344);
+INSERT INTO sockets VALUES (4611686018427387908, 8, 2819908046);
+INSERT INTO sockets VALUES (4611686018427387908, 9, 32051168);
+INSERT INTO sockets VALUES (4611686018427387908, 10, 702981643);
+INSERT INTO items VALUES (0, 0, 4, 4611686018427387909, 1636205905, 106, 1, 4, 0, 1, 11, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427387909, 0, 3961599962);
+INSERT INTO sockets VALUES (4611686018427387909, 1, 1844045567);
+INSERT INTO sockets VALUES (4611686018427387909, 2, 1844045567);
+INSERT INTO sockets VALUES (4611686018427387909, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427387909, 5, 2765543780);
+INSERT INTO sockets VALUES (4611686018427387909, 6, 969663972);
+INSERT INTO sockets VALUES (4611686018427387909, 7, 2236091344);
+INSERT INTO sockets VALUES (4611686018427387909, 8, 2819908046);
+INSERT INTO sockets VALUES (4611686018427387909, 9, 32051168);
+INSERT INTO sockets VALUES (4611686018427387909, 10, 702981643);
+INSERT INTO items VALUES (0, 0, 5, 4611686018427387910, 1863170823, 106, 1, 5, 0, 1, 11, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427387910, 0, 3961599962);
+INSERT INTO sockets VALUES (4611686018427387910, 1, 1659393211);
+INSERT INTO sockets VALUES (4611686018427387910, 2, 1659393211);
+INSERT INTO sockets VALUES (4611686018427387910, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427387910, 5, 2765543780);
+INSERT INTO sockets VALUES (4611686018427387910, 6, 969663972);
+INSERT INTO sockets VALUES (4611686018427387910, 7, 2236091344);
+INSERT INTO sockets VALUES (4611686018427387910, 8, 2819908046);
+INSERT INTO sockets VALUES (4611686018427387910, 9, 32051168);
+INSERT INTO sockets VALUES (4611686018427387910, 10, 702981643);
+INSERT INTO items VALUES (0, 0, 6, 4611686018427387911, 193869520, 106, 1, 6, 0, 1, 11, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427387911, 0, 3961599962);
+INSERT INTO sockets VALUES (4611686018427387911, 1, 573150099);
+INSERT INTO sockets VALUES (4611686018427387911, 2, 573150099);
+INSERT INTO sockets VALUES (4611686018427387911, 3, 1694242450);
+INSERT INTO sockets VALUES (4611686018427387911, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427387911, 5, 334475187);
+INSERT INTO sockets VALUES (4611686018427387911, 6, 2236091344);
+INSERT INTO sockets VALUES (4611686018427387911, 7, 3912049957);
+INSERT INTO sockets VALUES (4611686018427387911, 8, 91007917);
+INSERT INTO sockets VALUES (4611686018427387911, 9, 929438819);
+INSERT INTO sockets VALUES (4611686018427387911, 10, 702981643);
+INSERT INTO items VALUES (0, 0, 7, 4611686018427387912, 3044599574, 106, 1, 7, 0, 1, 7, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427387912, 0, 481675395);
+INSERT INTO sockets VALUES (4611686018427387912, 1, 1137289077);
+INSERT INTO sockets VALUES (4611686018427387912, 2, 1137289077);
+INSERT INTO sockets VALUES (4611686018427387912, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427387912, 5, 2765543780);
+INSERT INTO sockets VALUES (4611686018427387912, 6, 702981643);
+INSERT INTO items VALUES (0, 0, 8, 4611686018427387913, 4135938409, 0, 1, 8, 0, 1, 4, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427387913, 0, 4051388481);
+INSERT INTO sockets VALUES (4611686018427387913, 2, 3921006353);
+INSERT INTO sockets VALUES (4611686018427387913, 3, 2426387438);
+INSERT INTO items VALUES (0, 0, 9, 4611686018427387914, 3317837688, 0, 1, 9, 0, 1, 5, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427387914, 0, 4248210736);
+INSERT INTO sockets VALUES (4611686018427387914, 1, 2978337238);
+INSERT INTO sockets VALUES (4611686018427387914, 2, 2323170449);
+INSERT INTO sockets VALUES (4611686018427387914, 3, 1092719892);
+INSERT INTO sockets VALUES (4611686018427387914, 4, 1350878542);
+INSERT INTO items VALUES (0, 0, 10, 4611686018427387915, 292872938, 0, 1, 10, 0, 1, 2, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427387915, 0, 4248210736);
+INSERT INTO sockets VALUES (4611686018427387915, 1, 1390587439);
+INSERT INTO items VALUES (0, 0, 11, 4611686018427387916, 3635991036, 0, 1, 11, 0, 1, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 0, 12, 4611686018427387917, 1460578929, 0, 1, 12, 0, 1, 6, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427387917, 0, 918511364);
+INSERT INTO sockets VALUES (4611686018427387917, 1, 575272392);
+INSERT INTO sockets VALUES (4611686018427387917, 2, 3759858535);
+INSERT INTO sockets VALUES (4611686018427387917, 3, 1671674386);
+INSERT INTO sockets VALUES (4611686018427387917, 4, 1558250725);
+INSERT INTO sockets VALUES (4611686018427387917, 5, 2093762600);
+INSERT INTO items VALUES (0, 0, 13, 4611686018427387918, 1907674138, 0, 1, 13, 0, 1, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 0, 14, 4611686018427387919, 2038017661, 0, 1, 14, 0, 1, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 0, 15, 4611686018427388160, 152583919, 0, 1, 15, 0, 1, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 0, 16, 4611686018427388163, 1631206822, 0, 1, 16, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 0, 4611686018427387921, 1048266744, 106, 1, 17, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 1, 4611686018427387922, 640114618, 106, 1, 18, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 2, 4611686018427387923, 3924212056, 106, 1, 19, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 3, 4611686018427387924, 3393130645, 106, 1, 20, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 4, 4611686018427387925, 3297863558, 106, 1, 21, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 5, 4611686018427387926, 2723909519, 106, 1, 22, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 6, 4611686018427387927, 3691881271, 106, 1, 23, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 7, 4611686018427387928, 3740842661, 106, 1, 24, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 8, 4611686018427387929, 3690523502, 106, 1, 25, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 9, 4611686018427387930, 2715114534, 106, 1, 26, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 10, 4611686018427387931, 1729074423, 106, 1, 27, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 11, 4611686018427387932, 1085797441, 106, 1, 28, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 12, 4611686018427387933, 3537609113, 106, 1, 29, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 13, 4611686018427387934, 1868302492, 106, 1, 30, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 14, 4611686018427387935, 2824453288, 106, 1, 31, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 15, 4611686018427387936, 1705856569, 106, 1, 32, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 16, 4611686018427387937, 1593474975, 106, 1, 33, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 17, 4611686018427387938, 344548395, 106, 1, 34, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 18, 4611686018427387939, 3306564654, 106, 1, 35, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 19, 4611686018427387940, 659922705, 106, 1, 36, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 20, 4611686018427387941, 3571441640, 106, 1, 37, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 21, 4611686018427387942, 883769696, 106, 1, 38, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 22, 4611686018427387943, 377813570, 106, 1, 39, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 23, 4611686018427387944, 193805725, 106, 1, 40, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 24, 4611686018427387945, 4135938410, 0, 1, 41, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 25, 4611686018427387946, 813936739, 0, 1, 42, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 26, 4611686018427387947, 904825093, 0, 1, 43, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 27, 4611686018427387948, 1317468652, 0, 1, 44, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 28, 4611686018427387949, 1906867029, 0, 1, 45, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 29, 4611686018427387950, 2844014413, 0, 1, 46, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 30, 4611686018427387951, 3635192014, 0, 1, 47, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 31, 4611686018427387952, 3352019292, 0, 1, 48, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 32, 4611686018427387953, 298334056, 0, 1, 49, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 33, 4611686018427387954, 1516635053, 0, 1, 50, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 34, 4611686018427387955, 1294248797, 0, 1, 51, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 35, 4611686018427387956, 1447853644, 0, 1, 52, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 36, 4611686018427387920, 4012203003, 0, 1, 53, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 37, 4611686018427387957, 95537029, 0, 1, 54, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 38, 4611686018427387958, 2748215252, 0, 1, 55, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (0, 1, 39, 4611686018427387959, 3769820799, 0, 1, 56, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO characters VALUES (1, -7013740688821976830, 0, 0, 0, 50, 1, 1.0, 308080871, 1, 65535, -1, 57);
+INSERT INTO items VALUES (1, 0, 0, 4611686018427388005, 3843477312, 106, 1, 0, 0, 1, 12, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388005, 0, 2874284214);
+INSERT INTO sockets VALUES (4611686018427388005, 1, 3433396027);
+INSERT INTO sockets VALUES (4611686018427388005, 2, 106909392);
+INSERT INTO sockets VALUES (4611686018427388005, 3, 1168162263);
+INSERT INTO sockets VALUES (4611686018427388005, 4, 460017080);
+INSERT INTO sockets VALUES (4611686018427388005, 5, 4248210736);
+INSERT INTO sockets VALUES (4611686018427388005, 6, 2323986101);
+INSERT INTO sockets VALUES (4611686018427388005, 7, 2357520979);
+INSERT INTO sockets VALUES (4611686018427388005, 9, 2285418970);
+INSERT INTO sockets VALUES (4611686018427388005, 11, 3876796314);
+INSERT INTO items VALUES (1, 0, 1, 4611686018427388006, 1096206669, 106, 1, 1, 0, 1, 10, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388006, 0, 996573084);
+INSERT INTO sockets VALUES (4611686018427388006, 1, 1332244541);
+INSERT INTO sockets VALUES (4611686018427388006, 2, 106909392);
+INSERT INTO sockets VALUES (4611686018427388006, 3, 4071163871);
+INSERT INTO sockets VALUES (4611686018427388006, 4, 2360754333);
+INSERT INTO sockets VALUES (4611686018427388006, 5, 4248210736);
+INSERT INTO sockets VALUES (4611686018427388006, 6, 2323986101);
+INSERT INTO sockets VALUES (4611686018427388006, 9, 2285418970);
+INSERT INTO items VALUES (1, 0, 2, 4611686018427388007, 1864563948, 106, 1, 2, 0, 1, 8, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388007, 0, 3642491337);
+INSERT INTO sockets VALUES (4611686018427388007, 1, 938542991);
+INSERT INTO sockets VALUES (4611686018427388007, 2, 2363751990);
+INSERT INTO sockets VALUES (4611686018427388007, 3, 354401740);
+INSERT INTO sockets VALUES (4611686018427388007, 4, 2590710093);
+INSERT INTO sockets VALUES (4611686018427388007, 6, 2931483505);
+INSERT INTO sockets VALUES (4611686018427388007, 7, 2603105938);
+INSERT INTO items VALUES (1, 0, 3, 4611686018427388008, 3971250660, 106, 1, 3, 0, 1, 11, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388008, 0, 3961599962);
+INSERT INTO sockets VALUES (4611686018427388008, 1, 807186981);
+INSERT INTO sockets VALUES (4611686018427388008, 2, 807186981);
+INSERT INTO sockets VALUES (4611686018427388008, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427388008, 5, 2765543780);
+INSERT INTO sockets VALUES (4611686018427388008, 6, 969663972);
+INSERT INTO sockets VALUES (4611686018427388008, 7, 2236091344);
+INSERT INTO sockets VALUES (4611686018427388008, 8, 2819908046);
+INSERT INTO sockets VALUES (4611686018427388008, 9, 32051168);
+INSERT INTO sockets VALUES (4611686018427388008, 10, 702981643);
+INSERT INTO items VALUES (1, 0, 4, 4611686018427388009, 3918445245, 106, 1, 4, 0, 1, 11, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388009, 0, 3961599962);
+INSERT INTO sockets VALUES (4611686018427388009, 1, 1844045567);
+INSERT INTO sockets VALUES (4611686018427388009, 2, 1844045567);
+INSERT INTO sockets VALUES (4611686018427388009, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427388009, 5, 2765543780);
+INSERT INTO sockets VALUES (4611686018427388009, 6, 969663972);
+INSERT INTO sockets VALUES (4611686018427388009, 7, 2236091344);
+INSERT INTO sockets VALUES (4611686018427388009, 8, 2819908046);
+INSERT INTO sockets VALUES (4611686018427388009, 9, 32051168);
+INSERT INTO sockets VALUES (4611686018427388009, 10, 702981643);
+INSERT INTO items VALUES (1, 0, 5, 4611686018427388010, 1412416835, 106, 1, 5, 0, 1, 11, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388010, 0, 3961599962);
+INSERT INTO sockets VALUES (4611686018427388010, 1, 1659393211);
+INSERT INTO sockets VALUES (4611686018427388010, 2, 1659393211);
+INSERT INTO sockets VALUES (4611686018427388010, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427388010, 5, 2765543780);
+INSERT INTO sockets VALUES (4611686018427388010, 6, 969663972);
+INSERT INTO sockets VALUES (4611686018427388010, 7, 2236091344);
+INSERT INTO sockets VALUES (4611686018427388010, 8, 2819908046);
+INSERT INTO sockets VALUES (4611686018427388010, 9, 32051168);
+INSERT INTO sockets VALUES (4611686018427388010, 10, 702981643);
+INSERT INTO items VALUES (1, 0, 6, 4611686018427388011, 3539357318, 106, 1, 6, 0, 1, 11, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388011, 0, 3961599962);
+INSERT INTO sockets VALUES (4611686018427388011, 1, 573150099);
+INSERT INTO sockets VALUES (4611686018427388011, 2, 573150099);
+INSERT INTO sockets VALUES (4611686018427388011, 3, 3241194940);
+INSERT INTO sockets VALUES (4611686018427388011, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427388011, 5, 334475187);
+INSERT INTO sockets VALUES (4611686018427388011, 6, 2236091344);
+INSERT INTO sockets VALUES (4611686018427388011, 7, 3912049957);
+INSERT INTO sockets VALUES (4611686018427388011, 8, 32051168);
+INSERT INTO sockets VALUES (4611686018427388011, 9, 929438819);
+INSERT INTO sockets VALUES (4611686018427388011, 10, 702981643);
+INSERT INTO items VALUES (1, 0, 7, 4611686018427388012, 694120634, 106, 1, 7, 0, 1, 7, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388012, 0, 3961599962);
+INSERT INTO sockets VALUES (4611686018427388012, 1, 1137289077);
+INSERT INTO sockets VALUES (4611686018427388012, 2, 1137289077);
+INSERT INTO sockets VALUES (4611686018427388012, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427388012, 5, 2765543780);
+INSERT INTO sockets VALUES (4611686018427388012, 6, 702981643);
+INSERT INTO items VALUES (1, 0, 8, 4611686018427388013, 4135938409, 0, 1, 8, 0, 1, 4, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388013, 0, 4051388481);
+INSERT INTO sockets VALUES (4611686018427388013, 2, 3921006353);
+INSERT INTO sockets VALUES (4611686018427388013, 3, 2426387438);
+INSERT INTO items VALUES (1, 0, 9, 4611686018427388014, 3317837688, 0, 1, 9, 0, 1, 5, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388014, 0, 4248210736);
+INSERT INTO sockets VALUES (4611686018427388014, 1, 2978337238);
+INSERT INTO sockets VALUES (4611686018427388014, 2, 2323170449);
+INSERT INTO sockets VALUES (4611686018427388014, 3, 1092719892);
+INSERT INTO sockets VALUES (4611686018427388014, 4, 1350878542);
+INSERT INTO items VALUES (1, 0, 10, 4611686018427388015, 292872938, 0, 1, 10, 0, 1, 2, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388015, 0, 4248210736);
+INSERT INTO sockets VALUES (4611686018427388015, 1, 1390587439);
+INSERT INTO items VALUES (1, 0, 11, 4611686018427388016, 3105935002, 0, 1, 11, 0, 1, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 0, 12, 4611686018427388017, 1460578929, 0, 1, 12, 0, 1, 6, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388017, 0, 918511364);
+INSERT INTO sockets VALUES (4611686018427388017, 1, 575272392);
+INSERT INTO sockets VALUES (4611686018427388017, 2, 3759858535);
+INSERT INTO sockets VALUES (4611686018427388017, 3, 1671674386);
+INSERT INTO sockets VALUES (4611686018427388017, 4, 1558250725);
+INSERT INTO sockets VALUES (4611686018427388017, 5, 2093762600);
+INSERT INTO items VALUES (1, 0, 13, 4611686018427388018, 1907674139, 0, 1, 13, 0, 1, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 0, 14, 4611686018427388019, 2038017661, 0, 1, 14, 0, 1, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 0, 15, 4611686018427388161, 152583919, 0, 1, 15, 0, 1, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 0, 16, 4611686018427388164, 1631206822, 0, 1, 16, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 0, 4611686018427388021, 1048266744, 106, 1, 17, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 1, 4611686018427388022, 640114618, 106, 1, 18, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 2, 4611686018427388023, 3924212056, 106, 1, 19, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 3, 4611686018427388024, 3393130645, 106, 1, 20, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 4, 4611686018427388025, 3297863558, 106, 1, 21, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 5, 4611686018427388026, 2723909519, 106, 1, 22, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 6, 4611686018427388027, 3691881271, 106, 1, 23, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 7, 4611686018427388028, 3740842661, 106, 1, 24, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 8, 4611686018427388029, 3690523502, 106, 1, 25, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 9, 4611686018427388030, 1370341044, 106, 1, 26, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 10, 4611686018427388031, 4071576013, 106, 1, 27, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 11, 4611686018427388032, 2523633779, 106, 1, 28, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 12, 4611686018427388033, 447407759, 106, 1, 29, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 13, 4611686018427388034, 434092458, 106, 1, 30, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 14, 4611686018427388035, 4097166900, 106, 1, 31, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 15, 4611686018427388036, 2503434573, 106, 1, 32, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 16, 4611686018427388037, 4070309619, 106, 1, 33, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 17, 4611686018427388038, 3174233615, 106, 1, 34, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 18, 4611686018427388039, 1980768298, 106, 1, 35, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 19, 4611686018427388040, 272413517, 106, 1, 36, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 20, 4611686018427388041, 925079356, 106, 1, 37, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 21, 4611686018427388042, 2568538788, 106, 1, 38, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 22, 4611686018427388043, 310888006, 106, 1, 39, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 23, 4611686018427388044, 3312368889, 106, 1, 40, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 24, 4611686018427388045, 4135938408, 0, 1, 41, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 25, 4611686018427388046, 2857908936, 0, 1, 42, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 26, 4611686018427388047, 1173626681, 0, 1, 43, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 27, 4611686018427388048, 2067296769, 0, 1, 44, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 28, 4611686018427388049, 3403859120, 0, 1, 45, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 29, 4611686018427388050, 4079130220, 0, 1, 46, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 30, 4611686018427388051, 3941202506, 0, 1, 47, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 31, 4611686018427388052, 3352019292, 0, 1, 48, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 32, 4611686018427388053, 298334056, 0, 1, 49, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 33, 4611686018427388054, 3141315153, 0, 1, 50, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 34, 4611686018427388055, 3474738931, 0, 1, 51, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 35, 4611686018427388056, 697327226, 0, 1, 52, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 36, 4611686018427388020, 2854370169, 0, 1, 53, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 37, 4611686018427388057, 530754878, 0, 1, 54, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 38, 4611686018427388058, 815877596, 0, 1, 55, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (1, 1, 39, 4611686018427388059, 1188569234, 0, 1, 56, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO characters VALUES (2, -7013740688821976829, 0, 0, 2, 50, 1, 1.0, 308080871, 1, 65535, -1, 57);
+INSERT INTO items VALUES (2, 0, 0, 4611686018427388105, 3843477312, 106, 1, 0, 0, 1, 12, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388105, 0, 2874284214);
+INSERT INTO sockets VALUES (4611686018427388105, 1, 3433396027);
+INSERT INTO sockets VALUES (4611686018427388105, 2, 106909392);
+INSERT INTO sockets VALUES (4611686018427388105, 3, 1168162263);
+INSERT INTO sockets VALUES (4611686018427388105, 4, 460017080);
+INSERT INTO sockets VALUES (4611686018427388105, 5, 4248210736);
+INSERT INTO sockets VALUES (4611686018427388105, 6, 2323986101);
+INSERT INTO sockets VALUES (4611686018427388105, 7, 2357520979);
+INSERT INTO sockets VALUES (4611686018427388105, 9, 2285418970);
+INSERT INTO sockets VALUES (4611686018427388105, 11, 3876796314);
+INSERT INTO items VALUES (2, 0, 1, 4611686018427388106, 1096206669, 106, 1, 1, 0, 1, 10, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388106, 0, 996573084);
+INSERT INTO sockets VALUES (4611686018427388106, 1, 1332244541);
+INSERT INTO sockets VALUES (4611686018427388106, 2, 106909392);
+INSERT INTO sockets VALUES (4611686018427388106, 3, 4071163871);
+INSERT INTO sockets VALUES (4611686018427388106, 4, 2360754333);
+INSERT INTO sockets VALUES (4611686018427388106, 5, 4248210736);
+INSERT INTO sockets VALUES (4611686018427388106, 6, 2323986101);
+INSERT INTO sockets VALUES (4611686018427388106, 9, 2285418970);
+INSERT INTO items VALUES (2, 0, 2, 4611686018427388107, 1864563948, 106, 1, 2, 0, 1, 8, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388107, 0, 3642491337);
+INSERT INTO sockets VALUES (4611686018427388107, 1, 938542991);
+INSERT INTO sockets VALUES (4611686018427388107, 2, 2363751990);
+INSERT INTO sockets VALUES (4611686018427388107, 3, 354401740);
+INSERT INTO sockets VALUES (4611686018427388107, 4, 2590710093);
+INSERT INTO sockets VALUES (4611686018427388107, 6, 2931483505);
+INSERT INTO sockets VALUES (4611686018427388107, 7, 2603105938);
+INSERT INTO items VALUES (2, 0, 3, 4611686018427388108, 3926141285, 106, 1, 3, 0, 1, 11, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388108, 0, 3961599962);
+INSERT INTO sockets VALUES (4611686018427388108, 1, 807186981);
+INSERT INTO sockets VALUES (4611686018427388108, 2, 807186981);
+INSERT INTO sockets VALUES (4611686018427388108, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427388108, 5, 2765543780);
+INSERT INTO sockets VALUES (4611686018427388108, 6, 969663972);
+INSERT INTO sockets VALUES (4611686018427388108, 7, 2236091344);
+INSERT INTO sockets VALUES (4611686018427388108, 8, 2819908046);
+INSERT INTO sockets VALUES (4611686018427388108, 9, 32051168);
+INSERT INTO sockets VALUES (4611686018427388108, 10, 702981643);
+INSERT INTO items VALUES (2, 0, 4, 4611686018427388109, 411850804, 106, 1, 4, 0, 1, 11, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388109, 0, 3961599962);
+INSERT INTO sockets VALUES (4611686018427388109, 1, 1844045567);
+INSERT INTO sockets VALUES (4611686018427388109, 2, 1844045567);
+INSERT INTO sockets VALUES (4611686018427388109, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427388109, 5, 2765543780);
+INSERT INTO sockets VALUES (4611686018427388109, 6, 969663972);
+INSERT INTO sockets VALUES (4611686018427388109, 7, 2236091344);
+INSERT INTO sockets VALUES (4611686018427388109, 8, 2819908046);
+INSERT INTO sockets VALUES (4611686018427388109, 9, 32051168);
+INSERT INTO sockets VALUES (4611686018427388109, 10, 702981643);
+INSERT INTO items VALUES (2, 0, 5, 4611686018427388110, 4167605324, 106, 1, 5, 0, 1, 11, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388110, 0, 3961599962);
+INSERT INTO sockets VALUES (4611686018427388110, 1, 1659393211);
+INSERT INTO sockets VALUES (4611686018427388110, 2, 1659393211);
+INSERT INTO sockets VALUES (4611686018427388110, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427388110, 5, 2765543780);
+INSERT INTO sockets VALUES (4611686018427388110, 6, 969663972);
+INSERT INTO sockets VALUES (4611686018427388110, 7, 2236091344);
+INSERT INTO sockets VALUES (4611686018427388110, 8, 2819908046);
+INSERT INTO sockets VALUES (4611686018427388110, 9, 32051168);
+INSERT INTO sockets VALUES (4611686018427388110, 10, 702981643);
+INSERT INTO items VALUES (2, 0, 6, 4611686018427388111, 138282166, 106, 1, 6, 0, 1, 11, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388111, 0, 3961599962);
+INSERT INTO sockets VALUES (4611686018427388111, 1, 573150099);
+INSERT INTO sockets VALUES (4611686018427388111, 2, 573150099);
+INSERT INTO sockets VALUES (4611686018427388111, 3, 3347978673);
+INSERT INTO sockets VALUES (4611686018427388111, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427388111, 5, 334475187);
+INSERT INTO sockets VALUES (4611686018427388111, 6, 2236091344);
+INSERT INTO sockets VALUES (4611686018427388111, 7, 3135249387);
+INSERT INTO sockets VALUES (4611686018427388111, 8, 91007917);
+INSERT INTO sockets VALUES (4611686018427388111, 9, 4085212425);
+INSERT INTO sockets VALUES (4611686018427388111, 10, 702981643);
+INSERT INTO items VALUES (2, 0, 7, 4611686018427388112, 2571396481, 106, 1, 7, 0, 1, 7, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388112, 0, 481675395);
+INSERT INTO sockets VALUES (4611686018427388112, 1, 1137289077);
+INSERT INTO sockets VALUES (4611686018427388112, 2, 1137289077);
+INSERT INTO sockets VALUES (4611686018427388112, 4, 1422712818);
+INSERT INTO sockets VALUES (4611686018427388112, 5, 2765543780);
+INSERT INTO sockets VALUES (4611686018427388112, 6, 702981643);
+INSERT INTO items VALUES (2, 0, 8, 4611686018427388113, 4135938409, 0, 1, 8, 0, 1, 4, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388113, 0, 4051388481);
+INSERT INTO sockets VALUES (4611686018427388113, 2, 3921006353);
+INSERT INTO sockets VALUES (4611686018427388113, 3, 2426387438);
+INSERT INTO items VALUES (2, 0, 9, 4611686018427388114, 3317837688, 0, 1, 9, 0, 1, 5, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388114, 0, 4248210736);
+INSERT INTO sockets VALUES (4611686018427388114, 1, 2978337238);
+INSERT INTO sockets VALUES (4611686018427388114, 2, 2323170449);
+INSERT INTO sockets VALUES (4611686018427388114, 3, 1092719892);
+INSERT INTO sockets VALUES (4611686018427388114, 4, 1350878542);
+INSERT INTO items VALUES (2, 0, 10, 4611686018427388115, 292872938, 0, 1, 10, 0, 1, 2, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388115, 0, 4248210736);
+INSERT INTO sockets VALUES (4611686018427388115, 1, 1390587439);
+INSERT INTO items VALUES (2, 0, 11, 4611686018427388116, 3481861797, 0, 1, 11, 0, 1, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 0, 12, 4611686018427388117, 1460578929, 0, 1, 12, 0, 1, 6, 4, 7, 10, 11, 2, 0);
+INSERT INTO sockets VALUES (4611686018427388117, 0, 918511364);
+INSERT INTO sockets VALUES (4611686018427388117, 1, 575272392);
+INSERT INTO sockets VALUES (4611686018427388117, 2, 3759858535);
+INSERT INTO sockets VALUES (4611686018427388117, 3, 1671674386);
+INSERT INTO sockets VALUES (4611686018427388117, 4, 1558250725);
+INSERT INTO sockets VALUES (4611686018427388117, 5, 2093762600);
+INSERT INTO items VALUES (2, 0, 13, 4611686018427388118, 1907674137, 0, 1, 13, 0, 1, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 0, 14, 4611686018427388119, 2038017661, 0, 1, 14, 0, 1, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 0, 15, 4611686018427388162, 152583919, 0, 1, 15, 0, 1, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 0, 16, 4611686018427388165, 1631206822, 0, 1, 16, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 0, 4611686018427388121, 1048266744, 106, 1, 17, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 1, 4611686018427388122, 640114618, 106, 1, 18, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 2, 4611686018427388123, 3924212056, 106, 1, 19, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 3, 4611686018427388124, 3393130645, 106, 1, 20, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 4, 4611686018427388125, 3297863558, 106, 1, 21, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 5, 4611686018427388126, 2723909519, 106, 1, 22, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 6, 4611686018427388127, 3691881271, 106, 1, 23, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 7, 4611686018427388128, 3740842661, 106, 1, 24, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 8, 4611686018427388129, 3690523502, 106, 1, 25, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 9, 4611686018427388130, 1554079989, 106, 1, 26, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 10, 4611686018427388131, 229923140, 106, 1, 27, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 11, 4611686018427388132, 3388454204, 106, 1, 28, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 12, 4611686018427388133, 2160569198, 106, 1, 29, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 13, 4611686018427388134, 845354673, 106, 1, 30, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 14, 4611686018427388135, 185695659, 106, 1, 31, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 15, 4611686018427388136, 2761343386, 106, 1, 32, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 16, 4611686018427388137, 2859583726, 106, 1, 33, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 17, 4611686018427388138, 188778964, 106, 1, 34, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 18, 4611686018427388139, 3602032567, 106, 1, 35, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 19, 4611686018427388140, 1528483180, 106, 1, 36, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 20, 4611686018427388141, 682780965, 106, 1, 37, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 21, 4611686018427388142, 3692187003, 106, 1, 38, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 22, 4611686018427388143, 1030110631, 106, 1, 39, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 23, 4611686018427388144, 2048903186, 106, 1, 40, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 24, 4611686018427388145, 813936739, 0, 1, 41, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 25, 4611686018427388146, 779216206, 0, 1, 42, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 26, 4611686018427388147, 1317468652, 0, 1, 43, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 27, 4611686018427388148, 3382260610, 0, 1, 44, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 28, 4611686018427388149, 2844014413, 0, 1, 45, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 29, 4611686018427388150, 672488948, 0, 1, 46, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 30, 4611686018427388151, 3564452901, 0, 1, 47, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 31, 4611686018427388152, 3352019292, 0, 1, 48, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 32, 4611686018427388153, 298334056, 0, 1, 49, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 33, 4611686018427388154, 1491605562, 0, 1, 50, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 34, 4611686018427388155, 1492613344, 0, 1, 51, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 35, 4611686018427388156, 3401563735, 0, 1, 52, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 36, 4611686018427388120, 254514436, 0, 1, 53, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 37, 4611686018427388157, 4111030162, 0, 1, 54, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 38, 4611686018427388158, 4009267290, 0, 1, 55, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO items VALUES (2, 1, 39, 4611686018427388159, 1749473785, 0, 1, 56, 0, 0, 0, 4, 7, 10, 11, 2, 0);
+INSERT INTO profile_items VALUES (0, 0, 3159615086, 100000, 0, 1);
+INSERT INTO profile_items VALUES (1, 0, 1022552290, 50000, 0, 1);
+INSERT INTO profile_items VALUES (2, 0, 2817410917, 50000, 0, 1);
+INSERT INTO profile_items VALUES (3, 0, 2979281381, 25, 0, 1);
+INSERT INTO profile_items VALUES (4, 0, 685157383, 500, 0, 1);
+INSERT INTO profile_items VALUES (5, 0, 3853748946, 999, 0, 1);
+INSERT INTO profile_items VALUES (6, 0, 4257549984, 50, 0, 1);
+INSERT INTO profile_items VALUES (7, 0, 4257549985, 10, 0, 1);
+INSERT INTO profile_items VALUES (8, 0, 1422712818, 1000, 0, 1);
+INSERT INTO profile_items VALUES (9, 0, 3668669364, 1000, 0, 1);
+INSERT INTO profile_items VALUES (10, 0, 3448612594, 1000, 0, 1);
+INSERT INTO dismantle_rewards VALUES (0, 3159615086, 25, 2, 0, 0);
+INSERT INTO dismantle_rewards VALUES (1, 3159615086, 50, 4, 0, 0);
+INSERT INTO dismantle_rewards VALUES (2, 3159615086, 100, 8, 0, 0);
+INSERT INTO dismantle_rewards VALUES (3, 3159615086, 250, 16, 0, 0);
+INSERT INTO dismantle_rewards VALUES (4, 3159615086, 500, 32, 0, 0);
+INSERT INTO dismantle_rewards VALUES (5, 1022552290, 3, 16, 0, 0);
+INSERT INTO dismantle_rewards VALUES (6, 1022552290, 5, 32, 0, 0);
+INSERT INTO dismantle_rewards VALUES (7, 685157383, 1, 8, 1, 0);
+INSERT INTO dismantle_rewards VALUES (8, 685157383, 3, 48, 1, 0);
+INSERT INTO dismantle_rewards VALUES (9, 3853748946, 3, 48, 0, 1);
+INSERT INTO unlocks VALUES (-1, 0, 26, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 27, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 28, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 29, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 30, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 31, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 32, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 33, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 34, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 35, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 36, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 37, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 38, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 39, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 40, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 41, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 42, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 43, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 44, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 45, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 46, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 52, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 78, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 81, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 83, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 84, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 85, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 89, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 90, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 95, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 97, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 98, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 99, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 101, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 111, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 141, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 207, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 241, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 295, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 296, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 297, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 298, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 299, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 300, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 301, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 303, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 304, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 305, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 306, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 307, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 308, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 309, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 310, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 311, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 312, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 313, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 314, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 315, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 316, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 320, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 321, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 322, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 323, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 324, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 325, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 326, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 327, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 328, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 329, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 330, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 331, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 332, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 333, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 334, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 335, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 336, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 337, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 338, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 339, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 340, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 342, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 343, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 344, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 345, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 346, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 347, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 348, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 349, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 350, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 351, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 355, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 356, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 357, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 358, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 359, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 360, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 361, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 362, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 363, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 364, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 365, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 366, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 367, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 368, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 369, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 370, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 371, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 372, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 373, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 374, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 376, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 377, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 378, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 379, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 380, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 381, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 382, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 383, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 384, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 385, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 386, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 390, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 391, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 392, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 393, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 394, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 395, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 396, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 397, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 398, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 399, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 400, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 401, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 402, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 403, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 404, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 405, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 406, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 407, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 408, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 409, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 410, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 411, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 412, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 413, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 414, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 415, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 416, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 417, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 418, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 419, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 420, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 421, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 422, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 423, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 424, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 425, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 426, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 427, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 428, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 429, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 430, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 431, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 432, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 433, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 434, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 435, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 436, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 437, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 438, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 439, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 440, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 441, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 442, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 443, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 444, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 445, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 446, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 447, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 448, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 449, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 450, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 451, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 452, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 453, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 454, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 455, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 456, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 457, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 458, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 459, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 460, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 461, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 462, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 463, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 464, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 465, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 466, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 467, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 468, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 469, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 470, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 471, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 472, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 473, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 474, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 475, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 476, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 477, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 478, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 479, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 480, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 481, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 482, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 483, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 484, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 487, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 488, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 489, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 490, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 491, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 492, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 493, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 494, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 495, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 496, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 497, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 498, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 499, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 500, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 501, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 502, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 503, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 504, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 505, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 506, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 507, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 508, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 509, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 510, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 511, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 512, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 513, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 514, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 515, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 516, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 517, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 518, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 519, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 520, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 521, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 522, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 523, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 524, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 525, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 526, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 527, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 528, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 529, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 530, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 531, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 532, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 533, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 534, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 535, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 536, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 537, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 538, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 539, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 540, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 541, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 542, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 543, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 544, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 545, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 546, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 547, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 548, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 549, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 550, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 551, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 552, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 553, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 554, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 555, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 556, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 557, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 558, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 561, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 562, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 563, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 564, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 565, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 566, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 567, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 568, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 569, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 570, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 571, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 572, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 573, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 574, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 575, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 576, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 577, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 578, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 579, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 580, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 581, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 582, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 583, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 584, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 585, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 586, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 587, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 588, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 589, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 590, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 591, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 592, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 593, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 594, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 595, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 596, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 597, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 598, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 599, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 600, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 601, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 602, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 603, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 604, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 605, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 606, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 607, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 608, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 609, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 610, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 611, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 612, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 613, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 614, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 615, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 616, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 617, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 618, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 619, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 620, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 621, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 622, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 623, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 624, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 625, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 626, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 627, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 628, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 629, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 630, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 631, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 632, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 635, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 636, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 637, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 638, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 639, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 640, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 641, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 642, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 643, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 644, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 645, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 646, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 647, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 648, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 649, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 650, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 651, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 652, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 653, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 654, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 655, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 656, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 657, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 658, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 659, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 660, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 661, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 662, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 663, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 664, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 665, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 666, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 681, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 683, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 684, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 685, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 686, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 687, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 717, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 718, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 728, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 729, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 730, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 731, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 732, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 733, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 734, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 735, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 745, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 746, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 747, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 748, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 749, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 750, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 754, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 758, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 759, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 760, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 761, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 762, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 763, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 764, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 765, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 766, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 767, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 768, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 769, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 770, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 771, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 772, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 773, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 774, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 775, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 776, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 777, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 778, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 779, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 780, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 781, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 782, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 783, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 784, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 785, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 786, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 787, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 788, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 789, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 796, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 797, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 798, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 799, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 800, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 801, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 802, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 803, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 804, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 805, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 806, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 807, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 808, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 810, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 811, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 812, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 813, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 814, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 815, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 816, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 817, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 818, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 819, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 820, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 821, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 822, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 823, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 824, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 825, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 826, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 827, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 828, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 829, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 831, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 832, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 833, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 834, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 835, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 836, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 837, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 838, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 839, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 840, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 841, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 842, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 843, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 844, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 845, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 846, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 847, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 848, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 849, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 860, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 861, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 862, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 863, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 864, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 865, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 866, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 867, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 868, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 869, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 870, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 871, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 872, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 873, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 874, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 875, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 876, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 877, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 878, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 879, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 880, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 881, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 882, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 883, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 884, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 885, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 935, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 936, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 937, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 938, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 939, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 940, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 941, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 942, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 943, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 944, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 945, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 946, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 947, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 948, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 949, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 950, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 951, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 952, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 954, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 955, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 956, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 957, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 958, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 959, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 960, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 961, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 962, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 963, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 964, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 965, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 966, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 967, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 968, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 969, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 970, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 971, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 972, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 973, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 974, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 975, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 976, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 977, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 978, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 986, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1034, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1039, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1058, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1063, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1095, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1100, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1202, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1217, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1585, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1599, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1600, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1601, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1606, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1614, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1615, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1616, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1617, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1618, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1619, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1620, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1621, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1622, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1623, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1624, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1625, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1626, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1627, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1628, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1629, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1630, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1631, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1632, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1633, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1634, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1635, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1638, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1641, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1644, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1647, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1650, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1653, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1656, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1659, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1662, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1669, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1670, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1671, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1672, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1673, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1674, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1675, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1676, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1677, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1678, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1679, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1680, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1681, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1682, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1683, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1684, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1685, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1688, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1691, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1694, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1697, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1698, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1699, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1700, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1701, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1702, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1703, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1704, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1705, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1706, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1707, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1708, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1709, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1710, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1711, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1712, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1713, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1714, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1715, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1716, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1717, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1718, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1719, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1720, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1721, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1722, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1723, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1724, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1725, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1726, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1727, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1728, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1729, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1730, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1731, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1732, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1733, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1734, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1735, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1736, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1737, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1738, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1739, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1740, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1741, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1742, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1743, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1744, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1745, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1746, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1747, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1748, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1749, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1750, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1751, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1752, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1753, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1754, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1755, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1756, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1757, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1758, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1759, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1760, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1761, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1762, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1763, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1764, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1765, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1766, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1767, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1768, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1769, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1770, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1771, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1772, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1773, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1774, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1791, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1792, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1793, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1794, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1795, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1796, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1797, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1798, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1799, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1800, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1801, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1802, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1803, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1804, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1805, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1806, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1807, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1808, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1809, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1810, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1811, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1812, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1813, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1814, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1815, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1816, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1817, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1818, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1819, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1820, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1821, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1822, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1823, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1824, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1825, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1827, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1828, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1829, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1830, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1832, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1833, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1834, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1835, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1836, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1837, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1838, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1839, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1840, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1841, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1842, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1843, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1844, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1845, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1846, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1847, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1848, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1849, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1850, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1851, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1852, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1853, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1854, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1855, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1856, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1857, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1858, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1859, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1860, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1861, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1862, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1863, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1864, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1865, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1866, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1867, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1868, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1869, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1870, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1871, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1872, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1873, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1874, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1875, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1876, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1877, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1878, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1879, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1880, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1881, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1882, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1883, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1884, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1885, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1886, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1887, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1888, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1889, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1890, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1891, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1892, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1893, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1894, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1895, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1896, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1897, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1898, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1899, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1900, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1901, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1902, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1903, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1904, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1905, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1906, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1907, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1908, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1909, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1910, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1911, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1912, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1913, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1914, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1915, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1916, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1917, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1918, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1919, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1920, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1921, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1922, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1923, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1924, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1925, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1926, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1927, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1928, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1929, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1930, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1931, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1932, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1933, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1934, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1935, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1936, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1937, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1938, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1939, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1940, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1941, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1942, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1943, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1944, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1945, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1946, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1947, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1948, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1949, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1950, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1951, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1952, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1953, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1954, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1955, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1956, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1957, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1958, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1959, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1960, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1961, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1962, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1963, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1964, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1965, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1966, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1967, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1968, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1969, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1970, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1971, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1972, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1973, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1974, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1975, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1976, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1977, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1978, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1979, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1980, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1981, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1982, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1983, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1984, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1985, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1986, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1987, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1988, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1989, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1990, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1991, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1992, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1993, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1994, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1995, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1996, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1997, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1998, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 1999, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2000, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2001, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2002, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2003, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2005, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2006, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2007, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2008, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2009, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2010, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2011, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2012, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2013, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2014, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2015, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2016, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2017, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2018, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2019, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2020, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2021, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2022, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2023, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2024, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2026, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2027, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2028, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2029, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2031, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2032, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2033, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2034, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2036, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2037, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2038, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2039, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2041, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2042, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2043, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2044, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2046, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2047, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2048, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2049, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2051, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2052, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2053, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2054, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2056, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2057, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2058, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2059, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2061, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2065, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2066, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2067, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2068, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2069, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2070, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2071, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2072, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2073, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2074, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2075, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2076, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2077, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2078, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2079, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2080, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2081, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2082, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2083, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2084, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2085, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2086, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2087, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2088, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2089, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2090, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2091, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2092, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2093, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2094, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2095, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2096, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2097, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2099, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2100, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2101, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2102, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2103, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2104, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2105, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2106, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2107, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2108, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2109, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2110, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2111, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2112, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2113, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2121, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2122, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2123, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2124, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2125, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2126, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2127, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2128, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2129, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2130, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2131, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2132, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2133, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2134, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2135, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2136, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2137, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2138, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2139, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2140, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2141, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2142, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2143, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2144, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2145, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2146, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2147, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2148, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2149, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2150, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2151, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2152, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2153, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2154, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2155, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2156, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2157, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2158, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2159, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2160, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2161, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2162, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2163, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2164, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2165, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2166, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2167, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2168, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2169, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2170, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2171, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2172, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2173, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2174, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2175, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2176, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2177, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2178, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2179, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2180, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2181, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2182, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2183, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2184, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2185, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2186, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2187, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2188, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2189, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2190, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2191, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2192, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2193, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2194, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2195, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2196, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2197, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2198, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2199, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2200, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2201, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2202, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2203, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2204, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2205, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2206, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2207, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2208, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2211, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2213, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2214, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2215, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2216, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2217, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2218, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2219, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2220, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2221, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2222, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2223, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2224, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2225, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2226, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2227, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2228, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2229, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2230, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2231, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2232, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2233, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2234, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2235, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2236, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2237, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2238, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2239, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2240, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2241, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2242, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2243, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2244, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2245, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2246, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2247, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2248, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2249, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2250, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2251, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2252, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2253, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2254, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2255, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2256, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2257, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2259, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2260, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2261, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2262, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2263, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2264, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2265, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2266, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2267, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2268, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2269, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2270, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2271, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2272, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2273, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2274, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2275, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2276, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2277, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2278, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2279, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2280, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2281, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2282, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2283, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2284, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2285, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2286, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2287, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2288, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2289, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2290, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2291, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2292, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2293, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2294, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2295, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2296, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2297, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2298, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2299, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2300, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2301, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2302, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2303, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2304, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2305, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2306, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2307, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2308, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2309, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2310, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2311, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2312, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2313, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2314, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2315, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2316, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2317, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2318, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2319, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2320, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2321, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2322, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2323, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2324, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2325, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2326, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2327, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2328, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2329, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2330, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2331, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2332, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2333, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2334, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2335, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2336, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2337, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2338, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2339, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2340, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2341, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2342, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2343, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2344, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2345, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2346, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2347, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2348, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2349, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2351, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2352, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2353, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2354, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2355, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2356, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2357, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2358, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2359, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2360, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2361, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2362, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2363, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2364, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2365, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2366, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2367, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2368, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2369, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2370, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2371, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2372, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2373, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2374, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2375, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2376, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2377, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2378, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2379, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2380, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2381, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2382, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2383, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2384, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2385, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2386, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2387, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2388, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2389, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2390, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2391, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2392, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2393, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2394, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2395, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2396, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2397, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2398, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2400, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2401, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2402, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2403, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2404, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2405, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2406, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2407, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2408, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2409, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2410, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2411, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2412, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2413, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2414, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2415, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2416, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2417, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2418, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2419, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2420, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2421, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2422, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2423, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2424, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2425, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2426, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2427, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2428, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2429, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2430, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2431, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2432, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2433, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2434, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2435, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2436, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2437, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2438, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2439, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2440, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2441, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2442, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2443, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2444, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2445, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2446, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2447, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2449, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2450, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2451, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2452, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2453, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2454, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2455, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2456, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2457, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2458, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2464, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2465, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2466, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2467, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2468, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2469, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2470, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2471, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2472, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2473, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2474, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2475, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2476, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2477, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2478, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2479, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2480, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2481, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2482, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2483, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2484, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2485, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2486, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2487, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2488, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2489, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2490, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2491, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2507, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2508, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2509, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2510, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2511, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2512, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2513, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2514, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2515, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2516, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2517, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2518, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2519, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2520, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2521, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2522, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2523, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2524, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2525, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2554, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2555, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2556, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2557, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2558, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2559, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2560, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2561, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2562, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2563, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2564, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2569, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2570, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2571, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2572, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2573, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2574, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2575, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2576, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2577, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2578, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2579, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2580, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2581, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2582, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2583, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2584, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2585, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2586, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2587, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2588, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2589, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2590, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2591, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2592, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2593, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2594, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2595, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2596, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2597, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2598, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2599, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2600, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2601, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2602, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2603, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2604, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2605, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2606, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2607, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2608, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2609, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2610, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2611, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2612, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2613, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2614, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2615, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2616, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2617, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2618, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2619, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2620, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2621, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2622, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2623, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2624, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2625, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2626, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2627, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2628, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2629, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2630, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2642, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2643, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2644, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2645, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2646, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2647, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2648, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2649, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2650, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2651, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2652, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2653, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2654, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2655, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2656, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2657, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2658, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2659, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2660, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2661, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2662, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2663, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2664, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2665, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2666, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2667, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2668, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2669, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2670, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2671, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2672, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2673, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2674, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2675, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2676, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2677, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2678, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2679, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2680, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2681, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2682, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2683, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2684, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2685, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2686, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2687, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2688, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2689, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2690, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2691, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2692, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2693, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2694, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2695, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2696, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2697, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2698, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2699, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2700, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2701, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2702, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2703, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2704, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2705, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2706, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2707, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2708, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2709, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2710, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2711, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2712, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2713, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2714, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2715, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2716, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2717, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2718, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2719, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2720, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2721, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2722, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2723, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2724, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2725, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2726, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2727, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2728, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2735, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2736, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2737, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2738, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2739, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2740, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2741, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2742, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2743, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2744, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2745, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2746, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2747, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2748, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2749, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2750, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2751, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2752, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2753, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2754, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2755, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2756, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2757, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2758, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2759, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2760, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2761, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2762, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2764, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2765, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2766, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2767, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2768, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2772, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2775, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2776, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2777, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2778, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2779, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2780, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2784, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2785, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2786, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2787, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2788, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2789, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2790, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2791, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2792, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2793, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2794, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2795, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2796, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2808, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2809, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2810, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2811, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2812, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2813, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2814, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2815, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2816, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2817, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2818, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2821, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2822, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2823, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2824, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2825, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2826, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2827, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2830, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2831, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2832, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2833, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2834, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2835, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2836, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2837, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2838, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2839, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2840, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2841, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2843, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2845, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2846, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2848, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2849, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2850, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2851, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2852, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2853, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2855, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2856, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2857, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2858, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2859, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2860, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2861, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2862, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2863, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2864, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2865, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2867, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2868, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2869, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2870, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2871, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2872, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2873, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2874, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2875, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2876, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2877, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2878, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2879, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2880, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2881, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2882, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2883, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2884, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2885, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2886, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2887, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2888, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2889, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2890, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2891, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2892, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2893, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2894, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2895, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2896, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2897, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2898, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2899, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2900, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2901, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2902, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2903, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2904, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2905, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2906, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2908, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2909, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2910, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2911, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2912, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2913, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2914, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2915, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2916, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2917, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2918, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2919, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2920, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2921, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2922, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2923, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2924, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2925, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2926, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2927, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2928, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2929, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2930, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2931, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2932, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2933, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2934, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2935, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2936, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2937, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2938, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2939, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2940, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2941, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2942, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2943, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2945, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2946, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2947, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2948, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2949, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2950, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2951, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2952, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2953, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2954, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2955, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2956, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2957, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2958, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2959, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2960, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2961, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2962, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2963, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2964, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2965, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2966, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2967, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2968, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2969, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2970, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2971, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2972, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2973, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2974, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2975, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2976, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2977, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2978, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2979, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2980, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2981, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2982, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2983, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2984, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 2985, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3001, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3002, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3003, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3004, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3005, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3006, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3007, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3008, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3009, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3010, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3011, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3012, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3013, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3014, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3015, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3016, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3017, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3018, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3019, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3020, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3021, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3022, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3023, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3024, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3025, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3026, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3027, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3028, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3029, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3030, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3031, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3032, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3033, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3034, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3035, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3036, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3037, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3038, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3039, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3040, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3041, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3042, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3043, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3044, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3045, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3046, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3051, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3052, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3053, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3054, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3055, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3056, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3057, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3058, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3059, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3060, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3061, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3062, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3063, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3064, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3065, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3066, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3067, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3068, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3069, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3070, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3071, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3072, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3073, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3074, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3075, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3076, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3077, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3078, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3079, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3080, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3081, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3082, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3083, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3084, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3085, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3089, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3090, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3091, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3092, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3093, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3094, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3095, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3096, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3097, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3098, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3099, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3100, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3107, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3108, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3109, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3110, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3133, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3134, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3135, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3136, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3137, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3138, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3139, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3140, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3141, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3142, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3143, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3144, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3145, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3146, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3147, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3153, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3154, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3155, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3156, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3157, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3158, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3159, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3160, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3161, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3162, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3163, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3164, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3165, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3166, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3167, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3173, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3174, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3175, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3176, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3177, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3178, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3179, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3180, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3181, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3182, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3183, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3184, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3185, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3186, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3187, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3193, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3194, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3195, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3196, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3197, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3198, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3199, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3200, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3201, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3202, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3203, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3204, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3205, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3206, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3207, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3208, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3209, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3210, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3211, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3212, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3213, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3214, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3215, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3216, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3217, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3218, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3220, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3221, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3222, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3223, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3224, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3225, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3226, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3227, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3228, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3229, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3230, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3231, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3232, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3233, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3240, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3241, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3245, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3248, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3249, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3250, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3251, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3252, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3253, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3254, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3255, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3256, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3257, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3258, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3259, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3265, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3266, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3303, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3304, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3305, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3306, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3307, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3308, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3309, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3310, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3311, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3312, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3313, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3314, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3315, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3316, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3317, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3318, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3319, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3320, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3321, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3322, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3323, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3324, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3325, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3326, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3327, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3328, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3329, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3330, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3331, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3332, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3333, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3334, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3335, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3336, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3337, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3338, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3339, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3340, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3341, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3342, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3343, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3344, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3345, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3346, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3347, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3348, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3349, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3350, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3351, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3352, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3353, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3354, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3370, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3371, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3372, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3373, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3374, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3375, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3376, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3377, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3378, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3379, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3380, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3381, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3382, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3383, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3384, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3385, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3386, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3387, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3388, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3389, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3390, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3391, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3392, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3393, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3394, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3395, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3396, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3397, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3398, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3399, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3400, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3401, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3402, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3403, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3404, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3405, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3406, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3407, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3408, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3409, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3410, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3411, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3412, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3413, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3414, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3415, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3416, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3417, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3418, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3419, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3420, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3421, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3422, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3423, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3424, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3425, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3426, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3427, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3428, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3429, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3430, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3431, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3447, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3448, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3449, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3450, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3451, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3452, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3453, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3454, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3455, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3456, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3457, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3458, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3459, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3460, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3461, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3462, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3463, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3464, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3465, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3466, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3467, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3468, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3469, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3470, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3471, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3472, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3473, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3474, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3475, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3476, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3477, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3478, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3479, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3480, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3481, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3482, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3483, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3484, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3485, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3486, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3487, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3488, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3489, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3490, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3491, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3492, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3493, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3494, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3495, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3496, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3497, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3498, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3499, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3500, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3501, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3502, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3503, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3504, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3505, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3506, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3507, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3508, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3524, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3525, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3526, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3527, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3528, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3529, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3530, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3531, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3532, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3533, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3534, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3535, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3536, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3537, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3538, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3540, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3541, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3542, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3543, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3544, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3545, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3546, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3547, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3548, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3549, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3550, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3551, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3552, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3553, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3554, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3555, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3556, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3557, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3558, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3559, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3560, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3561, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3562, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3563, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3564, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3565, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3566, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3568, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3569, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3570, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3571, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3572, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3573, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3574, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3575, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3576, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3577, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3581, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3582, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3583, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3584, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3585, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3586, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3587, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3588, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3589, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3590, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3591, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3593, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3594, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3596, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3597, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3599, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3600, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3602, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3603, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3641, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3642, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3644, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3646, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3647, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3648, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3649, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3650, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3651, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3652, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3653, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3654, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3655, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3656, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3657, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3658, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3659, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3660, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3661, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3662, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3663, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3664, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3665, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3666, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3667, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3668, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3669, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3670, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3671, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3672, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3673, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3674, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3675, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3676, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3677, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3678, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3679, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3680, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3681, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3682, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3683, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3684, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3685, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3686, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3687, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3688, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3689, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3690, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3691, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3692, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3693, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3694, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3695, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3696, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3697, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3698, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3699, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3700, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3701, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3702, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3703, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3704, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3705, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3706, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3707, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3713, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3714, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3720, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3721, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3727, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3728, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3729, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3730, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3731, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3732, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3733, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3734, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3735, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3736, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3737, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3738, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3739, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3740, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3741, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3742, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3743, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3744, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3745, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3746, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3747, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3748, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3749, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3750, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3751, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3752, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3753, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3754, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3755, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3756, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3757, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3758, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3759, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3760, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3761, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3762, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3763, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3764, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3765, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3766, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3767, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3768, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3769, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3770, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3771, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3772, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3773, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3774, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3775, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3776, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3777, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3778, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3779, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3780, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3781, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3782, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3783, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3784, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3785, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3786, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3787, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3788, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3789, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3790, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3791, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3792, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3854, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3855, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3856, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3930, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3931, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3960, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3961, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3962, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3963, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3964, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3965, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3966, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3967, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3968, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3969, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3970, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3971, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3972, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3973, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3974, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3975, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3976, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3977, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3978, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3979, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3980, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3984, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3985, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3986, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3987, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3988, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3989, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3990, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3991, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3992, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3993, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3994, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3995, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3996, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3997, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3998, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 3999, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4000, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4001, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4002, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4003, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4004, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4005, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4006, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4007, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4008, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4009, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4010, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4011, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4012, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4013, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4014, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4015, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4016, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4017, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4018, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4019, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4020, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4021, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4022, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4023, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4024, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4025, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4026, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4027, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4028, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4029, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4030, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4031, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4032, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4033, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4034, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4035, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4036, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4037, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4038, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4039, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4040, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4041, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4042, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4043, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4044, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4046, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4047, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4048, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4049, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4050, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4051, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4052, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4053, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4054, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4055, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4056, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4057, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4058, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4059, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4061, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4062, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4063, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4068, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4069, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4071, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4072, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4073, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4074, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4076, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4081, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4083, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4084, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4085, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4086, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4087, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4088, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4089, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4090, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4091, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4092, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4093, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4094, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4095, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4096, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4097, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4098, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4099, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4100, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4101, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4102, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4103, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4104, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4105, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4106, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4107, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4108, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4109, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4110, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4111, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4112, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4113, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4114, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4115, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4116, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4117, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4118, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4119, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4120, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4122, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4123, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4124, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4125, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4126, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4127, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4128, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4129, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4130, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4144, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4145, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4146, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4147, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4148, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4149, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4150, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4151, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4152, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4153, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4154, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4155, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4156, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4157, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4158, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4159, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4160, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4161, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4162, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4163, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4164, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4165, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4166, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4167, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4168, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4169, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4170, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4171, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4172, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4173, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4183, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4184, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4185, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4186, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4187, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4188, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4189, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4190, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4191, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4192, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4193, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4194, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4195, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4196, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4197, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4198, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4199, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4200, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4201, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4202, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4203, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4204, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4206, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4207, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4208, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4209, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4210, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4211, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4212, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4213, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4214, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4215, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4216, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4217, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4218, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4219, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4220, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4221, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4222, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4223, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4224, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4225, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4226, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4227, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4228, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4229, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4230, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4231, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4245, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4246, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4247, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4248, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4249, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4250, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4251, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4252, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4253, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4254, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4255, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4256, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4257, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4258, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4259, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4260, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4261, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4262, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4263, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4264, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4265, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4266, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4267, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4268, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4269, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4270, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4271, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4272, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4273, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4274, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4275, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4276, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4277, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4278, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4279, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4280, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4281, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4282, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4283, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4284, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4285, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4286, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4287, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4288, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4289, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4290, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4291, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4292, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4293, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4294, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4295, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4296, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4297, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4298, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4299, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4300, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4301, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4302, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4303, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4304, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4305, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4306, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4307, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4308, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4309, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4310, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4311, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4312, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4313, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4314, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4315, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4316, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4317, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4318, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4319, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4320, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4321, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4322, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4323, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4324, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4325, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4330, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4331, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4332, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4333, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4347, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4348, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4349, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4350, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4351, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4352, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4353, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4354, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4355, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4356, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4357, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4362, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4363, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4364, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4365, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4366, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4367, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4368, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4369, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4370, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4376, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4377, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4378, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4379, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4380, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4381, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4382, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4383, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4384, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4385, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4386, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4387, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4388, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4389, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4390, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4391, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4392, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4393, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4394, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4395, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4396, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4397, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4398, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4399, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4400, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4401, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4402, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4404, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4405, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4406, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4410, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4411, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4412, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4413, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4414, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4415, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4416, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4417, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4418, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4419, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4420, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4421, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4424, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4425, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4428, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4429, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4430, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4431, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4432, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4433, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4434, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4435, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4436, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4437, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4438, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4439, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4440, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4441, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4442, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4443, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4444, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4445, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4446, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4447, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4448, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4449, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4451, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4452, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4454, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4474, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4478, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4490, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4491, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4492, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4493, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4494, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4495, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4496, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4497, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4498, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4499, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4500, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4501, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4502, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4503, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4505, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4508, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4509, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4510, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4511, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4512, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4513, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4514, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4515, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4516, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4517, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4518, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4519, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4520, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4521, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4522, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4523, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4524, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4525, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4526, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4527, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4528, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4529, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4530, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4531, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4533, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4534, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4535, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4536, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4538, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4539, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4540, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4541, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4542, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4543, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4544, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4545, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4546, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4547, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4548, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4549, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4550, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4551, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4552, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4553, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4554, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4555, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4556, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4557, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4558, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4559, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4560, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4561, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4562, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4563, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4564, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4565, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4566, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4567, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4568, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4569, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4570, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4571, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4572, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4573, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4574, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4575, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4576, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4577, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4578, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4579, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4580, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4581, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4582, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4583, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4584, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4585, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4586, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4587, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4588, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4589, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4590, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4591, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4592, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4593, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4594, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4595, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4596, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4597, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4598, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4599, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4600, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4601, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4602, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4603, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4604, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4605, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4606, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4607, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4608, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4609, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4610, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4611, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4612, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4613, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4614, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4615, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4616, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4617, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4618, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4619, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4620, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4621, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4622, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4623, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4624, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4625, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4626, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4627, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4628, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4629, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4630, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4631, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4632, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4633, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4641, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4642, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4643, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4644, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4645, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4646, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4647, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4648, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4649, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4650, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4651, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4652, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4653, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4654, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4655, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4656, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4657, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4658, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4659, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4660, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4661, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4662, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4663, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4664, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4665, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4666, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4667, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4668, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4669, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4670, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4671, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4672, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4673, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4674, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4675, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4676, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4677, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4678, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4679, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4680, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4681, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4682, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4683, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4684, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4685, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4686, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4687, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4688, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4689, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4690, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4691, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4692, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4693, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4694, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4695, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4696, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4697, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4698, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4699, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4700, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4701, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4702, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4703, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4704, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4705, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4706, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4707, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4708, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4709, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4710, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4711, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4712, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4713, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4714, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4715, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4716, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4717, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4718, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4719, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4720, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4721, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4722, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4723, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4724, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4725, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4726, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4727, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4728, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4729, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4730, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4731, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4732, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4733, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4734, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4735, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4736, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4737, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4738, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4739, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4740, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4741, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4742, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4743, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4744, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4745, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4746, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4747, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4748, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4749, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4750, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4751, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4752, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4753, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4754, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4755, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4756, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4757, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4758, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4759, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4760, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4761, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4762, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4763, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4764, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4765, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4766, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4767, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4768, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4769, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4770, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4771, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4772, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4773, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4774, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4775, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4776, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4777, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4778, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4779, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4780, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4781, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4782, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4783, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4784, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4785, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4786, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4787, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4788, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4789, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4790, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4791, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4792, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4793, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4794, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4795, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4796, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4797, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4798, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4799, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4800, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4801, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4802, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4803, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4804, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4805, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4806, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4807, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4808, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4809, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4810, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4811, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4812, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4813, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4814, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4815, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4816, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4817, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4818, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4819, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4820, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4821, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4822, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4823, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4824, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4825, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4826, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4827, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4828, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4829, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4830, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4831, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4832, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4833, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4834, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4835, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4836, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4837, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4838, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4839, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4840, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4841, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4842, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4843, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4844, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4845, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4846, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4847, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4848, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4849, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4850, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4851, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4852, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4853, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4854, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4855, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4856, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4857, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4858, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4859, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4860, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4861, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4862, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4863, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4864, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4865, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4866, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4867, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4868, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4869, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4870, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4871, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4872, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4873, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4874, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4875, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4876, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4877, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4878, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4879, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4880, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4881, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4882, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4883, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4884, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4903, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4904, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4905, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4906, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4907, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4908, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4909, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4910, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4911, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4912, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4913, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4914, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4915, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4916, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4917, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4918, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4919, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4920, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4921, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4922, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4923, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4924, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4925, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4926, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4927, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4928, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4929, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4930, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4931, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4932, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4934, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4935, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4936, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4937, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4938, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4939, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4946, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4947, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4948, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4949, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4950, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4951, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4954, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4955, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4956, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4957, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4961, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4962, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4963, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4964, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4965, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4966, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4969, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4970, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4971, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4972, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4977, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4978, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4981, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4982, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4985, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4986, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4989, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4991, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4995, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4997, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 4999, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5005, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5009, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5031, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5032, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5033, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5034, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5035, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5036, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5037, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5038, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5039, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5040, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5041, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5042, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5043, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5044, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5045, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5046, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5047, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5048, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5049, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5050, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5051, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5052, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5053, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5054, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5055, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5056, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5057, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5058, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5059, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5060, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5061, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5062, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5063, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5065, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5066, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5067, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5068, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5069, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5070, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5071, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5072, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5073, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5074, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5075, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5076, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5077, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5078, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5079, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5080, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5081, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5082, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5083, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5084, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5085, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5086, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5087, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5088, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5089, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5090, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5096, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5098, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5099, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5100, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5101, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5102, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5103, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5104, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5105, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5106, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5107, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5108, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5109, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5110, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5111, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5114, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5115, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5116, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5117, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5118, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5119, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5126, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5127, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5128, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5129, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5130, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5131, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5132, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5133, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5134, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5135, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5136, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5137, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5138, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5139, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5140, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5141, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5144, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5145, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5146, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5147, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5148, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5149, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5156, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5158, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5159, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5160, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5161, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5162, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5163, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5164, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5165, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5166, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5167, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5168, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5169, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5170, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5171, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5172, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5173, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5174, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5235, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5236, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5238, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5241, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5242, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5243, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5244, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5245, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5246, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5247, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5248, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5249, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5250, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5251, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5252, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5253, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5254, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5255, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5261, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5262, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5263, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5264, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5265, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5271, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5272, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5273, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5274, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5275, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5276, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5277, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5278, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5279, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5280, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5281, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5282, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5283, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5284, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5285, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5286, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5287, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5288, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5289, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5290, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5291, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5292, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5293, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5294, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5295, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5296, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5297, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5298, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5299, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5300, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5301, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5302, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5303, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5304, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5305, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5306, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5307, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5308, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5309, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5310, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5311, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5317, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5318, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5319, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5320, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5321, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5327, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5328, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5329, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5330, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5331, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5332, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5333, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5334, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5335, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5336, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5337, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5338, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5339, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5340, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5341, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5342, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5343, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5344, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5345, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5346, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5347, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5348, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5349, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5350, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5351, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5352, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5353, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5354, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5355, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5356, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5357, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5358, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5359, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5360, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5361, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5362, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5363, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5364, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5365, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5366, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5367, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5373, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5374, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5375, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5376, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5377, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5383, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5384, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5385, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5386, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5387, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5388, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5389, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5390, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5391, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5392, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5393, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5394, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5395, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5396, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5397, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5398, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5399, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5400, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5401, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5402, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5403, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5404, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5405, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5406, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5407, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5408, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5410, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5436, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5439, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5440, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5441, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5442, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5443, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5444, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5445, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5446, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5447, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5448, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5449, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5450, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5451, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5452, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5453, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5454, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5455, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5456, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5457, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5458, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5459, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5460, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5461, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5462, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5463, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5464, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5465, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5466, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5467, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5468, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5469, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5470, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5471, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5472, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5473, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5474, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5475, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5476, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5477, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5478, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5480, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5481, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5482, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5483, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5484, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5485, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5486, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5487, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5488, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5489, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5490, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5491, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5492, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5493, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5494, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5495, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5497, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5498, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5601, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5602, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5603, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5604, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5605, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5606, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5607, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5608, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5609, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5610, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5611, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5612, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5613, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5614, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5615, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5616, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5617, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5618, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5619, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5620, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5621, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5622, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5623, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5632, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5633, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5635, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5652, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5653, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5654, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5655, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5657, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5658, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5659, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5660, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5661, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5669, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5670, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5671, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5672, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5673, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5674, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5675, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5676, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5677, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5678, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5679, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5680, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5681, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5682, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5683, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5684, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5685, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5686, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5687, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5689, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5690, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5693, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5694, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5695, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5696, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5697, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5698, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5699, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5700, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5701, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5702, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5703, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5704, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5705, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5706, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5707, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5708, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5709, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5710, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5711, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5712, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5713, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5714, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5715, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5716, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5717, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5718, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5720, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5721, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5722, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5723, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5724, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5725, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5726, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5727, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5728, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5729, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5730, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5731, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5733, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5734, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5735, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5738, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5759, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5761, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5775, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5776, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5818, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5819, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5820, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5840, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5841, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5844, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5845, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5846, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5847, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5848, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5849, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5855, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5856, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5857, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5858, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5859, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5860, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5861, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5862, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5863, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5864, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5865, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5866, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5867, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5868, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5869, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5870, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5871, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5872, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5873, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5874, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5875, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5876, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5877, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5878, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5879, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5880, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5881, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5882, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5883, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5884, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5885, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5886, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5887, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5888, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5889, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5890, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5892, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5894, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5895, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5896, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5897, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5898, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5899, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5900, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5901, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5902, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5903, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5904, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5905, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5906, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5907, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5908, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5909, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5910, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5911, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5912, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5913, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5931, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5965, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5966, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5967, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5968, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5969, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5970, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5971, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5972, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5973, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5974, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5975, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5976, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5977, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5979, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5980, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5981, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5982, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5983, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5984, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5985, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5987, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5988, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5989, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5990, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5991, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5992, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 5993, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6000, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6001, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6002, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6003, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6004, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6005, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6006, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6007, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6008, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6009, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6010, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6011, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6012, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6013, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6014, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6015, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6016, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6018, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6019, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6020, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6021, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6022, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6023, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6024, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6025, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6026, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6027, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6028, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6029, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6030, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6031, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6032, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6033, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6040, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6041, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6042, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6043, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6044, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6045, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6046, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6047, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6048, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6049, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6050, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6051, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6052, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6053, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6054, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6055, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6057, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6058, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6059, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6060, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6061, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6064, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6065, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6066, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6067, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6068, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6071, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6072, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6073, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6074, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6075, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6076, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6077, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6078, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6080, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6084, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6085, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6086, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6087, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6088, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6089, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6090, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6091, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6092, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6093, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6094, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6095, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6096, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6097, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6098, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6102, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6103, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6104, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6105, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6106, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6107, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6113, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6114, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6115, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6116, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6117, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6118, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6119, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6120, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6121, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6122, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6123, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6124, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6125, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6126, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6127, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6129, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6130, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6131, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6132, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6133, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6134, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6135, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6136, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6137, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6138, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6139, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6140, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6141, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6142, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6143, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6144, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6151, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6152, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6153, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6154, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6155, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6156, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6157, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6158, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6159, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6160, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6161, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6162, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6163, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6164, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6165, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6166, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6167, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6168, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6169, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6170, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6171, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6172, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6173, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6174, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6175, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6176, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6187, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6188, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6189, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6190, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6192, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6193, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6194, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6195, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6196, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6197, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6198, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6199, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6201, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6208, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6209, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6210, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6211, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6212, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6213, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6214, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6215, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6216, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6217, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6218, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6219, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6220, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6221, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6222, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6223, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6224, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6225, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6226, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6227, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6228, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6229, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6230, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6231, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6234, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6236, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6237, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6238, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6239, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6240, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6241, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6242, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6243, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6244, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6245, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6246, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6247, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6248, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6249, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6250, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6251, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6252, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6253, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6254, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6255, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6256, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6257, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6258, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6259, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6260, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6261, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6262, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6263, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6264, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6265, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6266, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6267, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6268, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6269, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6270, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6271, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6272, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6273, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6274, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6275, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6276, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6277, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6278, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6279, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6280, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6281, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6282, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6283, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6284, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6285, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6286, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6287, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6288, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6289, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6291, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6304, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6305, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6306, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6307, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6308, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6309, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6310, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6311, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6312, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6313, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6314, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6315, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6316, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6317, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6318, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6319, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6320, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6321, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6322, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6323, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6324, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6325, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6326, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6327, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6328, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6329, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6330, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6331, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6332, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6333, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6334, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6335, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6336, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6337, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6338, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6339, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6340, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6341, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6342, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6343, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6344, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6345, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6348, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6349, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6353, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6354, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6355, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6356, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6357, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6358, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6359, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6360, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6361, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6362, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6363, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6364, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6365, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6366, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6367, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6368, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6369, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6370, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6371, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6372, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6373, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6401, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6402, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6403, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6404, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6405, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6406, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6407, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6408, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6409, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6410, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6411, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6412, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6413, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6414, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6415, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6416, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6417, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6418, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6419, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6420, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6421, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6422, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6423, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6424, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6425, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6426, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6427, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6428, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6429, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6430, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6431, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6432, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6433, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6434, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6435, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6436, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6437, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6438, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6439, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6440, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6441, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6442, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6443, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6444, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6445, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6446, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6447, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6448, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6449, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6450, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6452, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6453, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6454, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6455, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6456, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6457, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6458, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6459, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6461, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6462, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6463, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6464, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6465, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6466, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6467, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6468, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6471, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6472, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6473, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6474, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6475, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6476, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6477, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6478, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6479, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6480, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6481, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6483, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6484, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6485, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6486, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6487, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6488, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6489, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6490, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6491, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6492, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6493, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6494, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6495, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6496, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6497, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6498, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6499, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6503, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6505, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6507, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6508, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6509, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6510, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6511, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6512, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6513, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6514, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6515, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6516, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6517, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6518, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6519, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6520, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6521, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6522, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6523, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6524, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6525, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6526, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6527, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6528, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6529, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6530, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6531, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6532, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6533, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6534, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6535, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6536, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6537, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6538, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6539, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6540, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6564, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6565, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6566, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6567, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6568, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6569, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6570, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6571, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6572, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6573, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6574, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6575, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6576, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6577, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6578, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6579, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6580, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6581, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6586, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6587, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6588, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6589, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6590, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6591, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6592, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6593, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6594, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6595, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6596, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6597, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6598, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6599, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6600, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6601, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6602, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6603, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6604, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6605, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6606, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6607, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6608, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6609, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6610, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6611, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6612, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6613, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6614, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6615, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6616, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6617, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6619, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6621, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6623, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6624, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6625, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6626, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6627, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6628, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6629, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6630, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6631, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6632, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6633, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6634, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6635, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6636, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6637, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6638, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6639, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6646, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6647, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6648, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6649, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6650, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6651, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6652, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6653, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6654, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6655, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6656, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6657, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6658, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6659, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6660, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6661, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6662, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6663, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6664, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6665, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6666, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6667, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6668, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6669, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6670, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6671, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6672, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6673, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6674, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6675, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6676, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6677, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6678, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6679, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6680, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6681, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6682, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6683, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6684, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6685, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6686, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6687, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6688, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6689, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6690, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6695, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6696, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6697, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6698, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6699, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6700, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6701, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6702, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6703, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6704, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6705, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6706, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6707, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6708, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6709, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6710, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6711, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6715, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6716, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6717, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6718, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6722, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6723, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6724, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6725, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6726, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6727, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6728, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6729, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6730, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6731, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6732, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6733, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6734, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6735, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6736, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6737, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6738, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6739, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6740, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6741, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6742, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6743, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6744, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6745, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6746, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6747, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6748, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6749, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6750, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6751, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6752, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6753, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6754, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6755, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6756, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6757, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6758, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6759, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6784, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6785, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6786, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6787, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6788, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6789, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6790, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6791, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6792, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6793, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6794, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6795, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6796, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6797, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6798, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6799, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6800, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6801, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6802, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6803, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6804, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6805, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6806, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6807, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6808, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6809, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6810, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6811, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6812, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6813, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6814, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6815, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6816, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6817, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6818, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6819, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6820, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6821, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6822, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6823, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6824, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6825, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6826, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6827, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6828, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6829, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6830, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6831, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6832, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6833, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6834, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6835, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6836, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6837, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6838, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6839, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6840, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6841, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6842, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6843, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6844, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6845, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6846, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6848, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6873, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6874, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6876, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6877, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6878, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6879, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6880, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6881, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6882, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6883, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6884, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6885, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6886, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6887, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6888, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6889, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6890, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6891, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6892, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6893, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6894, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6895, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6896, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6897, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6898, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6899, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6900, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6901, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6902, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6903, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6904, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6905, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6906, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6907, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6908, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6909, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6910, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6911, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6959, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6960, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6961, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6962, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6963, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6964, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6965, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6966, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6967, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6968, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6969, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6970, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6971, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6972, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6973, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6974, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6975, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6976, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6977, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6978, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6979, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6980, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6981, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6982, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6983, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6984, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6985, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6986, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6987, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6988, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6989, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6990, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6991, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6992, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6993, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6994, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6995, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6996, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6997, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6998, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 6999, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7000, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7001, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7002, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7003, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7004, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7005, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7006, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7007, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7008, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7009, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7010, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7011, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7012, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7013, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7014, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7015, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7019, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7021, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7025, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7026, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7027, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7028, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7029, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7030, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7031, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7032, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7033, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7034, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7035, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7036, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7037, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7038, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7039, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7040, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7041, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7042, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7043, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7044, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7045, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7046, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7047, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7048, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7049, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7050, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7051, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7052, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7053, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7054, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7055, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7056, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7057, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7058, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7059, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7060, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7061, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7062, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7063, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7064, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7065, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7066, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7067, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7068, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7069, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7070, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7071, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7072, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7073, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7074, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7075, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7076, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7077, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7078, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7079, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7080, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7081, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7082, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7083, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7084, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7085, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7090, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7091, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7092, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7093, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7094, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7095, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7096, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7097, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7098, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7099, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7100, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7101, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7102, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7103, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7104, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7105, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7106, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7107, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7108, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7109, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7110, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7111, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7112, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7113, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7114, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7115, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7116, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7117, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7121, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7122, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7123, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7124, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7125, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7126, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7127, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7128, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7129, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7130, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7131, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7132, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7133, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7134, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7135, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7136, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7137, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7138, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7139, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7140, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7141, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7142, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7143, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7144, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7145, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7146, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7147, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7148, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7149, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7150, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7151, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7152, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7153, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7154, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7155, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7156, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7157, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7158, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7159, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7160, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7161, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7162, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7163, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7164, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7165, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7166, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7167, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7168, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7169, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7170, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7171, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7172, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7173, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7174, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7175, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7176, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7177, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7178, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7179, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7180, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7181, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7182, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7183, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7184, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7185, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7186, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7187, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7188, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7189, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7190, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7191, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7192, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7193, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7194, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7195, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7196, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7197, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7198, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7199, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7200, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7201, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7202, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7203, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7204, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7205, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7206, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7207, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7208, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7209, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7210, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7211, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7212, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7213, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7214, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7215, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7216, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7217, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7218, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7219, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7220, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7221, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7222, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7223, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7224, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7242, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7245, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7246, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7247, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7248, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7251, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7252, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7253, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7254, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7255, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7256, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7257, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7258, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7259, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7260, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7261, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7262, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7263, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7264, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7265, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7266, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7267, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7268, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7269, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7270, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7271, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7272, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7273, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7274, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7275, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7276, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7277, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7278, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7279, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7280, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7281, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7282, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7283, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7284, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7285, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7286, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7287, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7288, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7289, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7290, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7291, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7292, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7293, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7294, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7295, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7296, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7297, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7298, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7299, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7300, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7301, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7302, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7303, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7304, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7305, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7306, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7307, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7308, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7309, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7310, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7311, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7312, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7313, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7314, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7315, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7316, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7336, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7337, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7338, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7339, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7340, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7341, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7342, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7343, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7344, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7345, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7346, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7347, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7348, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7349, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7350, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7351, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7352, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7353, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7354, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7355, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7356, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7357, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7358, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7359, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7360, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7361, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7362, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7363, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7364, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7365, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7366, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7367, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7368, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7369, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7370, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7371, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7372, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7373, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7374, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7375, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7376, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7377, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7378, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7379, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7380, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7381, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7382, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7383, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7384, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7385, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7386, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7387, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7388, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7389, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7391, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7395, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7396, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7397, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7398, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7399, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7400, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7401, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7402, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7403, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7404, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7405, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7406, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7407, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7408, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7409, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7410, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7411, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7412, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7413, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7414, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7415, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7416, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7417, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7418, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7419, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7420, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7421, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7422, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7423, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7424, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7425, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7426, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7427, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7428, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7429, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7430, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7431, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7432, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7433, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7434, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7435, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7436, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7437, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7438, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7439, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7440, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7441, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7442, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7443, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7444, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7445, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7446, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7447, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7448, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7449, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7450, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7451, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7452, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7453, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7454, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7455, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7456, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7457, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7458, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7459, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7460, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7461, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7462, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7463, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7464, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7465, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7466, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7468, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7469, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7470, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7471, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7472, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7473, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7474, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7475, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7476, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7477, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7478, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7479, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7480, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7481, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7482, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7488, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7489, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7490, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7491, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7492, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7498, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7499, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7500, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7501, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7502, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7503, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7504, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7505, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7506, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7507, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7509, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7510, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7511, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7512, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7513, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7514, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7515, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7516, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7517, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7518, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7519, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7520, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7521, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7522, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7523, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7529, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7530, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7531, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7532, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7533, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7539, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7540, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7541, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7542, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7543, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7544, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7545, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7546, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7547, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7548, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7550, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7551, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7552, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7553, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7554, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7555, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7556, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7557, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7558, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7559, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7560, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7561, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7562, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7563, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7564, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7570, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7571, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7572, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7573, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7574, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7580, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7581, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7582, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7583, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7584, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7585, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7586, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7587, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7588, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7589, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7663, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7717, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7735, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7736, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7737, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7738, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7739, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7740, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7741, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7742, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7743, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7744, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7745, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7746, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7747, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7748, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7761, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7762, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7763, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7764, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7767, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7768, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7769, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7770, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7771, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7774, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7775, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7777, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7780, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7781, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7782, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7952, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 7953, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 8184, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 8251, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 8252, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 8253, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 8254, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 8255, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 8284, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 8285, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 8286, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 8291, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 8420, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 10308, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 10420, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 10579, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 10580, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 10581, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 10699, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 11145, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 11146, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 11147, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 11148, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 11149, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 11150, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 11151, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 11152, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 11153, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 11154, 0, 2);
+INSERT INTO unlocks VALUES (-1, 0, 11155, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 1, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 4, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 6, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 7, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 9, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 10, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 11, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 130, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 131, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 132, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 133, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 134, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 137, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 139, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 140, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 141, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 142, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 143, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 144, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 145, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 146, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 147, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 148, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 149, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 150, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 151, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 152, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 153, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 154, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 155, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 156, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 157, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 158, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 159, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 160, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 161, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 162, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 163, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 164, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 165, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 166, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 167, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 169, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 170, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 171, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 173, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 177, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 178, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 179, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 180, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 181, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 182, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 183, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 184, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 185, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 186, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 187, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 188, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 189, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 190, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 191, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 192, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 193, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 194, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 195, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 196, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 197, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 198, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 199, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 200, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 201, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 202, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 203, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 204, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 205, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 206, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 207, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 208, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 209, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 211, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 217, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 219, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 220, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 221, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 222, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 223, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 224, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 225, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 226, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 235, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 236, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 238, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 239, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 243, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 244, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 245, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 246, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 247, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 248, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 249, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 250, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 251, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 252, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 253, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 254, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 255, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 256, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 257, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 258, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 259, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 261, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 262, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 263, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 264, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 265, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 266, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 267, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 268, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 269, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 270, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 271, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 272, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 273, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 275, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 276, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 277, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 278, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 279, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 280, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 281, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 282, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 283, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 284, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 285, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 286, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 287, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 288, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 289, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 290, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 291, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 292, 0, 2);
+INSERT INTO unlocks VALUES (-1, 1, 293, 0, 2);
+INSERT INTO unlocks VALUES (0, 2, 16, 0, 2);
+INSERT INTO unlocks VALUES (0, 2, 17, 0, 2);
+INSERT INTO unlocks VALUES (0, 2, 18, 0, 2);
+INSERT INTO unlocks VALUES (0, 2, 19, 0, 2);
+INSERT INTO unlocks VALUES (0, 2, 82, 0, 2);
+INSERT INTO unlocks VALUES (0, 2, 90, 0, 2);
+INSERT INTO unlocks VALUES (1, 2, 16, 0, 2);
+INSERT INTO unlocks VALUES (1, 2, 17, 0, 2);
+INSERT INTO unlocks VALUES (1, 2, 18, 0, 2);
+INSERT INTO unlocks VALUES (1, 2, 19, 0, 2);
+INSERT INTO unlocks VALUES (1, 2, 82, 0, 2);
+INSERT INTO unlocks VALUES (1, 2, 90, 0, 2);
+INSERT INTO unlocks VALUES (2, 2, 16, 0, 2);
+INSERT INTO unlocks VALUES (2, 2, 17, 0, 2);
+INSERT INTO unlocks VALUES (2, 2, 18, 0, 2);
+INSERT INTO unlocks VALUES (2, 2, 19, 0, 2);
+INSERT INTO unlocks VALUES (2, 2, 82, 0, 2);
+INSERT INTO unlocks VALUES (2, 2, 90, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 58, 0, 5000);
+INSERT INTO unlocks VALUES (-1, 3, 59, 0, 5000);
+INSERT INTO unlocks VALUES (-1, 3, 60, 0, 5000);
+INSERT INTO unlocks VALUES (-1, 3, 61, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 62, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 63, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 64, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 65, 0, 1000);
+INSERT INTO unlocks VALUES (-1, 3, 68, 0, 60);
+INSERT INTO unlocks VALUES (-1, 3, 75, 0, 75);
+INSERT INTO unlocks VALUES (-1, 3, 78, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 79, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 80, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 81, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 82, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 83, 0, 1000);
+INSERT INTO unlocks VALUES (-1, 3, 84, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 85, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 86, 0, 250);
+INSERT INTO unlocks VALUES (-1, 3, 87, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 88, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 89, 0, 200);
+INSERT INTO unlocks VALUES (-1, 3, 92, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 93, 0, 75);
+INSERT INTO unlocks VALUES (-1, 3, 94, 0, 4000);
+INSERT INTO unlocks VALUES (-1, 3, 96, 0, 800);
+INSERT INTO unlocks VALUES (-1, 3, 104, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 105, 0, 7);
+INSERT INTO unlocks VALUES (-1, 3, 106, 0, 250);
+INSERT INTO unlocks VALUES (-1, 3, 108, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 158, 0, 400);
+INSERT INTO unlocks VALUES (-1, 3, 159, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 160, 0, 20);
+INSERT INTO unlocks VALUES (-1, 3, 161, 0, 75);
+INSERT INTO unlocks VALUES (-1, 3, 162, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 163, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 165, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 167, 0, 150000);
+INSERT INTO unlocks VALUES (-1, 3, 168, 0, 150000);
+INSERT INTO unlocks VALUES (-1, 3, 169, 0, 150000);
+INSERT INTO unlocks VALUES (-1, 3, 170, 0, 900000);
+INSERT INTO unlocks VALUES (-1, 3, 171, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 172, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 173, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 175, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 176, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 177, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 179, 0, 1000);
+INSERT INTO unlocks VALUES (-1, 3, 180, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 181, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 182, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 183, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 185, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 186, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 191, 0, 7);
+INSERT INTO unlocks VALUES (-1, 3, 192, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 193, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 195, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 196, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 396, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 397, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 398, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 400, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 401, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 402, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 403, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 404, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 405, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 406, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 407, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 408, 0, 9);
+INSERT INTO unlocks VALUES (-1, 3, 409, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 410, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 411, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 412, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 413, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 414, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 415, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 416, 0, 29);
+INSERT INTO unlocks VALUES (-1, 3, 417, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 418, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 419, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 420, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 421, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 422, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 423, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 424, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 425, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 426, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 427, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 432, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 433, 0, 13);
+INSERT INTO unlocks VALUES (-1, 3, 434, 0, 16);
+INSERT INTO unlocks VALUES (-1, 3, 435, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 436, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 437, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 438, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 439, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 440, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 441, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 442, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 443, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 444, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 445, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 446, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 447, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 448, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 449, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 450, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 451, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 452, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 453, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 454, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 455, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 456, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 457, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 458, 0, 21);
+INSERT INTO unlocks VALUES (-1, 3, 459, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 460, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 461, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 462, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 463, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 464, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 465, 0, 36);
+INSERT INTO unlocks VALUES (-1, 3, 466, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 467, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 468, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 469, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 470, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 471, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 472, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 473, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 474, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 475, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 476, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 483, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 484, 0, 4);
+INSERT INTO unlocks VALUES (-1, 3, 485, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 486, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 487, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 488, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 489, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 490, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 491, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 492, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 493, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 494, 0, 6);
+INSERT INTO unlocks VALUES (-1, 3, 495, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 496, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 497, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 498, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 499, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 500, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 501, 0, 17);
+INSERT INTO unlocks VALUES (-1, 3, 502, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 503, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 504, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 505, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 506, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 507, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 508, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 509, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 510, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 511, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 512, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 517, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 518, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 519, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 520, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 521, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 522, 0, 200);
+INSERT INTO unlocks VALUES (-1, 3, 523, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 524, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 525, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 526, 0, 150);
+INSERT INTO unlocks VALUES (-1, 3, 527, 0, 9);
+INSERT INTO unlocks VALUES (-1, 3, 528, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 529, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 530, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 531, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 532, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 533, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 534, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 535, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 536, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 537, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 538, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 539, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 540, 0, 75);
+INSERT INTO unlocks VALUES (-1, 3, 541, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 542, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 543, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 544, 0, 75);
+INSERT INTO unlocks VALUES (-1, 3, 545, 0, 75);
+INSERT INTO unlocks VALUES (-1, 3, 546, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 549, 0, 9);
+INSERT INTO unlocks VALUES (-1, 3, 550, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 551, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 552, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 553, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 554, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 555, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 556, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 557, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 558, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 559, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 560, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 561, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 562, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 563, 0, 9);
+INSERT INTO unlocks VALUES (-1, 3, 564, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 565, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 566, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 567, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 568, 0, 75);
+INSERT INTO unlocks VALUES (-1, 3, 569, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 570, 0, 150);
+INSERT INTO unlocks VALUES (-1, 3, 571, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 572, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 573, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 574, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 575, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 576, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 577, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 578, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 579, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 580, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 581, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 582, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 583, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 585, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 586, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 587, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 588, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 595, 0, 20);
+INSERT INTO unlocks VALUES (-1, 3, 596, 0, 20);
+INSERT INTO unlocks VALUES (-1, 3, 597, 0, 20);
+INSERT INTO unlocks VALUES (-1, 3, 598, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 599, 0, 20);
+INSERT INTO unlocks VALUES (-1, 3, 600, 0, 7);
+INSERT INTO unlocks VALUES (-1, 3, 601, 0, 18);
+INSERT INTO unlocks VALUES (-1, 3, 602, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 603, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 604, 0, 7);
+INSERT INTO unlocks VALUES (-1, 3, 605, 0, 45);
+INSERT INTO unlocks VALUES (-1, 3, 607, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 608, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 609, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 610, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 611, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 612, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 613, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 614, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 615, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 616, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 617, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 618, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 619, 0, 7);
+INSERT INTO unlocks VALUES (-1, 3, 620, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 622, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 624, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 625, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 626, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 627, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 628, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 629, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 630, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 631, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 632, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 633, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 634, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 635, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 636, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 637, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 638, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 639, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 640, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 641, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 642, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 643, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 644, 0, 21);
+INSERT INTO unlocks VALUES (-1, 3, 645, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 646, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 647, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 648, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 649, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 650, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 651, 0, 32);
+INSERT INTO unlocks VALUES (-1, 3, 652, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 653, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 654, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 655, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 656, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 657, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 658, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 659, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 660, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 661, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 662, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 669, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 670, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 671, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 672, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 673, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 674, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 675, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 676, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 677, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 678, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 679, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 680, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 681, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 682, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 683, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 684, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 685, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 686, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 687, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 688, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 689, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 690, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 691, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 692, 0, 7);
+INSERT INTO unlocks VALUES (-1, 3, 694, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 695, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 696, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 697, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 698, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 699, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 700, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 701, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 702, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 706, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 707, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 708, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 709, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 710, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 711, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 712, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 713, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 714, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 715, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 716, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 717, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 718, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 719, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 720, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 721, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 722, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 723, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 724, 0, 20);
+INSERT INTO unlocks VALUES (-1, 3, 725, 0, 72);
+INSERT INTO unlocks VALUES (-1, 3, 726, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 728, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 729, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 730, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 731, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 732, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 733, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 734, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 735, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 736, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 737, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 738, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 739, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 740, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 741, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 742, 0, 1200000);
+INSERT INTO unlocks VALUES (-1, 3, 743, 0, 250);
+INSERT INTO unlocks VALUES (-1, 3, 744, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 745, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 746, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 747, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 748, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 749, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 750, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 751, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 752, 0, 1200000);
+INSERT INTO unlocks VALUES (-1, 3, 753, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 754, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 755, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 756, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 757, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 758, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 759, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 760, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 761, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 762, 0, 1200000);
+INSERT INTO unlocks VALUES (-1, 3, 763, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 764, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 765, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 766, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 767, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 768, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 769, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 770, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 771, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 772, 0, 1200000);
+INSERT INTO unlocks VALUES (-1, 3, 773, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 774, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 775, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 776, 0, 15);
+INSERT INTO unlocks VALUES (-1, 3, 777, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 778, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 779, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 780, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 781, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 782, 0, 1200000);
+INSERT INTO unlocks VALUES (-1, 3, 783, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 784, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 785, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 786, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 787, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 788, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 789, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 790, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 791, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 792, 0, 1200000);
+INSERT INTO unlocks VALUES (-1, 3, 793, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 794, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 795, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 796, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 797, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 798, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 799, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 800, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 801, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 802, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 803, 0, 200);
+INSERT INTO unlocks VALUES (-1, 3, 804, 0, 150);
+INSERT INTO unlocks VALUES (-1, 3, 805, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 806, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 807, 0, 250);
+INSERT INTO unlocks VALUES (-1, 3, 808, 0, 150);
+INSERT INTO unlocks VALUES (-1, 3, 809, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 810, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 811, 0, 9);
+INSERT INTO unlocks VALUES (-1, 3, 812, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 813, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 814, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 815, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 816, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 817, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 818, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 819, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 820, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 821, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 822, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 823, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 824, 0, 200);
+INSERT INTO unlocks VALUES (-1, 3, 825, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 826, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 827, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 828, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 829, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 830, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 831, 0, 9);
+INSERT INTO unlocks VALUES (-1, 3, 832, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 833, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 834, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 835, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 836, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 837, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 838, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 839, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 840, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 841, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 842, 0, 200);
+INSERT INTO unlocks VALUES (-1, 3, 843, 0, 75);
+INSERT INTO unlocks VALUES (-1, 3, 844, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 845, 0, 9);
+INSERT INTO unlocks VALUES (-1, 3, 846, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 847, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 848, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 849, 0, 75);
+INSERT INTO unlocks VALUES (-1, 3, 850, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 851, 0, 200);
+INSERT INTO unlocks VALUES (-1, 3, 852, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 853, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 854, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 855, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 856, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 857, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 858, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 859, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 860, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 861, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 862, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 863, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 864, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 865, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 866, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 868, 0, 21);
+INSERT INTO unlocks VALUES (-1, 3, 869, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 870, 0, 150);
+INSERT INTO unlocks VALUES (-1, 3, 872, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 873, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 874, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 875, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 876, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 877, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 878, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 879, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 880, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 881, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 882, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 883, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 884, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 885, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 886, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 887, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 888, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 889, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 890, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 891, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 892, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 893, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 894, 0, 250);
+INSERT INTO unlocks VALUES (-1, 3, 895, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 896, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 897, 0, 9);
+INSERT INTO unlocks VALUES (-1, 3, 898, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 899, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 900, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 901, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 902, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 903, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 904, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 905, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 906, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 907, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 908, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 909, 0, 75);
+INSERT INTO unlocks VALUES (-1, 3, 910, 0, 200);
+INSERT INTO unlocks VALUES (-1, 3, 911, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 912, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 913, 0, 75);
+INSERT INTO unlocks VALUES (-1, 3, 914, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 915, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 916, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 917, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 918, 0, 9);
+INSERT INTO unlocks VALUES (-1, 3, 919, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 920, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 921, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 922, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 923, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 924, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 925, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 926, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 927, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 928, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 929, 0, 75);
+INSERT INTO unlocks VALUES (-1, 3, 930, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 931, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 932, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 933, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 934, 0, 150);
+INSERT INTO unlocks VALUES (-1, 3, 935, 0, 200);
+INSERT INTO unlocks VALUES (-1, 3, 936, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 937, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 938, 0, 9);
+INSERT INTO unlocks VALUES (-1, 3, 939, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 940, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 941, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 942, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 943, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 944, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 945, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 946, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 947, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 948, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 949, 0, 16);
+INSERT INTO unlocks VALUES (-1, 3, 950, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 951, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 952, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 953, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 954, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 955, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 956, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 957, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 958, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 960, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 961, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 962, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 963, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 964, 0, 13);
+INSERT INTO unlocks VALUES (-1, 3, 965, 0, 23);
+INSERT INTO unlocks VALUES (-1, 3, 966, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 967, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 968, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 969, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 970, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 971, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 972, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 973, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 974, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 975, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 976, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 977, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 978, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 979, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 980, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 981, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 982, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 983, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 984, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 985, 0, 8);
+INSERT INTO unlocks VALUES (-1, 3, 986, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 987, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 988, 0, 4000);
+INSERT INTO unlocks VALUES (-1, 3, 989, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 990, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 991, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 992, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 993, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 994, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 995, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 996, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 997, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 998, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 999, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1000, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1001, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1002, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1003, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1004, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1005, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1006, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1007, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1008, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1009, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1010, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1011, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1012, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1013, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1014, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1015, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1016, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1017, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1018, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1019, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1020, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1021, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1022, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1023, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1024, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1025, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1026, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1027, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1028, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1029, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1030, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1031, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1032, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1033, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1034, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1035, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1036, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1037, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1038, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1039, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1040, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1041, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1042, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1043, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1044, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1045, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1046, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1047, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1048, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1049, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1050, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1051, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1052, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1053, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1054, 0, 4);
+INSERT INTO unlocks VALUES (-1, 3, 1055, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 1056, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 1057, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 1058, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 1059, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1060, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1061, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1062, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1063, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1210, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1211, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1212, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1213, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1214, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1215, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1216, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1217, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1218, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1219, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1220, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 1221, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 1222, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 1223, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 1224, 0, 250);
+INSERT INTO unlocks VALUES (-1, 3, 1230, 0, 15);
+INSERT INTO unlocks VALUES (-1, 3, 1231, 0, 255);
+INSERT INTO unlocks VALUES (-1, 3, 1232, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 1233, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1234, 0, 150);
+INSERT INTO unlocks VALUES (-1, 3, 1240, 0, 15);
+INSERT INTO unlocks VALUES (-1, 3, 1241, 0, 165);
+INSERT INTO unlocks VALUES (-1, 3, 1242, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 1243, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1244, 0, 150);
+INSERT INTO unlocks VALUES (-1, 3, 1250, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 1251, 0, 165);
+INSERT INTO unlocks VALUES (-1, 3, 1252, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 1253, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 1254, 0, 250);
+INSERT INTO unlocks VALUES (-1, 3, 1260, 0, 15);
+INSERT INTO unlocks VALUES (-1, 3, 1261, 0, 210);
+INSERT INTO unlocks VALUES (-1, 3, 1262, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 1263, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1264, 0, 200);
+INSERT INTO unlocks VALUES (-1, 3, 1270, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1271, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1272, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1273, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1274, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1280, 0, 7);
+INSERT INTO unlocks VALUES (-1, 3, 1281, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 1282, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 1283, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 1284, 0, 7);
+INSERT INTO unlocks VALUES (-1, 3, 1285, 0, 7);
+INSERT INTO unlocks VALUES (-1, 3, 1286, 0, 250);
+INSERT INTO unlocks VALUES (-1, 3, 1297, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 1298, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 1299, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 1300, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 1301, 0, 1000);
+INSERT INTO unlocks VALUES (-1, 3, 1336, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1337, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1340, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 1342, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 1344, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 1346, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1349, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1351, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 1353, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1356, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1358, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 1360, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1363, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 1365, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1368, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 1370, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 1372, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1375, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1377, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1379, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1381, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1383, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1386, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 1388, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 1390, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 1392, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1395, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 1397, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1399, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1402, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 1404, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1406, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1409, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 1411, 0, 2);
+INSERT INTO unlocks VALUES (-1, 3, 1413, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1416, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 1437, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1438, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1448, 0, 600);
+INSERT INTO unlocks VALUES (-1, 3, 1449, 0, 250);
+INSERT INTO unlocks VALUES (-1, 3, 1450, 0, 15);
+INSERT INTO unlocks VALUES (-1, 3, 1451, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1452, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 1458, 0, 65);
+INSERT INTO unlocks VALUES (-1, 3, 1459, 0, 85);
+INSERT INTO unlocks VALUES (-1, 3, 1460, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1461, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 1462, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 1468, 0, 55);
+INSERT INTO unlocks VALUES (-1, 3, 1469, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 1470, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1471, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 1472, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 1478, 0, 130);
+INSERT INTO unlocks VALUES (-1, 3, 1479, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 1480, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1481, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 1482, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 1488, 0, 70);
+INSERT INTO unlocks VALUES (-1, 3, 1489, 0, 165);
+INSERT INTO unlocks VALUES (-1, 3, 1490, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1491, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 1492, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 1498, 0, 70);
+INSERT INTO unlocks VALUES (-1, 3, 1499, 0, 90);
+INSERT INTO unlocks VALUES (-1, 3, 1500, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1501, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 1502, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 1508, 0, 65);
+INSERT INTO unlocks VALUES (-1, 3, 1509, 0, 135);
+INSERT INTO unlocks VALUES (-1, 3, 1510, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1511, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 1512, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 1518, 0, 21);
+INSERT INTO unlocks VALUES (-1, 3, 1519, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 1520, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 1521, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 1522, 0, 100);
+INSERT INTO unlocks VALUES (-1, 3, 1528, 0, 65);
+INSERT INTO unlocks VALUES (-1, 3, 1529, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 1530, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1531, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 1532, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 1538, 0, 80);
+INSERT INTO unlocks VALUES (-1, 3, 1539, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 1540, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1541, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 1542, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 1548, 0, 110);
+INSERT INTO unlocks VALUES (-1, 3, 1549, 0, 25);
+INSERT INTO unlocks VALUES (-1, 3, 1550, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1551, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 1552, 0, 30);
+INSERT INTO unlocks VALUES (-1, 3, 1558, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1559, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1560, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1561, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1562, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1568, 0, 35);
+INSERT INTO unlocks VALUES (-1, 3, 1569, 0, 15);
+INSERT INTO unlocks VALUES (-1, 3, 1570, 0, 366);
+INSERT INTO unlocks VALUES (-1, 3, 1571, 0, 40);
+INSERT INTO unlocks VALUES (-1, 3, 1572, 0, 1500);
+INSERT INTO unlocks VALUES (-1, 3, 1611, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1613, 0, 250);
+INSERT INTO unlocks VALUES (-1, 3, 1615, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1617, 0, 1000);
+INSERT INTO unlocks VALUES (-1, 3, 1619, 0, 2500);
+INSERT INTO unlocks VALUES (-1, 3, 1620, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1622, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1623, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1625, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1627, 0, 1000);
+INSERT INTO unlocks VALUES (-1, 3, 1628, 0, 250);
+INSERT INTO unlocks VALUES (-1, 3, 1630, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 1631, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1633, 0, 1000);
+INSERT INTO unlocks VALUES (-1, 3, 1634, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1636, 0, 1000);
+INSERT INTO unlocks VALUES (-1, 3, 1638, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 1640, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1642, 0, 1000);
+INSERT INTO unlocks VALUES (-1, 3, 1644, 0, 150);
+INSERT INTO unlocks VALUES (-1, 3, 1646, 0, 150);
+INSERT INTO unlocks VALUES (-1, 3, 1647, 0, 150);
+INSERT INTO unlocks VALUES (-1, 3, 1648, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 1650, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1652, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 1653, 0, 1000);
+INSERT INTO unlocks VALUES (-1, 3, 1655, 0, 200);
+INSERT INTO unlocks VALUES (-1, 3, 1657, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1659, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1661, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1664, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1665, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1667, 0, 250);
+INSERT INTO unlocks VALUES (-1, 3, 1669, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1671, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 1672, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1674, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 1676, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 1678, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 1680, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 1681, 0, 1000);
+INSERT INTO unlocks VALUES (-1, 3, 1682, 0, 2000);
+INSERT INTO unlocks VALUES (-1, 3, 1683, 0, 1000);
+INSERT INTO unlocks VALUES (-1, 3, 1684, 0, 50);
+INSERT INTO unlocks VALUES (-1, 3, 1927, 0, 19);
+INSERT INTO unlocks VALUES (-1, 3, 2219, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2220, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2221, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2222, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2223, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2224, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2225, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2226, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2227, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2228, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2229, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2230, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2231, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2232, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2233, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2290, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2291, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2292, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2293, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2294, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2295, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2313, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2318, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2319, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2320, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2321, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2322, 0, 400);
+INSERT INTO unlocks VALUES (-1, 3, 2323, 0, 350);
+INSERT INTO unlocks VALUES (-1, 3, 2324, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2325, 0, 350);
+INSERT INTO unlocks VALUES (-1, 3, 2326, 0, 350);
+INSERT INTO unlocks VALUES (-1, 3, 2327, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2328, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2329, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2330, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2331, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2332, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2333, 0, 350);
+INSERT INTO unlocks VALUES (-1, 3, 2334, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2335, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2336, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2337, 0, 350);
+INSERT INTO unlocks VALUES (-1, 3, 2338, 0, 500);
+INSERT INTO unlocks VALUES (-1, 3, 2350, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2351, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2352, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2384, 0, 250);
+INSERT INTO unlocks VALUES (-1, 3, 2385, 0, 700);
+INSERT INTO unlocks VALUES (-1, 3, 2386, 0, 700);
+INSERT INTO unlocks VALUES (-1, 3, 2387, 0, 300);
+INSERT INTO unlocks VALUES (-1, 3, 2401, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 2402, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2403, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2404, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2405, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2411, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 2412, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2413, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2414, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2415, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2421, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 2422, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2423, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2424, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2425, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2466, 0, 700);
+INSERT INTO unlocks VALUES (-1, 3, 2467, 0, 700);
+INSERT INTO unlocks VALUES (-1, 3, 2468, 0, 400);
+INSERT INTO unlocks VALUES (-1, 3, 2469, 0, 400);
+INSERT INTO unlocks VALUES (-1, 3, 2470, 0, 700);
+INSERT INTO unlocks VALUES (-1, 3, 2471, 0, 700);
+INSERT INTO unlocks VALUES (-1, 3, 2472, 0, 400);
+INSERT INTO unlocks VALUES (-1, 3, 2549, 0, 400);
+INSERT INTO unlocks VALUES (-1, 3, 2550, 0, 700);
+INSERT INTO unlocks VALUES (-1, 3, 2551, 0, 700);
+INSERT INTO unlocks VALUES (-1, 3, 2576, 0, 700);
+INSERT INTO unlocks VALUES (-1, 3, 2577, 0, 700);
+INSERT INTO unlocks VALUES (-1, 3, 2578, 0, 400);
+INSERT INTO unlocks VALUES (-1, 3, 2608, 0, 400);
+INSERT INTO unlocks VALUES (-1, 3, 2609, 0, 700);
+INSERT INTO unlocks VALUES (-1, 3, 2610, 0, 5000);
+INSERT INTO unlocks VALUES (-1, 3, 2632, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2633, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2634, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 2635, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2636, 0, 7);
+INSERT INTO unlocks VALUES (-1, 3, 2642, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2643, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2644, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 2645, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2646, 0, 7);
+INSERT INTO unlocks VALUES (-1, 3, 2652, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2653, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2654, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 2655, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 2656, 0, 7);
+INSERT INTO unlocks VALUES (-1, 3, 2666, 0, 20);
+INSERT INTO unlocks VALUES (-1, 3, 2667, 0, 3);
+INSERT INTO unlocks VALUES (-1, 3, 2668, 0, 10);
+INSERT INTO unlocks VALUES (-1, 3, 2669, 0, 1000);
+INSERT INTO unlocks VALUES (-1, 3, 2670, 0, 5);
+INSERT INTO unlocks VALUES (-1, 3, 4719, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 4991, 0, 1);
+INSERT INTO unlocks VALUES (-1, 3, 5662, 0, -1);
+INSERT INTO unlocks VALUES (0, 4, 61, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 120, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 130, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 135, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 138, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 139, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 141, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 200, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 223, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 273, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 275, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 276, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 312, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 360, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 409, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 410, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 411, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 412, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 416, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 418, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 419, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 420, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 421, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 423, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 424, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 425, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 426, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 427, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 428, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 446, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 447, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 458, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 459, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 470, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 524, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 581, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 582, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 583, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 584, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 659, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 661, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 699, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 707, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 731, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 744, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 791, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 794, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 817, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 821, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 828, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 833, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 838, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 849, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 850, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 852, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 859, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 865, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 924, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 938, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 946, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 957, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 959, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 964, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 966, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 971, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 980, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 994, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1013, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1055, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1058, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1065, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1066, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1067, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1068, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1131, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1134, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1136, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1137, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1139, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1143, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1145, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1146, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1171, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1178, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1182, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1183, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1195, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1197, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1212, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1213, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1214, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1232, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1234, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1235, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1236, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1247, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1252, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1253, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1256, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1259, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1264, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1326, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1422, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1428, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1429, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1514, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1516, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1518, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1520, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1524, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1542, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1544, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1662, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1663, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1664, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1665, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1666, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1667, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1678, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1679, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1680, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1685, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1783, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1790, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1791, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1837, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1838, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1839, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1840, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1841, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1842, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1848, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1849, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1853, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1854, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1855, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1858, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1859, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1860, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1861, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1880, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1881, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1882, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1883, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1884, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 1885, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 2253, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 2254, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 2255, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 2256, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 2257, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 2258, 0, 2);
+INSERT INTO unlocks VALUES (0, 4, 2269, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 61, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 120, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 130, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 135, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 138, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 139, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 141, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 200, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 223, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 273, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 275, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 276, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 312, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 360, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 409, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 410, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 411, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 412, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 416, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 418, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 419, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 420, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 421, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 423, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 424, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 425, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 426, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 427, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 428, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 446, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 447, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 458, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 459, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 470, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 524, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 581, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 582, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 583, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 584, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 659, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 661, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 699, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 707, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 731, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 744, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 791, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 794, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 817, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 821, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 828, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 833, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 838, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 849, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 850, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 852, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 859, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 865, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 924, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 938, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 946, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 957, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 959, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 964, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 966, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 971, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 980, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 994, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1013, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1055, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1058, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1065, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1066, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1067, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1068, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1131, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1134, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1136, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1137, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1139, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1143, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1145, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1146, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1171, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1178, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1182, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1183, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1195, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1197, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1212, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1213, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1214, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1232, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1234, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1235, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1236, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1247, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1252, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1253, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1256, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1259, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1264, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1326, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1422, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1428, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1429, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1514, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1516, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1518, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1520, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1524, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1542, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1544, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1662, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1663, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1664, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1665, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1666, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1667, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1678, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1679, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1680, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1685, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1783, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1790, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1791, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1837, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1838, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1839, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1840, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1841, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1842, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1848, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1849, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1853, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1854, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1855, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1858, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1859, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1860, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1861, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1880, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1881, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1882, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1883, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1884, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 1885, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 2253, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 2254, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 2255, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 2256, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 2257, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 2258, 0, 2);
+INSERT INTO unlocks VALUES (1, 4, 2269, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 61, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 120, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 130, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 135, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 138, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 139, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 141, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 200, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 223, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 273, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 275, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 276, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 312, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 360, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 409, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 410, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 411, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 412, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 416, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 418, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 419, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 420, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 421, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 423, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 424, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 425, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 426, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 427, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 428, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 446, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 447, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 458, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 459, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 470, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 524, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 581, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 582, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 583, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 584, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 659, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 661, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 699, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 707, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 731, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 744, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 791, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 794, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 817, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 821, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 828, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 833, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 838, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 849, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 850, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 852, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 859, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 865, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 924, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 938, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 946, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 957, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 959, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 964, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 966, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 971, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 980, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 994, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1013, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1055, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1058, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1065, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1066, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1067, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1068, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1131, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1134, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1136, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1137, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1139, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1143, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1145, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1146, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1171, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1178, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1182, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1183, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1195, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1197, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1212, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1213, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1214, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1232, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1234, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1235, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1236, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1247, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1252, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1253, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1256, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1259, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1264, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1326, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1422, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1428, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1429, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1514, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1516, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1518, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1520, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1524, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1542, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1544, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1662, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1663, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1664, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1665, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1666, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1667, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1678, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1679, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1680, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1685, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1783, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1790, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1791, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1837, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1838, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1839, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1840, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1841, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1842, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1848, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1849, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1853, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1854, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1855, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1858, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1859, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1860, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1861, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1880, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1881, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1882, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1883, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1884, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 1885, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 2253, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 2254, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 2255, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 2256, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 2257, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 2258, 0, 2);
+INSERT INTO unlocks VALUES (2, 4, 2269, 0, 2);
+INSERT INTO unlocks VALUES (0, 5, 443, 0, -1);
+INSERT INTO unlocks VALUES (0, 5, 502, 0, -1);
+INSERT INTO unlocks VALUES (1, 5, 443, 0, -1);
+INSERT INTO unlocks VALUES (1, 5, 502, 0, -1);
+INSERT INTO unlocks VALUES (2, 5, 443, 0, -1);
+INSERT INTO unlocks VALUES (2, 5, 502, 0, -1);
+INSERT INTO family5 VALUES (0, 0, 2003, 2);
+INSERT INTO family5 VALUES (0, 1, 2260, 2);
+INSERT INTO family5 VALUES (0, 2, 3698, 2);
+INSERT INTO family5 VALUES (0, 3, 4661, 2);
+INSERT INTO family5 VALUES (0, 4, 5901, 2);
+INSERT INTO family5 VALUES (0, 5, 7188, 2);
+INSERT INTO family5 VALUES (0, 6, 9144, 2);
+INSERT INTO family5 VALUES (0, 7, 9150, 2);
+INSERT INTO family5 VALUES (0, 8, 9162, 2);
+INSERT INTO family5 VALUES (0, 9, 9164, 2);
+INSERT INTO family5 VALUES (0, 10, 9169, 2);
+INSERT INTO family5 VALUES (0, 11, 9171, 2);
+INSERT INTO family5 VALUES (0, 12, 9176, 2);
+INSERT INTO family5 VALUES (0, 13, 9178, 2);
+INSERT INTO family5 VALUES (0, 14, 9180, 2);
+INSERT INTO family5 VALUES (0, 15, 9183, 2);
+INSERT INTO family5 VALUES (0, 16, 9186, 2);
+INSERT INTO family5 VALUES (0, 17, 9279, 2);
+INSERT INTO family5 VALUES (0, 18, 9355, 2);
+INSERT INTO family5 VALUES (0, 19, 9567, 2);
+INSERT INTO family5 VALUES (0, 20, 11554, 2);
+INSERT INTO family5 VALUES (0, 21, 11558, 2);
+INSERT INTO family5 VALUES (0, 22, 15034, 2);
+INSERT INTO family5 VALUES (0, 23, 16840, 2);
+INSERT INTO family5 VALUES (0, 24, 16843, 2);
+INSERT INTO family5 VALUES (0, 25, 16846, 2);
+INSERT INTO family5 VALUES (0, 26, 16849, 2);
+INSERT INTO family5 VALUES (0, 27, 16852, 2);
+INSERT INTO family5 VALUES (0, 28, 16854, 2);
+INSERT INTO family5 VALUES (0, 29, 16856, 2);
+INSERT INTO family5 VALUES (0, 30, 16857, 2);
+INSERT INTO family5 VALUES (0, 31, 16860, 2);
+INSERT INTO family5 VALUES (0, 32, 16862, 2);
+INSERT INTO family5 VALUES (0, 33, 16865, 2);
+INSERT INTO family5 VALUES (0, 34, 16868, 2);
+INSERT INTO family5 VALUES (0, 35, 16871, 2);
+INSERT INTO family5 VALUES (0, 36, 16873, 2);
+INSERT INTO family5 VALUES (0, 37, 16875, 2);
+INSERT INTO family5 VALUES (0, 38, 16878, 2);
+INSERT INTO family5 VALUES (0, 39, 16884, 2);
+INSERT INTO family5 VALUES (0, 40, 16887, 2);
+INSERT INTO family5 VALUES (0, 41, 16889, 2);
+INSERT INTO family5 VALUES (0, 42, 16892, 2);
+INSERT INTO family5 VALUES (1, 0, 3510, 5);
+INSERT INTO family5 VALUES (1, 1, 462, 1010);
+INSERT INTO family5 VALUES (1, 2, 477, 1010);
+INSERT INTO family5 VALUES (1, 3, 12913, 42);
+INSERT INTO family5 VALUES (1, 4, 470, 1);
+INSERT INTO family5 VALUES (1, 5, 465, 20);
+INSERT INTO family5 VALUES (1, 6, 12823, 1000);
+INSERT INTO family5 VALUES (1, 7, 5159, 3);
+INSERT INTO family5 VALUES (1, 8, 5549, 50);
+INSERT INTO entitlements VALUES (0, '1085660', 1);
+INSERT INTO entitlements VALUES (1, 'STEAM_PAID_TIER', 1);
+INSERT INTO entitlements VALUES (2, 'STEAM_UGC_BLOCKED', 0);
+INSERT INTO entitlements VALUES (3, '1090090', 2);
+INSERT INTO entitlements VALUES (4, '1090091', 2);
+INSERT INTO entitlements VALUES (5, '1090092', 2);
+INSERT INTO entitlements VALUES (6, '1090093', 2);
+INSERT INTO entitlements VALUES (7, '1090094', 2);
+INSERT INTO entitlements VALUES (8, '1090095', 2);
+INSERT INTO entitlements VALUES (9, '1090096', 2);
+INSERT INTO entitlements VALUES (10, '1090150', 2);
+INSERT INTO entitlements VALUES (11, '1090151', 2);
+INSERT INTO entitlements VALUES (12, '1090152', 2);
+INSERT INTO entitlements VALUES (13, '1090170', 2);
+INSERT INTO entitlements VALUES (14, '1090171', 2);
+INSERT INTO entitlements VALUES (15, '1090200', 2);
+INSERT INTO entitlements VALUES (16, '1090201', 2);
+INSERT INTO entitlements VALUES (17, '1090202', 2);
+INSERT INTO entitlements VALUES (18, '1330040', 2);
+INSERT INTO bootstrap VALUES ('lore', 0);
+INSERT INTO family5 VALUES (1, 9, 607, 11);
+UPDATE items SET movement_ability=6,grenade_ability=7,super_ability=10,melee_ability=11,class_ability=2 WHERE character_slot=0 AND location=0 AND position=11;
+UPDATE items SET movement_ability=6,grenade_ability=7,super_ability=10,melee_ability=11,class_ability=2 WHERE character_slot=1 AND location=0 AND position=11;
+UPDATE items SET movement_ability=5,grenade_ability=7,super_ability=10,melee_ability=11,class_ability=2 WHERE character_slot=2 AND location=0 AND position=11;

+ 119 - 0
Sunrise/resources/database/investment_schema.sql

@@ -0,0 +1,119 @@
+PRAGMA application_id = 1397902921;
+PRAGMA user_version = 2;
+
+CREATE TABLE account (
+    id INTEGER PRIMARY KEY CHECK (id = 1),
+    soid INTEGER NOT NULL,
+    profile_setup_completed INTEGER NOT NULL CHECK (profile_setup_completed IN (0, 1))
+) STRICT;
+
+CREATE TABLE characters (
+    slot INTEGER PRIMARY KEY CHECK (slot BETWEEN 0 AND 2),
+    soid INTEGER NOT NULL UNIQUE,
+    race INTEGER NOT NULL CHECK (race BETWEEN 0 AND 2),
+    gender INTEGER NOT NULL CHECK (gender BETWEEN 0 AND 1),
+    class INTEGER NOT NULL CHECK (class BETWEEN 0 AND 2),
+    level INTEGER NOT NULL CHECK (level BETWEEN 0 AND 255),
+    preview_available INTEGER NOT NULL CHECK (preview_available IN (0, 1)),
+    appearance_value REAL NOT NULL,
+    last_orbited_destination INTEGER NOT NULL,
+    content_bypass INTEGER NOT NULL CHECK (content_bypass IN (0, 1)),
+    equipped_title INTEGER NOT NULL CHECK (equipped_title BETWEEN 0 AND 65535),
+    acquired_subclass_mask INTEGER NOT NULL,
+    next_inventory_serial INTEGER NOT NULL CHECK (next_inventory_serial BETWEEN 0 AND 4294967295)
+) STRICT;
+
+CREATE TABLE items (
+    character_slot INTEGER NOT NULL REFERENCES characters(slot),
+    location INTEGER NOT NULL CHECK (location IN (0, 1)),
+    position INTEGER NOT NULL CHECK (position >= 0),
+    instance_soid INTEGER NOT NULL UNIQUE,
+    definition_hash INTEGER NOT NULL CHECK (definition_hash BETWEEN 1 AND 4294967295),
+    level INTEGER NOT NULL,
+    quantity INTEGER NOT NULL CHECK (quantity > 0),
+    mutation_serial INTEGER NOT NULL CHECK (mutation_serial >= 0),
+    flags INTEGER NOT NULL CHECK (flags BETWEEN 0 AND 7),
+    socket_policy INTEGER NOT NULL CHECK (socket_policy IN (0, 1)),
+    plug_count INTEGER NOT NULL CHECK (plug_count BETWEEN 0 AND 12),
+    movement_ability INTEGER NOT NULL,
+    grenade_ability INTEGER NOT NULL,
+    super_ability INTEGER NOT NULL,
+    melee_ability INTEGER NOT NULL,
+    class_ability INTEGER NOT NULL,
+    seen INTEGER NOT NULL CHECK(seen IN(0,1)),
+    PRIMARY KEY (character_slot, location, position),
+    CHECK ((location = 0 AND position < 17) OR (location = 1 AND position < 135))
+) STRICT;
+
+CREATE TABLE sockets (
+    instance_soid INTEGER NOT NULL REFERENCES items(instance_soid) ON DELETE CASCADE,
+    lane INTEGER NOT NULL CHECK (lane BETWEEN 0 AND 11),
+    plug_hash INTEGER NOT NULL CHECK (plug_hash BETWEEN 1 AND 4294967295),
+    PRIMARY KEY (instance_soid, lane)
+) STRICT;
+
+CREATE TABLE profile_items (
+    position INTEGER PRIMARY KEY CHECK (position BETWEEN 0 AND 700),
+    instance_soid INTEGER NOT NULL,
+    definition_hash INTEGER NOT NULL,
+    quantity INTEGER NOT NULL CHECK (quantity > 0),
+    mutation_serial INTEGER NOT NULL CHECK (mutation_serial >= 0),
+    seen INTEGER NOT NULL CHECK(seen IN(0,1))
+) STRICT;
+
+CREATE TABLE character_stacks (
+    character_slot INTEGER NOT NULL REFERENCES characters(slot),
+    position INTEGER NOT NULL CHECK (position BETWEEN 0 AND 31),
+    definition_hash INTEGER NOT NULL,
+    quantity INTEGER NOT NULL CHECK (quantity > 0),
+    mutation_serial INTEGER NOT NULL CHECK (mutation_serial >= 0),
+    PRIMARY KEY (character_slot, position)
+) STRICT;
+
+CREATE TABLE dismantle_rewards (
+    position INTEGER PRIMARY KEY CHECK (position BETWEEN 0 AND 31),
+    definition_hash INTEGER NOT NULL,
+    quantity INTEGER NOT NULL CHECK (quantity > 0),
+    tier_mask INTEGER NOT NULL,
+    class_mask INTEGER NOT NULL,
+    masterwork INTEGER NOT NULL CHECK (masterwork BETWEEN 0 AND 2)
+) STRICT;
+
+CREATE TABLE unlocks (
+    character_slot INTEGER NOT NULL CHECK (character_slot BETWEEN -1 AND 2),
+    bank INTEGER NOT NULL CHECK (bank BETWEEN 0 AND 7),
+    slot INTEGER NOT NULL CHECK (slot >= 0),
+    lane INTEGER NOT NULL CHECK (lane BETWEEN 0 AND 2),
+    value INTEGER NOT NULL CHECK (value BETWEEN -2147483648 AND 2147483647),
+    PRIMARY KEY (character_slot, bank, slot, lane),
+    CHECK ((bank IN (0, 1, 3, 6) AND character_slot = -1)
+        OR (bank IN (2, 4, 5, 7) AND character_slot >= 0))
+) STRICT;
+
+CREATE TABLE family5 (
+    kind INTEGER NOT NULL CHECK (kind IN (0, 1)),
+    position INTEGER NOT NULL CHECK (position BETWEEN 0 AND 99),
+    slot INTEGER NOT NULL CHECK (slot BETWEEN 0 AND 65535),
+    value INTEGER NOT NULL CHECK (value BETWEEN -2147483648 AND 2147483647),
+    PRIMARY KEY (kind, position),
+    UNIQUE (kind, slot)
+) STRICT;
+
+CREATE TABLE entitlements (
+    position INTEGER PRIMARY KEY,
+    name TEXT NOT NULL,
+    ownership INTEGER NOT NULL CHECK (ownership BETWEEN 0 AND 2)
+) STRICT;
+
+CREATE TABLE bootstrap (
+    name TEXT PRIMARY KEY,
+    completed INTEGER NOT NULL CHECK (completed IN (0, 1))
+) STRICT;
+
+CREATE TABLE pending_rewards (
+    id INTEGER PRIMARY KEY AUTOINCREMENT,
+    character_slot INTEGER NOT NULL CHECK (character_slot BETWEEN 0 AND 2),
+    kind INTEGER NOT NULL CHECK (kind IN (0, 1)),
+    definition_hash INTEGER NOT NULL CHECK (definition_hash BETWEEN 1 AND 4294967295),
+    quantity INTEGER NOT NULL CHECK (quantity > 0)
+) STRICT;

Разлика између датотеке није приказан због своје велике величине
+ 2 - 31
Sunrise/resources/default_settings.json


+ 9 - 0
Sunrise/resources/resource.h

@@ -38,3 +38,12 @@
 #define SUNRISE_VER_BUILD 0
 /** The same version as display text. Windows shows this string, not the four fields. */
 #define SUNRISE_VER_STRING "0.4.0.0"
+
+/** SQLite schema, default rows, and upstream notice are embedded in the DLL. */
+#define IDR_INVESTMENT_SCHEMA 106
+#define IDR_INVESTMENT_DEFAULTS 107
+#define IDR_SQLITE_NOTICE 108
+
+/** Account preferences have their own schema and seed data in the save. */
+#define IDR_ACCOUNT_SETTINGS_SCHEMA 109
+#define IDR_ACCOUNT_SETTINGS_DEFAULTS 110

+ 7 - 0
Sunrise/resources/sunrise.rc

@@ -54,3 +54,10 @@ BEGIN
         VALUE "Translation", 0x409, 1200
     END
 END
+
+IDR_INVESTMENT_SCHEMA RCDATA "database/investment_schema.sql"
+IDR_INVESTMENT_DEFAULTS RCDATA "database/investment_defaults.sql"
+IDR_SQLITE_NOTICE RCDATA "../vendor/sqlite/NOTICE.txt"
+
+IDR_ACCOUNT_SETTINGS_SCHEMA RCDATA "database/account_settings_schema.sql"
+IDR_ACCOUNT_SETTINGS_DEFAULTS RCDATA "database/account_settings_defaults.sql"

+ 4 - 2
Sunrise/src/client/hooks/network/content_config/request/content_config_get_replacement.cpp

@@ -95,8 +95,10 @@ void complete_request(HttpRequestResult& result, LONG status, std::size_t size)
  */
 [[nodiscard]] bool encode_view(void* context, const state::content_manifest::View& view) noexcept {
     auto& encode = *static_cast<EncodeContext*>(context);
-    return middleware::content::manifest::encode(
-        state::entitlements::get(), view.rows, view.guid, encode.output, encode.size);
+    state::entitlements::Table ownership;
+    return state::entitlements::snapshot(ownership)
+           && middleware::content::manifest::encode(
+               ownership, view.rows, view.guid, encode.output, encode.size);
 }
 
 /** Exact ABI of the fetch wrapper this replacement stands in for. */

+ 7 - 9
Sunrise/src/core/runtime/core_runtime.cpp

@@ -18,6 +18,7 @@
 #include "../../state/activity_sdk/runtime.h"
 #include "../../state/content_manifest/content_manifest_state_runtime.h"
 #include "../../state/entitlements/entitlement_runtime.h"
+#include "../../state/investment/store.h"
 #include "../../state/runtime/runtime.h"
 #include "../../state/unlocks/unlocks_runtime.h"
 #include "../filesystem/path.h"
@@ -40,8 +41,11 @@ constexpr std::wstring_view kInstalledPackagesDirectory = L"packages";
 
 /** Initializes the base State before content-authenticated generated artifacts are considered. */
 [[nodiscard]] bool initialize_state(void* module) noexcept {
-    return state::initialize(
-        module, settings::get().initialAccount, settings::get().initialActivityDefaults);
+    if (!state::investment::store::initialize(module)) {
+        return false;
+    }
+    return state::investment::store::validate()
+           && state::initialize(module, settings::get().initialActivityDefaults);
 }
 
 /** Copies the live public installed-content fingerprint without retaining State-owned memory. */
@@ -149,7 +153,6 @@ bool initialize(void* module) noexcept {
         // Settings name their own failure; the sinks do not exist yet to carry a second line.
         return false;
     }
-    state::unlocks::publish(settings::get().initialUnlocks);
     // One stage per step, so a boot failure names the step instead of the whole expression.
     const char* stage = nullptr;
     if (!log::initialize(module, settings::get().logging)) {
@@ -165,8 +168,7 @@ bool initialize(void* module) noexcept {
             stage = "ui_hud";
         } else if (!ui::modules::logs::initialize()) {
             stage = "ui_logs";
-        } else if (!state::entitlements::publish(settings::get().server.entitlements)) {
-            stage = "entitlements";
+
         } else if (!initialize_state(module)) {
             stage = "state";
         } else if (!initialize_content_manifest(module)) {
@@ -192,12 +194,10 @@ bool initialize(void* module) noexcept {
         state::content_manifest::shutdown();
         state::activity_sdk::shutdown();
         state::shutdown();
-        state::entitlements::clear();
         ui::modules::logs::shutdown();
         ui::modules::hud::shutdown();
         ui::modules::registry::shutdown();
         ui::runtime::shutdown();
-        state::unlocks::clear();
         log::shutdown();
         settings::shutdown();
         return false;
@@ -224,13 +224,11 @@ bool shutdown() noexcept {
     state::content_manifest::shutdown();
     state::activity_sdk::shutdown();
     state::shutdown();
-    state::entitlements::clear();
     ui::modules::logs::shutdown();
     ui::modules::hud::shutdown();
     ui::modules::registry::shutdown();
     ui::runtime::shutdown();
     log::write(log::Channel::core, log::Level::info, "ev=shutdown result=ok");
-    state::unlocks::clear();
     log::shutdown();
     settings::shutdown();
     return true;

+ 3 - 80
Sunrise/src/core/settings/parser.h

@@ -24,6 +24,9 @@ public:
     /** Parses the root object on top of the caller's defaults. */
     [[nodiscard]] bool parse_root(Settings& output) noexcept;
 
+    /** Reads only the root version; a missing version is zero. */
+    [[nodiscard]] bool parse_version(std::uint32_t& output) noexcept;
+
 private:
     /** Parses the Core settings object. */
     [[nodiscard]] bool core(Settings& output) noexcept;
@@ -42,14 +45,6 @@ private:
     [[nodiscard]] bool activation_settings(server::activation::Settings& output) noexcept;
     /** Parses the gameplay endpoint block. Topology, addresses, port and reserve must agree. */
     [[nodiscard]] bool gameplay_settings(server::gameplay::Settings& output) noexcept;
-    /**
-     * Parses the authored entitlement array, replacing the bundled policy.
-     * Array order is the handle order the Client finds definitions by, so rows are kept as
-     * configured.
-     */
-    [[nodiscard]] bool entitlements(state::entitlements::Table& output) noexcept;
-    /** Parses one entitlement. It needs a bounded name and a supported ownership form. */
-    [[nodiscard]] bool entitlement(state::entitlements::Entitlement& output) noexcept;
     /** Parses Steam settings. Each supported object may appear at most once. */
     [[nodiscard]] bool steam_settings(steam::Settings& output) noexcept;
     /** Parses the single local Steam user. Its persona must be unique and bounded. */
@@ -68,78 +63,6 @@ private:
     /** Parses the arrival override table, which has to fit fixed storage. */
     [[nodiscard]] bool
     arrival_overrides(state::activity::defaults::ActivityDefaults& output) noexcept;
-    /** Parses the unlock table. */
-    [[nodiscard]] bool unlocks(state::unlocks::Table& output) noexcept;
-    /** Fills the flag bank from authored runs. */
-    [[nodiscard]] bool flag_runs(std::span<std::uint8_t> bank) noexcept;
-    /** Fills the flag bank from authored indices. */
-    [[nodiscard]] bool flag_indices(std::span<std::uint8_t> bank) noexcept;
-    /** Fills the objective bank from authored signed values. */
-    [[nodiscard]] bool objective_values(std::span<std::int32_t> bank) noexcept;
-    /** Fills the progression bank from authored values. */
-    [[nodiscard]] bool progression_values(state::unlocks::ProgressionBank& bank) noexcept;
-    /** Parses the investment group: family-5 overrides and the catalyst gate. */
-    [[nodiscard]] bool investment(Settings& output) noexcept;
-    /** Fills the flag-override list from [slot, value] pairs, each within its bounds. */
-    [[nodiscard]] bool unlock_flag_overrides(state::Family5State& output) noexcept;
-    /** Fills the signed value-override list from [slot, value] pairs, each within its bounds. */
-    [[nodiscard]] bool unlock_value_overrides(state::Family5State& output) noexcept;
-    /** Parses the account object. */
-    [[nodiscard]] bool account(state::AccountState& output) noexcept;
-    /** Parses the character array, in configuration order, up to the playable size. */
-    [[nodiscard]] bool characters(state::AccountState& output) noexcept;
-    /**
-     * Parses the account-wide item array, in configuration order.
-     * A profile item names only its definition and quantity. Its slot is not authored: the
-     * inventory bucket the definition belongs to names the first slot of that bucket's run.
-     */
-    [[nodiscard]] bool profile_items(state::AccountState& output) noexcept;
-    /** Parses the definition-driven ordinary-gear dismantle payout. */
-    [[nodiscard]] bool dismantle_rewards(state::AccountState& output) noexcept;
-    /** Parses one character identity. The object must contain one nonzero SOID. */
-    [[nodiscard]] bool character(state::CharacterState& output) noexcept;
-
-    /** Parses the equipment object. Every slot name must be known and appear at most once. */
-    [[nodiscard]] bool equipment(state::account::inventory::Equipment& output) noexcept;
-    /** Parses the unequipped inventory array, in authored bucket-placement order. */
-    [[nodiscard]] bool
-    character_inventory(state::account::inventory::CharacterItems& output) noexcept;
-    /** Parses one item. Every required named field must appear exactly once. */
-    [[nodiscard]] bool equipment_item(state::account::inventory::Item& output) noexcept;
-    /** Parses the socket policy: null for the native default, or up to 12 hash-or-null lanes. */
-    [[nodiscard]] bool equipment_plugs(state::account::inventory::Sockets& output) noexcept;
-    /** Parses one definition hash: any 32-bit value except the engine no-definition sentinel. */
-    [[nodiscard]] bool inventory_definition_hash(std::uint32_t& output) noexcept;
-    /** Parses the grouped account settings. Its migration latch has to be complete. */
-    [[nodiscard]] bool account_settings(state::account::settings::AccountSettings& output) noexcept;
-
-    // --- Account setting groups ---------------------------------------------------------------
-    // Each takes Sunrise-owned names and writes bounded value types. None exposes a record offset.
-
-    /** Parses controller and mouse settings. */
-    [[nodiscard]] bool controls_settings(state::account::settings::Controls& output) noexcept;
-    /** Parses voice, volume and migration settings. */
-    [[nodiscard]] bool audio_settings(state::account::settings::Audio& output) noexcept;
-    /** Parses screen and renderer settings. */
-    [[nodiscard]] bool display_settings(state::account::settings::Display& output) noexcept;
-    /** Parses HUD and text settings. */
-    [[nodiscard]] bool interface_settings(state::account::settings::Interface& output) noexcept;
-    /** Parses matchmaking and chat settings. */
-    [[nodiscard]] bool social_settings(state::account::settings::Social& output) noexcept;
-
-    /** Parses the action table. Every action appears once, with both input halves. */
-    [[nodiscard]] bool
-    key_bindings(state::account::settings::bindings::KeyBindings& output) noexcept;
-    /** Parses one binding. Both halves appear exactly once; null means unbound. */
-    [[nodiscard]] bool key_binding(state::account::settings::bindings::Binding& output) noexcept;
-    /** Parses one input name, or null for unbound. Numbers are not accepted. */
-    [[nodiscard]] bool optional_input_code(std::optional<std::uint16_t>& output) noexcept;
-    /**
-     * Turns one input name into its input code.
-     * @param name Key name, or one modifier and the key it prefixes joined by "+".
-     */
-    [[nodiscard]] static bool input_code_value(std::string_view name,
-                                               std::uint16_t& output) noexcept;
     /** Parses logging sinks and channel levels. */
     [[nodiscard]] bool logging(log::Settings& output) noexcept;
     /** Parses named channel levels and ignores unknown channels. */

+ 0 - 2
Sunrise/src/core/settings/server/definition.h

@@ -11,8 +11,6 @@ inline constexpr std::uint16_t kDefaultBapPort = 30974;
 
 /** Read-only Server settings. */
 struct Settings {
-    /** Authored ownership policy declared by SignOn and defined by the content manifest. */
-    state::entitlements::Table entitlements{};
     /** Gameplay UDP endpoint topology. Disabled leaves the channel unpublished. */
     gameplay::Settings gameplay{};
     /** Per-domain gates for the default client-activation work. */

+ 0 - 98
Sunrise/src/core/settings/server/entitlement_settings_parser.cpp

@@ -1,98 +0,0 @@
-#include <algorithm>
-
-#include "../../../state/entitlements/validation.h"
-#include "../parser.h"
-
-namespace sunrise::core::settings::parser {
-namespace {
-
-/** Settings name for a definition that is published but never declared owned. */
-constexpr std::string_view kOwnedNone = "none";
-/** Settings name for a definition owned and declared by its manifest handle. */
-constexpr std::string_view kOwnedHandle = "handle";
-/** Settings name for a definition owned and declared by its application id. */
-constexpr std::string_view kOwnedApplication = "application";
-
-/**
- * Maps one settings ownership name onto its declaration form.
- * @param text Authored ownership name.
- * @return False for an unsupported name.
- */
-[[nodiscard]] bool ownership_value(std::string_view text,
-                                   state::entitlements::Ownership& output) noexcept {
-    if (text == kOwnedNone) {
-        output = state::entitlements::Ownership::none;
-    } else if (text == kOwnedHandle) {
-        output = state::entitlements::Ownership::handle;
-    } else if (text == kOwnedApplication) {
-        output = state::entitlements::Ownership::application;
-    } else {
-        return false;
-    }
-    return true;
-}
-
-} // namespace
-
-/** Parses the authored entitlement array. */
-bool Parser::entitlements(state::entitlements::Table& output) noexcept {
-    output = {};
-    if (!consume('[')) {
-        return false;
-    }
-    if (consume(']')) {
-        return true;
-    }
-    for (;;) {
-        if (output.count >= output.entries.size() || !entitlement(output.entries[output.count])) {
-            return false;
-        }
-        ++output.count;
-        if (consume(']')) {
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/** Parses one authored entitlement definition. */
-bool Parser::entitlement(state::entitlements::Entitlement& output) noexcept {
-    output = {};
-    if (!consume('{')) {
-        return false;
-    }
-    bool hasName = false;
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        if (key == "name") {
-            std::string_view name;
-            if (hasName || !string(name) || name.empty()
-                || name.size() >= state::entitlements::kNameCapacity) {
-                return false;
-            }
-            std::copy(name.begin(), name.end(), output.name.begin());
-            output.nameLength = static_cast<std::uint8_t>(name.size());
-            hasName = true;
-        } else if (key == "owned") {
-            std::string_view owned;
-            if (!string(owned) || !ownership_value(owned, output.ownership)) {
-                return false;
-            }
-        } else if (!skip_value(0)) {
-            return false;
-        }
-        if (consume('}')) {
-            return hasName && state::entitlements::valid(output);
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-} // namespace sunrise::core::settings::parser

+ 2 - 9
Sunrise/src/core/settings/server/server_settings_parser.cpp

@@ -8,14 +8,12 @@ namespace sunrise::core::settings::parser {
 /** Checks the standalone Server settings object. */
 bool Parser::server_settings(server::Settings& output) noexcept {
     output = {};
-    output.entitlements = state::entitlements::authored();
     if (!consume('{')) {
         return false;
     }
     if (consume('}')) {
         return true;
     }
-    bool hasEntitlements = false;
     bool hasBapPort = false;
     bool hasGameplay = false;
     bool hasActivation = false;
@@ -24,12 +22,7 @@ bool Parser::server_settings(server::Settings& output) noexcept {
         if (!string(key) || !consume(':')) {
             return false;
         }
-        if (key == "entitlements") {
-            if (hasEntitlements || !entitlements(output.entitlements)) {
-                return false;
-            }
-            hasEntitlements = true;
-        } else if (key == "bap_port") {
+        if (key == "bap_port") {
             std::uint64_t value = 0;
             if (hasBapPort || !unsigned_integer(value) || value == 0
                 || value > (std::numeric_limits<std::uint16_t>::max)()) {
@@ -51,7 +44,7 @@ bool Parser::server_settings(server::Settings& output) noexcept {
             return false;
         }
         if (consume('}')) {
-            return state::entitlements::valid(output.entitlements);
+            return true;
         }
         if (!consume(',')) {
             return false;

+ 1 - 8
Sunrise/src/core/settings/settings.h

@@ -24,7 +24,7 @@ struct ActivitySdkGenerationSettings final {
  * Raise it when a key is renamed, removed, changes meaning, or must take a new default. Adding a
  * key needs no raise, because a missing key already takes its default.
  */
-inline constexpr std::uint32_t kSettingsVersion = 16;
+inline constexpr std::uint32_t kSettingsVersion = 18;
 
 /** Parsed read-only process settings. */
 struct Settings {
@@ -35,7 +35,6 @@ struct Settings {
     std::uint32_t version{};
     /**
      * Completes released exotic weapon catalysts while resolving client item state.
-     * Authored under `state.investment`, with the rest of the investment content policy.
      */
     bool completeExoticCatalysts{true};
     /** Core-owned sink and channel policy. */
@@ -48,14 +47,8 @@ struct Settings {
     server::Settings server;
     /** Options used only by the Steam compatibility layer. */
     steam::Settings steam;
-    /** Complete authored account State, or an empty account. */
-    state::AccountState initialAccount;
     /** Small local destination fallback published when State starts. */
     state::activity::defaults::ActivityDefaults initialActivityDefaults;
-    /** Authored acquired-flag and objective policy published into the account object. */
-    state::unlocks::Table initialUnlocks;
-    /** Authored family-5 unlock overrides. Only the two override lists are authored here. */
-    state::Family5State initialFamily5;
 };
 
 /** @return The complete default settings. */

+ 40 - 1
Sunrise/src/core/settings/settings_parser.cpp

@@ -9,6 +9,41 @@ namespace sunrise::core::settings::parser {
 /** @param input Complete JSON text, borrowed and never changed. */
 Parser::Parser(std::string_view input) noexcept : input_(input) {}
 
+/** Reads the version without interpreting settings from an older schema. */
+bool Parser::parse_version(std::uint32_t& output) noexcept {
+    output = 0;
+    if (!consume('{')) {
+        return false;
+    }
+    if (consume('}')) {
+        return at_end();
+    }
+    bool found = false;
+    for (;;) {
+        std::string_view key;
+        if (!string(key) || !consume(':')) {
+            return false;
+        }
+        if (key == "version") {
+            std::uint64_t value = 0;
+            if (found || !unsigned_integer(value)
+                || value > (std::numeric_limits<std::uint32_t>::max)()) {
+                return false;
+            }
+            output = static_cast<std::uint32_t>(value);
+            found = true;
+        } else if (!skip_value(0)) {
+            return false;
+        }
+        if (consume('}')) {
+            return at_end();
+        }
+        if (!consume(',')) {
+            return false;
+        }
+    }
+}
+
 /** Parses the supported root object and skips unknown top-level values. */
 bool Parser::parse_root(Settings& output) noexcept {
     if (!consume('{')) {
@@ -36,6 +71,10 @@ bool Parser::parse_root(Settings& output) noexcept {
             }
             output.version = static_cast<std::uint32_t>(value);
             hasVersion = true;
+        } else if (key == "complete_exotic_catalysts") {
+            if (!boolean(output.completeExoticCatalysts)) {
+                return false;
+            }
         } else if (key == "core") {
             if (hasCore || !core(output)) {
                 return false;
@@ -227,7 +266,7 @@ Settings defaults() noexcept {
         .completeExoticCatalysts = true,
         .logging = log::defaults(),
         .activitySdkGeneration = {},
-        .server = server::Settings{state::entitlements::authored()},
+        .server = server::Settings{},
         .initialActivityDefaults = state::activity::defaults::authored(),
     };
 }

+ 22 - 76
Sunrise/src/core/settings/settings_runtime.cpp

@@ -3,21 +3,21 @@
 #include <array>
 #include <cstdint>
 #include <cstdio>
+#include <memory>
+#include <new>
 #include <string_view>
 
 #include "../../../resources/resource.h"
 #include "../filesystem/path.h"
 #include "../logging/log.h"
+#include "parser.h"
 #include "settings.h"
-#include "settings_upgrade.h"
 
 namespace sunrise::core::settings {
 namespace {
 
 /** The JSON settings file is the only file stored directly in the owned folder. */
 constexpr std::wstring_view kSettingsFileSuffix = L"\\settings.json";
-/** An upgraded document is staged under this suffix before it replaces the settings file. */
-constexpr std::wstring_view kUpgradeStageSuffix = L".new";
 /** Largest settings file accepted into fixed storage. */
 constexpr std::size_t kConfigCapacity = 1024 * 1024;
 
@@ -43,7 +43,7 @@ Settings g_settings = defaults();
 }
 
 /**
- * Reports a file this build did not upgrade, which means a newer build wrote it.
+ * Reports a settings version that differs from this build.
  * @param fileVersion Version read from the file, or zero when the key was missing.
  */
 void report_version(std::uint32_t fileVersion) noexcept {
@@ -118,60 +118,6 @@ void report_version(std::uint32_t fileVersion) noexcept {
     return complete;
 }
 
-/**
- * Replaces the settings file with an upgraded document.
- * The text is staged beside the file and moved over it, so a failed write cannot leave half a file.
- * @param configPath Null-terminated settings path.
- * @param document Complete upgraded document.
- * @return True when the file now holds the upgraded document.
- */
-[[nodiscard]] bool store_upgraded(const path::Buffer& configPath,
-                                  std::string_view document) noexcept {
-    path::Buffer stagePath = configPath;
-    if (!path::append(stagePath, kUpgradeStageSuffix)) {
-        return false;
-    }
-    const HANDLE file = CreateFileW(stagePath.chars.data(),
-                                    GENERIC_WRITE,
-                                    0,
-                                    nullptr,
-                                    CREATE_ALWAYS,
-                                    FILE_ATTRIBUTE_NORMAL,
-                                    nullptr);
-    if (file == INVALID_HANDLE_VALUE) {
-        return false;
-    }
-    DWORD written = 0;
-    const auto size = static_cast<DWORD>(document.size());
-    bool complete =
-        WriteFile(file, document.data(), size, &written, nullptr) != FALSE && written == size;
-    complete = CloseHandle(file) != FALSE && complete;
-    complete =
-        complete
-        && MoveFileExW(stagePath.chars.data(), configPath.chars.data(), MOVEFILE_REPLACE_EXISTING)
-               != FALSE;
-    if (!complete) {
-        (void)DeleteFileW(stagePath.chars.data());
-    }
-    return complete;
-}
-
-/**
- * Reports the outcome of an in-place upgrade of the settings file.
- * @param stored True when the upgraded document replaced the file on disk.
- */
-void report_upgrade(bool stored) noexcept {
-    std::array<char, 96> line{};
-    const int written = std::snprintf(line.data(),
-                                      line.size(),
-                                      "ev=settings stage=upgrade version=%u stored=%u",
-                                      static_cast<unsigned>(kSettingsVersion),
-                                      stored ? 1U : 0U);
-    if (written > 0) {
-        log::early({line.data(), static_cast<std::size_t>(written)});
-    }
-}
-
 /**
  * Drops a leading UTF-8 byte order mark.
  * Common editors write one and the parser would read it as a stray token, which fails startup
@@ -234,38 +180,38 @@ bool initialize(void* module) noexcept {
         return fail("too_large");
     }
 
-    // Static because two 1 MiB banks overflow the stack. Settings load once, on one thread.
-    static std::array<char, kConfigCapacity> buffer{};
+    const std::unique_ptr<std::array<char, kConfigCapacity>> buffer{
+        new (std::nothrow) std::array<char, kConfigCapacity>{}};
+    if (!buffer) {
+        CloseHandle(readableFile);
+        return fail("allocate");
+    }
     DWORD read = 0;
     const bool readOk =
-        ReadFile(readableFile, buffer.data(), static_cast<DWORD>(size.QuadPart), &read, nullptr)
+        ReadFile(readableFile, buffer->data(), static_cast<DWORD>(size.QuadPart), &read, nullptr)
             != FALSE
         && read == size.QuadPart;
     const bool closed = CloseHandle(readableFile) != FALSE;
     if (!readOk || !closed) {
         return fail("read");
     }
-    std::string_view document = without_byte_order_mark(std::string_view(buffer.data(), read));
-    static std::array<char, kConfigCapacity> upgradedBuffer{};
-    const bool upgrading = upgrade::needed(document);
-    if (upgrading) {
-        std::string_view bundled;
-        std::size_t upgraded = 0;
-        if (!bundled_document(module, bundled)
-            || !upgrade::apply(document, bundled, upgradedBuffer, upgraded)) {
-            return fail("upgrade");
+    std::string_view document = without_byte_order_mark(std::string_view(buffer->data(), read));
+    std::uint32_t version = 0;
+    if (!parser::Parser(document).parse_version(version)) {
+        return fail("version");
+    }
+    if (version < kSettingsVersion) {
+        if (!DeleteFileW(configPath.chars.data())) {
+            return fail("delete_old");
+        }
+        if (!write_default(module, configPath) || !bundled_document(module, document)) {
+            return fail("write_default");
         }
-        document = std::string_view(upgradedBuffer.data(), upgraded);
     }
-
     Settings parsed;
     if (!parse(document, parsed)) {
         return fail("parse");
     }
-    // The file is replaced only once the upgraded document is known to parse.
-    if (upgrading) {
-        report_upgrade(store_upgraded(configPath, document));
-    }
     report_version(parsed.version);
     g_settings = parsed;
     return true;

+ 0 - 407
Sunrise/src/core/settings/settings_upgrade.cpp

@@ -1,407 +0,0 @@
-/**
- * Boot-time repair of a settings file written against an older layout version.
- * A member whose value form changed takes the bundled default, a renamed one is renamed in place
- * so its authored value survives, and one this build no longer reads is deleted.
- */
-
-#include "settings_upgrade.h"
-
-#include <array>
-#include <cstdint>
-#include <cstdio>
-
-#include "settings.h"
-
-namespace sunrise::core::settings::upgrade {
-namespace {
-
-/** The layout version member, quoted so a value string cannot match it. */
-constexpr std::string_view kVersionMember = "\"version\"";
-
-/** One replaced member, and the layout version that changed it. */
-struct ReplacedMember {
-    /** Quoted member name, so a value string cannot match it. */
-    std::string_view name;
-    /** Replaced only while the file is older than this version. */
-    std::uint32_t version;
-};
-
-/**
- * Members replaced with the bundled default, each with the version that changed it.
- * A member is listed because its value form changed, or because its default changed.
- */
-constexpr std::array<ReplacedMember, 10> kReplacedMembers{{
-    {"\"key_bindings\"", 3},
-    {"\"region_private\"", 5},
-    {"\"topology\"", 5},
-    {"\"characters\"", 5},
-    {"\"profile_items\"", 7},
-    // Version 8 turned the flat payout list into rows filtered by rarity, gear class and
-    // masterwork state.
-    {"\"dismantle_rewards\"", 8},
-    // Version 13 turned this on. A file that never carried it takes the new default; one that
-    // carried the old value is corrected here.
-    {"\"activity_public_membership\"", 13},
-    // Version 15 seeded the lore book unlock slots, so both banks take the new default.
-    {"\"character_flags\"", 15},
-    {"\"objective_values\"", 15},
-    // Version 16 dropped the generation switch. The whole block is replaced, because "enabled" is
-    // not unique in the document. The block also carries the lua_declarations default of
-    // version 13.
-    {"\"activity_sdk_generation\"", 16},
-}};
-
-/** One renamed member, and the layout version that renamed it. */
-struct RenamedMember {
-    /** Quoted old member name, so a value string cannot match it. */
-    std::string_view from;
-    /** Quoted new member name written in its place. */
-    std::string_view to;
-    /** Renamed only while the file is older than this version. */
-    std::uint32_t version;
-};
-
-/**
- * Members renamed with their values kept, each with the version that renamed it.
- * Only the key text is replaced, so an authored value survives the rename.
- */
-constexpr std::array<RenamedMember, 1> kRenamedMembers{{
-    // Version 11 named the field for what it holds: the activity the client asked from.
-    {"\"previous_activity_index\"", "\"source_activity_index\"", 11},
-}};
-
-/** One removed member, and the layout version that removed it. */
-struct RemovedMember {
-    /** Quoted member name, so a value string cannot match it. */
-    std::string_view name;
-    /** Removed only while the file is older than this version. */
-    std::uint32_t version;
-};
-
-/**
- * Members this build no longer reads, each with the version that removed it.
- * Only the first occurrence of a name is removed, so a member repeated per character, such as the
- * version-16 `accepted`, is left for the parser to skip as an unknown key.
- */
-constexpr std::array<RemovedMember, 11> kRemovedMembers{{
-    {"\"force_join_request_ready\"", 12},
-    // Version 14 dropped two client stand-ins and moved the catalyst gate under
-    // `state.investment`, so the root copy is no longer read.
-    {"\"skip_profile_setup\"", 14},
-    {"\"ignore_client_slot_release\"", 14},
-    {"\"complete_exotic_catalysts\"", 14},
-    // Version 16 dropped two gates nothing read and one that only skipped a receipt row.
-    {"\"activity_compatibility_mirror\"", 16},
-    {"\"gameplay_external_body\"", 16},
-    {"\"server_default_entity\"", 16},
-    // Version 16 dropped the four switches of the deleted spawn hold, fade release and relay hooks.
-    {"\"suppress_peer_relay\"", 16},
-    {"\"fade_release\"", 16},
-    {"\"hold_spawn\"", 16},
-    {"\"spawn_hold_ms\"", 16},
-}};
-
-/** One splice per replaced, renamed and removed member, plus the version member itself. */
-constexpr std::size_t kSpliceCapacity =
-    kReplacedMembers.size() + kRenamedMembers.size() + kRemovedMembers.size() + 1;
-/** Room for the version member and its digits when the file predates versioning. */
-constexpr std::size_t kVersionTextCapacity = 32;
-
-/** One region of the document and the text that takes its place. */
-struct Splice {
-    std::size_t start;
-    std::size_t end;
-    std::string_view text;
-};
-
-/**
- * Steps over one JSON string.
- * @param text Document text.
- * @param position Index of the opening quote.
- * @return Index after the closing quote, or the length when it never closes.
- */
-[[nodiscard]] std::size_t skip_string(std::string_view text, std::size_t position) noexcept {
-    for (++position; position < text.size(); ++position) {
-        if (text[position] == '\\') {
-            ++position;
-            continue;
-        }
-        if (text[position] == '"') {
-            return position + 1;
-        }
-    }
-    return text.size();
-}
-
-/**
- * Steps over one JSON value of any type. Strings are skipped whole, so a brace inside one cannot
- * close an object.
- * @param text Document text.
- * @param position Index of the first byte of the value.
- * @return Index after the value.
- */
-[[nodiscard]] std::size_t skip_value(std::string_view text, std::size_t position) noexcept {
-    if (position >= text.size()) {
-        return text.size();
-    }
-    if (text[position] == '"') {
-        return skip_string(text, position);
-    }
-    if (text[position] != '{' && text[position] != '[') {
-        std::size_t end = position;
-        while (end < text.size() && text[end] != ',' && text[end] != '}' && text[end] != ']') {
-            ++end;
-        }
-        // A scalar runs to its separator, so trailing layout belongs to the document, not the
-        // value.
-        while (end > position
-               && (text[end - 1] == ' ' || text[end - 1] == '\t' || text[end - 1] == '\r'
-                   || text[end - 1] == '\n')) {
-            --end;
-        }
-        return end;
-    }
-    std::size_t depth = 0;
-    for (; position < text.size(); ++position) {
-        const char value = text[position];
-        if (value == '"') {
-            position = skip_string(text, position) - 1;
-            continue;
-        }
-        if (value == '{' || value == '[') {
-            ++depth;
-            continue;
-        }
-        if (value == '}' || value == ']') {
-            --depth;
-            if (depth == 0) {
-                return position + 1;
-            }
-        }
-    }
-    return text.size();
-}
-
-/**
- * Finds one member's value inside a document.
- * @param text Document text.
- * @param member Quoted member name.
- * @param start Receives the first byte of the value.
- * @param end Receives the byte after the value.
- * @return True when the member is present with a value.
- */
-[[nodiscard]] bool value_span(std::string_view text,
-                              std::string_view member,
-                              std::size_t& start,
-                              std::size_t& end) noexcept {
-    const std::size_t found = text.find(member);
-    if (found == std::string_view::npos) {
-        return false;
-    }
-    std::size_t position = found + member.size();
-    const std::string_view blanks = " \t\r\n";
-    position = text.find_first_not_of(blanks, position);
-    if (position == std::string_view::npos || text[position] != ':') {
-        return false;
-    }
-    position = text.find_first_not_of(blanks, position + 1);
-    if (position == std::string_view::npos) {
-        return false;
-    }
-    start = position;
-    end = skip_value(text, position);
-    return end > start;
-}
-
-/**
- * Finds one member's own name inside a document.
- * @param text Document text.
- * @param member Quoted member name.
- * @param start Receives the opening quote.
- * @param end Receives the byte after the closing quote.
- * @return True when the member is present as a key.
- */
-[[nodiscard]] bool name_span(std::string_view text,
-                             std::string_view member,
-                             std::size_t& start,
-                             std::size_t& end) noexcept {
-    const std::size_t found = text.find(member);
-    if (found == std::string_view::npos) {
-        return false;
-    }
-    const std::size_t after = text.find_first_not_of(" \t\r\n", found + member.size());
-    if (after == std::string_view::npos || text[after] != ':') {
-        return false;
-    }
-    start = found;
-    end = found + member.size();
-    return true;
-}
-
-/**
- * Finds everything one member occupies, including the comma that joins it to a neighbour.
- * The comma after the value goes with the member. When the member is last, the comma before it
- * goes instead. Either way the object stays valid once the member is gone.
- * @param text Document text.
- * @param member Quoted member name.
- * @param start Receives the first byte to drop.
- * @param end Receives the byte after the last byte to drop.
- * @return True when the member is present as a key with a value.
- */
-[[nodiscard]] bool member_span(std::string_view text,
-                               std::string_view member,
-                               std::size_t& start,
-                               std::size_t& end) noexcept {
-    std::size_t nameStart = 0;
-    std::size_t nameEnd = 0;
-    if (!name_span(text, member, nameStart, nameEnd) || !value_span(text, member, start, end)) {
-        return false;
-    }
-    const std::string_view blanks = " \t\r\n";
-    start = nameStart;
-    while (start > 0 && blanks.find(text[start - 1]) != std::string_view::npos) {
-        --start;
-    }
-    const std::size_t next = text.find_first_not_of(blanks, end);
-    if (next != std::string_view::npos && text[next] == ',') {
-        end = next + 1;
-        return true;
-    }
-    // A last member takes the comma before it, or the object keeps a trailing one.
-    if (start > 0 && text[start - 1] == ',') {
-        --start;
-    }
-    return true;
-}
-
-/**
- * Reads the layout version a document was written against.
- * @param document Document text.
- * @return The version, or zero when the member is absent or unreadable.
- */
-[[nodiscard]] std::uint32_t document_version(std::string_view document) noexcept {
-    std::size_t start = 0;
-    std::size_t end = 0;
-    if (!value_span(document, kVersionMember, start, end)) {
-        return 0;
-    }
-    std::uint32_t version = 0;
-    for (std::size_t position = start; position < end; ++position) {
-        const char digit = document[position];
-        if (digit < '0' || digit > '9') {
-            return 0;
-        }
-        version = version * 10 + static_cast<std::uint32_t>(digit - '0');
-    }
-    return version;
-}
-
-} // namespace
-
-/** Reports whether the document predates the layout this build reads. */
-bool needed(std::string_view document) noexcept {
-    return document_version(document) < kSettingsVersion;
-}
-
-/** Replaces the changed members with the bundled defaults and stamps the current version. */
-bool apply(std::string_view document,
-           std::string_view bundled,
-           std::span<char> output,
-           std::size_t& written) noexcept {
-    written = 0;
-    std::array<Splice, kSpliceCapacity> splices{};
-    std::size_t count = 0;
-
-    std::array<char, kVersionTextCapacity> versionText{};
-    std::size_t start = 0;
-    std::size_t end = 0;
-    if (value_span(document, kVersionMember, start, end)) {
-        const int length = std::snprintf(
-            versionText.data(), versionText.size(), "%u", static_cast<unsigned>(kSettingsVersion));
-        if (length <= 0) {
-            return false;
-        }
-        splices[count++] = {start, end, {versionText.data(), static_cast<std::size_t>(length)}};
-    } else {
-        // A file that predates versioning carries no member to replace, so one is added first.
-        const std::size_t root = document.find('{');
-        if (root == std::string_view::npos) {
-            return false;
-        }
-        const int length = std::snprintf(versionText.data(),
-                                         versionText.size(),
-                                         "\"version\": %u,",
-                                         static_cast<unsigned>(kSettingsVersion));
-        if (length <= 0) {
-            return false;
-        }
-        splices[count++] = {
-            root + 1, root + 1, {versionText.data(), static_cast<std::size_t>(length)}};
-    }
-
-    const std::uint32_t from = document_version(document);
-    for (const ReplacedMember& member : kReplacedMembers) {
-        // A file at or past that version keeps its own value, so a user choice is never lost.
-        if (from >= member.version) {
-            continue;
-        }
-        std::size_t replacementStart = 0;
-        std::size_t replacementEnd = 0;
-        if (!value_span(document, member.name, start, end)
-            || !value_span(bundled, member.name, replacementStart, replacementEnd)) {
-            // A member the file never carried needs no replacement.
-            continue;
-        }
-        splices[count++] = {
-            start, end, bundled.substr(replacementStart, replacementEnd - replacementStart)};
-    }
-
-    for (const RenamedMember& member : kRenamedMembers) {
-        // A file at or past that version already carries the new name.
-        if (from >= member.version || !name_span(document, member.from, start, end)) {
-            continue;
-        }
-        splices[count++] = {start, end, member.to};
-    }
-
-    for (const RemovedMember& member : kRemovedMembers) {
-        // A file at or past that version was written without the member.
-        if (from >= member.version || !member_span(document, member.name, start, end)) {
-            continue;
-        }
-        splices[count++] = {start, end, {}};
-    }
-
-    for (std::size_t index = 1; index < count; ++index) {
-        const Splice held = splices[index];
-        std::size_t position = index;
-        while (position > 0 && splices[position - 1].start > held.start) {
-            splices[position] = splices[position - 1];
-            --position;
-        }
-        splices[position] = held;
-    }
-
-    std::size_t read = 0;
-    for (std::size_t index = 0; index < count; ++index) {
-        const Splice& splice = splices[index];
-        const std::size_t copied = splice.start - read;
-        if (written + copied + splice.text.size() > output.size()) {
-            return false;
-        }
-        document.copy(output.data() + written, copied, read);
-        written += copied;
-        splice.text.copy(output.data() + written, splice.text.size());
-        written += splice.text.size();
-        read = splice.end;
-    }
-    const std::size_t tail = document.size() - read;
-    if (written + tail > output.size()) {
-        return false;
-    }
-    document.copy(output.data() + written, tail, read);
-    written += tail;
-    return true;
-}
-
-} // namespace sunrise::core::settings::upgrade

+ 0 - 30
Sunrise/src/core/settings/settings_upgrade.h

@@ -1,30 +0,0 @@
-#pragma once
-
-#include <cstddef>
-#include <span>
-#include <string_view>
-
-namespace sunrise::core::settings::upgrade {
-
-/**
- * @param document Borrowed settings file text.
- * @return True when the document was written against an older layout version.
- */
-[[nodiscard]] bool needed(std::string_view document) noexcept;
-
-/**
- * Rewrites an older settings document onto the current layout. Members whose value form changed
- * take the bundled default, renamed members keep their value under the new name, and every other
- * member is copied through unchanged.
- * @param document Borrowed settings file text.
- * @param bundled Borrowed default document holding the replacement members.
- * @param output Receives the rewritten document.
- * @param written Receives the rewritten length.
- * @return True when the whole rewritten document fits the output.
- */
-[[nodiscard]] bool apply(std::string_view document,
-                         std::string_view bundled,
-                         std::span<char> output,
-                         std::size_t& written) noexcept;
-
-} // namespace sunrise::core::settings::upgrade

+ 0 - 336
Sunrise/src/core/settings/state/account_rows_parser.cpp

@@ -1,336 +0,0 @@
-#include <limits>
-
-#include "../../../state/build_data/items/item_catalog.h"
-#include "../parser.h"
-
-namespace sunrise::core::settings::parser {
-namespace {
-
-/** Character levels are stored in one unsigned byte in authored State. */
-constexpr std::uint64_t kMaximumCharacterLevel = (std::numeric_limits<std::uint8_t>::max)();
-/** A destination definition hash is one unsigned 32-bit field. */
-constexpr std::uint64_t kMaximumDestinationHash = (std::numeric_limits<std::uint32_t>::max)();
-/** The travelling-activity index is one unsigned 16-bit field in the family-4 character. */
-constexpr std::uint64_t kMaximumTravellingActivityIndex =
-    (std::numeric_limits<std::uint16_t>::max)();
-
-/** Sets the tier bit one rarity name stands for. */
-[[nodiscard]] bool dismantle_tier_bit(std::string_view name, std::uint8_t& mask) noexcept {
-    using Tier = state::build_data::items::Tier;
-    Tier tier = Tier::none;
-    if (name == "common") {
-        tier = Tier::common;
-    } else if (name == "uncommon") {
-        tier = Tier::uncommon;
-    } else if (name == "rare") {
-        tier = Tier::rare;
-    } else if (name == "legendary") {
-        tier = Tier::legendary;
-    } else if (name == "exotic") {
-        tier = Tier::exotic;
-    } else {
-        return false;
-    }
-    const std::uint8_t bit = static_cast<std::uint8_t>(1U << static_cast<unsigned>(tier));
-    if ((mask & bit) != 0) {
-        return false;
-    }
-    mask |= bit;
-    return true;
-}
-
-} // namespace
-
-/** Parses the materials credited by gear dismantles, with optional rarity and class filters. */
-bool Parser::dismantle_rewards(state::AccountState& output) noexcept {
-    output.dismantleRewards = {};
-    output.dismantleRewardCount = 0;
-    if (!consume('[')) {
-        return false;
-    }
-    if (consume(']')) {
-        return true;
-    }
-    for (;;) {
-        if (output.dismantleRewardCount >= output.dismantleRewards.size() || !consume('{')) {
-            return false;
-        }
-        state::DismantleRewardPolicy reward{};
-        bool hasHash = false;
-        bool hasQuantity = false;
-        for (;;) {
-            std::string_view key;
-            if (!string(key) || !consume(':')) {
-                return false;
-            }
-            std::uint64_t value = 0;
-            if (key == "definition_hash") {
-                if (hasHash || !unsigned_value(value) || value == 0
-                    || value > (std::numeric_limits<std::uint32_t>::max)()) {
-                    return false;
-                }
-                reward.definitionHash = static_cast<std::uint32_t>(value);
-                hasHash = true;
-            } else if (key == "quantity") {
-                if (hasQuantity || !unsigned_integer(value) || value == 0
-                    || value > (std::numeric_limits<std::int32_t>::max)()) {
-                    return false;
-                }
-                reward.quantity = static_cast<std::int32_t>(value);
-                hasQuantity = true;
-            } else if (key == "rarity") {
-                // One name or an array of names; each sets its tier bit.
-                if (reward.tierMask != 0) {
-                    return false;
-                }
-                const bool list = consume('[');
-                for (;;) {
-                    std::string_view name;
-                    if (!string(name) || !dismantle_tier_bit(name, reward.tierMask)) {
-                        return false;
-                    }
-                    if (!list || consume(']')) {
-                        break;
-                    }
-                    if (!consume(',')) {
-                        return false;
-                    }
-                }
-            } else if (key == "class") {
-                std::string_view name;
-                if (reward.classMask != 0 || !string(name)) {
-                    return false;
-                }
-                if (name == "weapon") {
-                    reward.classMask = static_cast<std::uint8_t>(state::DismantleGearClass::weapon);
-                } else if (name == "armor") {
-                    reward.classMask = static_cast<std::uint8_t>(state::DismantleGearClass::armor);
-                } else {
-                    return false;
-                }
-            } else if (key == "masterworked") {
-                bool masterworked = false;
-                if (reward.masterwork != state::DismantleMasterworkFilter::any
-                    || !boolean(masterworked)) {
-                    return false;
-                }
-                reward.masterwork = masterworked
-                                        ? state::DismantleMasterworkFilter::masterworked
-                                        : state::DismantleMasterworkFilter::notMasterworked;
-            } else if (!skip_value(0)) {
-                return false;
-            }
-            if (consume('}')) {
-                break;
-            }
-            if (!consume(',')) {
-                return false;
-            }
-        }
-        for (std::size_t index = 0; index < output.dismantleRewardCount; ++index) {
-            if (state::same_dismantle_policy_key(output.dismantleRewards[index], reward)) {
-                return false;
-            }
-        }
-        if (!hasHash || !hasQuantity) {
-            return false;
-        }
-        output.dismantleRewards[output.dismantleRewardCount++] = reward;
-        if (consume(']')) {
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/** Parses the authored account-wide item array. */
-bool Parser::profile_items(state::AccountState& output) noexcept {
-    namespace inventory = state::account::inventory;
-    output.profileItems = {};
-    output.profileItemCount = 0;
-    if (!consume('[')) {
-        return false;
-    }
-    if (consume(']')) {
-        return true;
-    }
-    for (;;) {
-        if (output.profileItemCount >= output.profileItems.size() || !consume('{')) {
-            return false;
-        }
-        inventory::ProfileItem item{};
-        bool hasHash = false;
-        bool hasQuantity = false;
-        for (;;) {
-            std::string_view key;
-            if (!string(key) || !consume(':')) {
-                return false;
-            }
-            std::uint64_t value = 0;
-            if (key == "definition_hash") {
-                if (hasHash || !unsigned_value(value)
-                    || value > (std::numeric_limits<std::uint32_t>::max)()) {
-                    return false;
-                }
-                item.definitionHash = static_cast<std::uint32_t>(value);
-                hasHash = true;
-            } else if (key == "quantity") {
-                if (hasQuantity || !unsigned_integer(value)
-                    || value > (std::numeric_limits<std::int32_t>::max)() || value == 0) {
-                    return false;
-                }
-                item.quantity = static_cast<std::int32_t>(value);
-                hasQuantity = true;
-            } else if (!skip_value(0)) {
-                return false;
-            }
-            if (consume('}')) {
-                break;
-            }
-            if (!consume(',')) {
-                return false;
-            }
-        }
-        if (!hasHash || !hasQuantity) {
-            return false;
-        }
-        output.profileItems[output.profileItemCount++] = item;
-        if (consume(']')) {
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/** Parses the authored character array. */
-bool Parser::characters(state::AccountState& output) noexcept {
-    output.characters = {};
-    output.characterCount = 0;
-    if (!consume('[')) {
-        return false;
-    }
-    if (consume(']')) {
-        return true;
-    }
-    for (;;) {
-        if (output.characterCount >= output.characters.size()
-            || !character(output.characters[output.characterCount])) {
-            return false;
-        }
-        ++output.characterCount;
-        if (consume(']')) {
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/** Parses one authored character identity. */
-bool Parser::character(state::CharacterState& output) noexcept {
-    output = {};
-    if (!consume('{')) {
-        return false;
-    }
-    bool hasSoid = false;
-    bool hasEquipment = false;
-    bool hasInventory = false;
-    if (consume('}')) {
-        return false;
-    }
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        if (key == "soid") {
-            if (!unsigned_value(output.soid) || output.soid == 0) {
-                return false;
-            }
-            hasSoid = true;
-        } else if (key == "race") {
-            std::uint64_t value = 0;
-            if (!unsigned_integer(value)
-                || value > static_cast<std::uint8_t>(state::CharacterRace::exo)) {
-                return false;
-            }
-            output.race = static_cast<state::CharacterRace>(value);
-        } else if (key == "gender") {
-            std::uint64_t value = 0;
-            if (!unsigned_integer(value)
-                || value > static_cast<std::uint8_t>(state::CharacterGender::female)) {
-                return false;
-            }
-            output.gender = static_cast<state::CharacterGender>(value);
-        } else if (key == "class") {
-            std::uint64_t value = 0;
-            if (!unsigned_integer(value)
-                || value > static_cast<std::uint8_t>(state::CharacterClass::warlock)) {
-                return false;
-            }
-            output.characterClass = static_cast<state::CharacterClass>(value);
-        } else if (key == "level") {
-            std::uint64_t value = 0;
-            if (!unsigned_integer(value) || value > kMaximumCharacterLevel) {
-                return false;
-            }
-            output.level = static_cast<std::uint8_t>(value);
-        } else if (key == "preview_available") {
-            if (!boolean(output.previewAvailable)) {
-                return false;
-            }
-        } else if (key == "appearance_value") {
-            if (!floating_point(output.appearanceValue)) {
-                return false;
-            }
-        } else if (key == "last_orbited_destination") {
-            std::uint64_t value = 0;
-            if (!unsigned_value(value) || value > kMaximumDestinationHash) {
-                return false;
-            }
-            output.lastOrbitedDestination = static_cast<std::uint32_t>(value);
-        } else if (key == "current_activity_index") {
-            std::uint64_t value = 0;
-            if (!unsigned_value(value) || value > kMaximumTravellingActivityIndex) {
-                return false;
-            }
-            output.currentActivityIndex = static_cast<std::uint16_t>(value);
-        } else if (key == "content_bypass") {
-            if (!boolean(output.contentBypass)) {
-                return false;
-            }
-        } else if (key == "movement_ability" || key == "grenade_ability" || key == "super_ability"
-                   || key == "melee_ability" || key == "class_ability") {
-            // Written out but never read back: the subclass screen's first paint each login shows
-            // the ability-entry defaults, which a restored pick would contradict.
-            if (!skip_value(0)) {
-                return false;
-            }
-        } else if (key == "equipment") {
-            if (hasEquipment || !equipment(output.equipment)) {
-                return false;
-            }
-            hasEquipment = true;
-        } else if (key == "inventory") {
-            if (hasInventory || !character_inventory(output.inventory)) {
-                return false;
-            }
-            hasInventory = true;
-        } else if (!skip_value(0)) {
-            return false;
-        }
-        if (consume('}')) {
-            return hasSoid;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-} // namespace sunrise::core::settings::parser

+ 0 - 100
Sunrise/src/core/settings/state/account_settings_parser.cpp

@@ -1,100 +0,0 @@
-#include <bitset>
-
-#include "../parser.h"
-
-namespace sunrise::core::settings::parser {
-namespace {
-
-/** Required account-setting groups use one fixed presence slot each. */
-enum class Group : std::size_t {
-    controls,
-    audio,
-    display,
-    interface,
-    social,
-    keyBindings,
-    count,
-};
-
-} // namespace
-
-/** Parses grouped account settings. Native record offsets stay hidden. */
-bool Parser::account_settings(state::account::settings::AccountSettings& output) noexcept {
-    output = {};
-    if (!consume('{')) {
-        return false;
-    }
-    std::bitset<static_cast<std::size_t>(Group::count)> supplied;
-    // Tracked apart from the bitset because this key is optional: an enumerated group is required
-    // by the supplied.all() below, and an older settings file does not carry it.
-    bool hasKeyBindingSource = false;
-    const auto mark = [&supplied](Group group) noexcept {
-        const std::size_t index = static_cast<std::size_t>(group);
-        if (supplied.test(index)) {
-            return false;
-        }
-        supplied.set(index);
-        return true;
-    };
-    if (consume('}')) {
-        return false;
-    }
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        if (key == "controls") {
-            if (!mark(Group::controls) || !controls_settings(output.controls)) {
-                return false;
-            }
-        } else if (key == "audio") {
-            if (!mark(Group::audio) || !audio_settings(output.audio)) {
-                return false;
-            }
-        } else if (key == "display") {
-            if (!mark(Group::display) || !display_settings(output.display)) {
-                return false;
-            }
-        } else if (key == "interface") {
-            if (!mark(Group::interface) || !interface_settings(output.interface)) {
-                return false;
-            }
-        } else if (key == "social") {
-            if (!mark(Group::social) || !social_settings(output.social)) {
-                return false;
-            }
-        } else if (key == "key_binding_source") {
-            std::string_view source;
-            if (hasKeyBindingSource || !string(source)) {
-                return false;
-            }
-            if (source == "account") {
-                output.keyBindingSource = state::account::settings::KeyBindingSource::account;
-            } else if (source == "computer") {
-                output.keyBindingSource = state::account::settings::KeyBindingSource::computer;
-            } else {
-                return false;
-            }
-            hasKeyBindingSource = true;
-        } else if (key == "key_bindings") {
-            if (!mark(Group::keyBindings) || !key_bindings(output.keyBindings)) {
-                return false;
-            }
-        } else if (!skip_value(0)) {
-            return false;
-        }
-        if (consume('}')) {
-            if (!supplied.all()) {
-                return false;
-            }
-            output.configured = true;
-            return state::account::settings::valid(output);
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-} // namespace sunrise::core::settings::parser

+ 0 - 91
Sunrise/src/core/settings/state/audio_parser.cpp

@@ -1,91 +0,0 @@
-#include <bitset>
-
-#include "../parser.h"
-
-namespace sunrise::core::settings::parser {
-
-/** Parses voice, volume, and migration settings under stable Sunrise-owned names. */
-bool Parser::audio_settings(state::account::settings::Audio& output) noexcept {
-    enum class Field : std::size_t {
-        voiceOutputMode,
-        teamVoiceChannel,
-        reservedMode,
-        migrationVersion,
-        chatVolume,
-        muteWhenUnfocused,
-        soundEffectsVolume,
-        dialogueVolume,
-        musicVolume,
-        count,
-    };
-
-    output = {};
-    if (!consume('{')) {
-        return false;
-    }
-    std::bitset<static_cast<std::size_t>(Field::count)> supplied;
-    const auto mark = [&supplied](Field field) noexcept {
-        const std::size_t index = static_cast<std::size_t>(field);
-        if (supplied.test(index)) {
-            return false;
-        }
-        supplied.set(index);
-        return true;
-    };
-    if (consume('}')) {
-        return false;
-    }
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        if (key == "voice_output_mode") {
-            if (!mark(Field::voiceOutputMode) || !signed_byte(output.voiceOutputMode)) {
-                return false;
-            }
-        } else if (key == "team_voice_channel") {
-            if (!mark(Field::teamVoiceChannel) || !signed_byte(output.teamVoiceChannel)) {
-                return false;
-            }
-        } else if (key == "reserved_mode") {
-            if (!mark(Field::reservedMode) || !signed_byte(output.reservedMode)) {
-                return false;
-            }
-        } else if (key == "migration_version") {
-            if (!mark(Field::migrationVersion) || !signed_byte(output.migrationVersion)) {
-                return false;
-            }
-        } else if (key == "chat_volume") {
-            if (!mark(Field::chatVolume) || !signed_byte(output.chatVolume)) {
-                return false;
-            }
-        } else if (key == "mute_when_unfocused") {
-            if (!mark(Field::muteWhenUnfocused) || !boolean(output.muteWhenUnfocused)) {
-                return false;
-            }
-        } else if (key == "sound_effects_volume") {
-            if (!mark(Field::soundEffectsVolume) || !signed_byte(output.soundEffectsVolume)) {
-                return false;
-            }
-        } else if (key == "dialogue_volume") {
-            if (!mark(Field::dialogueVolume) || !signed_byte(output.dialogueVolume)) {
-                return false;
-            }
-        } else if (key == "music_volume") {
-            if (!mark(Field::musicVolume) || !signed_byte(output.musicVolume)) {
-                return false;
-            }
-        } else if (!skip_value(0)) {
-            return false;
-        }
-        if (consume('}')) {
-            return supplied.all();
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-} // namespace sunrise::core::settings::parser

+ 0 - 126
Sunrise/src/core/settings/state/controls_parser.cpp

@@ -1,126 +0,0 @@
-#include <bitset>
-
-#include "../parser.h"
-
-namespace sunrise::core::settings::parser {
-
-/** Parses controller and mouse settings under stable Sunrise-owned names. */
-bool Parser::controls_settings(state::account::settings::Controls& output) noexcept {
-    enum class Field : std::size_t {
-        buttonLayout,
-        movementMode,
-        controllerLookSensitivity,
-        controllerInvertVertical,
-        controllerAutoLookCentering,
-        controllerVibration,
-        controllerSwapShoulders,
-        controllerInvertHorizontal,
-        mouseLookSensitivity,
-        mouseInvertVertical,
-        mouseInvertHorizontal,
-        unidentifiedToggle,
-        mouseAimSmoothing,
-        adsSensitivityModifier,
-        doublePressDelay,
-        count,
-    };
-
-    output = {};
-    if (!consume('{')) {
-        return false;
-    }
-    std::bitset<static_cast<std::size_t>(Field::count)> supplied;
-    const auto mark = [&supplied](Field field) noexcept {
-        const std::size_t index = static_cast<std::size_t>(field);
-        if (supplied.test(index)) {
-            return false;
-        }
-        supplied.set(index);
-        return true;
-    };
-    if (consume('}')) {
-        return false;
-    }
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        if (key == "button_layout") {
-            if (!mark(Field::buttonLayout) || !signed_byte(output.buttonLayout)) {
-                return false;
-            }
-        } else if (key == "movement_mode") {
-            if (!mark(Field::movementMode) || !signed_byte(output.movementMode)) {
-                return false;
-            }
-        } else if (key == "controller_look_sensitivity") {
-            if (!mark(Field::controllerLookSensitivity)
-                || !signed_byte(output.controllerLookSensitivity)) {
-                return false;
-            }
-        } else if (key == "controller_invert_vertical") {
-            if (!mark(Field::controllerInvertVertical)
-                || !boolean(output.controllerInvertVertical)) {
-                return false;
-            }
-        } else if (key == "controller_auto_look_centering") {
-            if (!mark(Field::controllerAutoLookCentering)
-                || !boolean(output.controllerAutoLookCentering)) {
-                return false;
-            }
-        } else if (key == "controller_vibration") {
-            if (!mark(Field::controllerVibration) || !boolean(output.controllerVibration)) {
-                return false;
-            }
-        } else if (key == "controller_swap_shoulders") {
-            if (!mark(Field::controllerSwapShoulders) || !boolean(output.controllerSwapShoulders)) {
-                return false;
-            }
-        } else if (key == "controller_invert_horizontal") {
-            if (!mark(Field::controllerInvertHorizontal)
-                || !boolean(output.controllerInvertHorizontal)) {
-                return false;
-            }
-        } else if (key == "mouse_look_sensitivity") {
-            if (!mark(Field::mouseLookSensitivity) || !signed_32(output.mouseLookSensitivity)) {
-                return false;
-            }
-        } else if (key == "mouse_invert_vertical") {
-            if (!mark(Field::mouseInvertVertical) || !boolean(output.mouseInvertVertical)) {
-                return false;
-            }
-        } else if (key == "mouse_invert_horizontal") {
-            if (!mark(Field::mouseInvertHorizontal) || !boolean(output.mouseInvertHorizontal)) {
-                return false;
-            }
-        } else if (key == "unidentified_toggle") {
-            if (!mark(Field::unidentifiedToggle) || !boolean(output.unidentifiedToggle)) {
-                return false;
-            }
-        } else if (key == "mouse_aim_smoothing") {
-            if (!mark(Field::mouseAimSmoothing) || !boolean(output.mouseAimSmoothing)) {
-                return false;
-            }
-        } else if (key == "ads_sensitivity_modifier") {
-            if (!mark(Field::adsSensitivityModifier)
-                || !floating_point(output.adsSensitivityModifier)) {
-                return false;
-            }
-        } else if (key == "double_press_delay") {
-            if (!mark(Field::doublePressDelay) || !signed_byte(output.doublePressDelay)) {
-                return false;
-            }
-        } else if (!skip_value(0)) {
-            return false;
-        }
-        if (consume('}')) {
-            return supplied.all();
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-} // namespace sunrise::core::settings::parser

+ 0 - 91
Sunrise/src/core/settings/state/display_parser.cpp

@@ -1,91 +0,0 @@
-#include <bitset>
-#include <limits>
-
-#include "../parser.h"
-
-namespace sunrise::core::settings::parser {
-
-/** Parses screen and renderer settings under stable Sunrise-owned names. */
-bool Parser::display_settings(state::account::settings::Display& output) noexcept {
-    enum class Field : std::size_t {
-        brightness,
-        showFps,
-        hdrMode,
-        calibrationPrimary,
-        calibrationAlpha,
-        count,
-    };
-
-    output = {};
-    if (!consume('{')) {
-        return false;
-    }
-    std::bitset<static_cast<std::size_t>(Field::count)> supplied;
-    // Tracked apart from the bitset because these two keys are optional: an enumerated field is
-    // required by the supplied.all() below, and an older settings file does not carry them.
-    bool hasVerticalSyncInterval = false;
-    bool hasFieldOfView = false;
-    const auto mark = [&supplied](Field field) noexcept {
-        const std::size_t index = static_cast<std::size_t>(field);
-        if (supplied.test(index)) {
-            return false;
-        }
-        supplied.set(index);
-        return true;
-    };
-    if (consume('}')) {
-        return false;
-    }
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        if (key == "brightness") {
-            if (!mark(Field::brightness) || !signed_byte(output.brightness)) {
-                return false;
-            }
-        } else if (key == "show_fps") {
-            if (!mark(Field::showFps) || !boolean(output.showFps)) {
-                return false;
-            }
-        } else if (key == "hdr_mode") {
-            if (!mark(Field::hdrMode) || !signed_byte(output.hdrMode)) {
-                return false;
-            }
-        } else if (key == "vertical_sync_interval") {
-            std::uint64_t value = 0;
-            // Bounds the narrowing only. The 0 to 4 presentation domain is checked with the rest
-            // of the account settings, so it is stated once.
-            if (hasVerticalSyncInterval || !unsigned_integer(value)
-                || value > (std::numeric_limits<std::uint8_t>::max)()) {
-                return false;
-            }
-            output.verticalSyncInterval = static_cast<std::uint8_t>(value);
-            hasVerticalSyncInterval = true;
-        } else if (key == "field_of_view") {
-            if (hasFieldOfView || !signed_32(output.fieldOfView)) {
-                return false;
-            }
-            hasFieldOfView = true;
-        } else if (key == "calibration_primary") {
-            if (!mark(Field::calibrationPrimary) || !floating_point(output.calibrationPrimary)) {
-                return false;
-            }
-        } else if (key == "calibration_alpha") {
-            if (!mark(Field::calibrationAlpha) || !floating_point(output.calibrationAlpha)) {
-                return false;
-            }
-        } else if (!skip_value(0)) {
-            return false;
-        }
-        if (consume('}')) {
-            return supplied.all();
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-} // namespace sunrise::core::settings::parser

+ 0 - 119
Sunrise/src/core/settings/state/family5_override_parser.cpp

@@ -1,119 +0,0 @@
-#include "../parser.h"
-
-namespace sunrise::core::settings::parser {
-namespace {
-
-/** The family-5 flag encoder rejects any override slot above 23499. */
-constexpr std::uint64_t kMaximumFlagSlot = 23499;
-/** Flag values run 0 to 2. The family-5 encoder adds the wire bias. */
-constexpr std::uint64_t kMaximumFlagValue = 2;
-/** The family-5 value encoder rejects any override slot above 15499. */
-constexpr std::uint64_t kMaximumValueSlot = 15499;
-/** Both family-5 override counts ship in a 7-bit wire field, so 127 rows is the wire limit. */
-constexpr std::size_t kMaximumOverrideRows = 127;
-
-// Fixed override storage is the tighter bound, so row parsers only check the array size.
-static_assert(state::kUnlockOverrideCapacity <= kMaximumOverrideRows,
-              "Override storage must fit the seven-bit wire count field.");
-
-} // namespace
-
-/** Parses the optional authored investment group: the family-5 overrides and the catalyst gate. */
-bool Parser::investment(Settings& output) noexcept {
-    state::Family5State parsed{};
-    bool catalysts = output.completeExoticCatalysts;
-    if (!consume('{')) {
-        return false;
-    }
-    if (consume('}')) {
-        output.initialFamily5 = parsed;
-        return true;
-    }
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        bool complete = false;
-        if (key == "family5_flag_overrides") {
-            complete = unlock_flag_overrides(parsed);
-        } else if (key == "family5_value_overrides") {
-            complete = unlock_value_overrides(parsed);
-        } else if (key == "complete_exotic_catalysts") {
-            complete = boolean(catalysts);
-        } else {
-            complete = skip_value(0);
-        }
-        if (!complete) {
-            return false;
-        }
-        if (consume('}')) {
-            // Publish both lists together, so a refused row leaves State untouched.
-            output.initialFamily5 = parsed;
-            output.completeExoticCatalysts = catalysts;
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/** Fills the flag-override list from [slot, value] pairs. */
-bool Parser::unlock_flag_overrides(state::Family5State& output) noexcept {
-    output.flagCount = 0;
-    if (!consume('[')) {
-        return false;
-    }
-    if (consume(']')) {
-        return true;
-    }
-    for (;;) {
-        std::uint64_t slot = 0;
-        std::uint64_t value = 0;
-        if (output.flagCount >= output.flags.size() || !consume('[') || !unsigned_integer(slot)
-            || !consume(',') || !unsigned_integer(value) || !consume(']') || slot > kMaximumFlagSlot
-            || value > kMaximumFlagValue) {
-            return false;
-        }
-        state::UnlockFlagOverride& row = output.flags[output.flagCount++];
-        row.slot = static_cast<std::uint16_t>(slot);
-        row.value = static_cast<std::uint8_t>(value);
-        if (consume(']')) {
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/** Fills the signed value-override list from [slot, value] pairs. */
-bool Parser::unlock_value_overrides(state::Family5State& output) noexcept {
-    output.valueCount = 0;
-    if (!consume('[')) {
-        return false;
-    }
-    if (consume(']')) {
-        return true;
-    }
-    for (;;) {
-        std::uint64_t slot = 0;
-        std::int32_t value = 0;
-        if (output.valueCount >= output.values.size() || !consume('[') || !unsigned_integer(slot)
-            || !consume(',') || !signed_32(value) || !consume(']') || slot > kMaximumValueSlot) {
-            return false;
-        }
-        state::UnlockValueOverride& row = output.values[output.valueCount++];
-        row.slot = static_cast<std::uint16_t>(slot);
-        row.value = value;
-        if (consume(']')) {
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-} // namespace sunrise::core::settings::parser

+ 0 - 116
Sunrise/src/core/settings/state/interface_parser.cpp

@@ -1,116 +0,0 @@
-#include <bitset>
-
-#include "../parser.h"
-
-namespace sunrise::core::settings::parser {
-
-/** Parses HUD and text settings under stable Sunrise-owned names. */
-bool Parser::interface_settings(state::account::settings::Interface& output) noexcept {
-    enum class Field : std::size_t {
-        subtitlesMode,
-        colorblindMode,
-        helmetMode,
-        hudOpacity,
-        displayHints,
-        backgroundOpacity,
-        reticleLocation,
-        reticleColor,
-        textSize,
-        textColor,
-        textBackgroundStyle,
-        textBackgroundOpacity,
-        reservedTextMode,
-        subtitleOptionsEntry,
-        count,
-    };
-
-    output = {};
-    if (!consume('{')) {
-        return false;
-    }
-    std::bitset<static_cast<std::size_t>(Field::count)> supplied;
-    const auto mark = [&supplied](Field field) noexcept {
-        const std::size_t index = static_cast<std::size_t>(field);
-        if (supplied.test(index)) {
-            return false;
-        }
-        supplied.set(index);
-        return true;
-    };
-    if (consume('}')) {
-        return false;
-    }
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        if (key == "subtitles_mode") {
-            if (!mark(Field::subtitlesMode) || !signed_byte(output.subtitlesMode)) {
-                return false;
-            }
-        } else if (key == "colorblind_mode") {
-            if (!mark(Field::colorblindMode) || !signed_byte(output.colorblindMode)) {
-                return false;
-            }
-        } else if (key == "helmet_mode") {
-            if (!mark(Field::helmetMode) || !signed_byte(output.helmetMode)) {
-                return false;
-            }
-        } else if (key == "hud_opacity") {
-            if (!mark(Field::hudOpacity) || !signed_byte(output.hudOpacity)) {
-                return false;
-            }
-        } else if (key == "display_hints") {
-            if (!mark(Field::displayHints) || !boolean(output.displayHints)) {
-                return false;
-            }
-        } else if (key == "background_opacity") {
-            if (!mark(Field::backgroundOpacity) || !signed_byte(output.backgroundOpacity)) {
-                return false;
-            }
-        } else if (key == "reticle_location") {
-            if (!mark(Field::reticleLocation) || !signed_byte(output.reticleLocation)) {
-                return false;
-            }
-        } else if (key == "reticle_color") {
-            if (!mark(Field::reticleColor) || !signed_byte(output.reticleColor)) {
-                return false;
-            }
-        } else if (key == "text_size") {
-            if (!mark(Field::textSize) || !signed_byte(output.textSize)) {
-                return false;
-            }
-        } else if (key == "text_color") {
-            if (!mark(Field::textColor) || !signed_byte(output.textColor)) {
-                return false;
-            }
-        } else if (key == "text_background_style") {
-            if (!mark(Field::textBackgroundStyle) || !signed_byte(output.textBackgroundStyle)) {
-                return false;
-            }
-        } else if (key == "text_background_opacity") {
-            if (!mark(Field::textBackgroundOpacity) || !signed_byte(output.textBackgroundOpacity)) {
-                return false;
-            }
-        } else if (key == "reserved_text_mode") {
-            if (!mark(Field::reservedTextMode) || !signed_byte(output.reservedTextMode)) {
-                return false;
-            }
-        } else if (key == "subtitle_options_entry") {
-            if (!mark(Field::subtitleOptionsEntry) || !signed_byte(output.subtitleOptionsEntry)) {
-                return false;
-            }
-        } else if (!skip_value(0)) {
-            return false;
-        }
-        if (consume('}')) {
-            return supplied.all();
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-} // namespace sunrise::core::settings::parser

+ 0 - 234
Sunrise/src/core/settings/state/inventory_parser.cpp

@@ -1,234 +0,0 @@
-#include <bitset>
-#include <limits>
-#include <optional>
-
-#include "../parser.h"
-
-namespace sunrise::core::settings::parser {
-namespace {
-
-namespace authored_inventory = state::account::inventory;
-
-/** Required item fields use one presence bit each. */
-enum class ItemField : std::size_t {
-    instanceSoid,
-    definitionHash,
-    level,
-    quantity,
-    plugs,
-    flags,
-    count,
-};
-
-} // namespace
-
-/** Parses the optional equipment object with its fixed named slots. */
-bool Parser::equipment(authored_inventory::Equipment& output) noexcept {
-    authored_inventory::Equipment parsed{};
-    if (!consume('{')) {
-        return false;
-    }
-    if (consume('}')) {
-        output = parsed;
-        return true;
-    }
-
-    std::bitset<authored_inventory::kEquipmentSlotCount> supplied;
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        const std::optional<authored_inventory::EquipmentSlot> slot =
-            authored_inventory::slot_from_name(key);
-        if (!slot.has_value()) {
-            return false;
-        }
-        const std::size_t index = static_cast<std::size_t>(*slot);
-        if (supplied.test(index)) {
-            return false;
-        }
-        supplied.set(index);
-
-        if (literal("null")) {
-            parsed.slots[index].reset();
-        } else {
-            authored_inventory::Item item{};
-            if (!equipment_item(item)) {
-                return false;
-            }
-            parsed.slots[index] = item;
-        }
-
-        if (consume('}')) {
-            if (!authored_inventory::valid(parsed)) {
-                return false;
-            }
-            output = parsed;
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/** Parses the optional unequipped character inventory array. */
-bool Parser::character_inventory(authored_inventory::CharacterItems& output) noexcept {
-    authored_inventory::CharacterItems parsed{};
-    if (!consume('[')) {
-        return false;
-    }
-    if (consume(']')) {
-        output = parsed;
-        return true;
-    }
-    for (;;) {
-        if (parsed.count >= parsed.values.size() || !equipment_item(parsed.values[parsed.count])) {
-            return false;
-        }
-        ++parsed.count;
-        if (consume(']')) {
-            if (!authored_inventory::valid(parsed)) {
-                return false;
-            }
-            output = parsed;
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/** Parses one item only when every required named field appears exactly once. */
-bool Parser::equipment_item(authored_inventory::Item& output) noexcept {
-    authored_inventory::Item parsed{};
-    if (!consume('{')) {
-        return false;
-    }
-    std::bitset<static_cast<std::size_t>(ItemField::count)> supplied;
-    const auto mark = [&supplied](ItemField field) noexcept {
-        const std::size_t index = static_cast<std::size_t>(field);
-        if (supplied.test(index)) {
-            return false;
-        }
-        supplied.set(index);
-        return true;
-    };
-    if (consume('}')) {
-        return false;
-    }
-
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        if (key == "instance_soid") {
-            if (!mark(ItemField::instanceSoid) || !unsigned_value(parsed.instanceSoid)
-                || parsed.instanceSoid == 0) {
-                return false;
-            }
-        } else if (key == "definition_hash") {
-            if (!mark(ItemField::definitionHash)
-                || !inventory_definition_hash(parsed.definitionHash)) {
-                return false;
-            }
-        } else if (key == "level") {
-            if (!mark(ItemField::level) || !signed_32(parsed.level)) {
-                return false;
-            }
-        } else if (key == "quantity") {
-            if (!mark(ItemField::quantity) || !signed_32(parsed.quantity)) {
-                return false;
-            }
-        } else if (key == "plugs") {
-            if (!mark(ItemField::plugs) || !equipment_plugs(parsed.sockets)) {
-                return false;
-            }
-        } else if (key == "flags") {
-            std::uint64_t flags = 0;
-            if (!mark(ItemField::flags) || !unsigned_value(flags)
-                || flags > (std::numeric_limits<std::uint32_t>::max)()
-                || !authored_inventory::valid_item_state(static_cast<std::uint32_t>(flags))) {
-                return false;
-            }
-            parsed.flags = static_cast<std::uint32_t>(flags);
-        } else {
-            return false;
-        }
-
-        if (consume('}')) {
-            // Flags are optional and an omitted value is the canonical zero. Every other item
-            // field stays mandatory.
-            supplied.set(static_cast<std::size_t>(ItemField::flags));
-            if (!supplied.all() || !authored_inventory::valid(parsed)) {
-                return false;
-            }
-            output = parsed;
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/** Parses the native-default policy or an authored plug-lane array. */
-bool Parser::equipment_plugs(authored_inventory::Sockets& output) noexcept {
-    authored_inventory::Sockets parsed{};
-    if (literal("null")) {
-        output = parsed;
-        return true;
-    }
-    if (!consume('[')) {
-        return false;
-    }
-    parsed.policy = authored_inventory::SocketPolicy::authored;
-    if (consume(']')) {
-        output = parsed;
-        return true;
-    }
-
-    for (;;) {
-        if (parsed.plugCount >= parsed.plugs.size()) {
-            return false;
-        }
-        std::optional<std::uint32_t>& plug = parsed.plugs[parsed.plugCount];
-        if (literal("null")) {
-            plug.reset();
-        } else {
-            std::uint32_t definitionHash = 0;
-            if (!inventory_definition_hash(definitionHash)) {
-                return false;
-            }
-            plug = definitionHash;
-        }
-        ++parsed.plugCount;
-
-        if (consume(']')) {
-            if (!authored_inventory::valid(parsed)) {
-                return false;
-            }
-            output = parsed;
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/** Parses one unsigned definition hash used by authored inventory. */
-bool Parser::inventory_definition_hash(std::uint32_t& output) noexcept {
-    std::uint64_t value = 0;
-    if (!unsigned_value(value) || value > (std::numeric_limits<std::uint32_t>::max)()
-        || value == authored_inventory::kNoDefinitionHash) {
-        return false;
-    }
-    output = static_cast<std::uint32_t>(value);
-    return true;
-}
-
-} // namespace sunrise::core::settings::parser

+ 0 - 426
Sunrise/src/core/settings/state/key_bindings_parser.cpp

@@ -1,426 +0,0 @@
-#include <algorithm>
-#include <array>
-
-#include "../parser.h"
-
-namespace sunrise::core::settings::parser {
-namespace {
-
-namespace bindings = state::account::settings::bindings;
-
-/** Stable JSON names follow the fixed authored action order in State. */
-constexpr std::array<std::string_view, bindings::kActionCount> kActionNames{
-    "fire",
-    "toggle_zoom",
-    "hold_zoom",
-    "melee",
-    "grenade",
-    "super",
-    "reload",
-    "light_attack",
-    "heavy_attack",
-    "block",
-    "switch_weapons",
-    "next_weapon",
-    "previous_weapon",
-    "primary_weapon",
-    "special_weapon",
-    "heavy_weapon",
-    "move_forward",
-    "move_backward",
-    "move_left",
-    "move_right",
-    "jump",
-    "toggle_crouch",
-    "hold_crouch",
-    "toggle_sprint",
-    "hold_sprint",
-    "vehicle_boost",
-    "vehicle_brake",
-    "vehicle_zoom",
-    "vehicle_fire_primary",
-    "vehicle_fire_secondary",
-    "vehicle_exit",
-    "interact",
-    "highlight_player",
-    "emote_1",
-    "emote_2",
-    "emote_3",
-    "emote_4",
-    "air_move",
-    "class_ability",
-    "death_cam_zoom_in",
-    "death_cam_zoom_out",
-    "push_to_talk",
-    "ui_gamepad_button_back",
-    "ui_open_director",
-    "ui_open_director_store_tab",
-    "ui_open_director_pursuits_tab",
-    "ui_open_director_map_tab",
-    "ui_open_director_destinations_tab",
-    "ui_open_director_roster_tab",
-    "ui_open_director_seasons_tab",
-    "ui_open_start_menu_alternative",
-    "ui_open_start_menu_records_tab",
-    "ui_open_start_menu_collections_tab",
-    "ui_open_start_menu_clan_tab",
-    "ui_open_start_menu_inventory_tab",
-    "ui_open_start_menu_settings_tab",
-    "ui_open_exit_dialog_confirm",
-    "ui_abort_activity",
-    "ui_text_chat_toggle_state",
-    "screenshot",
-};
-
-/**
- * Finds one action name without building a map at boot.
- * @param name Borrowed JSON property name.
- * @return Fixed State index, or the action count when the name is unknown.
- */
-[[nodiscard]] std::size_t action_index(std::string_view name) noexcept {
-    const auto found = std::find(kActionNames.begin(), kActionNames.end(), name);
-    return static_cast<std::size_t>(found - kActionNames.begin());
-}
-
-/** One authored input name and the input code it stands for. */
-struct InputName {
-    std::string_view name;
-    std::uint16_t code;
-};
-
-/**
- * The Client's own input names and codes, read from its name table. The names are its strings.
- * The last four rows are its own aliases, and the JSON escape for the backslash.
- */
-constexpr std::array<InputName, 121> kInputNames{{
-    {"escape", 0},
-    {"f1", 1},
-    {"f2", 2},
-    {"f3", 3},
-    {"f4", 4},
-    {"f5", 5},
-    {"f6", 6},
-    {"f7", 7},
-    {"f8", 8},
-    {"f9", 9},
-    {"f10", 10},
-    {"f11", 11},
-    {"f12", 12},
-    {"print screen", 13},
-    {"scroll lock", 14},
-    {"pause", 15},
-    {"`", 16},
-    {"1", 17},
-    {"2", 18},
-    {"3", 19},
-    {"4", 20},
-    {"5", 21},
-    {"6", 22},
-    {"7", 23},
-    {"8", 24},
-    {"9", 25},
-    {"0", 26},
-    {"-", 27},
-    {"=", 28},
-    {"backspace", 29},
-    {"tab", 30},
-    {"q", 31},
-    {"w", 32},
-    {"e", 33},
-    {"r", 34},
-    {"t", 35},
-    {"y", 36},
-    {"u", 37},
-    {"i", 38},
-    {"o", 39},
-    {"p", 40},
-    {"[", 41},
-    {"]", 42},
-    {"\\", 43},
-    {"caps lock", 44},
-    {"a", 45},
-    {"s", 46},
-    {"d", 47},
-    {"f", 48},
-    {"g", 49},
-    {"h", 50},
-    {"j", 51},
-    {"k", 52},
-    {"l", 53},
-    {";", 54},
-    {"'", 55},
-    {"return", 56},
-    {"left shift", 57},
-    {"z", 58},
-    {"x", 59},
-    {"c", 60},
-    {"v", 61},
-    {"b", 62},
-    {"n", 63},
-    {"m", 64},
-    {",", 65},
-    {".", 66},
-    {"/", 67},
-    {"right shift", 68},
-    {"left control", 69},
-    {"left windows", 70},
-    {"left alt", 71},
-    {"space", 72},
-    {"right alt", 73},
-    {"right windows", 74},
-    {"menu", 75},
-    {"right control", 76},
-    {"up", 77},
-    {"down", 78},
-    {"left", 79},
-    {"right", 80},
-    {"insert", 81},
-    {"home", 82},
-    {"page up", 83},
-    {"delete", 84},
-    {"end", 85},
-    {"page down", 86},
-    {"num lock", 87},
-    {"keypad /", 88},
-    {"keypad *", 89},
-    {"keypad 0", 90},
-    {"keypad 1", 91},
-    {"keypad 2", 92},
-    {"keypad 3", 93},
-    {"keypad 4", 94},
-    {"keypad 5", 95},
-    {"keypad 6", 96},
-    {"keypad 7", 97},
-    {"keypad 8", 98},
-    {"keypad 9", 99},
-    {"keypad -", 100},
-    {"keypad +", 101},
-    {"keypad enter", 102},
-    {"keypad .", 103},
-    {"<", 104},
-    {"shift", 105},
-    {"control", 106},
-    {"key_windows", 107},
-    {"alt", 108},
-    {"left mouse button", 109},
-    {"middle mouse button", 110},
-    {"right mouse button", 111},
-    {"extra mouse button 1", 112},
-    {"extra mouse button 2", 113},
-    {"mouse wheel up", 114},
-    {"mouse wheel down", 115},
-    {"unused", bindings::kUnboundInputCode},
-    {"ctrl", 106},
-    {"left ctrl", 69},
-    {"right ctrl", 76},
-    {"\\\\", 43},
-}};
-
-/** One code that may prefix another key, and the flag it sets there. */
-struct ModifierName {
-    std::uint16_t code;
-    std::uint16_t flag;
-};
-
-/** Both sides of a modifier fold onto the same flag, as they do in the Client. */
-constexpr std::array<ModifierName, 9> kModifiers{{
-    {57, bindings::kShiftModifierFlag},
-    {68, bindings::kShiftModifierFlag},
-    {105, bindings::kShiftModifierFlag},
-    {69, bindings::kControlModifierFlag},
-    {76, bindings::kControlModifierFlag},
-    {106, bindings::kControlModifierFlag},
-    {71, bindings::kAltModifierFlag},
-    {73, bindings::kAltModifierFlag},
-    {108, bindings::kAltModifierFlag},
-}};
-
-/** @return The name without leading and trailing ASCII blanks. */
-[[nodiscard]] constexpr std::string_view trim(std::string_view text) noexcept {
-    while (!text.empty() && (text.front() == ' ' || text.front() == '\t')) {
-        text.remove_prefix(1);
-    }
-    while (!text.empty() && (text.back() == ' ' || text.back() == '\t')) {
-        text.remove_suffix(1);
-    }
-    return text;
-}
-
-/** @return True when the two names match with ASCII case folded, as the Client compares them. */
-[[nodiscard]] constexpr bool same_name(std::string_view left, std::string_view right) noexcept {
-    if (left.size() != right.size()) {
-        return false;
-    }
-    for (std::size_t index = 0; index < left.size(); ++index) {
-        char first = left[index];
-        char second = right[index];
-        first = (first >= 'A' && first <= 'Z') ? static_cast<char>(first + ('a' - 'A')) : first;
-        second =
-            (second >= 'A' && second <= 'Z') ? static_cast<char>(second + ('a' - 'A')) : second;
-        if (first != second) {
-            return false;
-        }
-    }
-    return true;
-}
-
-/**
- * Finds one whole input name.
- * @param output Receives the code the table gives that name.
- * @return True when the name is in the table.
- */
-[[nodiscard]] bool named_code(std::string_view name, std::uint16_t& output) noexcept {
-    for (const InputName& entry : kInputNames) {
-        if (same_name(entry.name, name)) {
-            output = entry.code;
-            return true;
-        }
-    }
-    return false;
-}
-
-/**
- * @param code Code parsed from a prefix name.
- * @param output Receives the flag that code sets on the key it prefixes.
- * @return True when the code is a modifier.
- */
-[[nodiscard]] bool modifier_flag(std::uint16_t code, std::uint16_t& output) noexcept {
-    for (const ModifierName& entry : kModifiers) {
-        if (entry.code == code) {
-            output = entry.flag;
-            return true;
-        }
-    }
-    return false;
-}
-
-} // namespace
-
-/** Parses the whole fixed action table under named JSON properties. */
-bool Parser::key_bindings(bindings::KeyBindings& output) noexcept {
-    output = {};
-    if (!consume('{')) {
-        return false;
-    }
-    std::array<bool, bindings::kActionCount> present{};
-    std::size_t presentCount = 0;
-    if (consume('}')) {
-        return false;
-    }
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        const std::size_t index = action_index(key);
-        if (index == bindings::kActionCount) {
-            if (!skip_value(0)) {
-                return false;
-            }
-        } else {
-            if (present[index] || !key_binding(output.values[index])) {
-                return false;
-            }
-            present[index] = true;
-            ++presentCount;
-        }
-        if (consume('}')) {
-            output.configured = presentCount == bindings::kActionCount;
-            return output.configured;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/** Parses one binding with explicit primary and secondary halves. */
-bool Parser::key_binding(bindings::Binding& output) noexcept {
-    output = {};
-    if (!consume('{')) {
-        return false;
-    }
-    bool hasPrimary = false;
-    bool hasSecondary = false;
-    if (consume('}')) {
-        return false;
-    }
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        if (key == "primary") {
-            if (hasPrimary || !optional_input_code(output.primary)) {
-                return false;
-            }
-            hasPrimary = true;
-        } else if (key == "secondary") {
-            if (hasSecondary || !optional_input_code(output.secondary)) {
-                return false;
-            }
-            hasSecondary = true;
-        } else if (!skip_value(0)) {
-            return false;
-        }
-        if (consume('}')) {
-            return hasPrimary && hasSecondary;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/** Parses one optional input name. Null is the unbound half. */
-bool Parser::optional_input_code(std::optional<std::uint16_t>& output) noexcept {
-    if (literal("null")) {
-        output.reset();
-        return true;
-    }
-    std::string_view name;
-    std::uint16_t code = 0;
-    if (!string(name) || !input_code_value(name, code)) {
-        return false;
-    }
-    if (code == bindings::kUnboundInputCode) {
-        // The Client's "unused" table row is the wire sentinel, not a bindable input.
-        output.reset();
-        return true;
-    }
-    if ((code & bindings::kInputCodeMask) == bindings::kUnboundInputCode) {
-        // A modifier cannot turn the unbound sentinel into a real key.
-        return false;
-    }
-    output = code;
-    return true;
-}
-
-/** Turns one input name into the code the Client reads. */
-bool Parser::input_code_value(std::string_view name, std::uint16_t& output) noexcept {
-    const std::string_view text = trim(name);
-    if (text.empty()) {
-        return false;
-    }
-    if (named_code(text, output)) {
-        return true;
-    }
-    // Anything else is one modifier, then the key it prefixes. The key may hold a separator.
-    const std::size_t separator = text.find_first_of("+-");
-    if (separator == std::string_view::npos) {
-        return false;
-    }
-    std::uint16_t prefix = 0;
-    std::uint16_t flag = 0;
-    if (!named_code(trim(text.substr(0, separator)), prefix) || !modifier_flag(prefix, flag)) {
-        return false;
-    }
-    std::uint16_t key = 0;
-    if (!named_code(trim(text.substr(separator + 1)), key)) {
-        return false;
-    }
-    output = static_cast<std::uint16_t>(flag | key);
-    return true;
-}
-
-} // namespace sunrise::core::settings::parser

+ 0 - 101
Sunrise/src/core/settings/state/social_parser.cpp

@@ -1,101 +0,0 @@
-#include <bitset>
-
-#include "../parser.h"
-
-namespace sunrise::core::settings::parser {
-
-/** Parses matchmaking and chat settings under stable Sunrise-owned names. */
-bool Parser::social_settings(state::account::settings::Social& output) noexcept {
-    enum class Field : std::size_t {
-        preferGoodConnection,
-        textChatMode,
-        showRealNames,
-        clanInviteNotifications,
-        profanityFilter,
-        voiceChatEnabled,
-        whisperChatMode,
-        teamChatJoinMode,
-        localChatJoinMode,
-        clanChatJoinMode,
-        chatAutoHideMode,
-        count,
-    };
-
-    output = {};
-    if (!consume('{')) {
-        return false;
-    }
-    std::bitset<static_cast<std::size_t>(Field::count)> supplied;
-    const auto mark = [&supplied](Field field) noexcept {
-        const std::size_t index = static_cast<std::size_t>(field);
-        if (supplied.test(index)) {
-            return false;
-        }
-        supplied.set(index);
-        return true;
-    };
-    if (consume('}')) {
-        return false;
-    }
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        if (key == "prefer_good_connection") {
-            if (!mark(Field::preferGoodConnection) || !boolean(output.preferGoodConnection)) {
-                return false;
-            }
-        } else if (key == "text_chat_mode") {
-            if (!mark(Field::textChatMode) || !signed_byte(output.textChatMode)) {
-                return false;
-            }
-        } else if (key == "show_real_names") {
-            if (!mark(Field::showRealNames) || !boolean(output.showRealNames)) {
-                return false;
-            }
-        } else if (key == "clan_invite_notifications") {
-            if (!mark(Field::clanInviteNotifications) || !boolean(output.clanInviteNotifications)) {
-                return false;
-            }
-        } else if (key == "profanity_filter") {
-            if (!mark(Field::profanityFilter) || !boolean(output.profanityFilter)) {
-                return false;
-            }
-        } else if (key == "voice_chat_enabled") {
-            if (!mark(Field::voiceChatEnabled) || !boolean(output.voiceChatEnabled)) {
-                return false;
-            }
-        } else if (key == "whisper_chat_mode") {
-            if (!mark(Field::whisperChatMode) || !signed_byte(output.whisperChatMode)) {
-                return false;
-            }
-        } else if (key == "team_chat_join_mode") {
-            if (!mark(Field::teamChatJoinMode) || !signed_byte(output.teamChatJoinMode)) {
-                return false;
-            }
-        } else if (key == "local_chat_join_mode") {
-            if (!mark(Field::localChatJoinMode) || !signed_byte(output.localChatJoinMode)) {
-                return false;
-            }
-        } else if (key == "clan_chat_join_mode") {
-            if (!mark(Field::clanChatJoinMode) || !signed_byte(output.clanChatJoinMode)) {
-                return false;
-            }
-        } else if (key == "chat_auto_hide_mode") {
-            if (!mark(Field::chatAutoHideMode) || !signed_byte(output.chatAutoHideMode)) {
-                return false;
-            }
-        } else if (!skip_value(0)) {
-            return false;
-        }
-        if (consume('}')) {
-            return supplied.all();
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-} // namespace sunrise::core::settings::parser

+ 4 - 281
Sunrise/src/core/settings/state_settings.cpp

@@ -1,306 +1,29 @@
-#include <algorithm>
-#include <array>
-
-#include "../../state/activity/defaults/activity_defaults_validation.h"
 #include "parser.h"
 
 namespace sunrise::core::settings::parser {
 
-/**
- * Fills one flag bank from [start, length] runs. A run outside the bank is refused.
- * @param bank Expanded destination bank.
- * @return True when every run fits.
- */
-bool Parser::flag_runs(std::span<std::uint8_t> bank) noexcept {
-    if (!consume('[')) {
-        return false;
-    }
-    if (consume(']')) {
-        return true;
-    }
-    for (;;) {
-        std::uint64_t start = 0;
-        std::uint64_t length = 0;
-        if (!consume('[') || !unsigned_integer(start) || !consume(',') || !unsigned_integer(length)
-            || !consume(']') || length == 0 || start > bank.size()
-            || length > bank.size() - start) {
-            return false;
-        }
-        for (std::uint64_t offset = 0; offset < length; ++offset) {
-            bank[static_cast<std::size_t>(start + offset)] = state::unlocks::kFlagSet;
-        }
-        if (consume(']')) {
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/**
- * Fills one flag bank from plain indices.
- * @param bank Expanded destination bank.
- * @return True when every index fits.
- */
-bool Parser::flag_indices(std::span<std::uint8_t> bank) noexcept {
-    if (!consume('[')) {
-        return false;
-    }
-    if (consume(']')) {
-        return true;
-    }
-    for (;;) {
-        std::uint64_t index = 0;
-        if (!unsigned_integer(index) || index >= bank.size()) {
-            return false;
-        }
-        bank[static_cast<std::size_t>(index)] = state::unlocks::kFlagSet;
-        if (consume(']')) {
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/**
- * Fills one objective bank from [index, value] pairs.
- * @param bank Expanded destination bank.
- * @return True when every index fits.
- */
-bool Parser::objective_values(std::span<std::int32_t> bank) noexcept {
-    if (!consume('[')) {
-        return false;
-    }
-    if (consume(']')) {
-        return true;
-    }
-    for (;;) {
-        std::uint64_t index = 0;
-        std::int32_t value = 0;
-        if (!consume('[') || !unsigned_integer(index) || !consume(',') || !signed_32(value)
-            || !consume(']') || index >= bank.size()) {
-            return false;
-        }
-        bank[static_cast<std::size_t>(index)] = value;
-        if (consume(']')) {
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/**
- * Fills one progression bank from [definition_index, lane 0, lane 1, lane 2] rows.
- * Repeated rows for one definition merge by lane maximum, not by last write. The Client's
- * own definition-indexed bank merges the same way.
- * @param bank Authored lanes addressed by definition index.
- * @return True when every row names a possible definition and carries all 3 lanes.
- */
-bool Parser::progression_values(state::unlocks::ProgressionBank& bank) noexcept {
-    std::array<bool, state::build_data::progressions::kDefinitionCapacity> authored{};
-    if (!consume('[')) {
-        return false;
-    }
-    if (consume(']')) {
-        return true;
-    }
-    for (;;) {
-        std::uint64_t index = 0;
-        state::unlocks::ProgressionLanes lanes{};
-        if (!consume('[') || !unsigned_integer(index) || index >= bank.size()) {
-            return false;
-        }
-        for (std::int32_t& lane : lanes) {
-            if (!consume(',') || !signed_32(lane)) {
-                return false;
-            }
-        }
-        if (!consume(']')) {
-            return false;
-        }
-        const auto slot = static_cast<std::size_t>(index);
-        state::unlocks::ProgressionLanes& row = bank[slot];
-        for (std::size_t lane = 0; lane < row.size(); ++lane) {
-            // The first row of a definition is taken whole, so a negative lane is not clamped.
-            row[lane] = authored[slot] ? (std::max)(row[lane], lanes[lane]) : lanes[lane];
-        }
-        authored[slot] = true;
-        if (consume(']')) {
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/**
- * Parses the four authored unlock banks.
- * @param output Receives every expanded bank.
- * @return True when the object is valid JSON and every entry fits its bank.
- */
-bool Parser::unlocks(state::unlocks::Table& output) noexcept {
-    output = {};
-    if (!consume('{')) {
-        return false;
-    }
-    if (consume('}')) {
-        return true;
-    }
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        bool parsed = false;
-        if (key == "account_flag_runs") {
-            parsed = flag_runs(output.accountFlags);
-        } else if (key == "profile_flag_runs") {
-            parsed = flag_runs(output.profileFlags);
-        } else if (key == "character_flags") {
-            parsed = flag_indices(output.characterFlags);
-        } else if (key == "objective_values") {
-            parsed = objective_values(output.objectiveValues);
-        } else if (key == "character_flag_runs") {
-            parsed = flag_runs(output.characterObjectFlags);
-        } else if (key == "character_objective_values") {
-            parsed = objective_values(output.characterObjectValues);
-        } else if (key == "account_progressions") {
-            parsed = progression_values(output.accountProgressions);
-        } else if (key == "character_progressions") {
-            parsed = progression_values(output.characterProgressions);
-        } else {
-            parsed = skip_value(0);
-        }
-        if (!parsed) {
-            return false;
-        }
-        if (consume('}')) {
-            return true;
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/**
- * Parses authored State ids. Native mapping data is refused.
- * @param output Receives the initial account, unlock policy and activity defaults.
- * @return True when activity appears once and the cross-field rules hold.
- */
+/** Parses local activity policy; account preferences belong to the save. */
 bool Parser::state_settings(Settings& output) noexcept {
-    output.initialAccount = {};
-    output.initialUnlocks = {};
-    output.initialFamily5 = {};
-    output.initialActivityDefaults = state::activity::defaults::authored();
     if (!consume('{')) {
         return false;
     }
     if (consume('}')) {
         return true;
     }
-    bool hasActivity = false;
-    bool hasInvestment = false;
     for (;;) {
         std::string_view key;
         if (!string(key) || !consume(':')) {
             return false;
         }
-        if (key == "account") {
-            if (!account(output.initialAccount)) {
-                return false;
-            }
-        } else if (key == "characters") {
-            if (!characters(output.initialAccount)) {
+        if (key == "activity") {
+            if (!activity_settings(output.initialActivityDefaults)) {
                 return false;
             }
-        } else if (key == "unlocks") {
-            if (!unlocks(output.initialUnlocks)) {
-                return false;
-            }
-        } else if (key == "investment") {
-            if (hasInvestment || !investment(output)) {
-                return false;
-            }
-            hasInvestment = true;
-        } else if (key == "activity") {
-            if (hasActivity || !activity_settings(output.initialActivityDefaults)) {
-                return false;
-            }
-            hasActivity = true;
         } else if (!skip_value(0)) {
             return false;
         }
         if (consume('}')) {
-            return state::account::valid_authored(output.initialAccount)
-                   && state::activity::defaults::valid(output.initialActivityDefaults);
-        }
-        if (!consume(',')) {
-            return false;
-        }
-    }
-}
-
-/**
- * Parses an optional account id object.
- * @param output Receives the authored primary account SOID.
- * @return True for null or an object with one nonzero SOID and complete settings.
- */
-bool Parser::account(state::AccountState& output) noexcept {
-    if (literal("null")) {
-        output = {};
-        return true;
-    }
-    if (!consume('{')) {
-        return false;
-    }
-    bool hasPrimarySoid = false;
-    bool hasProfileSetupCompleted = false;
-    bool hasSettings = false;
-    bool hasDismantleRewards = false;
-    if (consume('}')) {
-        return false;
-    }
-    for (;;) {
-        std::string_view key;
-        if (!string(key) || !consume(':')) {
-            return false;
-        }
-        if (key == "primary_soid") {
-            if (hasPrimarySoid || !unsigned_value(output.primarySoid) || output.primarySoid == 0) {
-                return false;
-            }
-            hasPrimarySoid = true;
-        } else if (key == "profile_setup_completed") {
-            if (hasProfileSetupCompleted || !boolean(output.profileSetupCompleted)) {
-                return false;
-            }
-            hasProfileSetupCompleted = true;
-        } else if (key == "settings") {
-            if (hasSettings || !account_settings(output.settings)) {
-                return false;
-            }
-            hasSettings = true;
-        } else if (key == "profile_items") {
-            if (!profile_items(output)) {
-                return false;
-            }
-        } else if (key == "dismantle_rewards") {
-            if (hasDismantleRewards || !dismantle_rewards(output)) {
-                return false;
-            }
-            hasDismantleRewards = true;
-        } else if (!skip_value(0)) {
-            return false;
-        }
-        if (consume('}')) {
-            return hasPrimarySoid && hasSettings;
+            return true;
         }
         if (!consume(',')) {
             return false;

+ 19 - 5
Sunrise/src/middleware/datagen/family4/account/account_encoder.cpp

@@ -28,7 +28,8 @@ constexpr std::size_t kBucketIdentityCapacity = 256;
 /** Places one profile item in the next free row of its inventory bucket. */
 [[nodiscard]] bool place_profile_item(const state::account::inventory::ProfileItem& item,
                                       std::array<std::uint16_t, kBucketIdentityCapacity>& taken,
-                                      std::span<inventory::layout::Entry> rows) noexcept {
+                                      std::span<inventory::layout::Entry> rows,
+                                      std::span<std::uint32_t> newItems) noexcept {
     state::build_data::items::Definition definition{};
     state::build_data::items::details::Definition detail{};
     state::build_data::inventory::buckets::Descriptor bucket{};
@@ -62,6 +63,11 @@ constexpr std::size_t kBucketIdentityCapacity = 256;
     rows[slot].instanceSoid = item.instanceSoid;
     rows[slot].quantity = item.quantity;
     rows[slot].mutationSerial = item.mutationSerial;
+    // Each profile bitmap word covers 32 inventory rows.
+    constexpr std::size_t kWordBits = 32;
+    if (!item.seen) {
+        newItems[slot / kWordBits] |= 1U << (slot % kWordBits);
+    }
     return true;
 }
 
@@ -83,13 +89,20 @@ bool encode(const state::AccountState& state, std::span<std::byte> output) noexc
         return false;
     }
 
-    const state::unlocks::Table& unlocks = state::unlocks::get();
+    state::unlocks::Table unlocks;
+    if (!state::unlocks::snapshot(unlocks)) {
+        return false;
+    }
     object.acquiredFlags = unlocks.accountFlags;
     object.profileUnlockFlags = unlocks.profileFlags;
     object.objectiveValues = unlocks.objectiveValues;
 
-    for (layout::CharacterUnlockBlock& block : object.characterUnlocks) {
-        block.flags = unlocks.characterFlags;
+    for (std::size_t index = 0; index < state.characterCount; ++index) {
+        state::unlocks::Table character;
+        if (!state::unlocks::snapshot(character, static_cast<int>(index))) {
+            return false;
+        }
+        object.characterUnlocks[index].flags = character.characterFlags;
     }
     object.publicityExpiries.fill(kSuppressedPublicityDeadline);
     object.seenMessages.fill(kSeenMessageByte);
@@ -106,7 +119,8 @@ bool encode(const state::AccountState& state, std::span<std::byte> output) noexc
     // Profile rows are sentinelled above, so placement only has to claim its own slots.
     std::array<std::uint16_t, kBucketIdentityCapacity> takenSlots{};
     for (std::size_t index = 0; index < state.profileItemCount; ++index) {
-        if (!place_profile_item(state.profileItems[index], takenSlots, object.profileItems)) {
+        if (!place_profile_item(
+                state.profileItems[index], takenSlots, object.profileItems, object.newItemFlags)) {
             return false;
         }
     }

+ 9 - 3
Sunrise/src/middleware/datagen/family4/account/layout.h

@@ -34,8 +34,11 @@ inline constexpr std::size_t kSeenProfileSetupPaddingSize = 20;
 inline constexpr std::size_t kProfileSetupPreferencesPaddingSize = 3;
 /** 607 reserved bytes separate preference and keybinding records. */
 inline constexpr std::size_t kPreferencesBindingsPaddingSize = 607;
-/** 456 reserved bytes follow the replicated keybinding record. */
-inline constexpr std::size_t kBindingsProfilePaddingSize = 456;
+/** Padding around the profile's 88-byte new-item bitmap. */
+inline constexpr std::size_t kBindingsNewItemsPaddingSize = 72;
+inline constexpr std::size_t kNewItemsProfilePaddingSize = 296;
+inline constexpr std::size_t kProfileNewItemWordCount = 22;
+inline constexpr std::size_t kProfileNewItemFlagsOffset = 3976;
 /** Native inventory counts are followed by 4 reserved alignment bytes. */
 inline constexpr std::size_t kInventoryCountPaddingSize = 4;
 /** The profile inventory observer reads 16 transient mutation descriptors. */
@@ -141,7 +144,9 @@ struct Object {
     preferences::Record preferences{};
     std::array<std::byte, kPreferencesBindingsPaddingSize> preferencesBindingsPadding{};
     preferences::BindingsRecord bindings{};
-    std::array<std::byte, kBindingsProfilePaddingSize> bindingsProfilePadding{};
+    std::array<std::byte, kBindingsNewItemsPaddingSize> bindingsNewItemsPadding{};
+    std::array<std::uint32_t, kProfileNewItemWordCount> newItemFlags{};
+    std::array<std::byte, kNewItemsProfilePaddingSize> newItemsProfilePadding{};
     std::uint32_t profileItemCount{};
     std::array<std::byte, kInventoryCountPaddingSize> profileCountPadding{};
     std::array<inventory::layout::Entry, kProfileItemCapacity> profileItems{};
@@ -166,6 +171,7 @@ struct Object {
 inline constexpr std::size_t kMinimumSize = kObjectSize;
 
 static_assert(sizeof(Object) == kObjectSize);
+static_assert(offsetof(Object, newItemFlags) == kProfileNewItemFlagsOffset);
 static_assert(offsetof(Object, accountSoid) == kAccountSoidOffset);
 static_assert(offsetof(Object, roster) == kRosterOffset);
 static_assert(offsetof(Object, selectedCharacterSoid) == kSelectedCharacterSoidOffset);

+ 9 - 5
Sunrise/src/middleware/datagen/family4/character/character_encoder.cpp

@@ -280,7 +280,10 @@ bool encode(const state::CharacterState& state,
     }
     // Acquired flags and objective progress are live world state, written by the request that
     // changed them.
-    const state::unlocks::Table& unlocks = state::unlocks::get();
+    state::unlocks::Table unlocks;
+    if (!state::unlocks::snapshot(unlocks)) {
+        return false;
+    }
     for (std::size_t index = 0; index < object.acquiredFlags.size(); ++index) {
         object.acquiredFlags[index] = static_cast<std::byte>(
             index < unlocks.characterObjectFlags.size() ? unlocks.characterObjectFlags[index]
@@ -311,10 +314,11 @@ bool encode(const state::CharacterState& state,
         inventoryRow.quantity = item.quantity;
         inventoryRow.mutationSerial = item.mutationSerial;
         inventoryRow.flags = item.flags;
-        // Both companion arrays are indexed by inventory row, not by equipment slot, and the
-        // client's own producer marks every row it fills.
-        object.newItemFlags[item.inventoryRow / kBitsPerFlagByte] |=
-            std::byte{1U} << (item.inventoryRow % kBitsPerFlagByte);
+        // Badge state and instance watermarks are both addressed by inventory row.
+        if (!item.seen) {
+            object.newItemFlags[item.inventoryRow / kBitsPerFlagByte] |=
+                std::byte{1U} << (item.inventoryRow % kBitsPerFlagByte);
+        }
         object.instanceProgressWatermarks[item.inventoryRow] = kOccupiedRowWatermark;
         if (item.equipped) {
             object.equippedInstanceSoids[item.equipmentSlot] = item.instance.instanceSoid;

+ 1 - 1
Sunrise/src/middleware/datagen/family4/character/layout.h

@@ -186,7 +186,7 @@ struct Object {
     std::array<RosterMirrorEntry, kRosterMirrorCapacity> rosterMirror{};
     std::array<std::byte, kRosterDestinationPaddingSize> rosterDestinationPadding{};
     std::uint32_t lastOrbitedDestination{};
-    /** One bit per inventory row, set for every row the loadout occupies. */
+    /** One bit per inventory row, set while the item is unseen. */
     std::array<std::byte, kNewItemFlagByteCount> newItemFlags{};
     /** Per-row acknowledgement watermarks mirrored from the matching item instances. */
     std::array<std::int32_t, kInstanceProgressWatermarkCapacity> instanceProgressWatermarks{};

+ 1 - 8
Sunrise/src/middleware/datagen/family4/instance/instance_encoder.cpp

@@ -3,7 +3,6 @@
 #include <algorithm>
 #include <cstring>
 
-#include "../../../../state/build_data/runtime.h"
 #include "abi.h"
 #include "layout.h"
 
@@ -151,13 +150,7 @@ bool encode(const ResolvedInstance& input, std::span<std::byte> output) noexcept
             const std::optional<std::uint16_t>& plug = input.ordinarySockets.plugs[index];
             if (plug.has_value()) {
                 object.ordinarySockets.sockets[index].plugDefinitionIndex = *plug;
-                // The client reads each socket's own plug definition hash here. A wrong value
-                // blanks the socket's render, so an unresolved hash keeps the zero fill.
-                state::build_data::items::Definition plugDefinition{};
-                if (state::build_data::find_item_definition_index(*plug, plugDefinition)) {
-                    object.ordinarySockets.sockets[index].auxiliaryHashes.fill(
-                        plugDefinition.definitionHash);
-                }
+                // Auxiliary fields stay zero; nonzero values change the available plug choices.
             }
         }
     }

+ 1 - 0
Sunrise/src/middleware/datagen/family4/loadout/definition.h

@@ -28,6 +28,7 @@ struct ResolvedItem {
     /** Accumulated native item-state bits copied into the native inventory row. */
     std::uint32_t flags{};
     instance::ResolvedInstance instance{};
+    bool seen{};
 };
 
 /** One item instance together with the native equipment slot that owns it. */

+ 1 - 0
Sunrise/src/middleware/datagen/family4/loadout/loadout_item_resolver.cpp

@@ -164,6 +164,7 @@ bool resolve_item(const authored_inventory::Item& authored,
     candidate.item.equipmentSlot = nativeEquipmentSlot;
     candidate.item.mutationSerial = authored.mutationSerial;
     candidate.item.flags = authored.flags;
+    candidate.item.seen = authored.seen;
     if (!resolve_quantity(authored, itemDetail, candidate.item.quantity)
         || !resolve_ordinary_sockets(authored.sockets,
                                      itemDetail,

+ 7 - 13
Sunrise/src/middleware/datagen/family4/progression/progression_bank_keys.cpp

@@ -17,18 +17,6 @@ constexpr std::uint16_t kEmptyDefinitionIndex = 0xFFFF;
 // One lane type serves the authored bank and the native row, so no conversion can lose a lane.
 static_assert(std::is_same_v<layout::Values, state::unlocks::ProgressionLanes>);
 
-/**
- * Picks the authored lanes of one replicated scope.
- * @param scope Replicated object owning the bank.
- * @return Lanes addressed by definition index.
- */
-[[nodiscard]] const state::unlocks::ProgressionBank&
-authored_lanes(state::build_data::progressions::Scope scope) noexcept {
-    const state::unlocks::Table& table = state::unlocks::get();
-    return scope == state::build_data::progressions::Scope::account ? table.accountProgressions
-                                                                    : table.characterProgressions;
-}
-
 } // namespace
 
 /** Keys one object's progression bank and fills each keyed row from the authored lanes. */
@@ -43,7 +31,13 @@ bool key_bank(state::build_data::progressions::Scope scope,
     if (!state::build_data::find_progression_slots(scope, slots, count) || count > bank.size()) {
         return false;
     }
-    const state::unlocks::ProgressionBank& lanes = authored_lanes(scope);
+    state::unlocks::Table table;
+    if (!state::unlocks::snapshot(table)) {
+        return false;
+    }
+    const auto& lanes = scope == state::build_data::progressions::Scope::account
+                            ? table.accountProgressions
+                            : table.characterProgressions;
     for (std::size_t slot = 0; slot < count; ++slot) {
         // The definition catalog is dense, so every key it hands out addresses the authored bank.
         bank[slot].definitionIndex = slots[slot];

+ 29 - 10
Sunrise/src/middleware/web_service/messages/opcode701/opcode701_codec.cpp

@@ -565,18 +565,26 @@ template <typename ReadBody>
     if (!skip_optional_scalar(reader, kInt32Encoding)) {
         return false;
     }
-    // 0.1.2.1: client-local one-bit mirror; traversal-only.
-    if (!skip_optional_scalar(reader, kBoolEncoding)) {
+    bool present = false;
+    std::uint64_t value = 0;
+    if (!read_optional_scalar(reader, kBoolEncoding, present, value)) {
         return false;
     }
-    // 0.1.2.2: client-local VSync mirror.
-    if (!skip_optional_scalar(reader, kInt8ThreeBitEncoding)) {
+    if (present && !delta.social.voiceChatEnabled.has_value()) {
+        delta.social.voiceChatEnabled = value != 0;
+    }
+    if (!read_optional_scalar(reader, kInt8ThreeBitEncoding, present, value)) {
         return false;
     }
-    // 0.1.2.3: client-local FOV mirror.
-    if (!skip_optional_scalar(reader, kInt32Encoding)) {
+    if (present) {
+        delta.display.verticalSyncInterval = static_cast<std::uint8_t>(value);
+    }
+    if (!read_optional_scalar(reader, kInt32Encoding, present, value)) {
         return false;
     }
+    if (present) {
+        delta.display.fieldOfView = as_int32(value);
+    }
 
     // 0.1.2.4: authored keybinding source and routing input for the optional table.
     bool sourceSelectorPresent = false;
@@ -612,9 +620,18 @@ template <typename ReadBody>
            && reader.skip(kBooleanWidthBits);
 }
 
-/** Consumes present fixed-width group 0.1.5. */
-[[nodiscard]] bool skip_group_0_1_5(Reader& reader) noexcept {
-    return reader.skip(fixed_array_width_bits(kGroup_0_1_5ValueCount, kScalar32WidthBits));
+/** Reads the profile new-item bitmap carried by group 0.1.5. */
+[[nodiscard]] bool read_new_items(Reader& reader, Request& output) noexcept {
+    state::account::inventory::ProfileNewItems bits{};
+    for (auto& word : bits) {
+        std::uint64_t value = 0;
+        if (!reader.read(kScalar32WidthBits, value)) {
+            return false;
+        }
+        word = static_cast<std::uint32_t>(value);
+    }
+    output.newItems = bits;
+    return true;
 }
 
 /** Consumes present nested entry array 0.1.6.0. */
@@ -671,7 +688,9 @@ template <typename ReadBody>
     }
 
     // 0.1.5: 22 required 32-bit values.
-    if (!read_optional_group(reader, skip_group_0_1_5)) {
+    if (!read_optional_group(reader, [&output](Reader& groupReader) noexcept {
+            return read_new_items(groupReader, output);
+        })) {
         return false;
     }
 

+ 3 - 0
Sunrise/src/middleware/web_service/messages/opcode701/opcode701_codec.h

@@ -1,7 +1,9 @@
 #pragma once
 
 #include <cstdint>
+#include <optional>
 
+#include "../../../../state/account/inventory/seen_state.h"
 #include "../../../../state/account/settings/settings_delta.h"
 #include "../../web_service_envelope.h"
 
@@ -13,6 +15,7 @@ inline constexpr std::uint16_t kOpcode = 701;
 /** Semantic result decoded from one schema-0x80807603 request. */
 struct Request {
     state::account::settings::SettingsDelta settings;
+    std::optional<state::account::inventory::ProfileNewItems> newItems;
     /** Preference path 0.1.1.0; false when the body leaves that preference absent. */
     bool profileSetupCompleted{};
 };

+ 9 - 7
Sunrise/src/middleware/web_service/messages/opcode702.h

@@ -2,34 +2,36 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 
+#include "../../../state/account/inventory/seen_state.h"
 #include "../web_service_envelope.h"
 
 namespace sunrise::middleware::web_service::messages::opcode702 {
 
 /** Web Service opcode of the character object B write-back. */
 inline constexpr std::uint16_t kOpcode = 702;
-/** The body is the 5360-byte mirror at objB `+12032`, packed into exactly 4800 bytes. */
+/** The full 5360-byte character mirror packs into at most 4800 bytes. */
 inline constexpr std::size_t kPayloadSize = 4800;
 /** Value of the world-state field once the client has entered the world. */
 inline constexpr std::uint8_t kInWorld = 8;
 
-/** The one field the server acts on. Everything after it is client-owned state it stores. */
+/** Supported fields from the character writeback. */
 struct Request {
     /**
      * Five-bit field at objB `+12068`, schema path `.0.11.1.0.0.4`. Measured 0 on the orbit
      * screen, 1 from the launch through the load, 8 after `activity:in_world`.
      */
     std::uint8_t worldState{};
+    bool hasWorldState{};
+    std::optional<state::account::inventory::CharacterNewItems> newItems;
 };
 
 /**
- * Reads the world-state field from the front of a ws-702 body.
- * The 32-byte header and the 5-byte block before the field have fixed widths. So the field sits
- * at bits 293 to 297, whenever every presence bit before it is set.
+ * Reads the complete character writeback with optional groups and bounded zero padding.
  * @param message Parsed Web Service envelope.
- * @param request Receives the field.
- * @return True for a complete body whose leading presence bits are all set.
+ * @param request Receives only fields present in a valid body.
+ * @return False for malformed or truncated fields.
  */
 [[nodiscard]] bool parse_request(const Message& message, Request& request) noexcept;
 

+ 154 - 44
Sunrise/src/middleware/web_service/messages/opcode702_codec.cpp

@@ -1,3 +1,5 @@
+#include <algorithm>
+#include <array>
 #include <cstddef>
 
 #include "../../encoding/bit_reader.h"
@@ -5,66 +7,174 @@
 
 namespace sunrise::middleware::web_service::messages::opcode702 {
 namespace {
+using encoding::bits::Reader;
 
-/** Each optional field or array opens with one presence bit. */
-constexpr std::uint8_t kPresenceWidth = 1;
-/** The header's three floats at `+12032`, each behind its own presence bit. */
-constexpr std::size_t kHeaderFloatCount = 3;
-constexpr std::uint8_t kFloatWidth = 32;
-/** The four seen-message words at `+12044`, one presence bit for the whole array. */
-constexpr std::size_t kSeenWordCount = 4;
-constexpr std::uint8_t kSeenWordWidth = 32;
-/** Three presence bits open the body, its first struct and the 5-byte block. */
-constexpr std::size_t kBodyPresenceCount = 3;
-/** The block's three 8-bit fields at `+12064`, then its 3-bit field at `+12067`. */
-constexpr std::size_t kBlockByteCount = 3;
-constexpr std::uint8_t kBlockByteWidth = 8;
-constexpr std::uint8_t kBlockTriadWidth = 3;
-/** The world-state field at `+12068`. */
-constexpr std::uint8_t kWorldStateWidth = 5;
+/** Primitive widths in the character writeback schema. */
+constexpr std::uint8_t kPresenceBits = 1;
+constexpr std::uint8_t kByteBits = 8;
+constexpr std::uint8_t kShortBits = 16;
+constexpr std::uint8_t kWordBits = 32;
+constexpr std::uint8_t kLongBits = 64;
+constexpr std::uint8_t kWorldBits = 5;
+/** Fixed array lengths from the character writeback schema. */
+constexpr std::size_t kHeaderFloats = 3;
+constexpr std::size_t kSeenWords = 4;
+constexpr std::size_t kRosterItems = 20;
+constexpr std::size_t kRosterPlugs = 64;
+constexpr std::size_t kOpaqueBytes = 128;
+constexpr std::size_t kInventoryRows = 350;
+constexpr std::size_t kUnlockFlags = 768;
+constexpr std::size_t kTailBooleans = 3;
 
-/** Reads one presence bit and requires it set, so the fixed layout behind it holds. */
-bool read_present(encoding::bits::Reader& reader) noexcept {
+/** An absent field has no payload. */
+template <typename Read> bool optional(Reader& reader, Read read) noexcept {
     std::uint64_t present = 0;
-    return reader.read(kPresenceWidth, present) && present != 0;
+    return reader.read(kPresenceBits, present) && (present == 0 || read(reader));
 }
 
-/** Skips a field whose value the server does not read. */
-bool skip_field(encoding::bits::Reader& reader, std::uint8_t width) noexcept {
-    return reader.skip(width);
+bool skip_optional(Reader& reader, std::size_t width) noexcept {
+    return optional(reader, [width](Reader& field) noexcept { return field.skip(width); });
 }
 
-} // namespace
+/** Header floats carry their own presence bits; hash-array words do not. */
+bool read_header(Reader& reader) noexcept {
+    const auto floats = [](Reader& array) noexcept {
+        for (std::size_t index = 0; index < kHeaderFloats; ++index) {
+            if (!skip_optional(array, kWordBits)) {
+                return false;
+            }
+        }
+        return true;
+    };
+    return optional(reader, floats) && skip_optional(reader, kSeenWords * kWordBits)
+           && skip_optional(reader, kWordBits);
+}
 
-/** Reads the world-state field from the front of a ws-702 body. */
-bool parse_request(const Message& message, Request& request) noexcept {
-    request = {};
-    if (message.opcode != kOpcode || message.payload.size() != kPayloadSize) {
+/** The five-byte activity block carries the world-state field without an inner presence bit. */
+bool read_activity(Reader& reader, Request& output) noexcept {
+    const auto block = [&output](Reader& fields) noexcept {
+        // Three biased bytes and one three-bit selector precede the world state.
+        constexpr std::size_t kPrefixBits = 3 * kByteBits + 3;
+        std::uint64_t value = 0;
+        if (!fields.skip(kPrefixBits) || !fields.read(kWorldBits, value)) {
+            return false;
+        }
+        output.worldState = static_cast<std::uint8_t>(value);
+        output.hasWorldState = true;
+        return true;
+    };
+    return optional(reader, block) && skip_optional(reader, kWordBits)
+           && skip_optional(reader, kByteBits) && skip_optional(reader, kLongBits);
+}
+
+/** The roster mirror has twenty records and seven trailing optional scalars. */
+bool read_roster(Reader& reader) noexcept {
+    const auto items = [](Reader& array) noexcept {
+        for (std::size_t index = 0; index < kRosterItems; ++index) {
+            if (!skip_optional(array, kLongBits) || !skip_optional(array, kShortBits)
+                || !skip_optional(array, kShortBits)
+                || !skip_optional(array, kRosterPlugs * kShortBits) || !skip_optional(array, 4)) {
+                return false;
+            }
+        }
+        return true;
+    };
+    constexpr std::array<std::uint8_t, 7> kTailWidths{
+        kLongBits, kLongBits, kWordBits, kWordBits, kByteBits, kByteBits, 4};
+    if (!optional(reader, items)) {
         return false;
     }
-    encoding::bits::Reader reader(message.payload);
-    bool read = read_present(reader) && read_present(reader);
-    for (std::size_t index = 0; read && index < kHeaderFloatCount; ++index) {
-        read = read_present(reader) && skip_field(reader, kFloatWidth);
+    for (const auto width : kTailWidths) {
+        if (!skip_optional(reader, width)) {
+            return false;
+        }
     }
-    read = read && read_present(reader);
-    for (std::size_t index = 0; read && index < kSeenWordCount; ++index) {
-        read = skip_field(reader, kSeenWordWidth);
+    return true;
+}
+
+/** The leading byte counts the payload bytes, up to the buffer's capacity. */
+bool read_opaque_state(Reader& reader) noexcept {
+    const auto buffer = [](Reader& fields) noexcept {
+        std::uint64_t count = 0;
+        return fields.read(kByteBits, count) && count <= kOpaqueBytes
+               && fields.skip(static_cast<std::size_t>(count) * kByteBits);
+    };
+    return optional(reader, buffer) && skip_optional(reader, kLongBits);
+}
+
+/** New-item bits and instance watermarks share a group but have independent presence bits. */
+bool read_inventory(Reader& reader, Request& output) noexcept {
+    const auto bitmap = [&output](Reader& array) noexcept {
+        state::account::inventory::CharacterNewItems bits{};
+        for (auto& word : bits) {
+            std::uint64_t value = 0;
+            if (!array.read(kWordBits, value)) {
+                return false;
+            }
+            word = static_cast<std::uint32_t>(value);
+        }
+        output.newItems = bits;
+        return true;
+    };
+    return optional(reader, bitmap) && skip_optional(reader, kInventoryRows * kWordBits);
+}
+
+/** Each boolean in the final array has its own presence bit. */
+bool read_tail_booleans(Reader& reader) noexcept {
+    for (std::size_t index = 0; index < kTailBooleans; ++index) {
+        if (!skip_optional(reader, 1)) {
+            return false;
+        }
     }
-    read = read && read_present(reader) && skip_field(reader, kFloatWidth);
-    for (std::size_t index = 0; read && index < kBodyPresenceCount; ++index) {
-        read = read_present(reader);
+    return true;
+}
+
+/** Child order follows the 5328-byte character bank. */
+bool read_body(Reader& reader, Request& output) noexcept {
+    // The next record contains six shorts, one word, and one long.
+    constexpr std::size_t kFixedRecordBits = 6 * kShortBits + kWordBits + kLongBits;
+    constexpr std::size_t kUnlockFlagBits = 3;
+    return optional(reader,
+                    [&output](Reader& group) noexcept { return read_activity(group, output); })
+           && optional(reader, read_roster) && optional(reader, read_opaque_state)
+           && skip_optional(reader, kWordBits)
+           && optional(reader,
+                       [&output](Reader& group) noexcept { return read_inventory(group, output); })
+           && skip_optional(reader, kFixedRecordBits)
+           && skip_optional(reader, kUnlockFlags * kUnlockFlagBits)
+           && optional(reader, read_tail_booleans);
+}
+
+/** Unused bytes in the fixed-capacity request buffer must be zero. */
+bool zero_padding(Reader& reader) noexcept {
+    while (reader.remaining_bits() != 0) {
+        std::uint64_t value = 0;
+        const auto width =
+            static_cast<std::uint8_t>((std::min)(reader.remaining_bits(), std::size_t{kLongBits}));
+        if (!reader.read(width, value) || value != 0) {
+            return false;
+        }
     }
-    for (std::size_t index = 0; read && index < kBlockByteCount; ++index) {
-        read = skip_field(reader, kBlockByteWidth);
+    return true;
+}
+} // namespace
+
+/** Reads activity state and new-item flags without applying a partial writeback. */
+bool parse_request(const Message& message, Request& request) noexcept {
+    request = {};
+    if (message.opcode != kOpcode || message.payload.empty()
+        || message.payload.size() > kPayloadSize) {
+        return false;
     }
-    std::uint64_t worldState = 0;
-    read =
-        read && skip_field(reader, kBlockTriadWidth) && reader.read(kWorldStateWidth, worldState);
-    if (!read) {
+    Reader reader(message.payload);
+    Request candidate;
+    if (!optional(reader, read_header)
+        || !optional(reader,
+                     [&candidate](Reader& group) noexcept { return read_body(group, candidate); })
+        || !zero_padding(reader)) {
         return false;
     }
-    request.worldState = static_cast<std::uint8_t>(worldState);
+    request = candidate;
     return true;
 }
 

+ 56 - 88
Sunrise/src/server/bap/bap_world_reward_queue.cpp

@@ -1,131 +1,99 @@
-/** World reward queue: rewards earned outside a request, held until a peer can present one. */
-
-#include <array>
-#include <cstddef>
-#include <cstdint>
-
 #include "../../core/logging/log.h"
+#include "../../state/build_data/runtime.h"
+#include "../../state/investment/store_internal.h"
 #include "internal.h"
 
 namespace sunrise::server::bap {
 namespace {
 
-/** Rewards earned in world, oldest first, waiting for a Family-4 peer to present them. */
-std::array<WorldRewardRequest, kWorldRewardQueueCapacity> g_worldRewards{};
-std::size_t g_worldRewardHead{};
-std::size_t g_worldRewardCount{};
-
-/** Drops the oldest queued reward. */
-void pop_world_reward() noexcept {
-    g_worldRewards[g_worldRewardHead] = {};
-    g_worldRewardHead = (g_worldRewardHead + 1) % g_worldRewards.size();
-    --g_worldRewardCount;
-}
-
-/** Commits one reward straight into State, with no presentation. @return True when it lands. */
-[[nodiscard]] bool commit_world_reward(const WorldRewardRequest& request) noexcept {
+/** Grants and retires one earned reward in the same database transaction. */
+bool commit_world_reward(const WorldRewardRequest& request) noexcept {
+    state::investment::store::Transaction transaction;
+    if (!transaction.ready()) {
+        return false;
+    }
+    bool committed = false;
     if (request.kind == WorldRewardKind::item) {
-        state::PendingItemAcquisition acquisition{};
-        return state::prepare_item_acquisition_for_item(request.itemDefinitionIndex, acquisition)
-               && state::commit_item_acquisition(acquisition);
+        state::PendingItemAcquisition acquisition;
+        committed =
+            state::prepare_item_acquisition_for_item(request.itemDefinitionIndex, acquisition)
+            && state::commit_item_acquisition(acquisition);
+    } else {
+        state::PendingProfileItemAcquisition acquisition;
+        committed = state::prepare_profile_item_acquisition_for_item(
+                        request.itemDefinitionIndex, request.quantity, acquisition)
+                    && state::commit_profile_item_acquisition(acquisition);
     }
-    state::PendingProfileItemAcquisition acquisition{};
-    return state::prepare_profile_item_acquisition_for_item(
-               request.itemDefinitionIndex, request.quantity, acquisition)
-           && state::commit_profile_item_acquisition(acquisition);
+    return committed && complete_world_reward(request.id) && transaction.commit();
 }
 
-/**
- * Queues one reward for presentation, or commits it now when no peer can present it.
- * @param request Reward to grant.
- * @return True when the reward is queued or committed.
- */
-[[nodiscard]] bool enqueue_world_reward(WorldRewardRequest request) noexcept {
-    if (!has_active_family4_peer()) {
-        while (g_worldRewardCount != 0) {
-            if (!commit_world_reward(g_worldRewards[g_worldRewardHead])) {
-                core::log::write(core::log::Channel::server,
-                                 core::log::Level::warn,
-                                 "ev=world_reward stage=direct result=drop");
-            }
-            pop_world_reward();
-        }
-        return commit_world_reward(request);
+/** Saves the reward under its stable definition hash and earning character. */
+bool enqueue_world_reward(std::uint16_t definitionIndex,
+                          std::int32_t quantity,
+                          WorldRewardKind kind) noexcept {
+    state::build_data::items::Definition definition;
+    if (!state::build_data::find_item_definition_index(definitionIndex, definition)
+        || !state::investment::store::enqueue_reward(
+            definition.definitionHash, quantity, static_cast<std::uint8_t>(kind))) {
+        return false;
     }
-    if (g_worldRewardCount == g_worldRewards.size()) {
-        const bool committed = commit_world_reward(g_worldRewards[g_worldRewardHead]);
-        if (committed) {
-            arm_account_resync_everywhere();
-        }
-        pop_world_reward();
-        core::log::write(core::log::Channel::server,
-                         core::log::Level::warn,
-                         committed ? "ev=world_reward stage=queue_full result=direct"
-                                   : "ev=world_reward stage=queue_full result=drop");
+    if (!has_active_family4_peer()) {
+        settle_world_reward();
     }
-    g_worldRewards[(g_worldRewardHead + g_worldRewardCount) % g_worldRewards.size()] = request;
-    ++g_worldRewardCount;
     return true;
 }
 
 } // namespace
 
+/** Saves one item reward before its pickup presentation is queued. */
 bool arm_world_item_acquisition(std::uint16_t itemDefinitionIndex) noexcept {
-    return enqueue_world_reward({1, itemDefinitionIndex, WorldRewardKind::item});
+    return enqueue_world_reward(itemDefinitionIndex, 1, WorldRewardKind::item);
 }
 
+/** Saves a profile material reward before its pickup presentation is queued. */
 bool arm_world_profile_item_acquisition(std::uint16_t itemDefinitionIndex,
                                         std::int32_t quantity) noexcept {
-    if (quantity <= 0) {
-        return false;
-    }
-    return enqueue_world_reward({quantity, itemDefinitionIndex, WorldRewardKind::profileItem});
+    return quantity > 0
+           && enqueue_world_reward(itemDefinitionIndex, quantity, WorldRewardKind::profileItem);
 }
 
+/** Restores the oldest reward belonging to the selected character. */
 bool current_world_reward(WorldRewardRequest& request) noexcept {
-    if (g_worldRewardCount == 0) {
-        request = {};
+    request = {};
+    state::investment::store::PendingReward saved;
+    state::build_data::items::Definition definition;
+    if (!state::investment::store::next_reward(saved)
+        || !state::build_data::find_item_definition_hash(saved.definitionHash, definition)) {
         return false;
     }
-    request = g_worldRewards[g_worldRewardHead];
+    request.id = saved.id;
+    request.quantity = saved.quantity;
+    request.itemDefinitionIndex = definition.definitionIndex;
+    request.kind = static_cast<WorldRewardKind>(saved.kind);
     return true;
 }
 
-void complete_world_reward() noexcept {
-    if (g_worldRewardCount == 0) {
-        return;
-    }
-    pop_world_reward();
+/** Acknowledges exactly the reward whose inventory grant is being committed. */
+bool complete_world_reward(std::uint64_t id) noexcept {
+    return state::investment::store::complete_reward(id);
 }
 
-/** Commits the queued reward with no flyout once its presentation cannot be built. */
+/** A failed grant stays saved for a later attempt. */
 void settle_world_reward() noexcept {
-    if (g_worldRewardCount == 0) {
-        return;
-    }
-    const bool committed = commit_world_reward(g_worldRewards[g_worldRewardHead]);
-    pop_world_reward();
-    if (committed) {
+    WorldRewardRequest request;
+    if (current_world_reward(request) && commit_world_reward(request)) {
         arm_account_resync_everywhere();
     }
-    core::log::write(core::log::Channel::server,
-                     core::log::Level::warn,
-                     committed ? "ev=world_reward stage=settle result=direct"
-                               : "ev=world_reward stage=settle result=drop");
 }
 
-/** Commits every queued reward with no presentation and empties the queue. */
+/** Shutdown may grant ready rewards; rewards for other characters stay in the database. */
 void drain_world_rewards() noexcept {
-    while (g_worldRewardCount != 0) {
-        if (!commit_world_reward(g_worldRewards[g_worldRewardHead])) {
-            core::log::write(core::log::Channel::server,
-                             core::log::Level::warn,
-                             "ev=world_reward stage=shutdown result=drop");
+    WorldRewardRequest request;
+    while (current_world_reward(request)) {
+        if (!commit_world_reward(request)) {
+            break;
         }
-        pop_world_reward();
     }
-    g_worldRewards = {};
-    g_worldRewardHead = 0;
 }
 
 } // namespace sunrise::server::bap

+ 17 - 3
Sunrise/src/server/bap/encrypted/activity_message/receipts/activity_incident_grants.cpp

@@ -1,10 +1,9 @@
+#include "state/investment/store_internal.h"
 /**
  * Applies the state change a collectible report implies, once its outer body has passed.
  * The incident's own targets name the object. Nothing here reads the running game client.
  */
 
-#include "activity_incident_grants.h"
-
 #include <algorithm>
 #include <array>
 #include <cstddef>
@@ -22,6 +21,7 @@
 #include "../../../../../state/runtime/runtime.h"
 #include "../../../../../state/unlocks/unlocks_records.h"
 #include "../../../../bap/internal.h"
+#include "activity_incident_grants.h"
 
 namespace sunrise::server::bap::encrypted::activity_message::receipts {
 
@@ -394,7 +394,7 @@ void grant_random_moon_loot() noexcept {
  * Applies the state change one accepted collectible report implies.
  * @param incident Outer-valid incident whose targets name the reported object.
  */
-void apply_incident_grants(const message::incident::Incident& incident) noexcept {
+static void stage_incident_grants(const message::incident::Incident& incident) noexcept {
     // Preserve the common-header size gate before acting on the incident.
     if (incident.payloadLength < 13) {
         return;
@@ -497,4 +497,18 @@ void apply_incident_grants(const message::incident::Incident& incident) noexcept
     }
 }
 
+/** Commits collectible progress and every reward earned by the same report together. */
+void apply_incident_grants(const message::incident::Incident& incident) noexcept {
+    state::investment::store::Transaction transaction;
+    if (!transaction.ready()) {
+        return;
+    }
+    stage_incident_grants(incident);
+    if (!transaction.commit()) {
+        core::log::write(core::log::Channel::server,
+                         core::log::Level::error,
+                         "ev=incident_grant result=fail reason=store");
+    }
+}
+
 } // namespace sunrise::server::bap::encrypted::activity_message::receipts

+ 10 - 3
Sunrise/src/server/bap/encrypted/body/bap_service_body.cpp

@@ -23,6 +23,7 @@
 #include "../internal.h"
 #include "../matchmaking/matchmaking_route.h"
 #include "../queuez/queuez_state_validation.h"
+#include "state/investment/store_internal.h"
 
 namespace sunrise::server::bap::encrypted::body {
 namespace {
@@ -73,7 +74,8 @@ bool process(const ServiceRoute& route,
              std::span<const std::byte> requestBody,
              std::span<std::byte> output,
              std::size_t& written,
-             ServiceOutcome& outcome) noexcept {
+             ServiceOutcome& outcome,
+             std::span<const state::account::inventory::PresentedItemRow> presentation) noexcept {
     outcome = {};
     switch (route.bodyCodec) {
     case BodyCodec::empty:
@@ -221,8 +223,13 @@ bool process(const ServiceRoute& route,
             outcome.hasChangeCharacter = true;
             return true;
         }
+        state::investment::store::Transaction investmentTransaction;
+        if (!investmentTransaction.ready()) {
+            return false;
+        }
         web_service::Outcome webOutcome;
-        if (!sunrise::server::web_service::consume(requestBody, output, written, webOutcome)) {
+        if (!sunrise::server::web_service::consume(
+                requestBody, output, written, webOutcome, presentation)) {
             return false;
         }
         if (webOutcome.hasTitleEquip) {
@@ -679,7 +686,7 @@ bool process(const ServiceRoute& route,
                 sunrise::server::bap::arm_account_resync_everywhere();
             }
         }
-        return true;
+        return investmentTransaction.commit();
     }
     }
     written = 0;

+ 20 - 3
Sunrise/src/server/bap/encrypted/encrypted_runtime.cpp

@@ -21,6 +21,7 @@
 #include "internal.h"
 #include "push/activity/activity_roster_push.h"
 #include "queuez/queuez_outcome_staging.h"
+#include "state/investment/store_internal.h"
 #include "transactions/service_outcome_commit.h"
 
 namespace sunrise::server::bap::encrypted {
@@ -272,6 +273,20 @@ bool consume(Session& session,
                          core::log::Level::warn,
                          "ev=bap stage=web_service result=refuse reason=stale_manifest");
     }
+    state::investment::store::Transaction investmentTransaction;
+    if (!investmentTransaction.ready()) {
+        return false;
+    }
+    std::array<state::account::inventory::PresentedItemRow,
+               queuez::kAcquisitionPresentationRowCapacity>
+        presentation{};
+    if (session.acquisitionPresentationRowCount > presentation.size()) {
+        return false;
+    }
+    for (std::size_t index = 0; index < session.acquisitionPresentationRowCount; ++index) {
+        const auto& row = session.acquisitionPresentationRows[index];
+        presentation[index] = {row.instanceSoid, row.inventoryRow};
+    }
     // Pure one-way services consume only the authenticated receive nonce.
     if (!staleWebAction && processesBody
         && !body::process(route,
@@ -282,7 +297,8 @@ bool consume(Session& session,
                           frame.body,
                           scratch.responseBody,
                           responseBodySize,
-                          outcome)) {
+                          outcome,
+                          std::span(presentation).first(session.acquisitionPresentationRowCount))) {
         diagnostics::report_failure(frame.serviceId, "body");
         // A reply-mode service answers with an empty body instead of not at all. The Client
         // matches only the head of its pending ring. One unanswered request jams that ring for
@@ -402,8 +418,9 @@ bool consume(Session& session,
         if (!retirementValid) {
             commitReason = "entity_retirement_stale";
         }
-        handled =
-            fits && retirementValid && transactions::commit(outcome, publication, commitReason);
+        handled = fits && retirementValid
+                  && transactions::commit(outcome, publication, commitReason)
+                  && investmentTransaction.commit();
         if (!handled) {
             diagnostics::report_failure(
                 frame.serviceId, "commit", fits ? commitReason : "frame_capacity");

+ 393 - 9
Sunrise/src/server/bap/encrypted/internal.h

@@ -19,183 +19,296 @@
 #include "../internal.h"
 #include "activity_message/definition.h"
 #include "queuez/definition.h"
+#include "state/account/inventory/seen_state.h"
 #include "transactions/definition.h"
 
 namespace sunrise::server::bap::encrypted {
 
 /** Response-body codecs picked by the authenticated request service. */
+
 enum class BodyCodec : std::uint8_t {
+
     empty,
+
     accountTranslationResponse,
+
     activityHostManagerResponse,
+
     activityMessageRequest,
+
     activityHostResponse,
+
     clientConfigResponse,
+
     familySubscription,
+
     familyUnsubscription,
+
     matchmakingResponse,
+
     steamCertificate,
+
     userMessageResponse,
+
     webService,
+
 };
 
 /** Equipment mutation and the exact QueueZ after-image promised by its response. */
+
 struct EquipmentSwapTransaction {
+
     std::unique_ptr<state::PendingEquipmentSwap> pending{};
+
     queuez::EquipmentSwap update{};
 };
 
 /** Socket mutation and the exact QueueZ after-image promised by its response. */
+
 struct SocketPlugTransaction {
+
     std::unique_ptr<state::PendingSocketPlug> pending{};
+
     queuez::SocketPlug update{};
 };
 
 /** Subclass ability selection and the exact QueueZ after-image promised by its response. */
+
 struct SubclassSelectionTransaction {
+
     std::unique_ptr<state::PendingSubclassSelection> pending{};
+
     queuez::SubclassSelection update{};
 };
 
 /** Item-state mutation and the exact QueueZ character after-image promised by its response. */
+
 struct ItemStateTransaction {
+
     std::unique_ptr<state::PendingItemState> pending{};
+
     queuez::EquipmentSwap update{};
 };
 
 /** Artifact purchase and the exact selected-character after-image promised by opcode 901. */
+
 struct ArtifactPurchaseTransaction {
+
     std::unique_ptr<state::PendingArtifactPurchase> pending{};
+
     queuez::EquipmentSwap update{};
 };
 
 /** Current-activity mutation and the exact QueueZ character after-image sent with its reply. */
+
 struct CurrentActivityTransaction {
+
     state::PendingCurrentActivity pending{};
+
     queuez::EquipmentSwap update{};
 };
 
 /** Character acquisition and its exact QueueZ after-image. */
+
 struct ItemAcquisitionTransaction {
+
     std::unique_ptr<state::PendingItemAcquisition> pending{};
+
     queuez::ItemAcquisition update{};
 };
 
 /** Profile acquisition and its exact account/resident QueueZ after-image. */
+
 struct ProfileItemAcquisitionTransaction {
+
     std::unique_ptr<state::PendingProfileItemAcquisition> pending{};
+
     queuez::ProfileItemAcquisition update{};
 };
 
 /** Dismantle mutation and its exact QueueZ after-image. */
+
 struct ItemDismantleTransaction {
+
     std::unique_ptr<state::PendingItemDismantle> pending{};
+
     queuez::ItemDismantle update{};
 };
 
 /** Record-claim reward batch and its exact Queuez after-image. */
+
 struct RecordRewardGrantTransaction {
+
     std::unique_ptr<state::PendingRecordRewardGrant> pending{};
+
     queuez::RecordRewardGrant update{};
 };
 
 /** Season reward grant plus the exact Queuez after-image promised by opcode 2400. */
+
 struct SeasonPassRewardTransaction {
+
     std::unique_ptr<state::PendingSeasonPassReward> pending{};
+
     std::variant<std::monostate,
+
                  queuez::ItemAcquisition,
+
                  queuez::ProfileItemAcquisition,
+
                  queuez::RecordRewardGrant>
+
         update{};
 };
 
 /** Optional side effect produced while decoding one authenticated service body. */
+
 struct ServiceOutcome {
+
     bool hasSubscription{};
+
     /** A Triumph claim changed the account flag bank and its image has to follow. */
+
     bool hasRecordClaim{};
+
     bool hasArtifactReset{};
+
     state::ArtifactResetResult artifactReset{};
+
     middleware::queuez::Subscription subscription{};
+
     bool hasUnsubscription{};
+
     middleware::bap::family_unsubscription::Request unsubscription{};
+
     bool hasChangeCharacter{};
+
     bool hasSelectCharacter{};
+
     /** One service owns at most one independently versioned, exact-sized transaction. */
+
     using Transaction = std::variant<std::monostate,
+
                                      std::unique_ptr<state::activity::PendingAllocation>,
+
                                      std::unique_ptr<activity_message::ActivityPlan>,
+
                                      std::unique_ptr<state::matchmaking::PendingMutation>,
+
                                      std::unique_ptr<queuez::ChangeCharacter>,
+
                                      std::unique_ptr<queuez::SelectCharacter>,
+
                                      std::unique_ptr<EquipmentSwapTransaction>,
+
                                      std::unique_ptr<SubclassSelectionTransaction>,
+
                                      std::unique_ptr<SocketPlugTransaction>,
+
                                      std::unique_ptr<ItemStateTransaction>,
+
                                      std::unique_ptr<ArtifactPurchaseTransaction>,
+
                                      std::unique_ptr<CurrentActivityTransaction>,
+
                                      std::unique_ptr<ItemAcquisitionTransaction>,
+
                                      std::unique_ptr<ProfileItemAcquisitionTransaction>,
+
                                      std::unique_ptr<ItemDismantleTransaction>,
+
                                      std::unique_ptr<RecordRewardGrantTransaction>,
+
                                      std::unique_ptr<SeasonPassRewardTransaction>,
+
                                      std::unique_ptr<state::PendingSettingsUpdate>>;
+
     Transaction transaction{};
 };
 
 /** Allocates only the selected transaction outside the request's already deep call stack. */
 template <typename Transaction, typename... Args>
 [[nodiscard]] Transaction* emplace_transaction(ServiceOutcome& outcome, Args&&... args) noexcept {
+
     static_assert(std::is_nothrow_constructible_v<Transaction, Args...>);
+
     outcome.transaction.template emplace<std::monostate>();
+
     auto storage =
+
         std::unique_ptr<Transaction>{new (std::nothrow) Transaction(std::forward<Args>(args)...)};
+
     if (storage == nullptr) {
+
         return nullptr;
     }
+
     auto* transaction = storage.get();
+
     outcome.transaction.template emplace<std::unique_ptr<Transaction>>(std::move(storage));
+
     return transaction;
 }
 
 /** @return The service transaction of the requested type, or null for another route. */
+
 template <typename Transaction>
+
 [[nodiscard]] Transaction* transaction_if(ServiceOutcome& outcome) noexcept {
+
     auto* storage = std::get_if<std::unique_ptr<Transaction>>(&outcome.transaction);
+
     return storage == nullptr ? nullptr : storage->get();
 }
 
 /** @return The service transaction of the requested type, or null for another route. */
+
 template <typename Transaction>
+
 [[nodiscard]] const Transaction* transaction_if(const ServiceOutcome& outcome) noexcept {
+
     const auto* storage = std::get_if<std::unique_ptr<Transaction>>(&outcome.transaction);
+
     return storage == nullptr ? nullptr : storage->get();
 }
 
 [[nodiscard]] inline bool has_transaction(const ServiceOutcome& outcome) noexcept {
+
     return outcome.transaction.index() != 0;
 }
 
 inline void clear_transaction(ServiceOutcome& outcome) noexcept {
+
     outcome.transaction.template emplace<std::monostate>();
 }
 
 /** Outbound delivery behavior picked for one authenticated request service. */
+
 enum class ResponseMode : std::uint8_t {
+
     none,
+
     reply,
+
     /** Processes a request body and may emit notifications without a status response. */
+
     uncorrelatedPush,
+
 };
 
 /** Static response metadata for one supported encrypted request service. */
+
 struct ServiceRoute {
+
     ResponseMode responseMode{};
+
     middleware::bap::ResponseService response{};
+
     BodyCodec bodyCodec{};
 };
 
 /** Owns encrypted service-to-response routing. */
+
 namespace routing {
 
 [[nodiscard]] bool resolve(std::uint16_t request, ServiceRoute& route) noexcept;
@@ -203,18 +316,23 @@ namespace routing {
 } // namespace routing
 
 /** Owns failure reporting for encrypted requests. */
+
 namespace diagnostics {
 
 void report_failure(std::uint16_t service, std::string_view stage) noexcept;
 
 /** Reports one refusal that names which branch refused. */
+
 void report_failure(std::uint16_t service,
+
                     std::string_view stage,
+
                     std::string_view reason) noexcept;
 
 } // namespace diagnostics
 
 /** Owns correlated reply construction for one authenticated request. */
+
 namespace reply {
 
 /**
@@ -228,17 +346,25 @@ namespace reply {
  * @param framedSize Receives the complete outer-frame size, or zero on failure.
  * @return True when the payload, seal, and outer frame all fit.
  */
+
 [[nodiscard]] bool encode(Scratch& scratch,
+
                           const ServiceRoute& route,
+
                           std::uint32_t taskId,
+
                           std::span<const std::byte, state::kAesKeySize> key,
+
                           std::span<const std::byte, state::kBapNonceSize> nonce,
+
                           std::span<const std::byte> body,
+
                           std::size_t& framedSize) noexcept;
 
 } // namespace reply
 
 /** Owns request-body processing for an encrypted service route. */
+
 namespace body {
 
 /**
@@ -254,19 +380,32 @@ namespace body {
  * @param outcome Receives one validated transport action or deferred State transaction.
  * @return True when the chosen body codec succeeds.
  */
-[[nodiscard]] bool process(const ServiceRoute& route,
-                           const queuez::SessionState& queuezState,
-                           const ActivityClientBinding& activity,
-                           const RosterDecodeMap& rosterDecode,
-                           state::matchmaking::ContextHandle matchmakingContext,
-                           std::span<const std::byte> requestBody,
-                           std::span<std::byte> output,
-                           std::size_t& written,
-                           ServiceOutcome& outcome) noexcept;
+
+[[nodiscard]] bool
+process(const ServiceRoute& route,
+
+        const queuez::SessionState& queuezState,
+
+        const ActivityClientBinding& activity,
+
+        const RosterDecodeMap& rosterDecode,
+
+        state::matchmaking::ContextHandle matchmakingContext,
+
+        std::span<const std::byte> requestBody,
+
+        std::span<std::byte> output,
+
+        std::size_t& written,
+
+        ServiceOutcome& outcome,
+
+        std::span<const state::account::inventory::PresentedItemRow> presentation = {}) noexcept;
 
 } // namespace body
 
 /** Owns server-initiated encrypted frames appended after correlated replies. */
+
 namespace push {
 
 /**
@@ -274,6 +413,7 @@ namespace push {
  * Families 0, 3 and 4 each snapshot the account, so a migration inside one builder would leave
  * the others describing a different account. Idempotent.
  */
+
 void ensure_account_canonical() noexcept;
 
 /**
@@ -291,51 +431,91 @@ void ensure_account_canonical() noexcept;
  * @param armsRepush Receives whether the Family-4 companion needs its delayed second copy.
  * @param armsBannerRepush Receives whether a family-zero body needs its delayed second copy.
  */
+
 void append_queuez_notification(Scratch& scratch,
+
                                 const queuez::SessionState& before,
+
                                 const middleware::queuez::Subscription& subscription,
+
                                 std::span<const std::byte, state::kAesKeySize> key,
+
                                 std::array<std::byte, state::kBapNonceSize>& nonce,
+
                                 std::span<std::byte> response,
+
                                 std::size_t& written,
+
                                 queuez::SessionState& after,
+
                                 bool& armsRepush,
+
                                 bool& armsBannerRepush) noexcept;
 
 /** Appends one next-version full Family-4 snapshot used to resynchronize another peer. */
+
 [[nodiscard]] bool append_account_resync_notification(
+
     Scratch& scratch,
+
     const queuez::SessionState& before,
+
     std::span<const queuez::AcquisitionPresentationRow> acquisitionPresentationRows,
+
     std::span<const std::byte, state::kAesKeySize> key,
+
     std::array<std::byte, state::kBapNonceSize>& nonce,
+
     std::span<std::byte> response,
+
     std::size_t& written,
+
     queuez::SessionState& after) noexcept;
 
 /** Publishes one Season package as new residents plus their acquisition descriptors. */
+
 [[nodiscard]] bool append_season_pass_package_notification(
+
     Scratch& scratch,
+
     const queuez::SessionState& before,
+
     const state::PendingDirectItemBundle& mutation,
+
     std::uint16_t rewardIndex,
+
     std::span<const queuez::AcquisitionPresentationRow> acquisitionPresentationRows,
+
     std::span<const std::byte, state::kAesKeySize> key,
+
     std::span<const std::byte, state::kBapNonceSize> nonce,
+
     std::span<std::byte> response,
+
     std::size_t& written,
+
     queuez::SessionState& after) noexcept;
 
 /** Publishes every item and the claimed record in one Family-4 revision. */
+
 [[nodiscard]] bool append_record_reward_notification(
+
     Scratch& scratch,
+
     const queuez::SessionState& before,
+
     const queuez::RecordRewardGrant& update,
+
     const state::PendingRecordRewardGrant& mutation,
+
     std::span<const queuez::AcquisitionPresentationRow> acquisitionPresentationRows,
+
     std::span<const std::byte, state::kAesKeySize> key,
+
     std::span<const std::byte, state::kBapNonceSize> nonce,
+
     std::span<std::byte> response,
+
     std::size_t& written) noexcept;
 
 /**
@@ -352,13 +532,21 @@ void append_queuez_notification(Scratch& scratch,
  * @param after Receives the state carrying the recorded delivery.
  * @return True when the banner frame is appended.
  */
+
 [[nodiscard]] bool append_banner_notification(Scratch& scratch,
+
                                               const queuez::SessionState& before,
+
                                               std::uint64_t familyRootSoid,
+
                                               std::span<const std::byte, state::kAesKeySize> key,
+
                                               std::array<std::byte, state::kBapNonceSize>& nonce,
+
                                               std::span<std::byte> response,
+
                                               std::size_t& written,
+
                                               queuez::SessionState& after) noexcept;
 
 /**
@@ -374,14 +562,23 @@ void append_queuez_notification(Scratch& scratch,
  * @param after Receives the state published once the frame is copied.
  * @return True when a frame went out and `after` carries the advanced ladder.
  */
+
 [[nodiscard]] bool
+
 append_banner_move_notification(Scratch& scratch,
+
                                 const queuez::SessionState& before,
+
                                 std::uint64_t selectedCharacter,
+
                                 std::span<const std::byte, state::kAesKeySize> key,
+
                                 std::array<std::byte, state::kBapNonceSize>& nonce,
+
                                 std::span<std::byte> response,
+
                                 std::size_t& written,
+
                                 queuez::SessionState& after) noexcept;
 
 /**
@@ -394,12 +591,19 @@ append_banner_move_notification(Scratch& scratch,
  * @param written Existing byte count, updated after the complete push is appended.
  * @return True when the exact 17-byte patch and complete svc-123 frame fit.
  */
+
 [[nodiscard]] bool
+
 append_change_character_notification(Scratch& scratch,
+
                                      const queuez::ChangeCharacter& change,
+
                                      std::span<const std::byte, state::kAesKeySize> key,
+
                                      std::span<const std::byte, state::kBapNonceSize> nonce,
+
                                      std::span<std::byte> response,
+
                                      std::size_t& written) noexcept;
 
 /**
@@ -412,55 +616,97 @@ append_change_character_notification(Scratch& scratch,
  * @param written Existing byte count, updated after the complete push is appended.
  * @return True when the 3 object operations and the whole svc-123 frame fit.
  */
+
 [[nodiscard]] bool
+
 append_select_character_notification(Scratch& scratch,
+
                                      const queuez::SelectCharacter& select,
+
                                      std::span<const std::byte, state::kAesKeySize> key,
+
                                      std::span<const std::byte, state::kBapNonceSize> nonce,
+
                                      std::span<std::byte> response,
+
                                      std::size_t& written) noexcept;
 
 /** Appends the opcode-403 Family-4 character upsert that exposes the equipped item swap. */
+
 [[nodiscard]] bool append_equipment_swap_notification(
+
     Scratch& scratch,
+
     const queuez::EquipmentSwap& swap,
+
     const state::PendingEquipmentSwap& mutation,
+
     std::span<const queuez::AcquisitionPresentationRow> acquisitionPresentationRows,
+
     std::span<const std::byte, state::kAesKeySize> key,
+
     std::span<const std::byte, state::kBapNonceSize> nonce,
+
     std::span<std::byte> response,
+
     std::size_t& written) noexcept;
 
 /** Appends the Family-4 character upsert carrying the character's new current activity. */
+
 [[nodiscard]] bool
+
 append_current_activity_notification(Scratch& scratch,
+
                                      const queuez::EquipmentSwap& swap,
+
                                      const state::PendingCurrentActivity& mutation,
+
                                      std::span<const std::byte, state::kAesKeySize> key,
+
                                      std::span<const std::byte, state::kBapNonceSize> nonce,
+
                                      std::span<std::byte> response,
+
                                      std::size_t& written) noexcept;
 
 /** Appends the opcode-406 Family-4 character upsert carrying changed inventory-row flags. */
+
 [[nodiscard]] bool append_item_state_notification(
+
     Scratch& scratch,
+
     const queuez::EquipmentSwap& update,
+
     const state::PendingItemState& mutation,
+
     std::span<const queuez::AcquisitionPresentationRow> acquisitionPresentationRows,
+
     std::span<const std::byte, state::kAesKeySize> key,
+
     std::span<const std::byte, state::kBapNonceSize> nonce,
+
     std::span<std::byte> response,
+
     std::size_t& written) noexcept;
 
 /** Appends the selected-character upsert carrying one artifact ownership transition. */
+
 [[nodiscard]] bool append_artifact_purchase_notification(
+
     Scratch& scratch,
+
     const queuez::EquipmentSwap& update,
+
     const state::PendingArtifactPurchase& mutation,
+
     std::span<const queuez::AcquisitionPresentationRow> acquisitionPresentationRows,
+
     std::span<const std::byte, state::kAesKeySize> key,
+
     std::span<const std::byte, state::kBapNonceSize> nonce,
+
     std::span<std::byte> response,
+
     std::size_t& written) noexcept;
 
 /**
@@ -473,178 +719,316 @@ append_current_activity_notification(Scratch& scratch,
  * @param written Existing byte count, updated by a complete frame.
  * @return True when State encodes and the whole frame fits.
  */
+
 [[nodiscard]] bool
+
 append_family5_override_notification(Scratch& scratch,
+
                                      std::int32_t version,
+
                                      std::span<const std::byte, state::kAesKeySize> key,
+
                                      std::span<const std::byte, state::kBapNonceSize> nonce,
+
                                      std::span<std::byte> response,
+
                                      std::size_t& written) noexcept;
 
 /** Appends the account and selected-character state changed by an artifact reset. */
+
 [[nodiscard]] bool
+
 append_artifact_reset_notification(Scratch& scratch,
+
                                    const queuez::EquipmentSwap& update,
+
                                    std::span<const std::byte, state::kAesKeySize> key,
+
                                    std::span<const std::byte, state::kBapNonceSize> nonce,
+
                                    std::span<std::byte> response,
+
                                    std::size_t& written) noexcept;
 
 /** Appends one current item resident after artifact reset cleared an authored socket. */
+
 [[nodiscard]] bool
+
 append_artifact_item_refresh_notification(Scratch& scratch,
+
                                           const queuez::EquipmentSwap& update,
+
                                           std::uint64_t instanceSoid,
+
                                           std::span<const std::byte, state::kAesKeySize> key,
+
                                           std::span<const std::byte, state::kBapNonceSize> nonce,
+
                                           std::span<std::byte> response,
+
                                           std::size_t& written) noexcept;
 
 /**
  * Appends the same-character Family-0 appearance upsert paired with one equipment swap.
  * The update owns its nonce advance only after the complete notification fits.
  */
+
 [[nodiscard]] bool
+
 append_equipment_appearance_refresh_notification(Scratch& scratch,
+
                                                  const queuez::CharacterAppearanceRefresh& refresh,
+
                                                  const state::PendingEquipmentSwap& mutation,
+
                                                  std::span<const std::byte, state::kAesKeySize> key,
+
                                                  std::array<std::byte, state::kBapNonceSize>& nonce,
+
                                                  std::span<std::byte> response,
+
                                                  std::size_t& written) noexcept;
 
 /** Appends the Family-0 refresh owed by a socket change on an equipped item. */
+
 [[nodiscard]] bool
+
 append_socket_appearance_refresh_notification(Scratch& scratch,
+
                                               const queuez::CharacterAppearanceRefresh& refresh,
+
                                               const state::PendingSocketPlug& mutation,
+
                                               std::span<const std::byte, state::kAesKeySize> key,
+
                                               std::array<std::byte, state::kBapNonceSize>& nonce,
+
                                               std::span<std::byte> response,
+
                                               std::size_t& written) noexcept;
 
 /** Appends the Family-0 character ability refresh owed by a subclass selection. */
+
 [[nodiscard]] bool
+
 append_subclass_appearance_refresh_notification(Scratch& scratch,
+
                                                 const queuez::CharacterAppearanceRefresh& refresh,
+
                                                 const state::PendingSubclassSelection& mutation,
+
                                                 std::span<const std::byte, state::kAesKeySize> key,
+
                                                 std::array<std::byte, state::kBapNonceSize>& nonce,
+
                                                 std::span<std::byte> response,
+
                                                 std::size_t& written) noexcept;
 
 /** Appends a Family-3 character record followed by the changed account roster after equip. */
+
 [[nodiscard]] bool
+
 append_equipment_roster_refresh_notification(Scratch& scratch,
+
                                              const queuez::RosterAppearanceRefresh& refresh,
+
                                              const state::PendingEquipmentSwap& mutation,
+
                                              std::span<const std::byte, state::kAesKeySize> key,
+
                                              std::array<std::byte, state::kBapNonceSize>& nonce,
+
                                              std::span<std::byte> response,
+
                                              std::size_t& written) noexcept;
 
 /** Appends a Family-3 character-only appearance refresh after an equipped socket change. */
+
 [[nodiscard]] bool
+
 append_socket_roster_refresh_notification(Scratch& scratch,
+
                                           const queuez::RosterAppearanceRefresh& refresh,
+
                                           const state::PendingSocketPlug& mutation,
+
                                           std::span<const std::byte, state::kAesKeySize> key,
+
                                           std::array<std::byte, state::kBapNonceSize>& nonce,
+
                                           std::span<std::byte> response,
+
                                           std::size_t& written) noexcept;
 
 /** Appends a Family-3 character-only appearance refresh after a subclass selection. */
+
 [[nodiscard]] bool
+
 append_subclass_roster_refresh_notification(Scratch& scratch,
+
                                             const queuez::RosterAppearanceRefresh& refresh,
+
                                             const state::PendingSubclassSelection& mutation,
+
                                             std::span<const std::byte, state::kAesKeySize> key,
+
                                             std::array<std::byte, state::kBapNonceSize>& nonce,
+
                                             std::span<std::byte> response,
+
                                             std::size_t& written) noexcept;
 
 /** Refreshes the selected character's complete Family-0 appearance from committed State. */
+
 [[nodiscard]] bool
+
 append_account_resync_appearance_notification(Scratch& scratch,
+
                                               const queuez::SessionState& before,
+
                                               std::span<const std::byte, state::kAesKeySize> key,
+
                                               std::array<std::byte, state::kBapNonceSize>& nonce,
+
                                               std::span<std::byte> response,
+
                                               std::size_t& written,
+
                                               queuez::SessionState& after) noexcept;
 
 /** Refreshes the selected character and account roster from committed State. */
+
 [[nodiscard]] bool
+
 append_account_resync_roster_notification(Scratch& scratch,
+
                                           const queuez::SessionState& before,
+
                                           std::span<const std::byte, state::kAesKeySize> key,
+
                                           std::array<std::byte, state::kBapNonceSize>& nonce,
+
                                           std::span<std::byte> response,
+
                                           std::size_t& written,
+
                                           queuez::SessionState& after) noexcept;
 
 /** Appends the opcode-903 Family-4 item-instance upsert exposing one socket selection. */
+
 [[nodiscard]] bool
+
 append_socket_plug_notification(Scratch& scratch,
+
                                 const queuez::SocketPlug& socketPlug,
+
                                 const state::PendingSocketPlug& mutation,
+
                                 std::span<const std::byte, state::kAesKeySize> key,
+
                                 std::span<const std::byte, state::kBapNonceSize> nonce,
+
                                 std::span<std::byte> response,
+
                                 std::size_t& written) noexcept;
 
 /** Appends the opcode-801 Family-4 subclass item-instance upsert. */
+
 [[nodiscard]] bool
+
 append_subclass_selection_notification(Scratch& scratch,
+
                                        const queuez::SubclassSelection& selection,
+
                                        const state::PendingSubclassSelection& mutation,
+
                                        std::span<const std::byte, state::kAesKeySize> key,
+
                                        std::span<const std::byte, state::kBapNonceSize> nonce,
+
                                        std::span<std::byte> response,
+
                                        std::size_t& written) noexcept;
 
 /** Appends a Family-4 character upsert plus newly acquired item-instance upsert. */
+
 [[nodiscard]] bool append_item_acquisition_notification(
+
     Scratch& scratch,
+
     const queuez::ItemAcquisition& acquisition,
+
     const state::PendingItemAcquisition& mutation,
+
     std::span<const queuez::AcquisitionPresentationRow> acquisitionPresentationRows,
+
     std::span<const std::byte, state::kAesKeySize> key,
+
     std::span<const std::byte, state::kBapNonceSize> nonce,
+
     std::span<std::byte> response,
+
     std::size_t& written) noexcept;
 
 /** Appends one full Family-4 account upsert for a profile-stack acquisition. */
+
 [[nodiscard]] bool
+
 append_profile_item_acquisition_notification(Scratch& scratch,
+
                                              const queuez::ProfileItemAcquisition& acquisition,
+
                                              const state::PendingProfileItemAcquisition& mutation,
+
                                              std::span<const std::byte, state::kAesKeySize> key,
+
                                              std::span<const std::byte, state::kBapNonceSize> nonce,
+
                                              std::span<std::byte> response,
+
                                              std::size_t& written) noexcept;
 
 /** Appends the character/account increment that makes one seasonal XP gain visible in the HUD. */
+
 [[nodiscard]] bool append_seasonal_experience_notification(
+
     Scratch& scratch,
+
     const queuez::SessionState& before,
+
     std::int32_t amount,
+
     std::int32_t mutationSerial,
+
     std::span<const queuez::AcquisitionPresentationRow> acquisitionPresentationRows,
+
     std::span<const std::byte, state::kAesKeySize> key,
+
     std::span<const std::byte, state::kBapNonceSize> nonce,
+
     std::span<std::byte> response,
+
     std::size_t& written,
+
     queuez::SessionState& after) noexcept;
 
 /** Appends a Family-4 character upsert followed by one empty item-instance release. */
+
 [[nodiscard]] bool
+
 append_item_dismantle_notification(Scratch& scratch,
+
                                    const queuez::ItemDismantle& dismantle,
+
                                    const state::PendingItemDismantle& mutation,
+
                                    std::span<const std::byte, state::kAesKeySize> key,
+
                                    std::span<const std::byte, state::kBapNonceSize> nonce,
+
                                    std::span<std::byte> response,
+
                                    std::size_t& written) noexcept;
 
 } // namespace push

+ 4 - 2
Sunrise/src/server/bap/encrypted/push/snapshot/family4_selection_move.cpp

@@ -97,8 +97,10 @@ bool apply_acquisition_presentation(
         row.quantity = item->quantity;
         row.mutationSerial = item->mutationSerial;
         row.flags = item->flags;
-        characterObject.newItemFlags[presentation.inventoryRow / kBitsPerFlagByte] |=
-            std::byte{1U} << (presentation.inventoryRow % kBitsPerFlagByte);
+        if (!item->seen) {
+            characterObject.newItemFlags[presentation.inventoryRow / kBitsPerFlagByte] |=
+                std::byte{1U} << (presentation.inventoryRow % kBitsPerFlagByte);
+        }
         characterObject.instanceProgressWatermarks[presentation.inventoryRow] = 1;
     }
     return true;

+ 25 - 12
Sunrise/src/server/bap/encrypted/queuez/queuez_deferred_push.cpp

@@ -1,4 +1,4 @@
-#include <Windows.h>
+#include <Windows.h>
 
 #include <algorithm>
 #include <limits>
@@ -12,6 +12,7 @@
 #include "../internal.h"
 #include "../push/activity/activity_keepalive_push.h"
 #include "queuez_state_validation.h"
+#include "state/investment/store_internal.h"
 
 namespace sunrise::server::bap::encrypted {
 namespace {
@@ -58,6 +59,11 @@ selected_character(const state::AccountState& account) noexcept {
                                                   std::span<std::byte> response,
                                                   std::size_t& written,
                                                   bool& touchesScratch) noexcept {
+    state::investment::store::Transaction transaction;
+    if (!transaction.ready()) {
+        return false;
+    }
+
     state::PendingItemAcquisition pending{};
     if (!state::prepare_item_acquisition_for_item(request.itemDefinitionIndex, pending)) {
         core::log::write(core::log::Channel::server,
@@ -97,7 +103,8 @@ selected_character(const state::AccountState& account) noexcept {
         bap::settle_world_reward();
         return false;
     }
-    if (!state::commit_item_acquisition(pending)) {
+    if (!state::commit_item_acquisition(pending) || !bap::complete_world_reward(request.id)
+        || !transaction.commit()) {
         core::log::write(core::log::Channel::server,
                          core::log::Level::warn,
                          "ev=queuez stage=world_acquisition result=fail reason=commit");
@@ -109,7 +116,6 @@ selected_character(const state::AccountState& account) noexcept {
     middleware::secure_channel::advance_nonce(nextSendNonce);
     session.sendNonce = nextSendNonce;
     session.queuez = acquisition.after;
-    bap::complete_world_reward();
     bap::arm_account_resync_elsewhere(session);
     bap::arm_acquisition_presentation_hold(session);
     return true;
@@ -122,6 +128,11 @@ selected_character(const state::AccountState& account) noexcept {
                                                           std::span<std::byte> response,
                                                           std::size_t& written,
                                                           bool& touchesScratch) noexcept {
+    state::investment::store::Transaction transaction;
+    if (!transaction.ready()) {
+        return false;
+    }
+
     state::PendingProfileItemAcquisition pending{};
     if (!state::prepare_profile_item_acquisition_for_item(
             request.itemDefinitionIndex, request.quantity, pending)) {
@@ -161,7 +172,8 @@ selected_character(const state::AccountState& account) noexcept {
         bap::settle_world_reward();
         return false;
     }
-    if (!state::commit_profile_item_acquisition(pending)) {
+    if (!state::commit_profile_item_acquisition(pending) || !bap::complete_world_reward(request.id)
+        || !transaction.commit()) {
         core::log::write(core::log::Channel::server,
                          core::log::Level::warn,
                          "ev=queuez stage=world_profile_acquisition result=fail reason=commit");
@@ -173,7 +185,6 @@ selected_character(const state::AccountState& account) noexcept {
     middleware::secure_channel::advance_nonce(nextSendNonce);
     session.sendNonce = nextSendNonce;
     session.queuez = acquisition.after;
-    bap::complete_world_reward();
     bap::arm_account_resync_elsewhere(session);
     bap::arm_acquisition_presentation_hold(session);
     return true;
@@ -364,7 +375,8 @@ selected_character(const state::AccountState& account) noexcept {
 /**
  * Sends the family-two re-push the equip that moved the member record owes.
  * An emblem equip leaves the subscribe-time snapshot stale, so the body is rebuilt against the
- * root the subscribe was answered with. One attempt: the arm is spent before the frame is built.
+ * root the subscribe was answered with. One attempt: the arm is spent before the frame is
+ * built.
  * @param session Auth, nonce and queuez state owned by the connection.
  * @param scratch Transform buffers owned by the lock.
  * @param response Whole-frame storage owned by the caller.
@@ -623,8 +635,9 @@ selected_character(const state::AccountState& account) noexcept {
     session.queuez = update.after;
     ++session.artifactResetRefreshCursor;
     if (session.artifactResetRefreshCursor >= session.artifactResetRefresh.instanceCount) {
-        // Equipped sockets feed Family 0/3's derived perk banks. Refresh them once every changed
-        // item resident has landed so reset cannot leave the previous champion effect cached.
+        // Equipped sockets feed Family 0/3's derived perk banks. Refresh them once every
+        // changed item resident has landed so reset cannot leave the previous champion effect
+        // cached.
         session.abilityRefreshDueTick = GetTickCount64();
         session.abilityRefreshArmed = true;
     }
@@ -643,8 +656,8 @@ bool consume_deferred(Session& session,
     if (!session.authenticated) {
         return false;
     }
-    // The overrides go first: they are what the purchased mod unlocks, and the Family-4 companion
-    // waits on its own delay.
+    // The overrides go first: they are what the purchased mod unlocks, and the Family-4
+    // companion waits on its own delay.
     if (consume_artifact_family5_refresh(session, scratch, response, written, touchesScratch)) {
         return true;
     }
@@ -716,8 +729,8 @@ bool consume_deferred(Session& session,
                                      armsRepush,
                                      armsBannerRepush);
     if (framedSize == 0 || framedSize > response.size()) {
-        // Neither failure clears on a retry. Holding the arm starves the keepalive, and the client
-        // drops the activity session once the keepalive stops.
+        // Neither failure clears on a retry. Holding the arm starves the keepalive, and the
+        // client drops the activity session once the keepalive stops.
         session.family4RepushArmed = false;
         core::log::write(core::log::Channel::server,
                          core::log::Level::warn,

+ 2 - 8
Sunrise/src/server/bap/internal.h

@@ -304,17 +304,11 @@ enum class WorldRewardKind : std::uint8_t {
 
 /** One reward earned in world, held until a Family-4 peer can publish it. */
 struct WorldRewardRequest {
+    std::uint64_t id{};
     std::int32_t quantity{};
     std::uint16_t itemDefinitionIndex{};
     WorldRewardKind kind{};
 };
-/** Packed size of one world reward row: the queue is sized in whole rows of this width. */
-inline constexpr std::size_t kWorldRewardRequestSize = 8;
-static_assert(sizeof(WorldRewardRequest) == kWorldRewardRequestSize);
-
-/** One flyout runs for seconds, so the queue only has to cover a burst inside one activity. */
-inline constexpr std::size_t kWorldRewardQueueCapacity = 64;
-
 /** Mutable transport state owned by one BAP connection. */
 struct Session {
     std::uint64_t activityAdvertisementHostGeneration{};
@@ -523,7 +517,7 @@ void arm_acquisition_presentation_hold(Session& session) noexcept;
 [[nodiscard]] bool current_world_reward(WorldRewardRequest& request) noexcept;
 
 /** Removes the world reward returned by current_world_reward. */
-void complete_world_reward() noexcept;
+[[nodiscard]] bool complete_world_reward(std::uint64_t id) noexcept;
 
 /** Commits the queued reward with no flyout once its presentation cannot be built. */
 void settle_world_reward() noexcept;

+ 9 - 7
Sunrise/src/server/http/server_http.cpp

@@ -30,13 +30,15 @@ bool consume(const client::network::HttpRequest& request,
     const auto& signOnState = state::sign_on();
     const auto serverTime = static_cast<std::uint64_t>(core::runtime::server_clock_seconds());
     const std::uint64_t expiry = serverTime + signOnState.tokenLifetimeSeconds;
-    if (!middleware::signon::encode_success(signOnState,
-                                            state::entitlements::get(),
-                                            expiry,
-                                            serverTime,
-                                            kObservedClientAddress,
-                                            request.response,
-                                            response.size)) {
+    state::entitlements::Table ownership;
+    if (!state::entitlements::snapshot(ownership)
+        || !middleware::signon::encode_success(signOnState,
+                                               ownership,
+                                               expiry,
+                                               serverTime,
+                                               kObservedClientAddress,
+                                               request.response,
+                                               response.size)) {
         core::log::write(core::log::Channel::server,
                          core::log::Level::warn,
                          "ev=http method=post route=signon stage=encode result=fail");

+ 16 - 0
Sunrise/src/server/web_service/web_service_actions.cpp

@@ -15,6 +15,7 @@
 #include "../../middleware/web_service/messages/opcode903.h"
 #include "../../state/build_data/items/item_catalog.h"
 #include "../../state/build_data/runtime.h"
+#include "../../state/investment/store_internal.h"
 #include "../../state/runtime/runtime.h"
 #include "internal_actions.h"
 
@@ -40,6 +41,13 @@ state::SettingsUpdateDisposition mutate_settings(const middleware::web_service::
         return state::SettingsUpdateDisposition::rejected;
     }
 
+    state::investment::store::Transaction writeback;
+    if (!writeback.ready()) {
+        return state::SettingsUpdateDisposition::rejected;
+    }
+    if (request.newItems && !state::account::inventory::record_profile_seen(*request.newItems)) {
+        return state::SettingsUpdateDisposition::rejected;
+    }
     // The completion marker rides the same body; the caller's status path reports the result.
     if (request.profileSetupCompleted) {
         if (state::complete_profile_setup()) {
@@ -61,12 +69,20 @@ state::SettingsUpdateDisposition mutate_settings(const middleware::web_service::
         core::log::write(core::log::Channel::server,
                          core::log::Level::debug,
                          "ev=ws701 stage=prepare result=ready");
+        if (!writeback.commit()) {
+            clear_mutation(outcome);
+            return state::SettingsUpdateDisposition::rejected;
+        }
         return disposition;
     }
     if (disposition == state::SettingsUpdateDisposition::acceptedNoChange) {
         core::log::write(core::log::Channel::server,
                          core::log::Level::debug,
                          "ev=ws701 stage=prepare result=no_change");
+        if (!writeback.commit()) {
+            clear_mutation(outcome);
+            return state::SettingsUpdateDisposition::rejected;
+        }
         return disposition;
     }
 

+ 13 - 4
Sunrise/src/server/web_service/web_service_runtime.cpp

@@ -90,7 +90,9 @@ std::uint64_t next_family5_clock() noexcept {
 }
 
 /** Records the authoritative world state carried by the client's character write-back. */
-void note_character_writeback(const middleware::web_service::Message& message) noexcept {
+bool note_character_writeback(
+    const middleware::web_service::Message& message,
+    std::span<const state::account::inventory::PresentedItemRow> presentation) noexcept {
     namespace writeback = middleware::web_service::messages::opcode702;
     writeback::Request request{};
     const bool parsed = writeback::parse_request(message, request);
@@ -105,10 +107,14 @@ void note_character_writeback(const middleware::web_service::Message& message) n
                          core::log::Level::info,
                          {line.data(), static_cast<std::size_t>(written)});
     }
-    if (parsed) {
+    if (parsed && request.hasWorldState) {
         state::activity::membership::note_client_writeback(request.worldState
                                                            == writeback::kInWorld);
     }
+    return parsed
+           && (!request.newItems
+               || state::account::inventory::record_character_seen(*request.newItems,
+                                                                   presentation));
 }
 
 /** @return True when a purchase names the seasonal artifact vendor, which is answered here. */
@@ -294,7 +300,8 @@ bool encode_resident_dependent_refusal(std::span<const std::byte> request,
 bool consume(std::span<const std::byte> request,
              std::span<std::byte> response,
              std::size_t& written,
-             Outcome& outcome) noexcept {
+             Outcome& outcome,
+             std::span<const state::account::inventory::PresentedItemRow> presentation) noexcept {
     written = 0;
     outcome = {};
     middleware::web_service::Message message;
@@ -304,7 +311,9 @@ bool consume(std::span<const std::byte> request,
         return false;
     }
     if (message.opcode == middleware::web_service::messages::opcode702::kOpcode) {
-        note_character_writeback(message);
+        if (!note_character_writeback(message, presentation)) {
+            return false;
+        }
     }
     if (message.opcode == middleware::web_service::messages::opcode205::kOpcode) {
         state::InvestmentState investment{};

+ 7 - 4
Sunrise/src/server/web_service/web_service_runtime.h

@@ -10,6 +10,7 @@
 #include <variant>
 
 #include "../../middleware/web_service/messages/opcode206.h"
+#include "../../state/account/inventory/seen_state.h"
 #include "../../state/runtime/runtime.h"
 
 namespace sunrise::server::web_service {
@@ -161,10 +162,12 @@ void report_subclass_selection_response(const middleware::web_service::Message&
  * the action was refused or the reply could not be encoded.
  * @return False only when the envelope header does not parse.
  */
-[[nodiscard]] bool consume(std::span<const std::byte> request,
-                           std::span<std::byte> response,
-                           std::size_t& written,
-                           Outcome& outcome) noexcept;
+[[nodiscard]] bool
+consume(std::span<const std::byte> request,
+        std::span<std::byte> response,
+        std::size_t& written,
+        Outcome& outcome,
+        std::span<const state::account::inventory::PresentedItemRow> presentation = {}) noexcept;
 
 /** Encodes the normal refusal shape for a request that may publish resident references. */
 [[nodiscard]] bool encode_resident_dependent_refusal(std::span<const std::byte> request,

+ 3 - 7
Sunrise/src/state/account/account_state.h

@@ -155,11 +155,7 @@ struct CharacterState {
      * makes both rollovers due the moment the client accepts the record.
      */
     std::uint64_t signInSeconds{};
-    /**
-     * Runtime-only socket entries the player has selected at least once. Selected entries still
-     * publish active; this mask keeps a later inactive entry acquired instead of new. Unverified:
-     * defaulted all-set, assuming the Client only allows clicking an already-acquired node.
-     */
+    /** Saved acquisition mask; the all-set default preserves the existing local policy. */
     std::uint64_t acquiredSubclassAbilityMask{~std::uint64_t{0}};
     /** Authored loadout keyed only by stable semantic equipment slots. */
     account::inventory::Equipment equipment;
@@ -171,10 +167,10 @@ struct CharacterState {
     std::uint32_t nextInventorySerial{};
 };
 
-/** Account identity shared by backend object families. */
+/** Call-local account snapshot shared by backend object families. */
 struct AccountState {
     std::uint64_t primarySoid{};
-    /** Economy policy comes from configuration, never from item-specific runtime constants. */
+    /** Economy rows come from the investment store. */
     std::array<DismantleRewardPolicy, kDismantleRewardPolicyCapacity> dismantleRewards{};
     std::size_t dismantleRewardCount{};
     /** Account-wide currencies and materials, placed by bucket rather than by authored slot. */

+ 88 - 0
Sunrise/src/state/account/inventory/inventory_seen_runtime.cpp

@@ -0,0 +1,88 @@
+#include "../../../middleware/datagen/family4/loadout/loadout_resolver.h"
+#include "../../build_data/runtime.h"
+#include "../../investment/store_internal.h"
+#include "seen_state.h"
+
+namespace sunrise::state::account::inventory {
+namespace store = investment::store;
+namespace buckets = build_data::inventory::buckets;
+
+/** Profile bitmap indices follow the installed bucket ranges, not the saved list order. */
+bool record_profile_seen(const ProfileNewItems& newItems) noexcept {
+    store::Transaction transaction;
+    AccountState account;
+    if (!transaction.ready() || !store::read_account(account)) {
+        return false;
+    }
+    // Native bucket identities occupy one byte.
+    constexpr std::size_t kBucketCount = 256;
+    std::array<std::uint16_t, kBucketCount> taken{};
+    store::Statement update(
+        "UPDATE profile_items SET seen=? WHERE position=? AND definition_hash=?");
+    for (std::size_t index = 0; index < account.profileItemCount; ++index) {
+        const auto& item = account.profileItems[index];
+        build_data::items::Definition definition;
+        buckets::Descriptor bucket;
+        if (!build_data::find_item_definition_hash(item.definitionHash, definition)
+            || !build_data::find_inventory_bucket_descriptor(definition.bucketId, bucket)
+            || bucket.arraySelector != buckets::ArraySelector::profile
+            || taken[definition.bucketId] >= bucket.slotCount) {
+            return false;
+        }
+        const std::size_t row =
+            static_cast<std::size_t>(bucket.firstSlot) + taken[definition.bucketId]++;
+        if (row >= kProfileItemCapacity) {
+            return false;
+        }
+        const bool seen = seen_at(newItems, row);
+        if (seen != item.seen && !update.write(seen, index, item.definitionHash)) {
+            return false;
+        }
+    }
+    return transaction.commit();
+}
+
+/** Seen state follows the instance even when an acquisition temporarily relocates its row. */
+bool record_character_seen(const CharacterNewItems& newItems,
+                           std::span<const PresentedItemRow> presentation) noexcept {
+    store::Transaction transaction;
+    AccountState account;
+    if (!transaction.ready() || !store::read_account(account)) {
+        return false;
+    }
+    std::size_t selected = account.characterCount;
+    for (std::size_t index = 0; index < account.characterCount; ++index) {
+        if (account.characters[index].selected) {
+            selected = index;
+            break;
+        }
+    }
+    namespace loadout = middleware::datagen::family4::loadout;
+    loadout::ResolvedLoadout resolved;
+    if (selected == account.characterCount || !loadout::resolve(account, selected, resolved)) {
+        return false;
+    }
+    std::array<bool, buckets::kCharacterSlotCapacity> occupied{};
+    store::Statement update("UPDATE items SET seen=? WHERE instance_soid=?");
+    for (std::size_t index = 0; index < resolved.itemCount; ++index) {
+        const auto& item = resolved.items[index];
+        auto row = item.inventoryRow;
+        for (const auto& overlay : presentation) {
+            if (overlay.instanceSoid == item.instance.instanceSoid) {
+                row = overlay.inventoryRow;
+                break;
+            }
+        }
+        if (row >= occupied.size() || occupied[row]) {
+            return false;
+        }
+        occupied[row] = true;
+        const bool seen = seen_at(newItems, row);
+        if (seen != item.seen && !update.write(seen, item.instance.instanceSoid)) {
+            return false;
+        }
+    }
+    return transaction.commit();
+}
+
+} // namespace sunrise::state::account::inventory

+ 4 - 0
Sunrise/src/state/account/inventory/inventory_state.h

@@ -101,6 +101,8 @@ struct ProfileItem {
     std::int32_t quantity{};
     /** Rising generation copied into the native row and matched by acquisition feedback. */
     std::int32_t mutationSerial{};
+    /** The client has dismissed this item's new-item marker. */
+    bool seen{};
 };
 
 /** One authored equipment item without native table or wire-layout fields. */
@@ -128,6 +130,8 @@ struct Item {
     std::uint8_t superAbilityEntry{10};
     std::uint8_t meleeAbilityEntry{11};
     std::uint8_t classAbilityEntry{2};
+    /** The client has dismissed this item's new-item marker. */
+    bool seen{};
 };
 
 /** Ordered unequipped items placed into their native character-inventory bucket ranges. */

+ 31 - 0
Sunrise/src/state/account/inventory/seen_state.h

@@ -0,0 +1,31 @@
+#pragma once
+
+#include <array>
+#include <cstdint>
+#include <span>
+
+namespace sunrise::state::account::inventory {
+
+/** The profile and character writebacks carry 704 and 352 new-item bits. */
+using ProfileNewItems = std::array<std::uint32_t, 22>;
+using CharacterNewItems = std::array<std::uint32_t, 11>;
+
+/** A delivered acquisition can temporarily place an item outside its usual row. */
+struct PresentedItemRow {
+    std::uint64_t instanceSoid{};
+    std::uint16_t inventoryRow{};
+};
+
+[[nodiscard]] bool record_profile_seen(const ProfileNewItems& newItems) noexcept;
+[[nodiscard]] bool
+record_character_seen(const CharacterNewItems& newItems,
+                      std::span<const PresentedItemRow> presentation = {}) noexcept;
+
+/** A clear bit means the item at that published row has been seen. */
+template <std::size_t N>
+[[nodiscard]] bool seen_at(const std::array<std::uint32_t, N>& bits, std::size_t row) noexcept {
+    constexpr std::size_t kWordBits = 32;
+    return row < N * kWordBits && (bits[row / kWordBits] & (1U << (row % kWordBits))) == 0;
+}
+
+} // namespace sunrise::state::account::inventory

+ 1 - 1
Sunrise/src/state/account/settings/key_bindings.h

@@ -98,7 +98,7 @@ struct Binding {
 /** Fixed authored input table independent of the native packed account representation. */
 struct KeyBindings {
     std::array<Binding, kActionCount> values;
-    /** True only when configuration supplied every supported action. */
+    /** True after every supported action has been loaded. */
     bool configured{};
 
     bool operator==(const KeyBindings&) const = default;

+ 2 - 0
Sunrise/src/state/account/settings/settings_delta.cpp

@@ -51,6 +51,8 @@ static void apply_display(const DisplayDelta& update, Display& target) noexcept
     apply_if_present(update.brightness, target.brightness);
     apply_if_present(update.showFps, target.showFps);
     apply_if_present(update.hdrMode, target.hdrMode);
+    apply_if_present(update.verticalSyncInterval, target.verticalSyncInterval);
+    apply_if_present(update.fieldOfView, target.fieldOfView);
     apply_if_present(update.calibrationPrimary, target.calibrationPrimary);
     apply_if_present(update.calibrationAlpha, target.calibrationAlpha);
 }

+ 2 - 0
Sunrise/src/state/account/settings/settings_delta.h

@@ -47,6 +47,8 @@ struct DisplayDelta {
     std::optional<std::int8_t> brightness;
     std::optional<bool> showFps;
     std::optional<std::int8_t> hdrMode;
+    std::optional<std::uint8_t> verticalSyncInterval;
+    std::optional<std::int32_t> fieldOfView;
     std::optional<float> calibrationPrimary;
     std::optional<float> calibrationAlpha;
 };

+ 2 - 2
Sunrise/src/state/account/settings/settings_state.h

@@ -111,7 +111,7 @@ struct Social {
     bool operator==(const Social&) const = default;
 };
 
-/** Complete authored account-setting values, independent of their native record layout. */
+/** Complete saved account preferences, independent of their native record layout. */
 struct AccountSettings {
     Controls controls;
     Audio audio;
@@ -120,7 +120,7 @@ struct AccountSettings {
     Social social;
     KeyBindingSource keyBindingSource{KeyBindingSource::computer};
     bindings::KeyBindings keyBindings;
-    /** True only when a settings object was supplied by configuration. */
+    /** True after every required preference group has been loaded. */
     bool configured{};
 
     bool operator==(const AccountSettings&) const = default;

+ 4 - 1
Sunrise/src/state/activity/membership/transactions/activity_membership_authoritative_prepare.cpp

@@ -3,6 +3,7 @@
 #include "../../../runtime/storage/internal.h"
 #include "../activity_membership_query.h"
 #include "internal.h"
+#include "state/investment/store_internal.h"
 
 namespace sunrise::state::activity::membership {
 
@@ -15,11 +16,13 @@ bool prepare_authoritative(std::uint64_t sessionId,
         return false;
     }
 
+    const std::lock_guard accountGuard(investment::store::g_mutex);
+    const auto primarySoid = investment::store::account().primarySoid;
     AcquireSRWLockShared(&runtime::storage::g_stateLock);
     const auto& root = runtime::storage::g_state;
     PendingMutation prepared{};
     const SessionRecord* record =
-        transactions::prepare_base(root.activity, root.account.primarySoid, sessionId, prepared);
+        transactions::prepare_base(root.activity, primarySoid, sessionId, prepared);
     bool ready = record != nullptr;
     if (ready) {
         const MembershipState merged = transactions::merge(record->membership, update);

+ 4 - 1
Sunrise/src/state/activity/membership/transactions/activity_membership_commit.cpp

@@ -5,6 +5,7 @@
 #include "../../../runtime/storage/internal.h"
 #include "../activity_membership_query.h"
 #include "internal.h"
+#include "state/investment/store_internal.h"
 
 namespace sunrise::state::activity::membership {
 namespace {
@@ -141,6 +142,8 @@ bool commit(PendingMutation& mutation, CommittedClientState* clientState) noexce
         return false;
     }
 
+    const std::lock_guard accountGuard(investment::store::g_mutex);
+    const auto primarySoid = investment::store::account().primarySoid;
     AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
     auto& root = runtime::storage::g_state;
     ActivityState& state = root.activity;
@@ -149,7 +152,7 @@ bool commit(PendingMutation& mutation, CommittedClientState* clientState) noexce
                      && record.joined && record.joinedRevision != kInvalidRevision
                      && record.sessionId == prepared.sessionId
                      && record.recordRevision == prepared.expectedRecordRevision
-                     && root.account.primarySoid == prepared.expectedPrimarySoid;
+                     && primarySoid == prepared.expectedPrimarySoid;
     if (committed && prepared.kind == MutationKind::identity) {
         committed = commit_identity(state, record, prepared);
     } else if (committed && prepared.kind == MutationKind::authoritative) {

+ 13 - 4
Sunrise/src/state/activity/membership/transactions/activity_membership_prepare.cpp

@@ -5,6 +5,7 @@
 #include "../../../runtime/storage/internal.h"
 #include "../activity_membership_query.h"
 #include "internal.h"
+#include "state/investment/store_internal.h"
 
 namespace sunrise::state::activity::membership {
 
@@ -17,11 +18,13 @@ bool prepare_identity(std::uint64_t sessionId,
         return false;
     }
 
+    const std::lock_guard accountGuard(investment::store::g_mutex);
+    const auto primarySoid = investment::store::account().primarySoid;
     AcquireSRWLockShared(&runtime::storage::g_stateLock);
     const auto& root = runtime::storage::g_state;
     PendingMutation prepared{};
     const SessionRecord* record =
-        transactions::prepare_base(root.activity, root.account.primarySoid, sessionId, prepared);
+        transactions::prepare_base(root.activity, primarySoid, sessionId, prepared);
     bool ready = record != nullptr && transactions::valid_identity(identity, record->memberKey);
     if (ready) {
         const bool changed = !record->membership.hasIdentity
@@ -60,11 +63,13 @@ bool prepare_refresh(std::uint64_t sessionId,
         return false;
     }
 
+    const std::lock_guard accountGuard(investment::store::g_mutex);
+    const auto primarySoid = investment::store::account().primarySoid;
     AcquireSRWLockShared(&runtime::storage::g_stateLock);
     const auto& root = runtime::storage::g_state;
     PendingMutation prepared{};
     const SessionRecord* record =
-        transactions::prepare_base(root.activity, root.account.primarySoid, sessionId, prepared);
+        transactions::prepare_base(root.activity, primarySoid, sessionId, prepared);
     if (record != nullptr) {
         if (record->membership.hasIdentity) {
             prepared.snapshot = transactions::make_snapshot(
@@ -91,11 +96,13 @@ bool prepare_republish(std::uint64_t sessionId, PendingMutation& mutation) noexc
         return false;
     }
 
+    const std::lock_guard accountGuard(investment::store::g_mutex);
+    const auto primarySoid = investment::store::account().primarySoid;
     AcquireSRWLockShared(&runtime::storage::g_stateLock);
     const auto& root = runtime::storage::g_state;
     PendingMutation prepared{};
     const SessionRecord* record =
-        transactions::prepare_base(root.activity, root.account.primarySoid, sessionId, prepared);
+        transactions::prepare_base(root.activity, primarySoid, sessionId, prepared);
     const bool ready = record != nullptr && record->membership.hasIdentity
                        && root.activity.stateRevision != activity::kMaximumRevision
                        && record->membership.revision != kMaximumMembershipRevision;
@@ -123,11 +130,13 @@ bool prepare_acknowledgement(std::uint64_t sessionId,
         return false;
     }
 
+    const std::lock_guard accountGuard(investment::store::g_mutex);
+    const auto primarySoid = investment::store::account().primarySoid;
     AcquireSRWLockShared(&runtime::storage::g_stateLock);
     const auto& root = runtime::storage::g_state;
     PendingMutation prepared{};
     const SessionRecord* record =
-        transactions::prepare_base(root.activity, root.account.primarySoid, sessionId, prepared);
+        transactions::prepare_base(root.activity, primarySoid, sessionId, prepared);
     bool ready = record != nullptr;
     if (ready) {
         const bool changed = record->membership.hasIdentity

+ 0 - 48
Sunrise/src/state/entitlements/entitlement_defaults.cpp

@@ -1,48 +0,0 @@
-#include <algorithm>
-#include <array>
-
-#include "validation.h"
-
-namespace sunrise::state::entitlements {
-namespace {
-
-/** One bundled definition in handle order. */
-struct Authored final {
-    std::string_view name;
-    Ownership ownership;
-};
-
-/**
- * The bundled ownership policy, in handle order. The first 3 are local: the base sku, the paid
- * tier, and the restriction that must be defined but never owned. The rest are the installed DLC,
- * named by public application id.
- */
-constexpr std::array kAuthored{
-    Authored{"1085660", Ownership::handle},         Authored{"STEAM_PAID_TIER", Ownership::handle},
-    Authored{"STEAM_UGC_BLOCKED", Ownership::none}, Authored{"1090090", Ownership::application},
-    Authored{"1090091", Ownership::application},    Authored{"1090092", Ownership::application},
-    Authored{"1090093", Ownership::application},    Authored{"1090094", Ownership::application},
-    Authored{"1090095", Ownership::application},    Authored{"1090096", Ownership::application},
-    Authored{"1090150", Ownership::application},    Authored{"1090151", Ownership::application},
-    Authored{"1090152", Ownership::application},    Authored{"1090170", Ownership::application},
-    Authored{"1090171", Ownership::application},    Authored{"1090200", Ownership::application},
-    Authored{"1090201", Ownership::application},    Authored{"1090202", Ownership::application},
-    Authored{"1330040", Ownership::application},
-};
-static_assert(kAuthored.size() <= kCapacity);
-
-} // namespace
-
-/** Supplies the ownership policy used when settings define none. */
-Table authored() noexcept {
-    Table table{};
-    for (const Authored& source : kAuthored) {
-        Entitlement& target = table.entries[table.count++];
-        std::copy(source.name.begin(), source.name.end(), target.name.begin());
-        target.nameLength = static_cast<std::uint8_t>(source.name.size());
-        target.ownership = source.ownership;
-    }
-    return table;
-}
-
-} // namespace sunrise::state::entitlements

+ 9 - 20
Sunrise/src/state/entitlements/entitlement_runtime.cpp

@@ -1,35 +1,24 @@
 #include "entitlement_runtime.h"
 
+#include "../investment/store.h"
 #include "validation.h"
 
 namespace sunrise::state::entitlements {
-namespace {
 
-/** @return Process-wide policy storage, seeded with the bundled policy on first use. */
-[[nodiscard]] Table& storage() noexcept {
-    static Table table = authored();
+/** @return A call-local ownership table from the saved account. */
+Table get() noexcept {
+    Table table;
+    (void)snapshot(table);
     return table;
 }
 
-} // namespace
-
-/** Publishes the immutable ownership policy for this process. */
-bool publish(const Table& table) noexcept {
-    if (!valid(table)) {
+/** An unavailable ownership table must not become a successful partial response. */
+bool snapshot(Table& output) noexcept {
+    if (!investment::store::read_entitlements(output) || !valid(output)) {
+        output = {};
         return false;
     }
-    storage() = table;
     return true;
 }
 
-/** @return The active ownership policy, or the bundled policy when none was published. */
-const Table& get() noexcept {
-    return storage();
-}
-
-/** Restores the bundled ownership policy. */
-void clear() noexcept {
-    storage() = authored();
-}
-
 } // namespace sunrise::state::entitlements

+ 3 - 12
Sunrise/src/state/entitlements/entitlement_runtime.h

@@ -4,17 +4,8 @@
 
 namespace sunrise::state::entitlements {
 
-/**
- * Publishes the immutable ownership policy for this process.
- * @param table Complete authored policy.
- * @return False when the table is invalid. The old policy is kept.
- */
-[[nodiscard]] bool publish(const Table& table) noexcept;
-
-/** @return The active ownership policy, or the bundled policy when none was published. */
-[[nodiscard]] const Table& get() noexcept;
-
-/** Restores the bundled ownership policy. */
-void clear() noexcept;
+/** @return A call-local ownership table from the saved account. */
+[[nodiscard]] Table get() noexcept;
+[[nodiscard]] bool snapshot(Table& output) noexcept;
 
 } // namespace sunrise::state::entitlements

+ 0 - 3
Sunrise/src/state/entitlements/validation.h

@@ -30,7 +30,4 @@ namespace sunrise::state::entitlements {
 [[nodiscard]] bool
 owned_identifier(const Table& table, std::size_t index, std::uint32_t& identifier) noexcept;
 
-/** @return The bundled ownership policy used when settings supply none. */
-[[nodiscard]] Table authored() noexcept;
-
 } // namespace sunrise::state::entitlements

+ 162 - 0
Sunrise/src/state/investment/investment_account_store.cpp

@@ -0,0 +1,162 @@
+#include "store_internal.h"
+
+namespace sunrise::state::investment::store {
+namespace {
+
+/** Reads characters in stable slot order and overlays only process-local session fields. */
+bool read_characters(AccountState& output) noexcept {
+    Statement rows("SELECT * FROM characters ORDER BY slot");
+    int result = rows.step();
+    while (result == SQLITE_ROW) {
+        std::size_t slot = 0;
+        CharacterState character;
+        if (!rows.columns(slot,
+                          character.soid,
+                          character.race,
+                          character.gender,
+                          character.characterClass,
+                          character.level,
+                          character.previewAvailable,
+                          character.appearanceValue,
+                          character.lastOrbitedDestination,
+                          character.contentBypass,
+                          character.equippedTitleRecordIndex,
+                          character.acquiredSubclassAbilityMask,
+                          character.nextInventorySerial)
+            || slot != output.characterCount || slot >= output.characters.size()) {
+            return false;
+        }
+        character.selected = g_session.selected[slot];
+        character.currentActivityIndex = g_session.activities[slot];
+        character.signInSeconds = g_session.signInSeconds;
+        output.characters[output.characterCount++] = character;
+        result = rows.step();
+    }
+    return result == SQLITE_DONE;
+}
+
+/** Economy rows keep their authored order and bounded capacity. */
+bool read_rewards(AccountState& output) noexcept {
+    Statement rows("SELECT * FROM dismantle_rewards ORDER BY position");
+    int result = rows.step();
+    while (result == SQLITE_ROW) {
+        std::size_t position = 0;
+        DismantleRewardPolicy reward;
+        if (!rows.columns(position,
+                          reward.definitionHash,
+                          reward.quantity,
+                          reward.tierMask,
+                          reward.classMask,
+                          reward.masterwork)
+            || position != output.dismantleRewardCount
+            || position >= output.dismantleRewards.size()) {
+            return false;
+        }
+        output.dismantleRewards[output.dismantleRewardCount++] = reward;
+        result = rows.step();
+    }
+    return result == SQLITE_DONE;
+}
+
+/** Characters are saved before their items to satisfy foreign keys. */
+bool write_characters(const AccountState& value) noexcept {
+    Statement rows("INSERT INTO characters VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)");
+    for (std::size_t slot = 0; slot < value.characterCount; ++slot) {
+        const auto& character = value.characters[slot];
+        if (!rows.write(slot,
+                        character.soid,
+                        character.race,
+                        character.gender,
+                        character.characterClass,
+                        character.level,
+                        character.previewAvailable,
+                        character.appearanceValue,
+                        character.lastOrbitedDestination,
+                        character.contentBypass,
+                        character.equippedTitleRecordIndex,
+                        character.acquiredSubclassAbilityMask,
+                        character.nextInventorySerial)) {
+            return false;
+        }
+    }
+    Statement rewards("INSERT INTO dismantle_rewards VALUES (?,?,?,?,?,?)");
+    for (std::size_t index = 0; index < value.dismantleRewardCount; ++index) {
+        const auto& reward = value.dismantleRewards[index];
+        if (!rewards.write(index,
+                           reward.definitionHash,
+                           reward.quantity,
+                           reward.tierMask,
+                           reward.classMask,
+                           reward.masterwork)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+} // namespace
+
+/** A read returns one complete account or an empty output on failure. */
+bool read_account(AccountState& output) noexcept {
+    Transaction transaction;
+    if (!transaction.ready()) {
+        output = {};
+        return false;
+    }
+    output = {};
+    Statement row("SELECT soid,profile_setup_completed FROM account WHERE id=1");
+    if (row.step() != SQLITE_ROW || !row.columns(output.primarySoid, output.profileSetupCompleted)
+        || row.step() != SQLITE_DONE || !read_characters(output) || !read_inventory(output)
+        || !read_rewards(output)) {
+        output = {};
+        return false;
+    }
+    if (!read_settings(output.settings)) {
+        output = {};
+        return false;
+    }
+    if (!account::valid_authored(output)) {
+        output = {};
+        return false;
+    }
+    return transaction.commit();
+}
+
+/** @return A call-local snapshot; a failed database read yields an empty account. */
+AccountState account() noexcept {
+    AccountState output;
+    (void)read_account(output);
+    return output;
+}
+
+/** The session overlay changes only after every durable account row commits. */
+bool write_account(const AccountState& value) noexcept {
+    if (!account::valid_authored(value)) {
+        return false;
+    }
+    Transaction transaction;
+    if (!transaction.ready()
+        || !execute("DELETE FROM items; DELETE FROM character_stacks; DELETE FROM characters;"
+                    "DELETE FROM profile_items; DELETE FROM dismantle_rewards;")) {
+        return false;
+    }
+    Statement accountRow("INSERT OR REPLACE INTO account VALUES (1,?,?)");
+    if (!accountRow.write(value.primarySoid, value.profileSetupCompleted)
+        || !write_characters(value) || !write_inventory(value) || !write_settings(value.settings)
+        || !transaction.commit()) {
+        return false;
+    }
+    for (std::size_t index = 0; index < value.characters.size(); ++index) {
+        g_session.selected[index] = value.characters[index].selected;
+        g_session.activities[index] = value.characters[index].currentActivityIndex;
+    }
+    return true;
+}
+
+/** A sign-in timestamp belongs only to the current connection lifetime. */
+void set_sign_in_time(std::uint64_t seconds) noexcept {
+    const std::lock_guard lock(g_mutex);
+    g_session.signInSeconds = seconds;
+}
+
+} // namespace sunrise::state::investment::store

+ 155 - 0
Sunrise/src/state/investment/investment_database.cpp

@@ -0,0 +1,155 @@
+#include "store_internal.h"
+
+namespace sunrise::state::investment::store {
+
+sqlite3* g_database{};
+std::recursive_mutex g_mutex;
+Session g_session;
+std::uint64_t g_failureSerial{};
+
+/** SQLite requires this sentinel to copy text borrowed from a caller. */
+sqlite3_destructor_type copy_text() noexcept {
+    return SQLITE_TRANSIENT; // NOLINT(performance-no-int-to-ptr)
+}
+
+/** SQL failures remain failures; no in-memory save replaces a failed disk write. */
+bool execute(const char* sql) noexcept {
+    const bool ready = g_database != nullptr
+                       && sqlite3_exec(g_database, sql, nullptr, nullptr, nullptr) == SQLITE_OK;
+    if (!ready) {
+        ++g_failureSerial;
+    }
+    return ready;
+}
+
+/** Nested saves belong to the outer transaction until it commits. */
+Transaction::Transaction() noexcept
+    : lock_(g_mutex), active_(execute("SAVEPOINT investment_write")), before_(g_session),
+      failureSerial_(g_failureSerial) {}
+
+/** A refused transaction leaves no partial rows. */
+Transaction::~Transaction() {
+    if (active_) {
+        (void)execute("ROLLBACK TO investment_write");
+        (void)execute("RELEASE investment_write");
+        g_session = before_;
+    }
+}
+
+/** @return True only after SQLite has committed every row. */
+bool Transaction::commit() noexcept {
+    if (!active_ || failureSerial_ != g_failureSerial || !execute("RELEASE investment_write")) {
+        return false;
+    }
+    active_ = false;
+    return true;
+}
+
+/** The caller holds the database lock until this statement is destroyed. */
+Statement::Statement(const char* sql) noexcept {
+    if (g_database != nullptr
+        && sqlite3_prepare_v2(g_database, sql, -1, &statement_, nullptr) != SQLITE_OK) {
+        sqlite3_finalize(statement_);
+        statement_ = nullptr;
+        ++g_failureSerial;
+    }
+}
+
+Statement::~Statement() {
+    sqlite3_finalize(statement_);
+}
+int Statement::step() noexcept {
+    const int result = statement_ != nullptr ? sqlite3_step(statement_) : SQLITE_ERROR;
+    if (result != SQLITE_ROW && result != SQLITE_DONE) {
+        ++g_failureSerial;
+    }
+    return result;
+}
+
+/** @return Borrowed text valid until the statement advances. */
+bool Statement::text(int column, std::string_view& value) const noexcept {
+    if (statement_ == nullptr || sqlite3_column_type(statement_, column) != SQLITE_TEXT) {
+        return false;
+    }
+    const auto* bytes = reinterpret_cast<const char*>(sqlite3_column_text(statement_, column));
+    if (bytes == nullptr) {
+        return false;
+    }
+    value = {bytes, static_cast<std::size_t>(sqlite3_column_bytes(statement_, column))};
+    return true;
+}
+
+/** New databases receive schema and defaults in one durable transaction. */
+bool open(std::string_view path,
+          std::string_view schema,
+          std::string_view defaults,
+          std::string_view settingsSchema,
+          std::string_view settingsDefaults) noexcept {
+    const std::lock_guard lock(g_mutex);
+    if (g_database != nullptr) {
+        return false;
+    }
+    const std::string filename(path);
+    if (sqlite3_open_v2(filename.c_str(),
+                        &g_database,
+                        SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX,
+                        nullptr)
+        != SQLITE_OK) {
+        shutdown();
+        return false;
+    }
+    // One short busy wait permits a local database editor to finish its transaction.
+    constexpr int kBusyMilliseconds = 5000;
+    sqlite3_busy_timeout(g_database, kBusyMilliseconds);
+    bool ready = execute("PRAGMA foreign_keys=ON; PRAGMA synchronous=FULL;");
+    int version = -1;
+    {
+        Statement query("PRAGMA user_version");
+        ready = ready && query.step() == SQLITE_ROW && query.column(0, version);
+    }
+    const std::string preferenceSchema(settingsSchema);
+    const std::string preferenceDefaults(settingsDefaults);
+    if (ready && version == 0) {
+        Transaction transaction;
+        const std::string schemaText(schema);
+        const std::string defaultText(defaults);
+        ready = transaction.ready() && !schema.empty() && !defaults.empty()
+                && execute(schemaText.c_str()) && execute(defaultText.c_str())
+                && !settingsSchema.empty() && !settingsDefaults.empty()
+                && execute(preferenceSchema.c_str()) && execute(preferenceDefaults.c_str())
+                && transaction.commit();
+    } else if (ready) {
+        // Version 2 adds account preferences and per-item seen state.
+        constexpr int kSchemaVersion = 2;
+        constexpr int kApplicationId = 1397902921;
+        int application = 0;
+        Statement query("PRAGMA application_id");
+        ready = (version == 1 || version == kSchemaVersion) && query.step() == SQLITE_ROW
+                && query.column(0, application) && application == kApplicationId;
+    }
+    if (ready && version == 1) {
+        Transaction transaction;
+        ready =
+            transaction.ready() && !settingsSchema.empty() && !settingsDefaults.empty()
+            && execute(
+                "ALTER TABLE items ADD COLUMN seen INTEGER NOT NULL DEFAULT 0 CHECK(seen IN(0,1));"
+                "ALTER TABLE profile_items ADD COLUMN seen INTEGER NOT NULL DEFAULT 1 CHECK(seen "
+                "IN(0,1));")
+            && execute(preferenceSchema.c_str()) && execute(preferenceDefaults.c_str())
+            && execute("PRAGMA user_version=2") && transaction.commit();
+    }
+    if (!ready) {
+        shutdown();
+    }
+    return ready;
+}
+
+/** Saves are synchronous, so shutdown only closes the handle and discards session fields. */
+void shutdown() noexcept {
+    const std::lock_guard lock(g_mutex);
+    sqlite3_close_v2(g_database);
+    g_database = nullptr;
+    g_session = {};
+}
+
+} // namespace sunrise::state::investment::store

+ 219 - 0
Sunrise/src/state/investment/investment_inventory_store.cpp

@@ -0,0 +1,219 @@
+#include "store_internal.h"
+
+namespace sunrise::state::investment::store {
+namespace {
+
+/** Location zero names equipment; location one names the unequipped ordered list. */
+constexpr int kEquipmentLocation = 0;
+constexpr int kInventoryLocation = 1;
+
+/** Reads each item into its bounded owner and location. */
+bool read_items(AccountState& output) noexcept {
+    Statement rows("SELECT * FROM items ORDER BY character_slot,location,position");
+    int result = rows.step();
+    while (result == SQLITE_ROW) {
+        std::size_t owner = 0;
+        int location = 0;
+        std::size_t position = 0;
+        account::inventory::Item item;
+        if (!rows.columns(owner,
+                          location,
+                          position,
+                          item.instanceSoid,
+                          item.definitionHash,
+                          item.level,
+                          item.quantity,
+                          item.mutationSerial,
+                          item.flags,
+                          item.sockets.policy,
+                          item.sockets.plugCount,
+                          item.movementAbilityEntry,
+                          item.grenadeAbilityEntry,
+                          item.superAbilityEntry,
+                          item.meleeAbilityEntry,
+                          item.classAbilityEntry,
+                          item.seen)
+            || owner >= output.characterCount) {
+            return false;
+        }
+        auto& character = output.characters[owner];
+        if (location == kEquipmentLocation && position < character.equipment.slots.size()) {
+            character.equipment.slots[position] = item;
+        } else if (location == kInventoryLocation && position == character.inventory.count
+                   && position < character.inventory.values.size()) {
+            character.inventory.values[character.inventory.count++] = item;
+        } else {
+            return false;
+        }
+        result = rows.step();
+    }
+    return result == SQLITE_DONE;
+}
+
+/** Socket joins keep empty lanes distinct from the native-default socket policy. */
+bool read_sockets(AccountState& output) noexcept {
+    Statement rows("SELECT i.character_slot,i.location,i.position,s.lane,s.plug_hash "
+                   "FROM sockets s JOIN items i USING(instance_soid)");
+    int result = rows.step();
+    while (result == SQLITE_ROW) {
+        std::size_t owner = 0;
+        int location = 0;
+        std::size_t position = 0;
+        std::size_t lane = 0;
+        std::uint32_t hash = 0;
+        if (!rows.columns(owner, location, position, lane, hash)
+            || owner >= output.characterCount) {
+            return false;
+        }
+        auto& character = output.characters[owner];
+        account::inventory::Item* item = nullptr;
+        if (location == kEquipmentLocation && position < character.equipment.slots.size()
+            && character.equipment.slots[position]) {
+            item = &*character.equipment.slots[position];
+        } else if (location == kInventoryLocation && position < character.inventory.count) {
+            item = &character.inventory.values[position];
+        }
+        if (item == nullptr || lane >= item->sockets.plugCount
+            || lane >= item->sockets.plugs.size()) {
+            return false;
+        }
+        item->sockets.plugs[lane] = hash;
+        result = rows.step();
+    }
+    return result == SQLITE_DONE;
+}
+
+/** Profile rows preserve stable instance identities and mutation serials. */
+bool read_profile(AccountState& output) noexcept {
+    Statement rows("SELECT * FROM profile_items ORDER BY position");
+    int result = rows.step();
+    while (result == SQLITE_ROW) {
+        std::size_t position = 0;
+        account::inventory::ProfileItem item;
+        if (!rows.columns(position,
+                          item.instanceSoid,
+                          item.definitionHash,
+                          item.quantity,
+                          item.mutationSerial,
+                          item.seen)
+            || position != output.profileItemCount || position >= output.profileItems.size()) {
+            return false;
+        }
+        output.profileItems[output.profileItemCount++] = item;
+        result = rows.step();
+    }
+    return result == SQLITE_DONE;
+}
+
+/** Character materials use their own ordered list, including runtime grants. */
+bool read_stacks(AccountState& output) noexcept {
+    Statement rows("SELECT * FROM character_stacks ORDER BY character_slot,position");
+    int result = rows.step();
+    while (result == SQLITE_ROW) {
+        std::size_t owner = 0;
+        std::size_t position = 0;
+        account::inventory::CharacterStack item;
+        if (!rows.columns(owner, position, item.definitionHash, item.quantity, item.mutationSerial)
+            || owner >= output.characterCount) {
+            return false;
+        }
+        auto& stacks = output.characters[owner].stacks;
+        if (position != stacks.count || position >= stacks.values.size()) {
+            return false;
+        }
+        stacks.values[stacks.count++] = item;
+        result = rows.step();
+    }
+    return result == SQLITE_DONE;
+}
+
+/** All socket and ability fields belong to the item instance being saved. */
+bool write_item(Statement& items,
+                Statement& sockets,
+                std::size_t owner,
+                int location,
+                std::size_t position,
+                const account::inventory::Item& item) noexcept {
+    if (!items.write(owner,
+                     location,
+                     position,
+                     item.instanceSoid,
+                     item.definitionHash,
+                     item.level,
+                     item.quantity,
+                     item.mutationSerial,
+                     item.flags,
+                     item.sockets.policy,
+                     item.sockets.plugCount,
+                     item.movementAbilityEntry,
+                     item.grenadeAbilityEntry,
+                     item.superAbilityEntry,
+                     item.meleeAbilityEntry,
+                     item.classAbilityEntry,
+                     item.seen)) {
+        return false;
+    }
+    for (std::size_t lane = 0; lane < item.sockets.plugCount; ++lane) {
+        if (item.sockets.plugs[lane]
+            && !sockets.write(item.instanceSoid, lane, *item.sockets.plugs[lane])) {
+            return false;
+        }
+    }
+    return true;
+}
+
+} // namespace
+
+/** The caller owns the database transaction and the empty account output. */
+bool read_inventory(AccountState& output) noexcept {
+    return read_items(output) && read_sockets(output) && read_profile(output)
+           && read_stacks(output);
+}
+
+/** Inventory rows are replaced inside the account's transaction. */
+bool write_inventory(const AccountState& value) noexcept {
+    Statement items("INSERT INTO items VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
+    Statement sockets("INSERT INTO sockets VALUES (?,?,?)");
+    Statement stacks("INSERT INTO character_stacks VALUES (?,?,?,?,?)");
+    for (std::size_t owner = 0; owner < value.characterCount; ++owner) {
+        const auto& character = value.characters[owner];
+        for (std::size_t position = 0; position < character.equipment.slots.size(); ++position) {
+            const auto& item = character.equipment.slots[position];
+            if (item && !write_item(items, sockets, owner, kEquipmentLocation, position, *item)) {
+                return false;
+            }
+        }
+        for (std::size_t position = 0; position < character.inventory.count; ++position) {
+            if (!write_item(items,
+                            sockets,
+                            owner,
+                            kInventoryLocation,
+                            position,
+                            character.inventory.values[position])) {
+                return false;
+            }
+        }
+        for (std::size_t position = 0; position < character.stacks.count; ++position) {
+            const auto& item = character.stacks.values[position];
+            if (!stacks.write(
+                    owner, position, item.definitionHash, item.quantity, item.mutationSerial)) {
+                return false;
+            }
+        }
+    }
+    Statement profile("INSERT INTO profile_items VALUES (?,?,?,?,?,?)");
+    for (std::size_t position = 0; position < value.profileItemCount; ++position) {
+        const auto& item = value.profileItems[position];
+        if (!profile.write(position,
+                           item.instanceSoid,
+                           item.definitionHash,
+                           item.quantity,
+                           item.mutationSerial,
+                           item.seen)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+} // namespace sunrise::state::investment::store

+ 49 - 0
Sunrise/src/state/investment/investment_reward_store.cpp

@@ -0,0 +1,49 @@
+#include "store_internal.h"
+
+namespace sunrise::state::investment::store {
+namespace {
+
+/** A reward is owned by the character that was selected when it was earned. */
+int selected() noexcept {
+    for (std::size_t slot = 0; slot < g_session.selected.size(); ++slot) {
+        if (g_session.selected[slot]) {
+            return static_cast<int>(slot);
+        }
+    }
+    return -1;
+}
+
+} // namespace
+
+/** Reward ownership and quantities are committed before presentation is attempted. */
+bool enqueue_reward(std::uint32_t definitionHash,
+                    std::int32_t quantity,
+                    std::uint8_t kind) noexcept {
+    const std::lock_guard lock(g_mutex);
+    const int owner = selected();
+    if (owner < 0) {
+        return false;
+    }
+    Statement row("INSERT INTO pending_rewards(character_slot,kind,definition_hash,quantity) "
+                  "VALUES (?,?,?,?)");
+    return row.write(owner, kind, definitionHash, quantity);
+}
+
+/** Other characters' earned rewards remain queued when the player changes character. */
+bool next_reward(PendingReward& output) noexcept {
+    const std::lock_guard lock(g_mutex);
+    output = {};
+    Statement row("SELECT id,definition_hash,quantity,kind FROM pending_rewards "
+                  "WHERE character_slot=? ORDER BY id LIMIT 1");
+    return row.parameters(selected()) && row.step() == SQLITE_ROW
+           && row.columns(output.id, output.definitionHash, output.quantity, output.kind);
+}
+
+/** The inventory grant and deletion of this reward must share one outer transaction. */
+bool complete_reward(std::uint64_t id) noexcept {
+    const std::lock_guard lock(g_mutex);
+    Statement row("DELETE FROM pending_rewards WHERE id=? AND character_slot=?");
+    return row.write(id, selected()) && sqlite3_changes(g_database) == 1;
+}
+
+} // namespace sunrise::state::investment::store

+ 248 - 0
Sunrise/src/state/investment/investment_settings_store.cpp

@@ -0,0 +1,248 @@
+#include "store_internal.h"
+
+namespace sunrise::state::investment::store {
+namespace {
+
+/** Restores the complete action table, including unbound input halves. */
+bool read_bindings(account::settings::AccountSettings& output) noexcept {
+    Statement rows(
+        "SELECT action,primary_code,secondary_code FROM account_key_bindings ORDER BY action");
+    std::size_t count = 0;
+    int result = rows.step();
+    while (result == SQLITE_ROW) {
+        std::size_t index = 0;
+        std::int32_t primary = -1;
+        std::int32_t secondary = -1;
+        if (!rows.columns(index, primary, secondary) || index != count
+            || index >= output.keyBindings.values.size() || primary < -1 || primary > 65535
+            || secondary < -1 || secondary > 65535) {
+            return false;
+        }
+        auto& binding = output.keyBindings.values[count++];
+        if (primary >= 0) {
+            binding.primary = static_cast<std::uint16_t>(primary);
+        }
+        if (secondary >= 0) {
+            binding.secondary = static_cast<std::uint16_t>(secondary);
+        }
+        result = rows.step();
+    }
+    output.keyBindings.configured =
+        result == SQLITE_DONE && count == output.keyBindings.values.size();
+    return output.keyBindings.configured;
+}
+
+} // namespace
+
+/** Reads every account preference from one database snapshot. */
+bool read_settings(account::settings::AccountSettings& output) noexcept {
+    Transaction transaction;
+    output = {};
+    if (!transaction.ready()) {
+        return false;
+    }
+    Statement root("SELECT key_binding_source FROM account_preferences WHERE id=1");
+    if (root.step() != SQLITE_ROW || !root.column(0, output.keyBindingSource)) {
+        return false;
+    }
+    Statement controls(
+        "SELECT "
+        "button_layout,movement_mode,controller_look_sensitivity,controller_invert_vertical,"
+        "controller_auto_look_centering,controller_vibration,controller_swap_shoulders,controller_"
+        "invert_horizontal,mouse_look_sensitivity,mouse_invert_vertical,mouse_invert_horizontal,"
+        "unidentified_toggle,mouse_aim_smoothing,ads_sensitivity_modifier,double_press_delay FROM "
+        "account_controls WHERE id=1");
+    if (controls.step() != SQLITE_ROW
+        || !controls.columns(output.controls.buttonLayout,
+                             output.controls.movementMode,
+                             output.controls.controllerLookSensitivity,
+                             output.controls.controllerInvertVertical,
+                             output.controls.controllerAutoLookCentering,
+                             output.controls.controllerVibration,
+                             output.controls.controllerSwapShoulders,
+                             output.controls.controllerInvertHorizontal,
+                             output.controls.mouseLookSensitivity,
+                             output.controls.mouseInvertVertical,
+                             output.controls.mouseInvertHorizontal,
+                             output.controls.unidentifiedToggle,
+                             output.controls.mouseAimSmoothing,
+                             output.controls.adsSensitivityModifier,
+                             output.controls.doublePressDelay)) {
+        return false;
+    }
+    Statement audio("SELECT "
+                    "voice_output_mode,team_voice_channel,reserved_mode,migration_version,chat_"
+                    "volume,mute_when_unfocused,sound_effects_volume,dialogue_volume,music_volume "
+                    "FROM account_audio WHERE id=1");
+    if (audio.step() != SQLITE_ROW
+        || !audio.columns(output.audio.voiceOutputMode,
+                          output.audio.teamVoiceChannel,
+                          output.audio.reservedMode,
+                          output.audio.migrationVersion,
+                          output.audio.chatVolume,
+                          output.audio.muteWhenUnfocused,
+                          output.audio.soundEffectsVolume,
+                          output.audio.dialogueVolume,
+                          output.audio.musicVolume)) {
+        return false;
+    }
+    Statement display("SELECT "
+                      "brightness,show_fps,hdr_mode,vertical_sync_interval,field_of_view,"
+                      "calibration_primary,calibration_alpha FROM account_display WHERE id=1");
+    if (display.step() != SQLITE_ROW
+        || !display.columns(output.display.brightness,
+                            output.display.showFps,
+                            output.display.hdrMode,
+                            output.display.verticalSyncInterval,
+                            output.display.fieldOfView,
+                            output.display.calibrationPrimary,
+                            output.display.calibrationAlpha)) {
+        return false;
+    }
+    Statement interface(
+        "SELECT "
+        "subtitles_mode,colorblind_mode,helmet_mode,hud_opacity,display_hints,background_opacity,"
+        "reticle_location,reticle_color,text_size,text_color,text_background_style,text_background_"
+        "opacity,reserved_text_mode,subtitle_options_entry FROM account_interface WHERE id=1");
+    if (interface.step() != SQLITE_ROW
+        || !interface.columns(output.interface.subtitlesMode,
+                              output.interface.colorblindMode,
+                              output.interface.helmetMode,
+                              output.interface.hudOpacity,
+                              output.interface.displayHints,
+                              output.interface.backgroundOpacity,
+                              output.interface.reticleLocation,
+                              output.interface.reticleColor,
+                              output.interface.textSize,
+                              output.interface.textColor,
+                              output.interface.textBackgroundStyle,
+                              output.interface.textBackgroundOpacity,
+                              output.interface.reservedTextMode,
+                              output.interface.subtitleOptionsEntry)) {
+        return false;
+    }
+    Statement social(
+        "SELECT "
+        "prefer_good_connection,text_chat_mode,show_real_names,clan_invite_notifications,profanity_"
+        "filter,voice_chat_enabled,whisper_chat_mode,team_chat_join_mode,local_chat_join_mode,clan_"
+        "chat_join_mode,chat_auto_hide_mode FROM account_social WHERE id=1");
+    if (social.step() != SQLITE_ROW
+        || !social.columns(output.social.preferGoodConnection,
+                           output.social.textChatMode,
+                           output.social.showRealNames,
+                           output.social.clanInviteNotifications,
+                           output.social.profanityFilter,
+                           output.social.voiceChatEnabled,
+                           output.social.whisperChatMode,
+                           output.social.teamChatJoinMode,
+                           output.social.localChatJoinMode,
+                           output.social.clanChatJoinMode,
+                           output.social.chatAutoHideMode)) {
+        return false;
+    }
+    output.configured = true;
+    return read_bindings(output) && account::settings::valid(output) && transaction.commit();
+}
+
+/** Preference and binding changes commit together. */
+bool write_settings(const account::settings::AccountSettings& value) noexcept {
+    if (!account::settings::valid(value)) {
+        return false;
+    }
+    Transaction transaction;
+    if (!transaction.ready()) {
+        return false;
+    }
+    Statement root("INSERT OR REPLACE INTO account_preferences VALUES(1,?)");
+    if (!root.write(value.keyBindingSource)) {
+        return false;
+    }
+    Statement controls(
+        "INSERT OR REPLACE INTO account_controls VALUES(1,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
+    if (!controls.write(value.controls.buttonLayout,
+                        value.controls.movementMode,
+                        value.controls.controllerLookSensitivity,
+                        value.controls.controllerInvertVertical,
+                        value.controls.controllerAutoLookCentering,
+                        value.controls.controllerVibration,
+                        value.controls.controllerSwapShoulders,
+                        value.controls.controllerInvertHorizontal,
+                        value.controls.mouseLookSensitivity,
+                        value.controls.mouseInvertVertical,
+                        value.controls.mouseInvertHorizontal,
+                        value.controls.unidentifiedToggle,
+                        value.controls.mouseAimSmoothing,
+                        value.controls.adsSensitivityModifier,
+                        value.controls.doublePressDelay)) {
+        return false;
+    }
+    Statement audio("INSERT OR REPLACE INTO account_audio VALUES(1,?,?,?,?,?,?,?,?,?)");
+    if (!audio.write(value.audio.voiceOutputMode,
+                     value.audio.teamVoiceChannel,
+                     value.audio.reservedMode,
+                     value.audio.migrationVersion,
+                     value.audio.chatVolume,
+                     value.audio.muteWhenUnfocused,
+                     value.audio.soundEffectsVolume,
+                     value.audio.dialogueVolume,
+                     value.audio.musicVolume)) {
+        return false;
+    }
+    Statement display("INSERT OR REPLACE INTO account_display VALUES(1,?,?,?,?,?,?,?)");
+    if (!display.write(value.display.brightness,
+                       value.display.showFps,
+                       value.display.hdrMode,
+                       value.display.verticalSyncInterval,
+                       value.display.fieldOfView,
+                       value.display.calibrationPrimary,
+                       value.display.calibrationAlpha)) {
+        return false;
+    }
+    Statement interface(
+        "INSERT OR REPLACE INTO account_interface VALUES(1,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
+    if (!interface.write(value.interface.subtitlesMode,
+                         value.interface.colorblindMode,
+                         value.interface.helmetMode,
+                         value.interface.hudOpacity,
+                         value.interface.displayHints,
+                         value.interface.backgroundOpacity,
+                         value.interface.reticleLocation,
+                         value.interface.reticleColor,
+                         value.interface.textSize,
+                         value.interface.textColor,
+                         value.interface.textBackgroundStyle,
+                         value.interface.textBackgroundOpacity,
+                         value.interface.reservedTextMode,
+                         value.interface.subtitleOptionsEntry)) {
+        return false;
+    }
+    Statement social("INSERT OR REPLACE INTO account_social VALUES(1,?,?,?,?,?,?,?,?,?,?,?)");
+    if (!social.write(value.social.preferGoodConnection,
+                      value.social.textChatMode,
+                      value.social.showRealNames,
+                      value.social.clanInviteNotifications,
+                      value.social.profanityFilter,
+                      value.social.voiceChatEnabled,
+                      value.social.whisperChatMode,
+                      value.social.teamChatJoinMode,
+                      value.social.localChatJoinMode,
+                      value.social.clanChatJoinMode,
+                      value.social.chatAutoHideMode)) {
+        return false;
+    }
+    if (!execute("DELETE FROM account_key_bindings")) {
+        return false;
+    }
+    Statement binding("INSERT INTO account_key_bindings VALUES(?,?,?)");
+    for (std::size_t index = 0; index < value.keyBindings.values.size(); ++index) {
+        const auto& row = value.keyBindings.values[index];
+        if (!binding.write(index,
+                           row.primary ? static_cast<int>(*row.primary) : -1,
+                           row.secondary ? static_cast<int>(*row.secondary) : -1)) {
+            return false;
+        }
+    }
+    return transaction.commit();
+}
+
+} // namespace sunrise::state::investment::store

+ 81 - 0
Sunrise/src/state/investment/investment_store_boot.cpp

@@ -0,0 +1,81 @@
+#include <Windows.h>
+
+#include "../../../resources/resource.h"
+#include "../../core/filesystem/path.h"
+#include "store_internal.h"
+
+namespace sunrise::state::investment::store {
+namespace {
+
+/** Resource views borrow bytes from the loaded DLL. */
+bool resource(void* module, int identifier, std::string_view& output) noexcept {
+    const auto loadedModule = static_cast<HMODULE>(module);
+    const HRSRC found = FindResourceW(loadedModule, MAKEINTRESOURCEW(identifier), RT_RCDATA);
+    if (found == nullptr) {
+        return false;
+    }
+    const DWORD size = SizeofResource(loadedModule, found);
+    const HGLOBAL loaded = LoadResource(loadedModule, found);
+    const auto* bytes =
+        loaded != nullptr ? static_cast<const char*>(LockResource(loaded)) : nullptr;
+    if (bytes == nullptr || size == 0) {
+        return false;
+    }
+    output = {bytes, size};
+    return true;
+}
+
+} // namespace
+
+/** Schema and seed data stay in DLL resources; only the persistent database is materialized. */
+bool initialize(void* module) noexcept {
+    core::path::Buffer directory;
+    if (!core::path::artifact_directory(module, directory)
+        || !core::path::append(directory, L"\\data")) {
+        return false;
+    }
+    if (!CreateDirectoryW(directory.chars.data(), nullptr)
+        && GetLastError() != ERROR_ALREADY_EXISTS) {
+        return false;
+    }
+    if (!core::path::append(directory, L"\\investment.sqlite3")) {
+        return false;
+    }
+    const int bytes = WideCharToMultiByte(CP_UTF8,
+                                          0,
+                                          directory.chars.data(),
+                                          static_cast<int>(directory.length),
+                                          nullptr,
+                                          0,
+                                          nullptr,
+                                          nullptr);
+    if (bytes <= 0) {
+        return false;
+    }
+    std::string filename(static_cast<std::size_t>(bytes), '\0');
+    if (WideCharToMultiByte(CP_UTF8,
+                            0,
+                            directory.chars.data(),
+                            static_cast<int>(directory.length),
+                            filename.data(),
+                            bytes,
+                            nullptr,
+                            nullptr)
+        != bytes) {
+        return false;
+    }
+    std::string_view schema;
+    std::string_view defaults;
+    std::string_view settingsSchema;
+    std::string_view settingsDefaults;
+    if (!resource(module, IDR_INVESTMENT_SCHEMA, schema)
+        || !resource(module, IDR_INVESTMENT_DEFAULTS, defaults)
+        || !resource(module, IDR_ACCOUNT_SETTINGS_SCHEMA, settingsSchema)
+        || !resource(module, IDR_ACCOUNT_SETTINGS_DEFAULTS, settingsDefaults)
+        || !open(filename, schema, defaults, settingsSchema, settingsDefaults)) {
+        return false;
+    }
+    return true;
+}
+
+} // namespace sunrise::state::investment::store

+ 38 - 0
Sunrise/src/state/investment/investment_store_validation.cpp

@@ -0,0 +1,38 @@
+#include "../entitlements/validation.h"
+#include "store_internal.h"
+
+namespace sunrise::state::investment::store {
+
+/** Startup refuses an incomplete or corrupt save without replacing it with defaults. */
+bool validate() noexcept {
+    Transaction transaction;
+    if (!transaction.ready()) {
+        return false;
+    }
+    Statement integrity("PRAGMA quick_check");
+    std::string_view verdict;
+    if (integrity.step() != SQLITE_ROW || !integrity.text(0, verdict) || verdict != "ok"
+        || integrity.step() != SQLITE_DONE) {
+        return false;
+    }
+    Statement references("PRAGMA foreign_key_check");
+    if (references.step() != SQLITE_DONE) {
+        return false;
+    }
+    AccountState account;
+    Family5State family;
+    entitlements::Table ownership;
+    if (!read_account(account) || !read_family5(family) || !read_entitlements(ownership)
+        || !entitlements::valid(ownership)) {
+        return false;
+    }
+    for (std::size_t character = 0; character < kCharacterCapacity; ++character) {
+        unlocks::Table banks;
+        if (!read_unlocks(banks, static_cast<int>(character))) {
+            return false;
+        }
+    }
+    return transaction.commit();
+}
+
+} // namespace sunrise::state::investment::store

+ 321 - 0
Sunrise/src/state/investment/investment_unlock_store.cpp

@@ -0,0 +1,321 @@
+#include "store_internal.h"
+
+namespace sunrise::state::investment::store {
+namespace {
+
+/** Before character selection, encoders use the first character's banner. */
+int selected_slot() noexcept {
+    for (std::size_t slot = 0; slot < g_session.selected.size(); ++slot) {
+        if (g_session.selected[slot]) {
+            return static_cast<int>(slot);
+        }
+    }
+    return 0;
+}
+
+/** Rejects rows outside the destination bank before assigning their scalar value. */
+template <typename T, std::size_t N>
+bool assign(std::array<T, N>& values,
+            std::size_t slot,
+            std::size_t lane,
+            std::int32_t value) noexcept {
+    if (slot >= values.size() || lane != 0) {
+        return false;
+    }
+    if constexpr (std::is_same_v<T, std::uint8_t>) {
+        if (value < 0 || value > (std::numeric_limits<T>::max)()) {
+            return false;
+        }
+    }
+    values[slot] = static_cast<T>(value);
+    return true;
+}
+
+bool assign(unlocks::ProgressionBank& values,
+            std::size_t slot,
+            std::size_t lane,
+            std::int32_t value) noexcept {
+    if (slot >= values.size() || lane >= unlocks::kProgressionLaneCount) {
+        return false;
+    }
+    values[slot][lane] = value;
+    return true;
+}
+
+/** Sparse rows decode into the exact native bank without changing untouched lanes. */
+bool assign(unlocks::Table& table,
+            Bank bank,
+            std::size_t slot,
+            std::size_t lane,
+            std::int32_t value) noexcept {
+    switch (bank) {
+    case Bank::accountFlags:
+        return assign(table.accountFlags, slot, lane, value);
+    case Bank::profileFlags:
+        return assign(table.profileFlags, slot, lane, value);
+    case Bank::characterFlags:
+        return assign(table.characterFlags, slot, lane, value);
+    case Bank::objectiveValues:
+        return assign(table.objectiveValues, slot, lane, value);
+    case Bank::characterObjectFlags:
+        return assign(table.characterObjectFlags, slot, lane, value);
+    case Bank::characterObjectValues:
+        return assign(table.characterObjectValues, slot, lane, value);
+    case Bank::accountProgressions:
+        return assign(table.accountProgressions, slot, lane, value);
+    case Bank::characterProgressions:
+        return assign(table.characterProgressions, slot, lane, value);
+    }
+    return false;
+}
+
+/** Only changed lanes reach SQLite, and zeros remove their sparse rows. */
+template <typename T, std::size_t N>
+bool write_bank(Statement& rows,
+                Statement& remove,
+                int owner,
+                Bank bank,
+                const std::array<T, N>& before,
+                const std::array<T, N>& values) noexcept {
+    const auto write = [&](std::size_t slot, std::size_t lane, std::int32_t value) noexcept {
+        return value == 0 ? remove.write(owner, bank, slot, lane)
+                          : rows.write(owner, bank, slot, lane, value);
+    };
+    for (std::size_t slot = 0; slot < values.size(); ++slot) {
+        if constexpr (std::is_integral_v<T>) {
+            if (values[slot] != before[slot] && !write(slot, 0, values[slot])) {
+                return false;
+            }
+        } else {
+            for (std::size_t lane = 0; lane < values[slot].size(); ++lane) {
+                if (values[slot][lane] != before[slot][lane]
+                    && !write(slot, lane, values[slot][lane])) {
+                    return false;
+                }
+            }
+        }
+    }
+    return true;
+}
+
+} // namespace
+
+/** Returns account banks and the selected character's banks under one database lock. */
+bool read_unlocks(unlocks::Table& output, int characterSlot) noexcept {
+    const std::lock_guard lock(g_mutex);
+    output = {};
+    const int selected = characterSlot < 0 ? selected_slot() : characterSlot;
+    if (selected >= static_cast<int>(kCharacterCapacity)) {
+        return false;
+    }
+    Statement rows("SELECT character_slot,bank,slot,lane,value FROM unlocks "
+                   "WHERE character_slot=-1 OR character_slot=?");
+    if (!rows.parameters(selected)) {
+        return false;
+    }
+    int result = rows.step();
+    while (result == SQLITE_ROW) {
+        int owner = 0;
+        Bank bank{};
+        std::size_t slot = 0;
+        std::size_t lane = 0;
+        std::int32_t value = 0;
+        if (!rows.columns(owner, bank, slot, lane, value)
+            || ((owner == -1 || owner == selected) && !assign(output, bank, slot, lane, value))) {
+            output = {};
+            return false;
+        }
+        result = rows.step();
+    }
+    return result == SQLITE_DONE;
+}
+
+/** Other characters' banks survive writes to the selected character. */
+bool write_unlocks(const unlocks::Table& value, int characterSlot) noexcept {
+    Transaction transaction;
+    const int selected = characterSlot < 0 ? selected_slot() : characterSlot;
+    if (selected >= static_cast<int>(kCharacterCapacity)) {
+        return false;
+    }
+    unlocks::Table before;
+    if (!transaction.ready() || !read_unlocks(before, selected)) {
+        return false;
+    }
+    Statement rows("INSERT OR REPLACE INTO unlocks VALUES (?,?,?,?,?)");
+    Statement remove("DELETE FROM unlocks WHERE character_slot=? AND bank=? AND slot=? AND lane=?");
+    return write_bank(rows, remove, -1, Bank::accountFlags, before.accountFlags, value.accountFlags)
+           && write_bank(
+               rows, remove, -1, Bank::profileFlags, before.profileFlags, value.profileFlags)
+           && write_bank(rows,
+                         remove,
+                         selected,
+                         Bank::characterFlags,
+                         before.characterFlags,
+                         value.characterFlags)
+           && write_bank(rows,
+                         remove,
+                         -1,
+                         Bank::objectiveValues,
+                         before.objectiveValues,
+                         value.objectiveValues)
+           && write_bank(rows,
+                         remove,
+                         selected,
+                         Bank::characterObjectFlags,
+                         before.characterObjectFlags,
+                         value.characterObjectFlags)
+           && write_bank(rows,
+                         remove,
+                         selected,
+                         Bank::characterObjectValues,
+                         before.characterObjectValues,
+                         value.characterObjectValues)
+           && write_bank(rows,
+                         remove,
+                         -1,
+                         Bank::accountProgressions,
+                         before.accountProgressions,
+                         value.accountProgressions)
+           && write_bank(rows,
+                         remove,
+                         selected,
+                         Bank::characterProgressions,
+                         before.characterProgressions,
+                         value.characterProgressions)
+           && transaction.commit();
+}
+
+/** Scalar readers use the indexed row instead of loading every unlock bank. */
+bool read_unlock(Bank bank, std::uint16_t slot, std::int32_t& value) noexcept {
+    const std::lock_guard lock(g_mutex);
+    value = 0;
+    const bool character = bank == Bank::characterFlags || bank == Bank::characterObjectFlags
+                           || bank == Bank::characterObjectValues
+                           || bank == Bank::characterProgressions;
+    Statement row(
+        "SELECT value FROM unlocks WHERE character_slot=? AND bank=? AND slot=? AND lane=0");
+    if (!row.parameters(character ? selected_slot() : -1, bank, slot)) {
+        return false;
+    }
+    const int result = row.step();
+    return result == SQLITE_DONE || (result == SQLITE_ROW && row.column(0, value));
+}
+
+/** One scalar write updates only its indexed bank entry. */
+bool write_unlock(Bank bank, std::uint16_t slot, std::int32_t value) noexcept {
+    const std::lock_guard lock(g_mutex);
+    const bool character = bank == Bank::characterFlags || bank == Bank::characterObjectFlags
+                           || bank == Bank::characterObjectValues
+                           || bank == Bank::characterProgressions;
+    const int owner = character ? selected_slot() : -1;
+    if (value == 0) {
+        Statement row(
+            "DELETE FROM unlocks WHERE character_slot=? AND bank=? AND slot=? AND lane=0");
+        return row.write(owner, bank, slot);
+    }
+    Statement row("INSERT OR REPLACE INTO unlocks VALUES (?,?,?,0,?)");
+    return row.write(owner, bank, slot, value);
+}
+
+/** Family-5 identity and the content gate are derived, not saved copies. */
+bool read_family5(Family5State& output) noexcept {
+    const std::lock_guard lock(g_mutex);
+    output = {};
+    output.objectSoid = static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)());
+    Statement gates("SELECT count(*) FROM characters WHERE content_bypass=1");
+    std::size_t bypassCount = 0;
+    if (gates.step() != SQLITE_ROW || !gates.column(0, bypassCount)) {
+        return false;
+    }
+    output.contentGateArm = bypassCount != 0;
+    Statement rows("SELECT kind,position,slot,value FROM family5 ORDER BY kind,position");
+    int result = rows.step();
+    while (result == SQLITE_ROW) {
+        int kind = 0;
+        std::size_t position = 0;
+        std::uint16_t slot = 0;
+        std::int32_t value = 0;
+        if (!rows.columns(kind, position, slot, value) || position >= kUnlockOverrideCapacity) {
+            return false;
+        }
+        if (kind == 0 && position == output.flagCount && value >= 0 && value <= 255) {
+            output.flags[output.flagCount++] = {slot, static_cast<std::uint8_t>(value)};
+        } else if (kind == 1 && position == output.valueCount) {
+            output.values[output.valueCount++] = {slot, value};
+        } else {
+            return false;
+        }
+        result = rows.step();
+    }
+    return result == SQLITE_DONE;
+}
+
+/** Saves both override lists in the same transaction. */
+bool write_family5(const Family5State& value) noexcept {
+    if (value.flagCount > value.flags.size() || value.valueCount > value.values.size()) {
+        return false;
+    }
+    Transaction transaction;
+    if (!transaction.ready() || !execute("DELETE FROM family5")) {
+        return false;
+    }
+    Statement rows("INSERT INTO family5 VALUES (?,?,?,?)");
+    for (std::size_t index = 0; index < value.flagCount; ++index) {
+        if (!rows.write(0, index, value.flags[index].slot, value.flags[index].value)) {
+            return false;
+        }
+    }
+    for (std::size_t index = 0; index < value.valueCount; ++index) {
+        if (!rows.write(1, index, value.values[index].slot, value.values[index].value)) {
+            return false;
+        }
+    }
+    return transaction.commit();
+}
+
+/** Ownership rows use stable positions because their manifest handles depend on order. */
+bool read_entitlements(entitlements::Table& output) noexcept {
+    const std::lock_guard lock(g_mutex);
+    output = {};
+    Statement rows("SELECT position,name,ownership FROM entitlements ORDER BY position");
+    int result = rows.step();
+    while (result == SQLITE_ROW) {
+        std::size_t position = 0;
+        entitlements::Ownership ownership{};
+        std::string_view name;
+        if (!rows.column(0, position) || !rows.text(1, name) || !rows.column(2, ownership)
+            || position != output.count || position >= output.entries.size() || name.empty()
+            || name.size() >= entitlements::kNameCapacity) {
+            return false;
+        }
+        auto& entry = output.entries[output.count++];
+        name.copy(entry.name.data(), name.size());
+        entry.nameLength = static_cast<std::uint8_t>(name.size());
+        entry.ownership = ownership;
+        result = rows.step();
+    }
+    return result == SQLITE_DONE;
+}
+
+/** Completed bootstrap transforms must not overwrite later player progress on a restart. */
+bool bootstrap_completed(std::string_view name) noexcept {
+    const std::lock_guard lock(g_mutex);
+    Statement rows("SELECT name,completed FROM bootstrap");
+    while (rows.step() == SQLITE_ROW) {
+        std::string_view key;
+        bool completed = false;
+        if (rows.text(0, key) && rows.column(1, completed) && key == name) {
+            return completed;
+        }
+    }
+    return false;
+}
+
+/** The caller commits this marker together with the bootstrap's changes. */
+bool complete_bootstrap(std::string_view name) noexcept {
+    const std::lock_guard lock(g_mutex);
+    Statement row("INSERT OR REPLACE INTO bootstrap VALUES (?,1)");
+    return row.write(name);
+}
+
+} // namespace sunrise::state::investment::store

+ 61 - 0
Sunrise/src/state/investment/store.h

@@ -0,0 +1,61 @@
+#pragma once
+
+#include <string>
+#include <string_view>
+
+#include "../account/account_state.h"
+#include "../entitlements/definition.h"
+#include "../unlocks/definition.h"
+#include "investment.h"
+
+namespace sunrise::state::investment::store {
+
+/** Bank identifiers are part of schema version 1. */
+enum class Bank : int {
+    accountFlags,
+    profileFlags,
+    characterFlags,
+    objectiveValues,
+    characterObjectFlags,
+    characterObjectValues,
+    accountProgressions,
+    characterProgressions
+};
+
+[[nodiscard]] bool initialize(void* module) noexcept;
+[[nodiscard]] bool validate() noexcept;
+[[nodiscard]] bool open(std::string_view path,
+                        std::string_view schema,
+                        std::string_view defaults,
+                        std::string_view settingsSchema,
+                        std::string_view settingsDefaults) noexcept;
+void shutdown() noexcept;
+[[nodiscard]] bool read_account(AccountState& output) noexcept;
+[[nodiscard]] AccountState account() noexcept;
+[[nodiscard]] bool write_account(const AccountState& value) noexcept;
+[[nodiscard]] bool read_settings(account::settings::AccountSettings& output) noexcept;
+[[nodiscard]] bool write_settings(const account::settings::AccountSettings& value) noexcept;
+void set_sign_in_time(std::uint64_t seconds) noexcept;
+[[nodiscard]] bool read_family5(Family5State& output) noexcept;
+[[nodiscard]] bool write_family5(const Family5State& value) noexcept;
+[[nodiscard]] bool read_unlocks(unlocks::Table& output, int characterSlot = -1) noexcept;
+[[nodiscard]] bool write_unlocks(const unlocks::Table& value, int characterSlot = -1) noexcept;
+[[nodiscard]] bool read_unlock(Bank bank, std::uint16_t slot, std::int32_t& value) noexcept;
+[[nodiscard]] bool write_unlock(Bank bank, std::uint16_t slot, std::int32_t value) noexcept;
+[[nodiscard]] bool read_entitlements(entitlements::Table& output) noexcept;
+[[nodiscard]] bool bootstrap_completed(std::string_view name) noexcept;
+[[nodiscard]] bool complete_bootstrap(std::string_view name) noexcept;
+
+/** An earned reward stays in the database until its inventory grant commits. */
+struct PendingReward {
+    std::uint64_t id{};
+    std::uint32_t definitionHash{};
+    std::int32_t quantity{};
+    std::uint8_t kind{};
+};
+[[nodiscard]] bool
+enqueue_reward(std::uint32_t definitionHash, std::int32_t quantity, std::uint8_t kind) noexcept;
+[[nodiscard]] bool next_reward(PendingReward& output) noexcept;
+[[nodiscard]] bool complete_reward(std::uint64_t id) noexcept;
+
+} // namespace sunrise::state::investment::store

+ 142 - 0
Sunrise/src/state/investment/store_internal.h

@@ -0,0 +1,142 @@
+#pragma once
+
+#include <bit>
+#include <cmath>
+#include <limits>
+#include <mutex>
+#include <sqlite3.h>
+#include <string>
+#include <type_traits>
+
+#include "store.h"
+
+namespace sunrise::state::investment::store {
+
+extern sqlite3* g_database;
+extern std::recursive_mutex g_mutex;
+extern std::uint64_t g_failureSerial;
+
+/** Only session fields survive between database calls. */
+struct Session {
+    std::array<bool, kCharacterCapacity> selected{};
+    std::array<std::uint16_t, kCharacterCapacity> activities{};
+    std::uint64_t signInSeconds{};
+};
+extern Session g_session;
+
+[[nodiscard]] bool execute(const char* sql) noexcept;
+[[nodiscard]] sqlite3_destructor_type copy_text() noexcept;
+
+/** A failed write rolls back before releasing the database lock. */
+class Transaction {
+public:
+    Transaction() noexcept;
+    ~Transaction();
+    Transaction(const Transaction&) = delete;
+    Transaction& operator=(const Transaction&) = delete;
+    [[nodiscard]] bool ready() const noexcept {
+        return active_;
+    }
+    [[nodiscard]] bool commit() noexcept;
+
+private:
+    std::unique_lock<std::recursive_mutex> lock_;
+    bool active_{};
+    Session before_;
+    std::uint64_t failureSerial_{};
+};
+
+/** Statements never outlive the locked database call that owns them. */
+class Statement {
+public:
+    explicit Statement(const char* sql) noexcept;
+    ~Statement();
+    Statement(const Statement&) = delete;
+    Statement& operator=(const Statement&) = delete;
+    [[nodiscard]] int step() noexcept;
+    [[nodiscard]] bool text(int column, std::string_view& value) const noexcept;
+
+    /** Reads one typed SQL scalar without narrowing an out-of-range value. */
+    template <typename T> [[nodiscard]] bool column(int index, T& value) const noexcept {
+        if (statement_ == nullptr) {
+            return false;
+        }
+        if constexpr (std::is_enum_v<T>) {
+            std::underlying_type_t<T> raw{};
+            if (!column(index, raw)) {
+                return false;
+            }
+            value = static_cast<T>(raw);
+        } else if constexpr (std::is_floating_point_v<T>) {
+            const double raw = sqlite3_column_double(statement_, index);
+            if (!std::isfinite(raw) || std::abs(raw) > (std::numeric_limits<T>::max)()) {
+                return false;
+            }
+            value = static_cast<T>(raw);
+        } else {
+            if (sqlite3_column_type(statement_, index) != SQLITE_INTEGER) {
+                return false;
+            }
+            const auto raw = sqlite3_column_int64(statement_, index);
+            if constexpr (std::is_same_v<T, std::uint64_t>) {
+                value = std::bit_cast<std::uint64_t>(static_cast<std::int64_t>(raw));
+            } else {
+                if (raw < static_cast<sqlite3_int64>((std::numeric_limits<T>::min)())
+                    || raw > static_cast<sqlite3_int64>((std::numeric_limits<T>::max)())) {
+                    return false;
+                }
+                value = static_cast<T>(raw);
+            }
+        }
+        return true;
+    }
+
+    template <typename... T> [[nodiscard]] bool columns(T&... values) const noexcept {
+        int index = 0;
+        return (column(index++, values) && ...);
+    }
+
+    /** Reuses one prepared insert for a bounded set of typed rows. */
+    template <typename... T> [[nodiscard]] bool parameters(const T&... values) noexcept {
+        if (statement_ == nullptr) {
+            return false;
+        }
+        sqlite3_reset(statement_);
+        sqlite3_clear_bindings(statement_);
+        int index = 1;
+        return (bind(index++, values) && ...);
+    }
+
+    template <typename... T> [[nodiscard]] bool write(const T&... values) noexcept {
+        return parameters(values...) && step() == SQLITE_DONE;
+    }
+
+private:
+    /** SQL integers preserve all 64 identity bits; text bindings copy their input. */
+    template <typename T> [[nodiscard]] bool bind(int index, T value) noexcept {
+        if constexpr (std::is_convertible_v<T, std::string_view>) {
+            const std::string_view textValue(value);
+            return sqlite3_bind_text64(statement_,
+                                       index,
+                                       textValue.data(),
+                                       textValue.size(),
+                                       copy_text(),
+                                       SQLITE_UTF8)
+                   == SQLITE_OK;
+        } else if constexpr (std::is_floating_point_v<T>) {
+            return sqlite3_bind_double(statement_, index, value) == SQLITE_OK;
+        } else if constexpr (std::is_same_v<T, std::uint64_t>) {
+            return sqlite3_bind_int64(statement_, index, std::bit_cast<std::int64_t>(value))
+                   == SQLITE_OK;
+        } else {
+            return sqlite3_bind_int64(statement_, index, static_cast<sqlite3_int64>(value))
+                   == SQLITE_OK;
+        }
+    }
+    sqlite3_stmt* statement_{};
+};
+
+[[nodiscard]] bool read_inventory(AccountState& output) noexcept;
+[[nodiscard]] bool write_inventory(const AccountState& value) noexcept;
+
+} // namespace sunrise::state::investment::store

+ 2 - 7
Sunrise/src/state/runtime/runtime.h

@@ -405,23 +405,18 @@ struct PendingSettingsUpdate {
 /**
  * Loads cached build data and generates secrets with Sunrise's authored activity defaults.
  * @param module Loaded Sunrise module, or null to disable disk persistence.
- * @param initialAccount Empty State, or a complete checked account from Core settings.
  * @return True when the cached data passes its checks and every secret is generated.
  */
-[[nodiscard]] bool initialize(void* module = nullptr,
-                              const AccountState& initialAccount = {}) noexcept;
+[[nodiscard]] bool initialize(void* module = nullptr) noexcept;
 
 /**
  * Loads cached build data and publishes fixed activity defaults in one step.
  * @param module Loaded Sunrise module, or null to disable disk persistence.
- * @param initialAccount Empty State, or a complete checked account from Core settings.
  * @param activityDefaults Complete local fallback policy from immutable Core settings.
  * @return True when account, defaults, cached data, and generated secrets are valid.
  */
 [[nodiscard]] bool
-initialize(void* module,
-           const AccountState& initialAccount,
-           const activity::defaults::ActivityDefaults& activityDefaults) noexcept;
+initialize(void* module, const activity::defaults::ActivityDefaults& activityDefaults) noexcept;
 
 /** Securely clears State, including activity destinations and matchmaking descriptors. */
 void shutdown() noexcept;

+ 0 - 2
Sunrise/src/state/runtime/state.h

@@ -47,9 +47,7 @@ struct BapState {
 struct State {
     SignOnState signOn;
     BapState bap;
-    AccountState account;
     activity::ActivityState activity;
-    InvestmentState investment;
     matchmaking::MatchmakingState matchmaking;
     steam::SteamState steam;
 };

+ 27 - 15
Sunrise/src/state/runtime/state_account_acquisition_runtime.cpp

@@ -8,6 +8,7 @@
 
 #include "../../middleware/datagen/family4/loadout/loadout_resolver.h"
 #include "../build_data/runtime.h"
+#include "../investment/store_internal.h"
 #include "runtime.h"
 #include "state_account_transaction_helpers.h"
 #include "storage/internal.h"
@@ -272,18 +273,23 @@ bool prepare_direct_item_bundle(std::uint32_t sourceDefinitionHash,
  */
 bool reserve_selected_character_inventory_serial(std::int32_t& mutationSerial) noexcept {
     mutationSerial = 0;
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState& account = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState account = investment::store::account();
     const std::size_t characterIndex = selected_character_index(account);
-    const bool ready =
-        account::valid(account) && characterIndex < account.characterCount
-        && account.characters[characterIndex].nextInventorySerial
-               < static_cast<std::uint32_t>((std::numeric_limits<std::int32_t>::max)());
+    bool ready = account::valid(account) && characterIndex < account.characterCount
+                 && account.characters[characterIndex].nextInventorySerial
+                        < static_cast<std::uint32_t>((std::numeric_limits<std::int32_t>::max)());
     if (ready) {
         mutationSerial =
             static_cast<std::int32_t>(account.characters[characterIndex].nextInventorySerial++);
     }
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    if (ready) {
+        ready = investment::store::write_account(account);
+    }
+    if (!ready) {
+        mutationSerial = 0;
+    }
+    investment::store::g_mutex.unlock();
     return ready;
 }
 
@@ -466,14 +472,17 @@ bool preview_direct_item_bundle(const PendingDirectItemBundle& mutation,
 bool commit_item_acquisition(PendingItemAcquisition& mutation) noexcept {
     const PendingItemAcquisition& prepared = mutation;
     const PendingConsumption consume{mutation};
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.lock();
     AccountState candidate{};
     const bool ready =
-        materialize_item_acquisition(runtime::storage::g_state.account, prepared, candidate);
+        materialize_item_acquisition(investment::store::account(), prepared, candidate);
     if (ready) {
-        runtime::storage::g_state.account = candidate;
+        if (!investment::store::write_account(candidate)) {
+            investment::store::g_mutex.unlock();
+            return false;
+        }
     }
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.unlock();
     return ready;
 }
 
@@ -689,14 +698,17 @@ bool commit_profile_item_acquisition(PendingProfileItemAcquisition& mutation) no
         return false;
     }
 
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.lock();
     AccountState candidate{};
     const bool ready =
-        materialize_profile_acquisition(runtime::storage::g_state.account, prepared, candidate);
+        materialize_profile_acquisition(investment::store::account(), prepared, candidate);
     if (ready) {
-        runtime::storage::g_state.account = candidate;
+        if (!investment::store::write_account(candidate)) {
+            investment::store::g_mutex.unlock();
+            return false;
+        }
     }
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.unlock();
     return ready;
 }
 

+ 8 - 4
Sunrise/src/state/runtime/state_account_dismantle_runtime.cpp

@@ -4,6 +4,7 @@
 #include <cstddef>
 #include <cstdint>
 
+#include "../investment/store_internal.h"
 #include "runtime.h"
 #include "state_account_transaction_helpers.h"
 #include "storage/internal.h"
@@ -98,14 +99,17 @@ bool commit_item_dismantle(PendingItemDismantle& mutation) noexcept {
                      prepared.movedInventoryItemCount,
                      prepared.afterCharacter.nextInventorySerial);
 
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.lock();
     AccountState candidate{};
     const bool ready =
-        materialize_item_dismantle(runtime::storage::g_state.account, prepared, candidate);
+        materialize_item_dismantle(investment::store::account(), prepared, candidate);
     if (ready) {
-        runtime::storage::g_state.account = candidate;
+        if (!investment::store::write_account(candidate)) {
+            investment::store::g_mutex.unlock();
+            return false;
+        }
     }
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.unlock();
 
     if (!ready) {
         return fail("stale_or_invalid");

+ 2 - 1
Sunrise/src/state/runtime/state_account_equipment_runtime.cpp

@@ -277,7 +277,8 @@ finalize_equipment_transition(const AccountState& account,
                                     const authored_inventory::Item& right) noexcept {
     return left.instanceSoid == right.instanceSoid && left.definitionHash == right.definitionHash
            && left.level == right.level && left.quantity == right.quantity
-           && left.flags == right.flags && left.sockets.policy == right.sockets.policy
+           && left.flags == right.flags && left.seen == right.seen
+           && left.sockets.policy == right.sockets.policy
            && left.sockets.plugCount == right.sockets.plugCount
            && left.sockets.plugs == right.sockets.plugs
            && left.movementAbilityEntry == right.movementAbilityEntry

+ 32 - 22
Sunrise/src/state/runtime/state_account_item_action_runtime.cpp

@@ -7,6 +7,7 @@
 #include "../../middleware/datagen/family4/loadout/loadout_resolver.h"
 #include "../../middleware/web_service/messages/opcode1901.h"
 #include "../build_data/runtime.h"
+#include "../investment/store_internal.h"
 #include "runtime.h"
 #include "state_account_transaction_helpers.h"
 #include "storage/internal.h"
@@ -309,15 +310,15 @@ bool commit_socket_plug(PendingSocketPlug& mutation) noexcept {
                        prepared.targetEquipped,
                        prepared.itemIndex);
 
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState candidate = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState candidate = investment::store::account();
     if (prepared.characterIndex >= candidate.characterCount
         || candidate.primarySoid != prepared.accountSoid
         || !same_profile_inventory(
             candidate, prepared.beforeProfileItems, prepared.expectedProfileItemCount)
         || !same_character(candidate.characters[prepared.characterIndex],
                            prepared.beforeCharacter)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return fail("stale");
     }
 
@@ -350,7 +351,7 @@ bool commit_socket_plug(PendingSocketPlug& mutation) noexcept {
         || canonical.targetEquipped != prepared.targetEquipped
         || !same_character(canonical.beforeCharacter, prepared.beforeCharacter)
         || !same_character(canonical.afterCharacter, prepared.afterCharacter)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return fail("transition");
     }
 
@@ -358,18 +359,21 @@ bool commit_socket_plug(PendingSocketPlug& mutation) noexcept {
     candidate.profileItemCount = canonical.afterProfileItemCount;
     if (!same_profile_inventory(
             candidate, prepared.afterProfileItems, prepared.afterProfileItemCount)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return fail("materials");
     }
     candidate.characters[prepared.characterIndex] = canonical.afterCharacter;
     family4_loadout::ResolvedLoadout checked{};
     if (!account::valid(candidate) || !valid_profile_inventory(candidate)
         || !family4_loadout::resolve(candidate, prepared.characterIndex, checked)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return fail("account_or_resolve");
     }
-    runtime::storage::g_state.account = candidate;
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    if (!investment::store::write_account(candidate)) {
+        investment::store::g_mutex.unlock();
+        return false;
+    }
+    investment::store::g_mutex.unlock();
 
     report_socket_plug("commit_end",
                        "ok",
@@ -460,12 +464,12 @@ bool commit_item_state(PendingItemState& mutation) noexcept {
         return fail("mutation");
     }
 
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState candidate = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState candidate = investment::store::account();
     if (prepared.characterIndex >= candidate.characterCount
         || !same_character(candidate.characters[prepared.characterIndex],
                            prepared.beforeCharacter)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return fail("stale");
     }
 
@@ -485,7 +489,7 @@ bool commit_item_state(PendingItemState& mutation) noexcept {
         || canonical.targetEquipped != prepared.targetEquipped
         || !same_character(canonical.beforeCharacter, prepared.beforeCharacter)
         || !same_character(canonical.afterCharacter, prepared.afterCharacter)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return fail("transition");
     }
 
@@ -493,11 +497,14 @@ bool commit_item_state(PendingItemState& mutation) noexcept {
     family4_loadout::ResolvedLoadout checked{};
     if (!account::valid(candidate)
         || !family4_loadout::resolve(candidate, prepared.characterIndex, checked)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return fail("account_or_resolve");
     }
-    runtime::storage::g_state.account = candidate;
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    if (!investment::store::write_account(candidate)) {
+        investment::store::g_mutex.unlock();
+        return false;
+    }
+    investment::store::g_mutex.unlock();
 
     report_item_state("commit",
                       "ok",
@@ -577,13 +584,13 @@ bool commit_subclass_selection(PendingSubclassSelection& mutation) noexcept {
         return false;
     }
 
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState candidate = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState candidate = investment::store::account();
     if (prepared.characterIndex >= candidate.characterCount
         || candidate.primarySoid != prepared.accountSoid
         || !same_character(candidate.characters[prepared.characterIndex],
                            prepared.beforeCharacter)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return false;
     }
     PendingSubclassSelection canonical{};
@@ -593,18 +600,21 @@ bool commit_subclass_selection(PendingSubclassSelection& mutation) noexcept {
                                   prepared.requestedEntry,
                                   canonical)
         || !same_character(canonical.afterCharacter, prepared.afterCharacter)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return false;
     }
     candidate.characters[prepared.characterIndex] = canonical.afterCharacter;
     family4_loadout::ResolvedLoadout checked{};
     if (!account::valid(candidate)
         || !family4_loadout::resolve(candidate, prepared.characterIndex, checked)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
+        return false;
+    }
+    if (!investment::store::write_account(candidate)) {
+        investment::store::g_mutex.unlock();
         return false;
     }
-    runtime::storage::g_state.account = candidate;
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.unlock();
 
     // The published ability buckets are keyed to whichever selection is currently active; that
     // just changed, so the domain is stale the moment the account write above becomes visible.

+ 2 - 1
Sunrise/src/state/runtime/state_account_profile_runtime.cpp

@@ -24,7 +24,8 @@ namespace inventory_buckets = build_data::inventory::buckets;
 [[nodiscard]] static bool same_profile_item(const authored_inventory::ProfileItem& left,
                                             const authored_inventory::ProfileItem& right) noexcept {
     return left.instanceSoid == right.instanceSoid && left.definitionHash == right.definitionHash
-           && left.quantity == right.quantity && left.mutationSerial == right.mutationSerial;
+           && left.quantity == right.quantity && left.mutationSerial == right.mutationSerial
+           && left.seen == right.seen;
 }
 
 /** @return True when a complete fixed profile inventory equals one captured view. */

+ 23 - 19
Sunrise/src/state/runtime/state_account_reward_grant_runtime.cpp

@@ -11,6 +11,7 @@
 
 #include "../../middleware/datagen/family4/loadout/loadout_resolver.h"
 #include "../build_data/runtime.h"
+#include "../investment/store_internal.h"
 #include "../progression/season_pass_reward_catalog.h"
 #include "../unlocks/unlocks_records.h"
 #include "runtime.h"
@@ -93,22 +94,22 @@ bool commit_season_pass_reward(PendingSeasonPassReward& mutation) noexcept {
         return false;
     }
 
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.lock();
     AccountState after{};
     bool ready = false;
     if (const auto* item = std::get_if<PendingItemAcquisition>(&mutation.grant)) {
-        ready = materialize_item_acquisition(runtime::storage::g_state.account, *item, after);
+        ready = materialize_item_acquisition(investment::store::account(), *item, after);
     } else if (const auto* profile = std::get_if<PendingProfileItemAcquisition>(&mutation.grant)) {
-        ready = materialize_profile_acquisition(runtime::storage::g_state.account, *profile, after);
+        ready = materialize_profile_acquisition(investment::store::account(), *profile, after);
     } else if (const auto* bundle = std::get_if<PendingDirectItemBundle>(&mutation.grant)) {
-        ready = materialize_direct_item_bundle(runtime::storage::g_state.account, *bundle, after);
+        ready = materialize_direct_item_bundle(investment::store::account(), *bundle, after);
     } else if (const auto* resources = std::get_if<PendingRecordRewardGrant>(&mutation.grant)) {
-        ready = materialize_record_reward(runtime::storage::g_state.account, *resources, after);
+        ready = materialize_record_reward(investment::store::account(), *resources, after);
     }
     if (ready) {
-        runtime::storage::g_state.account = after;
+        ready = investment::store::write_account(after);
     }
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.unlock();
     if (!ready) {
         // The claim was written when the reward was prepared, so a refused install undoes it.
         revoke_season_pass_reward(mutation.rewardIndex);
@@ -381,13 +382,13 @@ bool preview_record_reward_grant(const PendingRecordRewardGrant& mutation,
 /** Commits the shared reward after-image and claim together. */
 bool commit_record_reward(PendingRecordRewardGrant& mutation) noexcept {
     const PendingConsumption consume{mutation};
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.lock();
     AccountState after{};
-    bool ready = materialize_record_reward(runtime::storage::g_state.account, mutation, after);
+    bool ready = materialize_record_reward(investment::store::account(), mutation, after);
     if (ready) {
-        runtime::storage::g_state.account = after;
+        ready = investment::store::write_account(after);
     }
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.unlock();
     if (!ready && mutation.claimedRecordIndex != kUnclaimedRecordIndex) {
         // The claim was written when the reward was prepared, so a refused install undoes it.
         unlocks::records::revoke(mutation.claimedRecordIndex);
@@ -495,10 +496,10 @@ EmoteCollectionOutcome ensure_character_emote_collection() noexcept {
         return EmoteCollectionOutcome::unsupported;
     }
 
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState candidate = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState candidate = investment::store::account();
     if (!account::valid(candidate)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return EmoteCollectionOutcome::notReady;
     }
     bool changed = false;
@@ -544,19 +545,22 @@ EmoteCollectionOutcome ensure_character_emote_collection() noexcept {
         changed = true;
     }
     if (failed) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return EmoteCollectionOutcome::failed;
     }
     if (!changed) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return EmoteCollectionOutcome::ready;
     }
     if (!account::valid(candidate)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return EmoteCollectionOutcome::failed;
     }
-    runtime::storage::g_state.account = candidate;
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    if (!investment::store::write_account(candidate)) {
+        investment::store::g_mutex.unlock();
+        return EmoteCollectionOutcome::failed;
+    }
+    investment::store::g_mutex.unlock();
     return EmoteCollectionOutcome::ready;
 }
 

+ 63 - 43
Sunrise/src/state/runtime/state_account_runtime.cpp

@@ -9,6 +9,7 @@
 #include "../../core/logging/log.h"
 #include "../../middleware/datagen/family4/loadout/loadout_resolver.h"
 #include "../build_data/runtime.h"
+#include "../investment/store_internal.h"
 #include "runtime.h"
 #include "state.h"
 #include "state_account_transaction_helpers.h"
@@ -164,8 +165,8 @@ bool set_primary_soid(std::uint64_t primarySoid) noexcept {
     if (primarySoid == 0) {
         return false;
     }
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState candidate = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState candidate = investment::store::account();
     candidate.primarySoid = primarySoid;
     // Characters belong to the account key the Client uses. The reference account and its
     // characters differ only in the low byte, so the authored rows are rebased onto that key.
@@ -173,27 +174,34 @@ bool set_primary_soid(std::uint64_t primarySoid) noexcept {
         candidate.characters[index].soid = primarySoid + 1U + index;
     }
     if (!account::valid(candidate)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return false;
     }
     // Publish only after the settings and identity rules hold together.
-    runtime::storage::g_state.account = candidate;
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    if (!investment::store::write_account(candidate)) {
+        investment::store::g_mutex.unlock();
+        return false;
+    }
+    investment::store::g_mutex.unlock();
     return true;
 }
 
 /** Closes the account's one-time profile-setup gate. */
 bool complete_profile_setup() noexcept {
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState& accountState = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState accountState = investment::store::account();
     if (accountState.primarySoid == 0 || !account::valid(accountState)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return false;
     }
 
     const bool changed = !accountState.profileSetupCompleted;
     accountState.profileSetupCompleted = true;
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    if (!investment::store::write_account(accountState)) {
+        investment::store::g_mutex.unlock();
+        return false;
+    }
+    investment::store::g_mutex.unlock();
 
     if (changed) {
         core::log::write(core::log::Channel::state,
@@ -209,8 +217,8 @@ bool set_selected_character(std::uint64_t characterSoid, bool& changed) noexcept
     if (characterSoid == 0) {
         return false;
     }
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState candidate = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState candidate = investment::store::account();
     std::size_t picked = candidate.characterCount;
     for (std::size_t index = 0; index < candidate.characterCount; ++index) {
         if (candidate.characters[index].soid == characterSoid) {
@@ -218,7 +226,7 @@ bool set_selected_character(std::uint64_t characterSoid, bool& changed) noexcept
         }
     }
     if (picked == candidate.characterCount) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return false;
     }
 
@@ -228,12 +236,15 @@ bool set_selected_character(std::uint64_t characterSoid, bool& changed) noexcept
     }
     candidate.characters[picked].selected = true;
     if (!account::valid(candidate)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return false;
     }
     // Publish only after the whole account still meets its identity rules.
-    runtime::storage::g_state.account = candidate;
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    for (std::size_t index = 0; index < candidate.characters.size(); ++index) {
+        investment::store::g_session.selected[index] = candidate.characters[index].selected;
+    }
+    investment::store::g_mutex.unlock();
+    (void)seed_seasonal_progression();
     changed = !alreadySelected;
     return true;
 }
@@ -244,8 +255,8 @@ bool set_selected_title(std::uint16_t recordIndex,
                         bool& changed) noexcept {
     characterSoid = 0;
     changed = false;
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState candidate = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState candidate = investment::store::account();
     std::size_t selectedIndex = candidate.characterCount;
     for (std::size_t index = 0; index < candidate.characterCount; ++index) {
         if (candidate.characters[index].selected) {
@@ -254,7 +265,7 @@ bool set_selected_title(std::uint16_t recordIndex,
         }
     }
     if (selectedIndex == candidate.characterCount) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return false;
     }
     CharacterState& character = candidate.characters[selectedIndex];
@@ -264,11 +275,14 @@ bool set_selected_title(std::uint16_t recordIndex,
     if (!account::valid(candidate)) {
         characterSoid = 0;
         changed = false;
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return false;
     }
-    runtime::storage::g_state.account = candidate;
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    if (!investment::store::write_account(candidate)) {
+        investment::store::g_mutex.unlock();
+        return false;
+    }
+    investment::store::g_mutex.unlock();
     return true;
 }
 
@@ -310,21 +324,21 @@ bool commit_current_activity(PendingCurrentActivity& mutation) noexcept {
         || prepared.afterCharacter.soid != prepared.characterSoid) {
         return false;
     }
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState candidate = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState candidate = investment::store::account();
     if (prepared.characterIndex >= candidate.characterCount
         || !same_character(candidate.characters[prepared.characterIndex],
                            prepared.beforeCharacter)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return false;
     }
     candidate.characters[prepared.characterIndex] = prepared.afterCharacter;
     if (!account::valid(candidate)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return false;
     }
-    runtime::storage::g_state.account = candidate;
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_session.activities[prepared.characterIndex] = prepared.activityIndex;
+    investment::store::g_mutex.unlock();
     return true;
 }
 
@@ -574,19 +588,19 @@ bool commit_equipment_swap(PendingEquipmentSwap& mutation) noexcept {
         return false;
     }
 
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState candidate = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState candidate = investment::store::account();
     if (prepared.characterIndex >= candidate.characterCount
         || !same_character(candidate.characters[prepared.characterIndex],
                            prepared.beforeCharacter)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return false;
     }
     candidate.characters[prepared.characterIndex] = prepared.afterCharacter;
     family4_loadout::ResolvedLoadout checkedAfter{};
     if (!account::valid(candidate)
         || !family4_loadout::resolve(candidate, prepared.characterIndex, checkedAfter)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return false;
     }
     ResolvedPosition requestedPosition{};
@@ -594,11 +608,14 @@ bool commit_equipment_swap(PendingEquipmentSwap& mutation) noexcept {
     if (!find_resolved_position(checkedAfter, prepared.requestedInstanceSoid, requestedPosition)
         || requestedPosition.equipmentSlot != prepared.nativeEquipmentSlot
         || requestedPosition.equipped != expectedEquipped) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
+        return false;
+    }
+    if (!investment::store::write_account(candidate)) {
+        investment::store::g_mutex.unlock();
         return false;
     }
-    runtime::storage::g_state.account = candidate;
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.unlock();
 
     // The published ability buckets resolve against the equipped subclass, so swapping that item
     // makes them stale and they need the same invalidation an ability-entry pick does.
@@ -612,9 +629,9 @@ bool commit_equipment_swap(PendingEquipmentSwap& mutation) noexcept {
 
 /** @return A copy of the active account state, read under the lock. */
 AccountState account_snapshot() noexcept {
-    AcquireSRWLockShared(&runtime::storage::g_stateLock);
-    const AccountState snapshot = runtime::storage::g_state.account;
-    ReleaseSRWLockShared(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.lock();
+    const AccountState snapshot = investment::store::account();
+    investment::store::g_mutex.unlock();
     return snapshot;
 }
 
@@ -623,10 +640,10 @@ bool ensure_character_subclasses() noexcept {
     // Index of the subclass slot in the authored equipment array.
     constexpr std::size_t kSubclassSlot =
         static_cast<std::size_t>(authored_inventory::EquipmentSlot::subclass);
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState candidate = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState candidate = investment::store::account();
     if (!account::valid(candidate)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return true;
     }
     std::uint64_t nextSoid = 0;
@@ -688,11 +705,14 @@ bool ensure_character_subclasses() noexcept {
         }
     }
     if (failed || !changed || !account::valid(candidate)) {
-        ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+        investment::store::g_mutex.unlock();
         return !failed;
     }
-    runtime::storage::g_state.account = candidate;
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    if (!investment::store::write_account(candidate)) {
+        investment::store::g_mutex.unlock();
+        return false;
+    }
+    investment::store::g_mutex.unlock();
     return true;
 }
 

+ 5 - 5
Sunrise/src/state/runtime/state_account_settings_runtime.cpp

@@ -1,4 +1,5 @@
 #include "../account/settings/settings_delta.h"
+#include "../investment/store_internal.h"
 #include "runtime.h"
 #include "storage/internal.h"
 
@@ -42,8 +43,8 @@ bool commit_settings_update(PendingSettingsUpdate& mutation) noexcept {
         return false;
     }
 
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState candidate = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState candidate = investment::store::account();
     bool committed = false;
 
     if (candidate.primarySoid == prepared.accountSoid) {
@@ -53,13 +54,12 @@ bool commit_settings_update(PendingSettingsUpdate& mutation) noexcept {
         } else if (candidate.settings == prepared.beforeSettings) {
             candidate.settings = prepared.afterSettings;
             if (account::valid(candidate)) {
-                runtime::storage::g_state.account = candidate;
-                committed = true;
+                committed = investment::store::write_settings(candidate.settings);
             }
         }
     }
 
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.unlock();
     return committed;
 }
 

+ 90 - 49
Sunrise/src/state/runtime/state_progression_runtime.cpp

@@ -10,6 +10,7 @@
 
 #include "../build_data/runtime.h"
 #include "../investment/investment.h"
+#include "../investment/store_internal.h"
 #include "../progression/season_pass_reward_catalog.h"
 #include "../unlocks/definition.h"
 #include "../unlocks/unlocks_runtime.h"
@@ -198,8 +199,8 @@ struct CharacterArtifactWrite {
  * Writes the artifact ownership bits and the points-used counter into the character banks.
  * @param write Mapped sale rows with the mask and the used count to publish.
  */
-void publish_artifact_character_banks(CharacterArtifactWrite& write) noexcept {
-    unlocks::mutate(&write, [](void* context, unlocks::Table& table) noexcept {
+bool publish_artifact_character_banks(CharacterArtifactWrite& write) noexcept {
+    return unlocks::mutate(&write, [](void* context, unlocks::Table& table) noexcept {
         const auto& request = *static_cast<const CharacterArtifactWrite*>(context);
         for (std::size_t row = 0; row < request.count && row < 32; ++row) {
             const std::uint16_t mapped = (*request.rows)[row].characterFlagIndex;
@@ -240,20 +241,19 @@ void publish_artifact_character_banks(CharacterArtifactWrite& write) noexcept {
         return false;
     }
     CharacterArtifactWrite write{&rows, count, mask, used};
-    publish_artifact_character_banks(write);
-    return true;
+    return publish_artifact_character_banks(write);
 }
 
 /** Publishes the four seasonal progression lanes the current XP total implies. */
-void publish_experience_lanes(std::int32_t experience) noexcept {
-    (void)unlocks::set_account_progression(kArtifactPowerProgressionIndex, experience);
-    (void)unlocks::set_account_progression(kArtifactUnlockProgressionIndex, experience);
-    (void)unlocks::set_account_progression(pass::kProgressionDefinitionIndex,
-                                           (std::min)(experience, kMaximumPassExperience));
-    (void)unlocks::set_account_progression(pass::kHudProgressionDefinitionIndex,
-                                           experience < kMaximumPassExperience
-                                               ? experience % kExperiencePerRank
-                                               : experience - kMaximumPassExperience);
+bool publish_experience_lanes(std::int32_t experience) noexcept {
+    return unlocks::set_account_progression(kArtifactPowerProgressionIndex, experience)
+           && unlocks::set_account_progression(kArtifactUnlockProgressionIndex, experience)
+           && unlocks::set_account_progression(pass::kProgressionDefinitionIndex,
+                                               (std::min)(experience, kMaximumPassExperience))
+           && unlocks::set_account_progression(pass::kHudProgressionDefinitionIndex,
+                                               experience < kMaximumPassExperience
+                                                   ? experience % kExperiencePerRank
+                                                   : experience - kMaximumPassExperience);
 }
 
 } // namespace
@@ -266,19 +266,45 @@ std::int32_t seasonal_experience() noexcept {
 /** Publishes every seasonal value the seeded XP and artifact ownership imply. */
 bool seed_seasonal_progression() noexcept {
     const std::int32_t experience = seasonal_experience();
-    publish_experience_lanes(experience);
     SaleRows rows{};
     std::size_t count = 0;
     if (!sale_rows(rows, count)) {
         return false;
     }
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    Family5State& family = runtime::storage::g_state.investment.family5;
+    investment::store::g_mutex.lock();
+    investment::store::Transaction transaction;
+    Family5State family;
+    if (!transaction.ready() || !investment::store::read_family5(family)) {
+        investment::store::g_mutex.unlock();
+        return false;
+    }
     // An authored family-5 row still seeds ownership. The publish moves it to the character bank.
-    const std::uint32_t mask =
-        authored_artifact_mask_locked(family, rows, count) | artifact_mask(rows, count);
-    const bool published = publish_artifact_locked(family, mask, experience);
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    const std::uint32_t authoredMask = authored_artifact_mask_locked(family, rows, count);
+    if (authoredMask != 0) {
+        const AccountState account = investment::store::account();
+        for (std::size_t character = 0; character < account.characterCount; ++character) {
+            unlocks::Table banks;
+            if (!investment::store::read_unlocks(banks, static_cast<int>(character))) {
+                investment::store::g_mutex.unlock();
+                return false;
+            }
+            for (std::size_t row = 0; row < count && row < 32; ++row) {
+                const auto flag = rows[row].characterFlagIndex;
+                if ((authoredMask & (1U << row)) != 0 && flag < banks.characterObjectFlags.size()) {
+                    banks.characterObjectFlags[flag] = unlocks::kFlagSet;
+                }
+            }
+            if (!investment::store::write_unlocks(banks, static_cast<int>(character))) {
+                investment::store::g_mutex.unlock();
+                return false;
+            }
+        }
+    }
+    const std::uint32_t mask = artifact_mask(rows, count);
+    const bool published = publish_experience_lanes(experience)
+                           && publish_artifact_locked(family, mask, experience)
+                           && investment::store::write_family5(family) && transaction.commit();
+    investment::store::g_mutex.unlock();
     return published;
 }
 
@@ -291,8 +317,9 @@ std::uint16_t seasonal_rank() noexcept {
 
 /** @return Account-wide Power bonus published by the seasonal artifact. */
 std::uint16_t artifact_power_bonus() noexcept {
-    AcquireSRWLockShared(&runtime::storage::g_stateLock);
-    const Family5State& family = runtime::storage::g_state.investment.family5;
+    investment::store::g_mutex.lock();
+    Family5State family;
+    (void)investment::store::read_family5(family);
     std::int32_t bonus = 0;
     for (std::size_t index = 0; index < family.valueCount; ++index) {
         if (family.values[index].slot == kArtifactPowerBonusSlot) {
@@ -300,7 +327,7 @@ std::uint16_t artifact_power_bonus() noexcept {
             break;
         }
     }
-    ReleaseSRWLockShared(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.unlock();
     return bonus > 0 ? static_cast<std::uint16_t>(bonus) : 0U;
 }
 
@@ -309,20 +336,27 @@ bool grant_seasonal_experience(std::int32_t amount) noexcept {
     if (amount <= 0) {
         return false;
     }
+    investment::store::Transaction transaction;
+    if (!transaction.ready()) {
+        return false;
+    }
     const std::int32_t previous = seasonal_experience();
     if (previous > (std::numeric_limits<std::int32_t>::max)() - amount) {
         return false;
     }
     const std::int32_t total = previous + amount;
-    publish_experience_lanes(total);
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    Family5State& family = runtime::storage::g_state.investment.family5;
+
+    Family5State family;
+    if (!transaction.ready() || !investment::store::read_family5(family)) {
+        return false;
+    }
     SaleRows rows{};
     std::size_t count = 0;
     const std::uint32_t mask = sale_rows(rows, count) ? artifact_mask(rows, count) : 0U;
-    (void)publish_artifact_locked(family, mask, total);
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
-    return true;
+    const bool saved = publish_experience_lanes(total)
+                       && publish_artifact_locked(family, mask, total)
+                       && investment::store::write_family5(family) && transaction.commit();
+    return saved;
 }
 
 /** @return True when this Season pass reward row is already claimed. */
@@ -371,13 +405,19 @@ bool replace_artifact_mod_mask(std::uint32_t expected, std::uint32_t replacement
         return false;
     }
     const std::int32_t experience = seasonal_experience();
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    Family5State& family = runtime::storage::g_state.investment.family5;
+    investment::store::g_mutex.lock();
+    investment::store::Transaction transaction;
+    Family5State family;
+    if (!transaction.ready() || !investment::store::read_family5(family)) {
+        investment::store::g_mutex.unlock();
+        return false;
+    }
     bool replaced = artifact_mask(rows, count) == expected;
     if (replaced) {
-        replaced = publish_artifact_locked(family, replacement, experience);
+        replaced = publish_artifact_locked(family, replacement, experience)
+                   && investment::store::write_family5(family) && transaction.commit();
     }
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.unlock();
     return replaced;
 }
 
@@ -406,15 +446,21 @@ bool prepare_artifact_mod_unlock(std::uint16_t saleIndex,
     const std::uint32_t bit = 1U << saleIndex;
     const std::int32_t experience = seasonal_experience();
     const std::uint16_t earned = artifact_points_earned_for(experience);
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    Family5State& family = runtime::storage::g_state.investment.family5;
+    investment::store::g_mutex.lock();
+    investment::store::Transaction transaction;
+    Family5State family;
+    if (!transaction.ready() || !investment::store::read_family5(family)) {
+        investment::store::g_mutex.unlock();
+        return false;
+    }
     const std::uint32_t before = artifact_mask(rows, count);
     const std::uint16_t used = points_used(before);
     bool prepared = (before & bit) == 0 && used < earned && used >= column_tier(saleIndex);
     if (prepared) {
-        prepared = publish_artifact_locked(family, before | bit, experience);
+        prepared = publish_artifact_locked(family, before | bit, experience)
+                   && investment::store::write_family5(family) && transaction.commit();
     }
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.unlock();
     if (!prepared) {
         return false;
     }
@@ -433,18 +479,13 @@ bool commit_artifact_mod_unlock(PendingArtifactPurchase& mutation) noexcept {
     const PendingArtifactPurchase prepared = mutation;
     mutation = {};
     const AccountState account = account_snapshot();
-    const bool current =
-        prepared.prepared && prepared.accountSoid != 0 && prepared.characterSoid != 0
-        && prepared.beforeMask != prepared.afterMask
-        && prepared.characterIndex < account.characterCount
-        && account.primarySoid == prepared.accountSoid
-        && account.characters[prepared.characterIndex].soid == prepared.characterSoid
-        && account.characters[prepared.characterIndex].selected
-        && artifact_mod_mask() == prepared.afterMask;
-    if (!current && prepared.prepared) {
-        (void)replace_artifact_mod_mask(prepared.afterMask, prepared.beforeMask);
-    }
-    return current;
+    return prepared.prepared && prepared.accountSoid != 0 && prepared.characterSoid != 0
+           && prepared.beforeMask != prepared.afterMask
+           && prepared.characterIndex < account.characterCount
+           && account.primarySoid == prepared.accountSoid
+           && account.characters[prepared.characterIndex].soid == prepared.characterSoid
+           && account.characters[prepared.characterIndex].selected
+           && artifact_mod_mask() == prepared.afterMask;
 }
 
 } // namespace sunrise::state

+ 37 - 111
Sunrise/src/state/runtime/state_runtime.cpp

@@ -17,6 +17,7 @@
 #include "../../core/settings/settings.h"
 #include "../activity/defaults/activity_defaults_validation.h"
 #include "../build_data/runtime.h"
+#include "../investment/store_internal.h"
 #include "../unlocks/unlocks_records.h"
 #include "equipment/configured_equipment_identity.h"
 #include "runtime.h"
@@ -38,13 +39,6 @@ namespace {
 constexpr std::uint32_t kLoopbackAddress = 0x7F000001;
 /** Default one-hour lifetime for generated SignOn session tokens. */
 constexpr std::uint32_t kDefaultTokenLifetimeSeconds = 3600;
-/** Family 5 uses the largest signed 64-bit value as its process-global object key. */
-constexpr std::uint64_t kGlobalFamily5Soid =
-    static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)());
-/** Global unlock-value slot named by the installed build's season constants. */
-constexpr std::uint16_t kActiveSeasonValueSlot = 607;
-/** One-based season number carried by the Season of Arrivals definition. */
-constexpr std::int32_t kSeasonOfArrivalsNumber = 11;
 /** Glimmer item definition, the currency an artifact reset charges. */
 constexpr std::uint32_t kGlimmerHash = 3159615086U;
 
@@ -68,7 +62,8 @@ constexpr std::uint32_t kGlimmerHash = 3159615086U;
 [[nodiscard]] bool same_profile_item(const account::inventory::ProfileItem& left,
                                      const account::inventory::ProfileItem& right) noexcept {
     return left.instanceSoid == right.instanceSoid && left.definitionHash == right.definitionHash
-           && left.quantity == right.quantity && left.mutationSerial == right.mutationSerial;
+           && left.quantity == right.quantity && left.mutationSerial == right.mutationSerial
+           && left.seen == right.seen;
 }
 
 /** Restores artifact-mod sockets to their manifest-declared initial plugs. */
@@ -123,25 +118,6 @@ constexpr std::uint32_t kGlimmerHash = 3159615086U;
     return true;
 }
 
-/**
- * Makes one process-owned global value authoritative without disturbing authored overrides.
- * @return False only when a new row is needed and the bounded family-5 list is full.
- */
-[[nodiscard]] bool
-upsert_family5_value(Family5State& family, std::uint16_t slot, std::int32_t value) noexcept {
-    for (std::size_t index = 0; index < family.valueCount; ++index) {
-        if (family.values[index].slot == slot) {
-            family.values[index].value = value;
-            return true;
-        }
-    }
-    if (family.valueCount >= family.values.size()) {
-        return false;
-    }
-    family.values[family.valueCount++] = UnlockValueOverride{slot, value};
-    return true;
-}
-
 /**
  * Fills fixed secret storage with Windows system randomness.
  * @tparam Size Required secret byte count.
@@ -174,31 +150,6 @@ void secure_reset(State& state) noexcept {
     new (&state) State{};
 }
 
-/** Seeds canonical character row generations before installed build data is needed. */
-[[nodiscard]] bool seed_inventory_runtime_fields(AccountState& accountState) noexcept {
-    if (!account::valid_authored(accountState)) {
-        return false;
-    }
-    for (std::size_t characterIndex = 0; characterIndex < accountState.characterCount;
-         ++characterIndex) {
-        CharacterState& character = accountState.characters[characterIndex];
-        std::uint32_t next = 0;
-        for (std::optional<account::inventory::Item>& item : character.equipment.slots) {
-            if (item.has_value()) {
-                item->mutationSerial = static_cast<std::int32_t>(next++);
-            }
-        }
-        for (std::size_t index = 0; index < character.inventory.count; ++index) {
-            character.inventory.values[index].mutationSerial = static_cast<std::int32_t>(next++);
-        }
-        for (std::size_t index = 0; index < character.stacks.count; ++index) {
-            character.stacks.values[index].mutationSerial = static_cast<std::int32_t>(next++);
-        }
-        character.nextInventorySerial = next;
-    }
-    return account::valid(accountState);
-}
-
 /**
  * Canonicalizes only profile rows which the installed socket UI materializes as action sources.
  * @param accountState Account canonicalized in place.
@@ -273,32 +224,29 @@ void secure_reset(State& state) noexcept {
 /**
  * Loads build data and generates secrets with Sunrise's authored activity defaults.
  * @param module Loaded Sunrise module, or null to disable disk persistence.
- * @param initialAccount Empty State, or a complete checked account from Core settings.
  * @return True when the cached data passes its checks and every secret gets random bytes.
  */
-bool initialize(void* module, const AccountState& initialAccount) noexcept {
-    return initialize(module, initialAccount, activity::defaults::authored());
+bool initialize(void* module) noexcept {
+    return initialize(module, activity::defaults::authored());
 }
 
 /**
  * Loads build data and publishes fixed activity defaults in one step.
  * @param module Loaded Sunrise module, or null to disable disk persistence.
- * @param initialAccount Empty State, or a complete checked account from Core settings.
  * @param activityDefaults Complete local fallback policy from immutable Core settings.
  * @return True when account, defaults, cached data, and generated secrets are valid.
  */
 bool initialize(void* module,
-                const AccountState& initialAccount,
                 const activity::defaults::ActivityDefaults& activityDefaults) noexcept {
     // AccountState and State are multi-megabyte fixed-capacity values. Keeping both as locals
     // exceeds the game's startup-thread stack before this function can execute any code.
-    const std::unique_ptr<AccountState> runtimeAccount{new (std::nothrow)
-                                                           AccountState(initialAccount)};
+    const std::unique_ptr<AccountState> runtimeAccount{new (std::nothrow) AccountState{}};
     const std::unique_ptr<State> initialized{new (std::nothrow) State{}};
     if (!runtimeAccount || !initialized) {
         return false;
     }
-    if (!seed_inventory_runtime_fields(*runtimeAccount)
+    investment::store::Transaction transaction;
+    if (!transaction.ready() || !investment::store::read_account(*runtimeAccount)
         || !activity::defaults::valid(activityDefaults)) {
         return false;
     }
@@ -340,30 +288,11 @@ bool initialize(void* module,
     // The published relay port is the one the listener binds, so both move with one setting.
     initialized->signOn.relayPort = core::settings::get().server.bapPort;
     initialized->signOn.tokenLifetimeSeconds = kDefaultTokenLifetimeSeconds;
-    initialized->account = *runtimeAccount;
-    initialized->activity.defaults = activityDefaults;
-    initialized->investment.family5.objectSoid = kGlobalFamily5Soid;
-    // Only the override lists come from settings. Identity and gate stay owned by State.
-    const Family5State& authored = core::settings::get().initialFamily5;
-    initialized->investment.family5.flags = authored.flags;
-    initialized->investment.family5.flagCount = authored.flagCount;
-    initialized->investment.family5.values = authored.values;
-    initialized->investment.family5.valueCount = authored.valueCount;
-    if (!upsert_family5_value(
-            initialized->investment.family5, kActiveSeasonValueSlot, kSeasonOfArrivalsNumber)) {
-        secure_reset(*initialized);
+    if (!investment::store::write_account(*runtimeAccount)) {
         build_data::shutdown();
         return false;
     }
-    // The arm is account-wide and rides the first ws-503, sent before any character is picked.
-    // The per-character objB byte still decides which character it opens.
-    for (std::size_t index = 0; index < runtimeAccount->characterCount; ++index) {
-        if (runtimeAccount->characters[index].contentBypass) {
-            initialized->investment.family5.contentGateArm = true;
-            break;
-        }
-    }
-
+    initialized->activity.defaults = activityDefaults;
     // Publish one complete State only after every generated secret is valid.
     AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
     secure_reset(runtime::storage::g_state);
@@ -373,7 +302,7 @@ bool initialize(void* module,
     // The seeded banks decide every derived bar, gate and seasonal counter, so both run last.
     (void)seed_seasonal_progression();
     unlocks::records::seed();
-    return true;
+    return transaction.commit();
 }
 
 /** Securely erases State, including activity destinations and matchmaking descriptors. */
@@ -382,6 +311,7 @@ void shutdown() noexcept {
     secure_reset(runtime::storage::g_state);
     ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
     build_data::shutdown();
+    investment::store::shutdown();
 }
 
 /** @return Immutable generated SignOn session fields. */
@@ -391,13 +321,16 @@ const SignOnState& sign_on() noexcept {
 
 /** Ensures every native profile action source has one unique runtime item-instance key. */
 bool ensure_profile_item_identities() noexcept {
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState candidate = runtime::storage::g_state.account;
+    investment::store::g_mutex.lock();
+    AccountState candidate = investment::store::account();
     const bool ready = canonicalize_profile_item_identities(candidate);
     if (ready) {
-        runtime::storage::g_state.account = candidate;
+        if (!investment::store::write_account(candidate)) {
+            investment::store::g_mutex.unlock();
+            return false;
+        }
     }
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::g_mutex.unlock();
     return ready;
 }
 
@@ -418,12 +351,7 @@ bool publish_bootstrap_token(std::span<const std::byte> token) noexcept {
 
 /** Records when the account signed in, on every character the account owns. */
 void publish_sign_in_time(std::uint64_t seconds) noexcept {
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    AccountState& accountState = runtime::storage::g_state.account;
-    for (std::size_t index = 0; index < accountState.characterCount; ++index) {
-        accountState.characters[index].signInSeconds = seconds;
-    }
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
+    investment::store::set_sign_in_time(seconds);
 }
 
 /** @return Immutable generated BAP session fields. */
@@ -444,10 +372,11 @@ bool new_bap_session(BapState& output) noexcept {
 
 /** Copies one complete evaluated content state with build-derived catalyst overrides. */
 bool investment_snapshot(InvestmentState& output) noexcept {
-    AcquireSRWLockShared(&runtime::storage::g_stateLock);
-    InvestmentState snapshot = runtime::storage::g_state.investment;
-    ReleaseSRWLockShared(&runtime::storage::g_stateLock);
-    if (!build_data::complete_exotic_catalyst_investment(snapshot.family5)) {
+    investment::store::g_mutex.lock();
+    InvestmentState snapshot;
+    const bool loaded = investment::store::read_family5(snapshot.family5);
+    investment::store::g_mutex.unlock();
+    if (!loaded || !build_data::complete_exotic_catalyst_investment(snapshot.family5)) {
         core::log::write(core::log::Channel::state,
                          core::log::Level::warn,
                          "ev=investment stage=snapshot result=fail reason=catalyst");
@@ -464,6 +393,10 @@ bool investment_snapshot(InvestmentState& output) noexcept {
  */
 bool reset_artifact(std::int32_t glimmerCost, ArtifactResetResult& result) noexcept {
     result = {};
+    investment::store::Transaction transaction;
+    if (!transaction.ready()) {
+        return false;
+    }
     if (glimmerCost <= 0) {
         return false;
     }
@@ -562,25 +495,18 @@ bool reset_artifact(std::int32_t glimmerCost, ArtifactResetResult& result) noexc
         return false;
     }
 
-    AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
-    bool current = runtime::detail::same_profile_inventory(runtime::storage::g_state.account,
-                                                           before.profileItems,
-                                                           before.profileItemCount)
-                   && runtime::storage::g_state.account.characterCount == before.characterCount;
-    const AccountState& live = runtime::storage::g_state.account;
+    const AccountState live = investment::store::account();
+    bool current =
+        runtime::detail::same_profile_inventory(live, before.profileItems, before.profileItemCount)
+        && live.characterCount == before.characterCount;
     for (std::size_t index = 0; current && index < before.characterCount; ++index) {
         current = runtime::detail::same_character(live.characters[index], before.characters[index]);
     }
-    if (current) {
-        runtime::storage::g_state.account = candidate;
-    }
-    ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
-    if (!current) {
-        (void)replace_artifact_mod_mask(0, previousMods);
-    } else {
-        result = changed;
+    if (!current || !investment::store::write_account(candidate) || !transaction.commit()) {
+        return false;
     }
-    return current;
+    result = changed;
+    return true;
 }
 
 } // namespace sunrise::state

+ 1 - 1
Sunrise/src/state/runtime/storage/internal.h

@@ -6,7 +6,7 @@
 
 namespace sunrise::state::runtime::storage {
 
-/** Root process-local State shared by folder-backed State submodules. */
+/** Root process-local session State; progression lives in the investment store. */
 extern State g_state;
 /** Windows reader-writer lock protecting mutable root State fields. */
 extern SRWLOCK g_stateLock;

+ 1 - 4
Sunrise/src/state/unlocks/definition.h

@@ -40,10 +40,7 @@ inline constexpr std::uint8_t kFlagSet = 2;
  */
 inline constexpr std::uint8_t kFlagClear = 0;
 
-/**
- * Authored unlock policy published once for the process.
- * Every bank is expanded at parse time, so readers copy bytes with no run decoding.
- */
+/** Call-local unlock banks expanded from the investment store. */
 struct Table {
     std::array<std::uint8_t, kAccountFlagCapacity> accountFlags{};
     std::array<std::uint8_t, kProfileFlagCapacity> profileFlags{};

+ 16 - 17
Sunrise/src/state/unlocks/unlocks_records.cpp

@@ -10,6 +10,7 @@
 #include "../build_data/nodes/node_catalog.h"
 #include "../build_data/records/record_catalog.h"
 #include "../build_data/runtime.h"
+#include "../investment/store.h"
 #include "definition.h"
 #include "unlocks_runtime.h"
 
@@ -46,7 +47,6 @@ std::array<bool, kAccountFlagCapacity> g_counterGranted{};
 bool g_cacheReady{};
 
 /** The authored lore values still stand; they are replaced once the catalogs first load. */
-bool g_loreSeedOwed{true};
 
 /** @return True when that lore node's book counts bars instead of claims. */
 [[nodiscard]] constexpr bool counter_granted_node(std::uint16_t nodeIndex) noexcept {
@@ -393,13 +393,13 @@ void clear_lore_objectives(Table& table) noexcept;
 /** Re-derives every value the claims in the banks imply. Order matters: gates run last. */
 void publish_derived(Table& table) noexcept {
     ensure_cache();
-    if (g_cacheReady && g_loreSeedOwed) {
+    if (g_cacheReady && !investment::store::bootstrap_completed("lore")) {
         // A lore chapter's authored value is not claim state, so the catalogs replace it once.
         clear_lore_objectives(table);
-        (void)build_data::complete_exotic_catalyst_objectives(table.objectiveValues);
-        (void)build_data::complete_exotic_catalyst_flags(table.accountFlags);
-        g_loreSeedOwed = false;
+        (void)investment::store::complete_bootstrap("lore");
     }
+    (void)build_data::complete_exotic_catalyst_objectives(table.objectiveValues);
+    (void)build_data::complete_exotic_catalyst_flags(table.accountFlags);
     (void)node_catalog::apply_visibility(table.accountFlags);
     (void)node_catalog::apply_character_visibility(
         std::as_writable_bytes(std::span(table.characterObjectFlags)));
@@ -544,7 +544,6 @@ struct FlagOperation {
 void seed() noexcept {
     mutate(nullptr, [](void*, Table& table) noexcept {
         g_cacheReady = false;
-        g_loreSeedOwed = true;
         publish_derived(table);
     });
 }
@@ -565,30 +564,30 @@ bool claimed(std::uint16_t flagIndex) noexcept {
 /** @return True when that record reads complete while its flag stays clear. */
 bool claimable(std::uint16_t flagIndex) noexcept {
     FlagOperation operation{flagIndex, false, ObjectiveAdvance::unavailable};
-    mutate(&operation, [](void* context, Table& table) noexcept {
+    const bool saved = mutate(&operation, [](void* context, Table& table) noexcept {
         auto& query = *static_cast<FlagOperation*>(context);
         ensure_cache();
         catalog::Definition record{};
         query.result = !flag_set(table, query.flagIndex) && find_by_flag(query.flagIndex, record)
                        && complete(table, record);
     });
-    return operation.result;
+    return saved && operation.result;
 }
 
 /** Claims one record: sets its flag, adds its score, and re-derives the bars it feeds. */
 bool claim(std::uint16_t recordIndex) noexcept {
     RecordOperation operation{recordIndex, 0, false};
-    mutate(&operation, [](void* context, Table& table) noexcept {
+    const bool saved = mutate(&operation, [](void* context, Table& table) noexcept {
         auto& request = *static_cast<RecordOperation*>(context);
         request.result = claim_locked(table, request.recordIndex);
     });
-    return operation.result;
+    return saved && operation.result;
 }
 
 /** Undoes one claim so a refused commit cannot leave the record held. */
 void revoke(std::uint16_t recordIndex) noexcept {
     RecordOperation operation{recordIndex, 0, false};
-    mutate(&operation, [](void* context, Table& table) noexcept {
+    (void)mutate(&operation, [](void* context, Table& table) noexcept {
         auto& request = *static_cast<RecordOperation*>(context);
         ensure_cache();
         catalog::Definition record{};
@@ -606,7 +605,7 @@ void revoke(std::uint16_t recordIndex) noexcept {
 /** Redeems the next completed step of a record that scores per step. */
 bool claim_interval(std::uint16_t recordIndex, std::uint32_t definitionHash) noexcept {
     RecordOperation operation{recordIndex, definitionHash, false};
-    mutate(&operation, [](void* context, Table& table) noexcept {
+    const bool saved = mutate(&operation, [](void* context, Table& table) noexcept {
         auto& request = *static_cast<RecordOperation*>(context);
         catalog::Definition record{};
         if (!build_data::find_record_definition(request.recordIndex, record)
@@ -630,7 +629,7 @@ bool claim_interval(std::uint16_t recordIndex, std::uint32_t definitionHash) noe
         add_score(table, static_cast<std::int32_t>(step.score));
         request.result = true;
     });
-    return operation.result;
+    return saved && operation.result;
 }
 
 /** Marks one lore chapter collected. */
@@ -639,11 +638,11 @@ GrantOutcome grant_chapter(std::uint16_t recordIndex) noexcept {
         std::uint16_t recordIndex{};
         GrantOutcome outcome{GrantOutcome::refused};
     } operation{recordIndex, GrantOutcome::refused};
-    mutate(&operation, [](void* context, Table& table) noexcept {
+    const bool saved = mutate(&operation, [](void* context, Table& table) noexcept {
         auto& request = *static_cast<GrantOperation*>(context);
         request.outcome = grant_locked(table, request.recordIndex);
     });
-    return operation.outcome;
+    return saved ? operation.outcome : GrantOutcome::refused;
 }
 
 /** Advances one counted lore chapter by one objective unit. */
@@ -674,11 +673,11 @@ GrantOutcome advance_chapter(std::uint16_t recordIndex) noexcept {
 /** Advances the single-objective record that owns one completion flag. */
 ObjectiveAdvance advance_objective(std::uint16_t flagIndex) noexcept {
     FlagOperation operation{flagIndex, false, ObjectiveAdvance::unavailable};
-    mutate(&operation, [](void* context, Table& table) noexcept {
+    const bool saved = mutate(&operation, [](void* context, Table& table) noexcept {
         auto& request = *static_cast<FlagOperation*>(context);
         request.advance = advance_locked(table, request.flagIndex);
     });
-    return operation.advance;
+    return saved ? operation.advance : ObjectiveAdvance::unavailable;
 }
 
 /** @return Triumph score published in the account value bank. */

+ 79 - 89
Sunrise/src/state/unlocks/unlocks_runtime.cpp

@@ -4,134 +4,124 @@
 #include <mutex>
 #include <shared_mutex>
 
-#include "core/threading/srw_lock.h"
+#include "../investment/store_internal.h"
 
 namespace sunrise::state::unlocks {
-namespace {
+namespace store = investment::store;
 
-Table g_table{};
-core::threading::SrwLock g_lock;
-
-} // namespace
-
-/** Seeds the live unlock banks from the boot policy. */
+/** Replaces the saved unlock banks in one transaction. */
 void publish(const Table& table) noexcept {
-    const std::lock_guard guard(g_lock);
-    g_table = table;
+    (void)store::write_unlocks(table);
+}
+
+/** @return A call-local copy of the saved banks. */
+Table get() noexcept {
+    Table table;
+    if (!store::read_unlocks(table)) {
+        table = {};
+    }
+    return table;
 }
 
-/** @return The live unlock banks. */
-const Table& get() noexcept {
-    return g_table;
+/** Reads the requested character's banks and the shared account banks together. */
+bool snapshot(Table& output, int characterSlot) noexcept {
+    return store::read_unlocks(output, characterSlot);
 }
 
-/** Restores empty unlock banks. */
+/** Clears the saved banks for the active account and selected character. */
 void clear() noexcept {
-    const std::lock_guard guard(g_lock);
-    g_table = Table{};
+    (void)store::write_unlocks(Table{});
 }
 
-/** Runs one write over the live banks under the exclusive lock. */
-void mutate(void* context, void (*apply)(void*, Table&) noexcept) noexcept {
+/** Applies one mutation and reports success only after its database commit. */
+bool mutate(void* context, void (*apply)(void*, Table&) noexcept) noexcept {
     if (apply == nullptr) {
-        return;
+        return false;
+    }
+    store::Transaction transaction;
+    Table table;
+    if (!transaction.ready() || !store::read_unlocks(table)) {
+        return false;
     }
-    const std::lock_guard guard(g_lock);
-    apply(context, g_table);
+    apply(context, table);
+    return store::write_unlocks(table) && transaction.commit();
 }
 
-/** @return True when the account acquired flag at this row is set. */
+/** Reads one saved accountFlags entry. */
 bool account_flag_set(std::uint16_t index) noexcept {
-    const std::shared_lock guard(g_lock);
-    return index < g_table.accountFlags.size() && g_table.accountFlags[index] == kFlagSet;
+    std::int32_t value = 0;
+    const bool loaded =
+        index < kAccountFlagCapacity && store::read_unlock(store::Bank::accountFlags, index, value);
+    return loaded && value == kFlagSet;
 }
 
-/** @return True when the selected character's object flag at this row is set. */
+/** Reads one saved characterObjectFlags entry. */
 bool character_object_flag_set(std::uint16_t index) noexcept {
-    const std::shared_lock guard(g_lock);
-    return index < g_table.characterObjectFlags.size()
-           && g_table.characterObjectFlags[index] == kFlagSet;
+    std::int32_t value = 0;
+    const bool loaded = index < kCharacterObjectFlagCapacity
+                        && store::read_unlock(store::Bank::characterObjectFlags, index, value);
+    return loaded && value == kFlagSet;
 }
 
-/** Writes one account acquired flag. */
-bool set_account_flag(std::uint16_t index, std::uint8_t value) noexcept {
-    const std::lock_guard guard(g_lock);
-    if (index >= g_table.accountFlags.size()) {
-        return false;
-    }
-    g_table.accountFlags[index] = value;
-    return true;
+/** Reads one saved objectiveValues entry. */
+std::int32_t objective_value(std::uint16_t index) noexcept {
+    std::int32_t value = 0;
+    const bool loaded = index < kObjectiveValueCapacity
+                        && store::read_unlock(store::Bank::objectiveValues, index, value);
+    return loaded ? value : 0;
 }
 
-/** @return One account objective value. */
-std::int32_t objective_value(std::uint16_t index) noexcept {
-    const std::shared_lock guard(g_lock);
-    return index < g_table.objectiveValues.size() ? g_table.objectiveValues[index] : 0;
+/** Reads one saved accountProgressions entry. */
+std::int32_t account_progression(std::uint16_t definitionIndex) noexcept {
+    std::int32_t value = 0;
+    const bool loaded =
+        definitionIndex < build_data::progressions::kDefinitionCapacity
+        && store::read_unlock(store::Bank::accountProgressions, definitionIndex, value);
+    return loaded ? value : 0;
 }
 
-/** Writes one account objective value. */
-bool set_objective_value(std::uint16_t index, std::int32_t value) noexcept {
-    const std::lock_guard guard(g_lock);
-    if (index >= g_table.objectiveValues.size()) {
-        return false;
-    }
-    g_table.objectiveValues[index] = value;
-    return true;
+/** Saves one bounded accountFlags entry. */
+bool set_account_flag(std::uint16_t index, std::uint8_t value) noexcept {
+    return index < kAccountFlagCapacity
+           && store::write_unlock(store::Bank::accountFlags, index, value);
 }
 
-/** Adds to one account objective value. */
-bool add_objective_value(std::uint16_t index, std::int32_t amount) noexcept {
-    const std::lock_guard guard(g_lock);
-    if (index >= g_table.objectiveValues.size()) {
-        return false;
-    }
-    std::int32_t& slot = g_table.objectiveValues[index];
-    if (amount > 0 && slot > (std::numeric_limits<std::int32_t>::max)() - amount) {
-        return false;
-    }
-    if (amount < 0 && slot < (std::numeric_limits<std::int32_t>::min)() - amount) {
-        return false;
-    }
-    slot += amount;
-    return true;
+/** Saves one bounded objectiveValues entry. */
+bool set_objective_value(std::uint16_t index, std::int32_t value) noexcept {
+    return index < kObjectiveValueCapacity
+           && store::write_unlock(store::Bank::objectiveValues, index, value);
 }
 
-/** Writes one selected-character object flag. */
+/** Saves one bounded characterObjectFlags entry. */
 bool set_character_object_flag(std::uint16_t index, std::uint8_t value) noexcept {
-    const std::lock_guard guard(g_lock);
-    if (index >= g_table.characterObjectFlags.size()) {
-        return false;
-    }
-    g_table.characterObjectFlags[index] = value;
-    return true;
+    return index < kCharacterObjectFlagCapacity
+           && store::write_unlock(store::Bank::characterObjectFlags, index, value);
 }
 
-/** Writes one selected-character object value. */
+/** Saves one bounded characterObjectValues entry. */
 bool set_character_object_value(std::uint16_t index, std::int32_t value) noexcept {
-    const std::lock_guard guard(g_lock);
-    if (index >= g_table.characterObjectValues.size()) {
-        return false;
-    }
-    g_table.characterObjectValues[index] = value;
-    return true;
+    return index < kCharacterObjectValueCapacity
+           && store::write_unlock(store::Bank::characterObjectValues, index, value);
 }
 
-/** @return Lane 0 of one account progression. */
-std::int32_t account_progression(std::uint16_t definitionIndex) noexcept {
-    const std::shared_lock guard(g_lock);
-    return definitionIndex < g_table.accountProgressions.size()
-               ? g_table.accountProgressions[definitionIndex][0]
-               : 0;
+/** Saves one bounded accountProgressions entry. */
+bool set_account_progression(std::uint16_t definitionIndex, std::int32_t value) noexcept {
+    return definitionIndex < build_data::progressions::kDefinitionCapacity
+           && store::write_unlock(store::Bank::accountProgressions, definitionIndex, value);
 }
 
-/** Writes lane 0 of one account progression. */
-bool set_account_progression(std::uint16_t definitionIndex, std::int32_t value) noexcept {
-    const std::lock_guard guard(g_lock);
-    if (definitionIndex >= g_table.accountProgressions.size()) {
+/** Adds to an objective under the same transaction that guards overflow. */
+bool add_objective_value(std::uint16_t index, std::int32_t amount) noexcept {
+    store::Transaction transaction;
+    std::int32_t value = 0;
+    if (!transaction.ready() || index >= kObjectiveValueCapacity
+        || !store::read_unlock(store::Bank::objectiveValues, index, value)
+        || (amount > 0 && value > (std::numeric_limits<std::int32_t>::max)() - amount)
+        || (amount < 0 && value < (std::numeric_limits<std::int32_t>::min)() - amount)) {
         return false;
     }
-    g_table.accountProgressions[definitionIndex][0] = value;
-    return true;
+    return store::write_unlock(store::Bank::objectiveValues, index, value + amount)
+           && transaction.commit();
 }
 
 } // namespace sunrise::state::unlocks

+ 3 - 2
Sunrise/src/state/unlocks/unlocks_runtime.h

@@ -13,7 +13,8 @@ namespace sunrise::state::unlocks {
 void publish(const Table& table) noexcept;
 
 /** @return The live unlock banks. Every writer runs on the server thread. */
-[[nodiscard]] const Table& get() noexcept;
+[[nodiscard]] Table get() noexcept;
+[[nodiscard]] bool snapshot(Table& output, int characterSlot = -1) noexcept;
 
 /** Restores empty unlock banks. */
 void clear() noexcept;
@@ -24,7 +25,7 @@ void clear() noexcept;
  * @param context Passed through untouched.
  * @param apply Called once with the live banks.
  */
-void mutate(void* context, void (*apply)(void*, Table&) noexcept) noexcept;
+bool mutate(void* context, void (*apply)(void*, Table&) noexcept) noexcept;
 
 /** @param index Account flag bank row. @return True when the flag is set. */
 [[nodiscard]] bool account_flag_set(std::uint16_t index) noexcept;

+ 1 - 1
Sunrise/src/steam/interfaces/methods/apps_dlc.cpp

@@ -9,7 +9,7 @@ namespace sunrise::steam::interfaces::methods {
 namespace {
 
 /** @return The authored ownership policy. It also lists installed DLC. */
-[[nodiscard]] const state::entitlements::Table& policy() noexcept {
+[[nodiscard]] state::entitlements::Table policy() noexcept {
     return state::entitlements::get();
 }
 

+ 10 - 0
Sunrise/vendor/sqlite/NOTICE.txt

@@ -0,0 +1,10 @@
+SQLite 3.53.4
+
+SQLite is in the public domain. Its authors dedicate their contributions to the public domain.
+https://www.sqlite.org/copyright.html
+
+Source: https://www.sqlite.org/2026/sqlite-amalgamation-3530400.zip
+Archive SHA3-256: 628a44cfe82c66aed1ccbbe85a562d2e33ebe64b3288981ed76285612227934e
+
+The unmodified sqlite3.c and sqlite3.h amalgamation files are compiled into Sunrise.
+The command-line shell and loadable extensions are not included.

Неке датотеке нису приказане због велике количине промена