Browse Source

Civ commits pre 11/04/2025

Taislin 9 months ago
parent
commit
5209471577
100 changed files with 11823 additions and 2320 deletions
  1. 5 16
      .github/PULL_REQUEST_TEMPLATE.md
  2. 0 47
      .github/workflows/benchmarks.yml
  3. 0 41
      .github/workflows/build-docfx.yml
  4. 0 62
      .github/workflows/build-test-debug.yml
  5. 0 21
      .github/workflows/labeler-conflict.yml
  6. 0 20
      .github/workflows/labeler-size.yml
  7. 0 16
      .github/workflows/labeler-untriaged.yml
  8. 0 69
      .github/workflows/rsi-diff.yml
  9. 0 54
      .github/workflows/update-credits.yml
  10. 72 0
      .github/workflows/upload-client.yml
  11. 0 26
      .github/workflows/validate-rsis.yml
  12. 4 0
      .gitignore
  13. 3873 0
      Civ14-Wiki/MDwiki.js
  14. 7 0
      Civ14-Wiki/README.md
  15. 3 0
      Civ14-Wiki/config.json
  16. 8 0
      Civ14-Wiki/extlib/css/bootstrap-3.0.0.min.css
  17. 51 0
      Civ14-Wiki/extlib/css/colorbox.css
  18. 6 0
      Civ14-Wiki/extlib/css/prism.1.4.1.default.min.css
  19. 5 0
      Civ14-Wiki/extlib/js/bootstrap-3.0.0.min.js
  20. 1 0
      Civ14-Wiki/extlib/js/jquery-1.8.3.min.js
  21. 942 0
      Civ14-Wiki/extlib/js/jquery.colorbox.js
  22. 0 0
      Civ14-Wiki/extlib/js/jquery.colorbox.min.js
  23. 1 0
      Civ14-Wiki/extlib/js/prism.1.4.1.min.js
  24. BIN
      Civ14-Wiki/favicon.ico
  25. 3 0
      Civ14-Wiki/gamemodes/aotd.md
  26. 125 0
      Civ14-Wiki/gamemodes/nomads.md
  27. 3 0
      Civ14-Wiki/gamemodes/tdm.md
  28. 3 0
      Civ14-Wiki/guides/guide_to_combat.md
  29. 3 0
      Civ14-Wiki/guides/guide_to_construction.md
  30. 3 0
      Civ14-Wiki/guides/guide_to_crafting.md
  31. 54 0
      Civ14-Wiki/guides/guide_to_farming.md
  32. 3 0
      Civ14-Wiki/guides/guide_to_medical.md
  33. 3 0
      Civ14-Wiki/guides/guide_to_metallurgy.md
  34. 24 0
      Civ14-Wiki/guides/playing.md
  35. 178 0
      Civ14-Wiki/guides/starter_guide.md
  36. BIN
      Civ14-Wiki/img/arrival.png
  37. BIN
      Civ14-Wiki/img/boulder.png
  38. BIN
      Civ14-Wiki/img/flint_axe.png
  39. 137 0
      Civ14-Wiki/index.html
  40. 35 0
      Civ14-Wiki/index.md
  41. 33 0
      Civ14-Wiki/navigation.md
  42. 238 0
      Civ14-Wiki/rules/rules.md
  43. 11 0
      CivMigrations/README.md
  44. 5333 0
      CivMigrations/migrations.json
  45. 1 1
      Content.Benchmarks/MapLoadBenchmark.cs
  46. 2 2
      Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml
  47. 5 0
      Content.Client/CartridgeLoader/Cartridges/NanoTaskCartridgeSystem.cs
  48. 32 0
      Content.Client/CartridgeLoader/Cartridges/NanoTaskItemControl.xaml
  49. 33 0
      Content.Client/CartridgeLoader/Cartridges/NanoTaskItemControl.xaml.cs
  50. 67 0
      Content.Client/CartridgeLoader/Cartridges/NanoTaskItemPopup.xaml
  51. 109 0
      Content.Client/CartridgeLoader/Cartridges/NanoTaskItemPopup.xaml.cs
  52. 82 0
      Content.Client/CartridgeLoader/Cartridges/NanoTaskUi.cs
  53. 58 0
      Content.Client/CartridgeLoader/Cartridges/NanoTaskUiFragment.xaml
  54. 52 0
      Content.Client/CartridgeLoader/Cartridges/NanoTaskUiFragment.xaml.cs
  55. 1 1
      Content.Client/Clothing/ClientClothingSystem.cs
  56. 4 3
      Content.Client/Construction/UI/ConstructionMenuPresenter.cs
  57. 4 3
      Content.Client/CriminalRecords/CriminalRecordsConsoleWindow.xaml.cs
  58. 4 4
      Content.Client/Entry/EntryPoint.cs
  59. 6 1
      Content.Client/Hands/Systems/HandsSystem.cs
  60. 12 12
      Content.Client/Humanoid/HumanoidAppearanceSystem.cs
  61. 6 0
      Content.Client/IconSmoothing/IconSmoothComponent.cs
  62. 2 1
      Content.Client/IconSmoothing/IconSmoothSystem.cs
  63. 0 6
      Content.Client/Kitchen/UI/MicrowaveMenu.xaml
  64. 1 1
      Content.Client/Parallax/Data/ParallaxPrototype.cs
  65. 1 1
      Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml.cs
  66. 24 2
      Content.Client/SubFloor/SubFloorHideSystem.cs
  67. 14 2
      Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs
  68. 12 1
      Content.Client/UserInterface/Systems/Sandbox/Windows/SandboxWindow.xaml.cs
  69. 0 1
      Content.Docfx/articles/example-article.md
  70. 0 2
      Content.Docfx/articles/toc.yml
  71. 0 134
      Content.Docfx/docfx.json
  72. 0 9
      Content.Docfx/index.md
  73. 0 21
      Content.Docfx/templates/darkfx/LICENSE.txt
  74. 0 40
      Content.Docfx/templates/darkfx/partials/affix.tmpl.partial
  75. 0 108
      Content.Docfx/templates/darkfx/partials/class.header.tmpl.partial
  76. 0 29
      Content.Docfx/templates/darkfx/partials/footer.tmpl.partial
  77. 0 20
      Content.Docfx/templates/darkfx/partials/head.tmpl.partial
  78. 0 470
      Content.Docfx/templates/darkfx/styles/main.css
  79. 0 35
      Content.Docfx/templates/darkfx/styles/toggle-theme.js
  80. 0 18
      Content.Docfx/toc.yml
  81. 1 1
      Content.IntegrationTests/PoolManager.cs
  82. 7 7
      Content.IntegrationTests/Tests/Commands/ForceMapTest.cs
  83. 0 124
      Content.IntegrationTests/Tests/Construction/ConstructionActionValid.cs
  84. 0 164
      Content.IntegrationTests/Tests/Construction/ConstructionPrototypeTest.cs
  85. 0 97
      Content.IntegrationTests/Tests/Construction/Interaction/ComputerContruction.cs
  86. 0 131
      Content.IntegrationTests/Tests/Construction/Interaction/CraftingTests.cs
  87. 0 56
      Content.IntegrationTests/Tests/Construction/Interaction/GrilleWindowConstruction.cs
  88. 0 59
      Content.IntegrationTests/Tests/Construction/Interaction/MachineConstruction.cs
  89. 0 40
      Content.IntegrationTests/Tests/Construction/Interaction/PanelScrewing.cs
  90. 0 23
      Content.IntegrationTests/Tests/Construction/Interaction/PlaceableDeconstruction.cs
  91. 0 33
      Content.IntegrationTests/Tests/Construction/Interaction/WallConstruction.cs
  92. 0 50
      Content.IntegrationTests/Tests/Construction/Interaction/WindowConstruction.cs
  93. 0 42
      Content.IntegrationTests/Tests/Construction/Interaction/WindowRepair.cs
  94. 4 0
      Content.IntegrationTests/Tests/Destructible/DestructibleTestPrototypes.cs
  95. 94 0
      Content.IntegrationTests/Tests/DeviceLinking/DeviceLinkingTest.cs
  96. 0 150
      Content.IntegrationTests/Tests/DoAfter/DoAfterCancellationTests.cs
  97. 5 1
      Content.IntegrationTests/Tests/GameRules/NukeOpsTest.cs
  98. 10 7
      Content.IntegrationTests/Tests/Localization/LocalizedDatasetPrototypeTest.cs
  99. 3 34
      Content.IntegrationTests/Tests/PostMapInitTest.cs
  100. 0 1
      Content.IntegrationTests/Tests/PrototypeSaveTest.cs

+ 5 - 16
.github/PULL_REQUEST_TEMPLATE.md

@@ -1,29 +1,18 @@
-<!-- Guidelines: https://docs.spacestation14.io/en/getting-started/pr-guideline -->
-
 ## About the PR
 ## About the PR
-<!-- What did you change? -->
 
 
-## Why / Balance
-<!-- Discuss how this would affect game balance or explain why it was changed. Link any relevant discussions or issues. -->
+<!-- What did you change? -->
 
 
 ## Technical details
 ## Technical details
+
 <!-- Summary of code changes for easier review. -->
 <!-- Summary of code changes for easier review. -->
 
 
 ## Media
 ## Media
-<!-- Attach media if the PR makes ingame changes (clothing, items, features, etc). 
-Small fixes/refactors are exempt. Media may be used in SS14 progress reports with credit. -->
-
-## Requirements
-<!-- Confirm the following by placing an X in the brackets [X]: -->
-- [ ] I have read and am following the [Pull Request and Changelog Guidelines](https://docs.spacestation14.com/en/general-development/codebase-info/pull-request-guidelines.html).
-- [ ] I have added media to this PR or it does not require an ingame showcase.
-<!-- You should understand that not following the above may get your PR closed at maintainer’s discretion -->
 
 
-## Breaking changes
-<!-- List any breaking changes, including namespaces, public class/method/field changes, prototype renames; and provide instructions for fixing them.
-This will be posted in #codebase-changes. -->
+<!-- Attach media if the PR makes ingame changes (clothing, items, features, etc).
+Small fixes/refactors are exempt. Media may be used in SS14 progress reports with credit. -->
 
 
 **Changelog**
 **Changelog**
+
 <!-- Add a Changelog entry to make players aware of new features or changes that could affect gameplay.
 <!-- Add a Changelog entry to make players aware of new features or changes that could affect gameplay.
 Make sure to read the guidelines and take this Changelog template out of the comment block in order for it to show up.
 Make sure to read the guidelines and take this Changelog template out of the comment block in order for it to show up.
 Changelog must have a :cl: symbol, so the bot recognizes the changes and adds them to the game's changelog. -->
 Changelog must have a :cl: symbol, so the bot recognizes the changes and adds them to the game's changelog. -->

+ 0 - 47
.github/workflows/benchmarks.yml

@@ -1,47 +0,0 @@
-name: Benchmarks
-on:
-  workflow_dispatch:
-  schedule:
-    - cron: '0 8 * * *'
-
-concurrency: benchmarks
-
-jobs:
-  benchmark:
-    name: Run Benchmarks
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions/checkout@v3.6.0
-      with:
-        submodules: 'recursive'
-    - name: Get Engine version
-      run: |
-        cd RobustToolbox
-        git fetch --depth=1
-        echo "::set-output name=out::$(git rev-parse HEAD)"
-      id: engine_version
-    - name: Run script on centcomm
-      uses: appleboy/ssh-action@master
-      with:
-        host: centcomm.spacestation14.io
-        username: robust-benchmark-runner
-        key: ${{ secrets.CENTCOMM_ROBUST_BENCHMARK_RUNNER_KEY }}
-        command_timeout: 100000m
-        script: |
-          mkdir benchmark_run_content_${{ github.sha }}
-          cd benchmark_run_content_${{ github.sha }}
-          git clone https://github.com/space-wizards/space-station-14.git repo_dir --recursive
-          cd repo_dir
-          git checkout ${{ github.sha }}
-          cd Content.Benchmarks
-          dotnet restore
-          export ROBUST_BENCHMARKS_ENABLE_SQL=1
-          export ROBUST_BENCHMARKS_SQL_ADDRESS="${{ secrets.BENCHMARKS_WRITE_ADDRESS }}"
-          export ROBUST_BENCHMARKS_SQL_PORT="${{ secrets.BENCHMARKS_WRITE_PORT }}"
-          export ROBUST_BENCHMARKS_SQL_USER="${{ secrets.BENCHMARKS_WRITE_USER }}"
-          export ROBUST_BENCHMARKS_SQL_PASSWORD="${{ secrets.BENCHMARKS_WRITE_PASSWORD  }}"
-          export ROBUST_BENCHMARKS_SQL_DATABASE="content_benchmarks"
-          export GITHUB_SHA="${{ github.sha }}"
-          dotnet run --filter '*' --configuration Release
-          cd ../../..
-          rm -rf benchmark_run_content_${{ github.sha }}

+ 0 - 41
.github/workflows/build-docfx.yml

@@ -1,41 +0,0 @@
-name: Build & Publish Docfx
-
-on:
-  schedule:
-    - cron: "0 0 * * 0"
-
-jobs:
-  docfx:
-   runs-on: ubuntu-latest
-   steps:
-    - uses: actions/checkout@v3.6.0
-    - name: Setup submodule
-      run: |
-        git submodule update --init --recursive
-    - name: Pull engine updates
-      uses: space-wizards/submodule-dependency@v0.1.5
-    - name: Update Engine Submodules
-      run: |
-        cd RobustToolbox/
-        git submodule update --init --recursive
-    - name: Setup .NET Core
-      uses: actions/setup-dotnet@v3.2.0
-      with:
-        dotnet-version: 9.0.x
-
-    - name: Install dependencies
-      run: dotnet restore
-
-    - name: Build Project
-      run: dotnet build --no-restore /p:WarningsAsErrors=nullable
-
-    - name: Build DocFX
-      uses: nikeee/docfx-action@v1.0.0
-      with:
-        args: Content.Docfx/docfx.json
-
-    - name: Publish Docfx Documentation on GitHub Pages
-      uses: maxheld83/ghpages@master
-      env:
-        BUILD_DIR: Content.Docfx/_content-site
-        GH_PAT: ${{ secrets.GH_PAT }}

+ 0 - 62
.github/workflows/build-test-debug.yml

@@ -1,62 +0,0 @@
-name: Build & Test Debug
-
-on:
-  push:
-    branches: [ master, staging, stable ]
-  merge_group:
-  pull_request:
-    types: [ opened, reopened, synchronize, ready_for_review ]
-    branches: [ master, staging, stable ]
-
-jobs:
-  build:
-    if: github.actor != 'PJBot' && github.event.pull_request.draft == false
-    strategy:
-      matrix:
-        os: [ubuntu-latest]
-
-    runs-on: ${{ matrix.os }}
-
-    steps:
-    - name: Checkout Master
-      uses: actions/checkout@v3.6.0
-
-    - name: Setup Submodule
-      run: |
-        git submodule update --init --recursive
-
-    - name: Pull engine updates
-      uses: space-wizards/submodule-dependency@v0.1.5
-
-    - name: Update Engine Submodules
-      run: |
-        cd RobustToolbox/
-        git submodule update --init --recursive
-
-    - name: Setup .NET Core
-      uses: actions/setup-dotnet@v3.2.0
-      with:
-        dotnet-version: 9.0.x
-
-    - name: Install dependencies
-      run: dotnet restore
-
-    - name: Build Project
-      run: dotnet build --configuration DebugOpt --no-restore /p:WarningsAsErrors=nullable /m
-
-    - name: Run Content.Tests
-      run: dotnet test --no-build --configuration DebugOpt Content.Tests/Content.Tests.csproj -- NUnit.ConsoleOut=0
-
-    - name: Run Content.IntegrationTests
-      shell: pwsh
-      run: |
-        $env:DOTNET_gcServer=1
-        dotnet test --no-build --configuration DebugOpt Content.IntegrationTests/Content.IntegrationTests.csproj -- NUnit.ConsoleOut=0 NUnit.MapWarningTo=Failed
-  ci-success:
-    name: Build & Test Debug
-    needs:
-      - build
-    runs-on: ubuntu-latest
-    steps:
-      - name: CI succeeded
-        run: exit 0

+ 0 - 21
.github/workflows/labeler-conflict.yml

@@ -1,21 +0,0 @@
-name: Check Merge Conflicts
-
-on:
-  pull_request_target:
-    types:
-      - opened
-      - synchronize
-      - reopened
-      - ready_for_review
-
-jobs:
-  Label:
-    if: ( github.event.pull_request.draft == false ) && ( github.actor != 'PJBot' )
-    runs-on: ubuntu-latest
-    steps:
-      - name: Check for Merge Conflicts
-        uses: eps1lon/actions-label-merge-conflict@v3.0.0
-        with:
-          dirtyLabel: "S: Merge Conflict"
-          repoToken: "${{ secrets.GITHUB_TOKEN }}"
-          commentOnDirty: "This pull request has conflicts, please resolve those before we can evaluate the pull request."

+ 0 - 20
.github/workflows/labeler-size.yml

@@ -1,20 +0,0 @@
-name: "Labels: Size"
-on: pull_request_target
-jobs:
-  size-label:
-    runs-on: ubuntu-latest
-    steps:
-      - name: size-label
-        uses: "pascalgn/size-label-action@v0.5.5"
-        env:
-          GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
-        with:
-          # Custom size configuration
-          sizes: >
-            {
-              "0": "XS",
-              "10": "S",
-              "100": "M",
-              "1000": "L",
-              "5000": "XL"
-            }

+ 0 - 16
.github/workflows/labeler-untriaged.yml

@@ -1,16 +0,0 @@
-name: "Labels: Untriaged"
-
-on:
-  issues:
-    types: [opened]
-  pull_request_target:
-    types: [opened]
-
-jobs:
-  add_label:
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions-ecosystem/action-add-labels@v1
-      if: join(github.event.issue.labels) == ''
-      with:
-        labels: "S: Untriaged"

+ 0 - 69
.github/workflows/rsi-diff.yml

@@ -1,69 +0,0 @@
-name: Diff RSIs
-
-on:
-  pull_request_target:
-    paths:
-      - '**.rsi/**.png'
-
-jobs:
-  diff:
-    name: Diff
-    runs-on: ubuntu-latest
-    steps:
-      - name: Checkout
-        uses: actions/checkout@v3.6.0
-
-      - name: Get changed files
-        id: files
-        uses: Ana06/get-changed-files@v2.3.0
-        with:
-          format: 'space-delimited'
-          filter: | 
-            **.rsi
-            **.png
-
-      - name: Diff changed RSIs
-        id: diff
-        uses: space-wizards/RSIDiffBot@v1.1
-        with:
-          modified: ${{ steps.files.outputs.modified }}
-          removed: ${{ steps.files.outputs.removed }}
-          added: ${{ steps.files.outputs.added }}
-          basename: ${{ github.event.pull_request.base.repo.full_name }}
-          basesha: ${{ github.event.pull_request.base.sha }}
-          headname: ${{ github.event.pull_request.head.repo.full_name }}
-          headsha: ${{ github.event.pull_request.head.sha }}
-
-      - name: Potentially find comment
-        uses: peter-evans/find-comment@v1
-        id: fc
-        with:
-          issue-number: ${{ github.event.number }}
-          comment-author: 'github-actions[bot]'
-          body-includes: RSI Diff Bot
-
-      - name: Create comment if it doesn't exist
-        if: steps.fc.outputs.comment-id == ''
-        uses: peter-evans/create-or-update-comment@v1
-        with:
-          issue-number: ${{ github.event.number }}
-          body: |
-            ${{ steps.diff.outputs.summary-details }}
-
-      - name: Update comment if it exists
-        if: steps.fc.outputs.comment-id != ''
-        uses: peter-evans/create-or-update-comment@v1
-        with:
-          comment-id: ${{ steps.fc.outputs.comment-id }}
-          edit-mode: replace
-          body: |
-            ${{ steps.diff.outputs.summary-details }}
-
-      - name: Update comment to read that it has been edited
-        if: steps.fc.outputs.comment-id != ''
-        uses: peter-evans/create-or-update-comment@v1
-        with:
-          comment-id: ${{ steps.fc.outputs.comment-id }}
-          edit-mode: append
-          body: |
-            Edit: diff updated after ${{ github.event.pull_request.head.sha }}

+ 0 - 54
.github/workflows/update-credits.yml

@@ -1,54 +0,0 @@
-name: Update Contrib and Patreons in credits
-
-on:
-  workflow_dispatch:
-  schedule:
-    - cron: 0 0 * * 0
-    
-jobs:
-  get_credits:
-    runs-on: ubuntu-latest
-    # Hey there fork dev! If you like to include your own contributors in this then you can probably just change this to your own repo
-    # Do this in dump_github_contributors.ps1 too into your own repo
-    if: github.repository == 'space-wizards/space-station-14'
-    
-    steps:
-      - uses: actions/checkout@v3.6.0
-        with:
-          ref: master
-        
-      - name: Get this week's Contributors
-        shell: pwsh
-        env:
-          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
-        run: Tools/dump_github_contributors.ps1 > Resources/Credits/GitHub.txt
-
-      # TODO
-      #- name: Get this week's Patreons
-      #  run: Tools/script2dumppatreons > Resources/Credits/Patrons.yml        
-      
-      # MAKE SURE YOU ENABLED "Allow GitHub Actions to create and approve pull requests" IN YOUR ACTIONS, OTHERWISE IT WILL MOST LIKELY FAIL
-
-
-      # For this you can use a pat token of an account with direct push access to the repo if you have protected branches. 
-      # Uncomment this and comment the other line if you do this.
-      # https://github.com/stefanzweifel/git-auto-commit-action#push-to-protected-branches
-      
-      #- name: Commit new credit files
-      #  uses: stefanzweifel/git-auto-commit-action@v4
-      #  with:
-      #    commit_message: Update Credits
-      #    commit_author: PJBot <pieterjan.briers+bot@gmail.com>
-      
-      # This will make a PR
-      - name: Set current date as env variable
-        run: echo "NOW=$(date +'%Y-%m-%dT%H-%M-%S')" >> $GITHUB_ENV
-        
-      - name: Create Pull Request
-        uses: peter-evans/create-pull-request@v5
-        with:
-          commit-message: Update Credits
-          title: Update Credits
-          body: This is an automated Pull Request. This PR updates the github contributors in the credits section.
-          author: PJBot <pieterjan.briers+bot@gmail.com>
-          branch: automated/credits-${{env.NOW}}

+ 72 - 0
.github/workflows/upload-client.yml

@@ -0,0 +1,72 @@
+name: Compile and Update Compiled Client
+
+on:
+  push:
+    branches:
+      - master # Trigger on push to master branch
+
+jobs:
+  compile-and-push:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Install dependencies
+        run: sudo apt-get install -y python3-paramiko python3-lxml
+
+      - name: Checkout Source Repo (Civ14)
+        uses: actions/checkout@v3.6.0
+        with:
+          submodules: "recursive"
+
+      - name: Setup .NET Core
+        uses: actions/setup-dotnet@v3.2.0
+        with:
+          dotnet-version: 9.0.x
+
+      - name: Setup Submodule
+        run: |
+          git submodule update --init --recursive
+
+      - name: Pull engine updates
+        uses: space-wizards/submodule-dependency@v0.1.5
+
+      - name: Update Engine Submodules
+        run: |
+          cd RobustToolbox/
+          git submodule update --init --recursive
+
+      - name: Install dependencies
+        run: dotnet restore
+
+      - name: Package Client
+        run: dotnet build -c Release -r win-x64 Content.Client
+
+      - name: Checkout Target Repo (Compiled Client)
+        uses: actions/checkout@v4
+        with:
+          repository: taislin/civ14_compiled_client
+          token: ${{ secrets.TARGET_REPO_TOKEN }}
+          path: target-repo
+
+      - name: Debug Build Output
+        run: |
+          echo "Current directory: $(pwd)"
+          ls -la
+          find . -type d -name "bin"  # Find all 'bin' directories
+          find . -type f -name "*.dll"  # Find compiled DLLs
+          find . -type f -name "*.exe"  # Find compiled EXEs
+          ls -la ./bin/Content.Client/ || echo "Directory not found"
+
+      - name: Update Target Repo
+        run: |
+          # Copy compiled output to target-repo/
+          rsync -av --ignore-existing ./bin/Content.Client/win-x64/ target-repo/ || true
+          cd target-repo
+          git config user.name "GitHub Action"
+          git config user.email "action@github.com"
+          git add .
+          if git status --porcelain | grep .; then
+            git commit -m "Update compiled client from Civ14 - changed files only"
+            git push
+          else
+            echo "No changes detected, skipping commit and push"
+          fi

+ 0 - 26
.github/workflows/validate-rsis.yml

@@ -1,26 +0,0 @@
-name: RSI Validator
-
-on:
-  push:
-    branches: [ master, staging, stable ]
-  merge_group:
-  pull_request:
-    paths:
-      - '**.rsi/**'
-
-jobs:
-  validate_rsis:
-    name: Validate RSIs
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v3.6.0
-      - name: Setup Submodule
-        run: git submodule update --init
-      - name: Pull engine updates
-        uses: space-wizards/submodule-dependency@v0.1.5
-      - name: Install Python dependencies
-        run: |
-          pip3 install --ignore-installed --user pillow jsonschema
-      - name: Validate RSIs
-        run: |
-          python3 RobustToolbox/Schemas/validate_rsis.py Resources/

+ 4 - 0
.gitignore

@@ -306,3 +306,7 @@ Resources/MapImages
 
 
 # Direnv stuff
 # Direnv stuff
 .direnv/
 .direnv/
+Civ14.code-workspace
+_extras/
+server_config.toml
+Resources/Maps/civ/nomads_classic.yml

+ 3873 - 0
Civ14-Wiki/MDwiki.js

@@ -0,0 +1,3873 @@
+(function () {
+    /**
+     * Block-Level Grammar
+     */
+
+    var block = {
+        newline: /^\n+/,
+        code: /^( {4}[^\n]+\n*)+/,
+        fences: noop,
+        hr: /^( *[-*_]){3,} *(?:\n+|$)/,
+        heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
+        nptable: noop,
+        lheading: /^([^\n]+)\n *(=|-){3,} *\n*/,
+        blockquote: /^( *>[^\n]+(\n[^\n]+)*\n*)+/,
+        list: /^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
+        html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,
+        def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
+        table: noop,
+        paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
+        text: /^[^\n]+/,
+    };
+
+    block.bullet = /(?:[*+-]|\d+\.)/;
+    block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
+    block.item = replace(block.item, "gm")(/bull/g, block.bullet)();
+
+    block.list = replace(block.list)(/bull/g, block.bullet)("hr", /\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/)();
+
+    block._tag =
+        "(?!(?:" +
+        "a|em|strong|small|s|cite|q|dfn|abbr|data|time|code" +
+        "|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo" +
+        "|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b";
+
+    block.html = replace(block.html)("comment", /<!--[\s\S]*?-->/)("closed", /<(tag)[\s\S]+?<\/\1>/)(
+        "closing",
+        /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/
+    )(/tag/g, block._tag)();
+
+    block.paragraph = replace(block.paragraph)("hr", block.hr)("heading", block.heading)("lheading", block.lheading)(
+        "blockquote",
+        block.blockquote
+    )("tag", "<" + block._tag)("def", block.def)();
+
+    /**
+     * Normal Block Grammar
+     */
+
+    block.normal = merge({}, block);
+
+    /**
+     * GFM Block Grammar
+     */
+
+    block.gfm = merge({}, block.normal, {
+        fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,
+        paragraph: /^/,
+    });
+
+    block.gfm.paragraph = replace(block.paragraph)(
+        "(?!",
+        "(?!" + block.gfm.fences.source.replace("\\1", "\\2") + "|"
+    )();
+
+    /**
+     * GFM + Tables Block Grammar
+     */
+
+    block.tables = merge({}, block.gfm, {
+        nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
+        table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/,
+    });
+
+    /**
+     * Block Lexer
+     */
+
+    function Lexer(options) {
+        this.tokens = [];
+        this.tokens.links = {};
+        this.options = options || marked.defaults;
+        this.rules = block.normal;
+
+        if (this.options.gfm) {
+            if (this.options.tables) {
+                this.rules = block.tables;
+            } else {
+                this.rules = block.gfm;
+            }
+        }
+    }
+
+    /**
+     * Expose Block Rules
+     */
+
+    Lexer.rules = block;
+
+    /**
+     * Static Lex Method
+     */
+
+    Lexer.lex = function (src, options) {
+        var lexer = new Lexer(options);
+        return lexer.lex(src);
+    };
+
+    /**
+     * Preprocessing
+     */
+
+    Lexer.prototype.lex = function (src) {
+        src = src
+            .replace(/\r\n|\r/g, "\n")
+            .replace(/\t/g, "    ")
+            .replace(/\u00a0/g, " ")
+            .replace(/\u2424/g, "\n");
+
+        return this.token(src, true);
+    };
+
+    /**
+     * Lexing
+     */
+
+    Lexer.prototype.token = function (src, top) {
+        var src = src.replace(/^ +$/gm, ""),
+            next,
+            loose,
+            cap,
+            bull,
+            b,
+            item,
+            space,
+            i,
+            l;
+
+        while (src) {
+            // newline
+            if ((cap = this.rules.newline.exec(src))) {
+                src = src.substring(cap[0].length);
+                if (cap[0].length > 1) {
+                    this.tokens.push({
+                        type: "space",
+                    });
+                }
+            }
+
+            // code
+            if ((cap = this.rules.code.exec(src))) {
+                src = src.substring(cap[0].length);
+                cap = cap[0].replace(/^ {4}/gm, "");
+                this.tokens.push({
+                    type: "code",
+                    text: !this.options.pedantic ? cap.replace(/\n+$/, "") : cap,
+                });
+                continue;
+            }
+
+            // fences (gfm)
+            if ((cap = this.rules.fences.exec(src))) {
+                src = src.substring(cap[0].length);
+                this.tokens.push({
+                    type: "code",
+                    lang: cap[2],
+                    text: cap[3],
+                });
+                continue;
+            }
+
+            // heading
+            if ((cap = this.rules.heading.exec(src))) {
+                src = src.substring(cap[0].length);
+                this.tokens.push({
+                    type: "heading",
+                    depth: cap[1].length,
+                    text: cap[2],
+                });
+                continue;
+            }
+
+            // table no leading pipe (gfm)
+            if (top && (cap = this.rules.nptable.exec(src))) {
+                src = src.substring(cap[0].length);
+
+                item = {
+                    type: "table",
+                    header: cap[1].replace(/^ *| *\| *$/g, "").split(/ *\| */),
+                    align: cap[2].replace(/^ *|\| *$/g, "").split(/ *\| */),
+                    cells: cap[3].replace(/\n$/, "").split("\n"),
+                };
+
+                for (i = 0; i < item.align.length; i++) {
+                    if (/^ *-+: *$/.test(item.align[i])) {
+                        item.align[i] = "right";
+                    } else if (/^ *:-+: *$/.test(item.align[i])) {
+                        item.align[i] = "center";
+                    } else if (/^ *:-+ *$/.test(item.align[i])) {
+                        item.align[i] = "left";
+                    } else {
+                        item.align[i] = null;
+                    }
+                }
+
+                for (i = 0; i < item.cells.length; i++) {
+                    item.cells[i] = item.cells[i].split(/ *\| */);
+                }
+
+                this.tokens.push(item);
+
+                continue;
+            }
+
+            // lheading
+            if ((cap = this.rules.lheading.exec(src))) {
+                src = src.substring(cap[0].length);
+                this.tokens.push({
+                    type: "heading",
+                    depth: cap[2] === "=" ? 1 : 2,
+                    text: cap[1],
+                });
+                continue;
+            }
+
+            // hr
+            if ((cap = this.rules.hr.exec(src))) {
+                src = src.substring(cap[0].length);
+                this.tokens.push({
+                    type: "hr",
+                });
+                continue;
+            }
+
+            // blockquote
+            if ((cap = this.rules.blockquote.exec(src))) {
+                src = src.substring(cap[0].length);
+
+                this.tokens.push({
+                    type: "blockquote_start",
+                });
+
+                cap = cap[0].replace(/^ *> ?/gm, "");
+
+                // Pass `top` to keep the current
+                // "toplevel" state. This is exactly
+                // how markdown.pl works.
+                this.token(cap, top);
+
+                this.tokens.push({
+                    type: "blockquote_end",
+                });
+
+                continue;
+            }
+
+            // list
+            if ((cap = this.rules.list.exec(src))) {
+                src = src.substring(cap[0].length);
+                bull = cap[2];
+
+                this.tokens.push({
+                    type: "list_start",
+                    ordered: bull.length > 1,
+                });
+
+                // Get each top-level item.
+                cap = cap[0].match(this.rules.item);
+
+                next = false;
+                l = cap.length;
+                i = 0;
+
+                for (; i < l; i++) {
+                    item = cap[i];
+
+                    // Remove the list item's bullet
+                    // so it is seen as the next token.
+                    space = item.length;
+                    item = item.replace(/^ *([*+-]|\d+\.) +/, "");
+
+                    // Outdent whatever the
+                    // list item contains. Hacky.
+                    if (~item.indexOf("\n ")) {
+                        space -= item.length;
+                        item = !this.options.pedantic
+                            ? item.replace(new RegExp("^ {1," + space + "}", "gm"), "")
+                            : item.replace(/^ {1,4}/gm, "");
+                    }
+
+                    // Determine whether the next list item belongs here.
+                    // Backpedal if it does not belong in this list.
+                    if (this.options.smartLists && i !== l - 1) {
+                        b = block.bullet.exec(cap[i + 1])[0];
+                        if (bull !== b && !(bull.length > 1 && b.length > 1)) {
+                            src = cap.slice(i + 1).join("\n") + src;
+                            i = l - 1;
+                        }
+                    }
+
+                    // Determine whether item is loose or not.
+                    // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
+                    // for discount behavior.
+                    loose = next || /\n\n(?!\s*$)/.test(item);
+                    if (i !== l - 1) {
+                        next = item[item.length - 1] === "\n";
+                        if (!loose) loose = next;
+                    }
+
+                    this.tokens.push({
+                        type: loose ? "loose_item_start" : "list_item_start",
+                    });
+
+                    // Recurse.
+                    this.token(item, false);
+
+                    this.tokens.push({
+                        type: "list_item_end",
+                    });
+                }
+
+                this.tokens.push({
+                    type: "list_end",
+                });
+
+                continue;
+            }
+
+            // html
+            if ((cap = this.rules.html.exec(src))) {
+                src = src.substring(cap[0].length);
+                this.tokens.push({
+                    type: this.options.sanitize ? "paragraph" : "html",
+                    pre: cap[1] === "pre" || cap[1] === "script",
+                    text: cap[0],
+                });
+                continue;
+            }
+
+            // def
+            if (top && (cap = this.rules.def.exec(src))) {
+                src = src.substring(cap[0].length);
+                this.tokens.links[cap[1].toLowerCase()] = {
+                    href: cap[2],
+                    title: cap[3],
+                };
+                continue;
+            }
+
+            // table (gfm)
+            if (top && (cap = this.rules.table.exec(src))) {
+                src = src.substring(cap[0].length);
+
+                item = {
+                    type: "table",
+                    header: cap[1].replace(/^ *| *\| *$/g, "").split(/ *\| */),
+                    align: cap[2].replace(/^ *|\| *$/g, "").split(/ *\| */),
+                    cells: cap[3].replace(/(?: *\| *)?\n$/, "").split("\n"),
+                };
+
+                for (i = 0; i < item.align.length; i++) {
+                    if (/^ *-+: *$/.test(item.align[i])) {
+                        item.align[i] = "right";
+                    } else if (/^ *:-+: *$/.test(item.align[i])) {
+                        item.align[i] = "center";
+                    } else if (/^ *:-+ *$/.test(item.align[i])) {
+                        item.align[i] = "left";
+                    } else {
+                        item.align[i] = null;
+                    }
+                }
+
+                for (i = 0; i < item.cells.length; i++) {
+                    item.cells[i] = item.cells[i].replace(/^ *\| *| *\| *$/g, "").split(/ *\| */);
+                }
+
+                this.tokens.push(item);
+
+                continue;
+            }
+
+            // top-level paragraph
+            if (top && (cap = this.rules.paragraph.exec(src))) {
+                src = src.substring(cap[0].length);
+                this.tokens.push({
+                    type: "paragraph",
+                    text: cap[1][cap[1].length - 1] === "\n" ? cap[1].slice(0, -1) : cap[1],
+                });
+                continue;
+            }
+
+            // text
+            if ((cap = this.rules.text.exec(src))) {
+                // Top-level should never reach here.
+                src = src.substring(cap[0].length);
+                this.tokens.push({
+                    type: "text",
+                    text: cap[0],
+                });
+                continue;
+            }
+
+            if (src) {
+                throw new Error("Infinite loop on byte: " + src.charCodeAt(0));
+            }
+        }
+
+        return this.tokens;
+    };
+
+    /**
+     * Inline-Level Grammar
+     */
+
+    var inline = {
+        escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
+        autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
+        url: noop,
+        tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
+        link: /^!?\[(inside)\]\(href\)/,
+        reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
+        nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
+        strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
+        em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
+        code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
+        br: /^ {2,}\n(?!\s*$)/,
+        del: noop,
+        text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/,
+    };
+
+    inline._inside = /(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/;
+    inline._href = /\s*<?(.*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
+
+    inline.link = replace(inline.link)("inside", inline._inside)("href", inline._href)();
+
+    inline.reflink = replace(inline.reflink)("inside", inline._inside)();
+
+    /**
+     * Normal Inline Grammar
+     */
+
+    inline.normal = merge({}, inline);
+
+    /**
+     * Pedantic Inline Grammar
+     */
+
+    inline.pedantic = merge({}, inline.normal, {
+        strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+        em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,
+    });
+
+    /**
+     * GFM Inline Grammar
+     */
+
+    inline.gfm = merge({}, inline.normal, {
+        escape: replace(inline.escape)("])", "~|])")(),
+        url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
+        del: /^~~(?=\S)([\s\S]*?\S)~~/,
+        text: replace(inline.text)("]|", "~]|")("|", "|https?://|")(),
+    });
+
+    /**
+     * GFM + Line Breaks Inline Grammar
+     */
+
+    inline.breaks = merge({}, inline.gfm, {
+        br: replace(inline.br)("{2,}", "*")(),
+        text: replace(inline.gfm.text)("{2,}", "*")(),
+    });
+
+    /**
+     * Inline Lexer & Compiler
+     */
+
+    function InlineLexer(links, options) {
+        this.options = options || marked.defaults;
+        this.links = links;
+        this.rules = inline.normal;
+
+        if (!this.links) {
+            throw new Error("Tokens array requires a `links` property.");
+        }
+
+        if (this.options.gfm) {
+            if (this.options.breaks) {
+                this.rules = inline.breaks;
+            } else {
+                this.rules = inline.gfm;
+            }
+        } else if (this.options.pedantic) {
+            this.rules = inline.pedantic;
+        }
+    }
+
+    /**
+     * Expose Inline Rules
+     */
+
+    InlineLexer.rules = inline;
+
+    /**
+     * Static Lexing/Compiling Method
+     */
+
+    InlineLexer.output = function (src, links, options) {
+        var inline = new InlineLexer(links, options);
+        return inline.output(src);
+    };
+
+    /**
+     * Lexing/Compiling
+     */
+
+    InlineLexer.prototype.output = function (src) {
+        var out = "",
+            link,
+            text,
+            href,
+            cap;
+
+        while (src) {
+            // escape
+            if ((cap = this.rules.escape.exec(src))) {
+                src = src.substring(cap[0].length);
+                out += cap[1];
+                continue;
+            }
+
+            // autolink
+            if ((cap = this.rules.autolink.exec(src))) {
+                src = src.substring(cap[0].length);
+                if (cap[2] === "@") {
+                    text = cap[1][6] === ":" ? this.mangle(cap[1].substring(7)) : this.mangle(cap[1]);
+                    href = this.mangle("mailto:") + text;
+                } else {
+                    text = escape(cap[1]);
+                    href = text;
+                }
+                out += '<a href="' + href + '">' + text + "</a>";
+                continue;
+            }
+
+            // url (gfm)
+            if ((cap = this.rules.url.exec(src))) {
+                src = src.substring(cap[0].length);
+                text = escape(cap[1]);
+                href = text;
+                out += '<a href="' + href + '">' + text + "</a>";
+                continue;
+            }
+
+            // tag
+            if ((cap = this.rules.tag.exec(src))) {
+                src = src.substring(cap[0].length);
+                out += this.options.sanitize ? escape(cap[0]) : cap[0];
+                continue;
+            }
+
+            // link
+            if ((cap = this.rules.link.exec(src))) {
+                src = src.substring(cap[0].length);
+                out += this.outputLink(cap, {
+                    href: cap[2],
+                    title: cap[3],
+                });
+                continue;
+            }
+
+            // reflink, nolink
+            if ((cap = this.rules.reflink.exec(src)) || (cap = this.rules.nolink.exec(src))) {
+                src = src.substring(cap[0].length);
+                link = (cap[2] || cap[1]).replace(/\s+/g, " ");
+                link = this.links[link.toLowerCase()];
+                if (!link || !link.href) {
+                    out += cap[0][0];
+                    src = cap[0].substring(1) + src;
+                    continue;
+                }
+                out += this.outputLink(cap, link);
+                continue;
+            }
+
+            // strong
+            if ((cap = this.rules.strong.exec(src))) {
+                src = src.substring(cap[0].length);
+                out += "<strong>" + this.output(cap[2] || cap[1]) + "</strong>";
+                continue;
+            }
+
+            // em
+            if ((cap = this.rules.em.exec(src))) {
+                src = src.substring(cap[0].length);
+                out += "<em>" + this.output(cap[2] || cap[1]) + "</em>";
+                continue;
+            }
+
+            // code
+            if ((cap = this.rules.code.exec(src))) {
+                src = src.substring(cap[0].length);
+                out += "<code>" + escape(cap[2], true) + "</code>";
+                continue;
+            }
+
+            // br
+            if ((cap = this.rules.br.exec(src))) {
+                src = src.substring(cap[0].length);
+                out += "<br>";
+                continue;
+            }
+
+            // del (gfm)
+            if ((cap = this.rules.del.exec(src))) {
+                src = src.substring(cap[0].length);
+                out += "<del>" + this.output(cap[1]) + "</del>";
+                continue;
+            }
+
+            // text
+            if ((cap = this.rules.text.exec(src))) {
+                src = src.substring(cap[0].length);
+                out += escape(cap[0]);
+                continue;
+            }
+
+            if (src) {
+                throw new Error("Infinite loop on byte: " + src.charCodeAt(0));
+            }
+        }
+
+        return out;
+    };
+
+    /**
+     * Compile Link
+     */
+
+    InlineLexer.prototype.outputLink = function (cap, link) {
+        if (cap[0][0] !== "!") {
+            return (
+                '<a href="' +
+                escape(link.href) +
+                '"' +
+                (link.title ? ' title="' + escape(link.title) + '"' : "") +
+                ">" +
+                this.output(cap[1]) +
+                "</a>"
+            );
+        } else {
+            return (
+                '<img src="' +
+                escape(link.href) +
+                '" alt="' +
+                escape(cap[1]) +
+                '"' +
+                (link.title ? ' title="' + escape(link.title) + '"' : "") +
+                ">"
+            );
+        }
+    };
+
+    /**
+     * Smartypants Transformations
+     */
+
+    InlineLexer.prototype.smartypants = function (text) {
+        if (!this.options.smartypants) return text;
+        return text
+            .replace(/--/g, "—")
+            .replace(/'([^']*)'/g, "‘$1’")
+            .replace(/"([^"]*)"/g, "“$1”")
+            .replace(/\.{3}/g, "…");
+    };
+
+    /**
+     * Mangle Links
+     */
+
+    InlineLexer.prototype.mangle = function (text) {
+        var out = "",
+            l = text.length,
+            i = 0,
+            ch;
+
+        for (; i < l; i++) {
+            ch = text.charCodeAt(i);
+            if (Math.random() > 0.5) {
+                ch = "x" + ch.toString(16);
+            }
+            out += "&#" + ch + ";";
+        }
+
+        return out;
+    };
+
+    /**
+     * Parsing & Compiling
+     */
+
+    function Parser(options) {
+        this.tokens = [];
+        this.token = null;
+        this.options = options || marked.defaults;
+    }
+
+    /**
+     * Static Parse Method
+     */
+
+    Parser.parse = function (src, options) {
+        var parser = new Parser(options);
+        return parser.parse(src);
+    };
+
+    /**
+     * Parse Loop
+     */
+
+    Parser.prototype.parse = function (src) {
+        this.inline = new InlineLexer(src.links, this.options);
+        this.tokens = src.reverse();
+
+        var out = "";
+        while (this.next()) {
+            out += this.tok();
+        }
+
+        return out;
+    };
+
+    /**
+     * Next Token
+     */
+
+    Parser.prototype.next = function () {
+        return (this.token = this.tokens.pop());
+    };
+
+    /**
+     * Preview Next Token
+     */
+
+    Parser.prototype.peek = function () {
+        return this.tokens[this.tokens.length - 1] || 0;
+    };
+
+    /**
+     * Parse Text Tokens
+     */
+
+    Parser.prototype.parseText = function () {
+        var body = this.token.text;
+
+        while (this.peek().type === "text") {
+            body += "\n" + this.next().text;
+        }
+
+        return this.inline.output(body);
+    };
+
+    /**
+     * Parse Current Token
+     */
+
+    Parser.prototype.tok = function () {
+        switch (this.token.type) {
+            case "space": {
+                return "";
+            }
+            case "hr": {
+                return "<hr>\n";
+            }
+            case "heading": {
+                return (
+                    "<h" +
+                    this.token.depth +
+                    ">" +
+                    this.inline.output(this.token.text) +
+                    "</h" +
+                    this.token.depth +
+                    ">\n"
+                );
+            }
+            case "code": {
+                if (this.options.highlight) {
+                    var code = this.options.highlight(this.token.text, this.token.lang);
+                    if (code != null && code !== this.token.text) {
+                        this.token.escaped = true;
+                        this.token.text = code;
+                    }
+                }
+
+                if (!this.token.escaped) {
+                    this.token.text = escape(this.token.text, true);
+                }
+
+                return (
+                    "<pre><code" +
+                    (this.token.lang ? ' class="' + this.options.langPrefix + this.token.lang + '"' : "") +
+                    ">" +
+                    this.token.text +
+                    "</code></pre>\n"
+                );
+            }
+            case "table": {
+                var body = "",
+                    heading,
+                    i,
+                    row,
+                    cell,
+                    j;
+
+                // header
+                body += "<thead>\n<tr>\n";
+                for (i = 0; i < this.token.header.length; i++) {
+                    heading = this.inline.output(this.token.header[i]);
+                    body += this.token.align[i]
+                        ? '<th align="' + this.token.align[i] + '">' + heading + "</th>\n"
+                        : "<th>" + heading + "</th>\n";
+                }
+                body += "</tr>\n</thead>\n";
+
+                // body
+                body += "<tbody>\n";
+                for (i = 0; i < this.token.cells.length; i++) {
+                    row = this.token.cells[i];
+                    body += "<tr>\n";
+                    for (j = 0; j < row.length; j++) {
+                        cell = this.inline.output(row[j]);
+                        body += this.token.align[j]
+                            ? '<td align="' + this.token.align[j] + '">' + cell + "</td>\n"
+                            : "<td>" + cell + "</td>\n";
+                    }
+                    body += "</tr>\n";
+                }
+                body += "</tbody>\n";
+
+                return "<table>\n" + body + "</table>\n";
+            }
+            case "blockquote_start": {
+                var body = "";
+
+                while (this.next().type !== "blockquote_end") {
+                    body += this.tok();
+                }
+
+                return "<blockquote>\n" + body + "</blockquote>\n";
+            }
+            case "list_start": {
+                var type = this.token.ordered ? "ol" : "ul",
+                    body = "";
+
+                while (this.next().type !== "list_end") {
+                    body += this.tok();
+                }
+
+                return "<" + type + ">\n" + body + "</" + type + ">\n";
+            }
+            case "list_item_start": {
+                var body = "";
+
+                while (this.next().type !== "list_item_end") {
+                    body += this.token.type === "text" ? this.parseText() : this.tok();
+                }
+
+                return "<li>" + body + "</li>\n";
+            }
+            case "loose_item_start": {
+                var body = "";
+
+                while (this.next().type !== "list_item_end") {
+                    body += this.tok();
+                }
+
+                return "<li>" + body + "</li>\n";
+            }
+            case "html": {
+                return !this.token.pre && !this.options.pedantic
+                    ? this.inline.output(this.token.text)
+                    : this.token.text;
+            }
+            case "paragraph": {
+                return "<p>" + this.inline.output(this.token.text) + "</p>\n";
+            }
+            case "text": {
+                return "<p>" + this.parseText() + "</p>\n";
+            }
+        }
+    };
+
+    /**
+     * Helpers
+     */
+
+    function escape(html, encode) {
+        return html
+            .replace(!encode ? /&(?!#?\w+;)/g : /&/g, "&amp;")
+            .replace(/</g, "&lt;")
+            .replace(/>/g, "&gt;")
+            .replace(/"/g, "&quot;")
+            .replace(/'/g, "&#39;");
+    }
+
+    function replace(regex, opt) {
+        regex = regex.source;
+        opt = opt || "";
+        return function self(name, val) {
+            if (!name) return new RegExp(regex, opt);
+            val = val.source || val;
+            val = val.replace(/(^|[^\[])\^/g, "$1");
+            regex = regex.replace(name, val);
+            return self;
+        };
+    }
+
+    function noop() {}
+    noop.exec = noop;
+
+    function merge(obj) {
+        var i = 1,
+            target,
+            key;
+
+        for (; i < arguments.length; i++) {
+            target = arguments[i];
+            for (key in target) {
+                if (Object.prototype.hasOwnProperty.call(target, key)) {
+                    obj[key] = target[key];
+                }
+            }
+        }
+
+        return obj;
+    }
+
+    /**
+     * Marked
+     */
+
+    function marked(src, opt, callback) {
+        if (callback || typeof opt === "function") {
+            if (!callback) {
+                callback = opt;
+                opt = null;
+            }
+
+            if (opt) opt = merge({}, marked.defaults, opt);
+
+            var tokens = Lexer.lex(tokens, opt),
+                highlight = opt.highlight,
+                pending = 0,
+                l = tokens.length,
+                i = 0;
+
+            if (!highlight || highlight.length < 3) {
+                return callback(null, Parser.parse(tokens, opt));
+            }
+
+            var done = function () {
+                delete opt.highlight;
+                var out = Parser.parse(tokens, opt);
+                opt.highlight = highlight;
+                return callback(null, out);
+            };
+
+            for (; i < l; i++) {
+                (function (token) {
+                    if (token.type !== "code") return;
+                    pending++;
+                    return highlight(token.text, token.lang, function (err, code) {
+                        if (code == null || code === token.text) {
+                            return --pending || done();
+                        }
+                        token.text = code;
+                        token.escaped = true;
+                        --pending || done();
+                    });
+                })(tokens[i]);
+            }
+
+            return;
+        }
+        try {
+            if (opt) opt = merge({}, marked.defaults, opt);
+            return Parser.parse(Lexer.lex(src, opt), opt);
+        } catch (e) {
+            e.message += "\nPlease report this to https://github.com/chjj/marked.";
+            if ((opt || marked.defaults).silent) {
+                return "<p>An error occured:</p><pre>" + escape(e.message + "", true) + "</pre>";
+            }
+            throw e;
+        }
+    }
+
+    /**
+     * Options
+     */
+
+    marked.options = marked.setOptions = function (opt) {
+        merge(marked.defaults, opt);
+        return marked;
+    };
+
+    marked.defaults = {
+        gfm: true,
+        tables: true,
+        breaks: false,
+        pedantic: false,
+        sanitize: false,
+        smartLists: false,
+        silent: false,
+        highlight: null,
+        langPrefix: "lang-",
+    };
+
+    /**
+     * Expose
+     */
+
+    marked.Parser = Parser;
+    marked.parser = Parser.parse;
+
+    marked.Lexer = Lexer;
+    marked.lexer = Lexer.lex;
+
+    marked.InlineLexer = InlineLexer;
+    marked.inlineLexer = InlineLexer.output;
+
+    marked.parse = marked;
+
+    if (typeof exports === "object") {
+        module.exports = marked;
+    } else if (typeof define === "function" && define.amd) {
+        define(function () {
+            return marked;
+        });
+    } else {
+        this.marked = marked;
+    }
+}).call(
+    (function () {
+        return this || (typeof window !== "undefined" ? window : global);
+    })()
+);
+
+(function ($) {
+    "use strict";
+
+    // hide the whole page so we dont see the DOM flickering
+    // will be shown upon page load complete or error
+    $("html").addClass("md-hidden-load");
+
+    // register our $.md object
+    $.md = function (method) {
+        if ($.md.publicMethods[method]) {
+            return $.md.publicMethods[method].apply(this, Array.prototype.slice.call(arguments, 1));
+        } else {
+            $.error("Method " + method + " does not exist on jquery.md");
+        }
+    };
+    // default config
+    $.md.config = {
+        title: null,
+        useSideMenu: true,
+        lineBreaks: "gfm",
+        additionalFooterText: "",
+        anchorCharacter: "&para;",
+        tocAnchor: "[ &uarr; ]",
+    };
+
+    $.md.gimmicks = [];
+    $.md.stages = [];
+
+    // the location of the main markdown file we display
+    $.md.mainHref = "";
+
+    // the in-page anchor that is specified after the !
+    $.md.inPageAnchor = "";
+
+    $.md.loglevel = {
+        TRACE: 10,
+        DEBUG: 20,
+        INFO: 30,
+        WARN: 40,
+        ERROR: 50,
+        FATAL: 60,
+    };
+    // $.md.logThreshold = $.md.loglevel.DEBUG;
+    $.md.logThreshold = $.md.loglevel.WARN;
+})(jQuery);
+
+(function ($) {
+    "use strict";
+    $.md.getLogger = function () {
+        var loglevel = $.md.loglevel;
+
+        var log = function (logtarget) {
+            var self = this;
+            var level = loglevel[logtarget];
+            return function (msg) {
+                if ($.md.logThreshold <= level) {
+                    console.log("[" + logtarget + "] " + msg);
+                }
+            };
+        };
+
+        var logger = {};
+        logger.trace = log("TRACE");
+        logger.debug = log("DEBUG");
+        logger.info = log("INFO");
+        logger.warn = log("WARN");
+        logger.error = log("ERROR");
+        logger.fatal = log("FATAL");
+
+        return logger;
+    };
+})(jQuery);
+
+(function ($) {
+    "use strict";
+    var log = $.md.getLogger();
+
+    $.Stage = function (name) {
+        var self = $.extend($.Deferred(), {});
+        self.name = name;
+        self.events = [];
+        self.started = false;
+
+        self.reset = function () {
+            self.complete = $.Deferred();
+            self.outstanding = [];
+        };
+
+        self.reset();
+
+        self.subscribe = function (fn) {
+            if (self.started) {
+                $.error("Subscribing to stage which already started!");
+            }
+            self.events.push(fn);
+        };
+        self.unsubscribe = function (fn) {
+            self.events.remove(fn);
+        };
+
+        self.executeSubscribedFn = function (fn) {
+            var d = $.Deferred();
+            self.outstanding.push(d);
+
+            // display an error if our done() callback is not called
+            $.md.util.wait(2500).done(function () {
+                if (d.state() !== "resolved") {
+                    log.fatal(
+                        "Timeout reached for done callback in stage: " +
+                            self.name +
+                            ". Did you forget a done() call in a .subscribe() ?"
+                    );
+                    log.fatal("stage " + name + " failed running subscribed function: " + fn);
+                }
+            });
+
+            var done = function () {
+                d.resolve();
+            };
+            fn(done);
+        };
+
+        self.run = function () {
+            self.started = true;
+            $(self.events).each(function (i, fn) {
+                self.executeSubscribedFn(fn);
+            });
+
+            // if no events are in our queue, we resolve immediately
+            if (self.outstanding.length === 0) {
+                self.resolve();
+            }
+
+            // we resolve when all our registered events have completed
+            $.when
+                .apply($, self.outstanding)
+                .done(function () {
+                    self.resolve();
+                })
+                .fail(function () {
+                    self.resolve();
+                });
+        };
+
+        self.done(function () {
+            log.debug("stage " + self.name + " completed successfully.");
+        });
+        self.fail(function () {
+            log.debug("stage " + self.name + " completed with errors!");
+        });
+        return self;
+    };
+})(jQuery);
+
+(function ($) {
+    "use strict";
+
+    var log = $.md.getLogger();
+
+    function init() {
+        $.md.stages = [
+            $.Stage("init"),
+
+            // loads config, initial markdown and navigation
+            $.Stage("load"),
+
+            // will transform the markdown to html
+            $.Stage("transform"),
+
+            // HTML transformation finished
+            $.Stage("ready"),
+
+            // after we have a polished html skeleton
+            $.Stage("skel_ready"),
+
+            // will bootstrapify the skeleton
+            $.Stage("bootstrap"),
+
+            // before we run any gimmicks
+            $.Stage("pregimmick"),
+
+            // after we have bootstrapified the skeleton
+            $.Stage("gimmick"),
+
+            // postprocess
+            $.Stage("postgimmick"),
+
+            $.Stage("all_ready"),
+
+            // used for integration tests, not intended to use in MDwiki itself
+            $.Stage("final_tests"),
+        ];
+
+        $.md.stage = function (name) {
+            var m = $.grep($.md.stages, function (e, i) {
+                return e.name === name;
+            });
+            if (m.length === 0) {
+                $.error("A stage by name " + name + "  does not exist");
+            } else {
+                return m[0];
+            }
+        };
+    }
+    init();
+
+    function resetStages() {
+        var old_stages = $.md.stages;
+        $.md.stages = [];
+        $(old_stages).each(function (i, e) {
+            $.md.stages.push($.Stage(e.name));
+        });
+    }
+
+    var publicMethods = {};
+    $.md.publicMethods = $.extend({}, $.md.publicMethods, publicMethods);
+
+    function transformMarkdown(markdown) {
+        var options = {
+            gfm: true,
+            tables: true,
+            breaks: true,
+        };
+        if ($.md.config.lineBreaks === "original") options.breaks = false;
+        else if ($.md.config.lineBreaks === "gfm") options.breaks = true;
+
+        marked.setOptions(options);
+
+        // get sample markdown
+        var uglyHtml = marked(markdown);
+        return uglyHtml;
+    }
+
+    function registerFetchMarkdown() {
+        var md = "";
+
+        $.md.stage("init").subscribe(function (done) {
+            var ajaxReq = {
+                url: $.md.mainHref,
+                dataType: "text",
+            };
+
+            // Request the md page
+            $.ajax(ajaxReq)
+                .done(function (data) {
+                    md = data;
+                    done();
+                })
+
+                // Failed to find the md page we were looking for
+                .fail(function () {
+                    // Warn that this page wasn't found
+                    var log = $.md.getLogger();
+                    log.warn("Could not get " + $.md.mainHref);
+
+                    // Attempt to gracefully recover by displaying a user defined 404 page
+                    ajaxReq.url = "404.md";
+                    $.ajax(ajaxReq)
+                        .done(function (data) {
+                            md = data;
+                            done();
+                        })
+
+                        // The user has not defined a 404.md.
+                        .fail(function (data) {
+                            log.fatal("Could not get a user defined 404.md");
+
+                            // Our last attempt to provide a good user expierence by proving a hard coded
+                            // 'page not found' text.
+                            md = "# Page Not Found";
+
+                            done();
+                        });
+                });
+        });
+
+        // find baseUrl
+        $.md.stage("transform").subscribe(function (done) {
+            var len = $.md.mainHref.lastIndexOf("/");
+            var baseUrl = $.md.mainHref.substring(0, len + 1);
+            $.md.baseUrl = baseUrl;
+            done();
+        });
+
+        $.md.stage("transform").subscribe(function (done) {
+            var uglyHtml = transformMarkdown(md);
+            $("#md-content").html(uglyHtml);
+            md = "";
+            var dfd = $.Deferred();
+            loadExternalIncludes(dfd);
+            dfd.always(function () {
+                done();
+            });
+        });
+    }
+
+    // load [include](/foo/bar.md) external links
+    function loadExternalIncludes(parent_dfd) {
+        function findExternalIncludes() {
+            return $("a").filter(function () {
+                var href = $(this).attr("href");
+                var text = $(this).toptext();
+                var isMarkdown = $.md.util.hasMarkdownFileExtension(href);
+                var isInclude = text === "include";
+                var isPreview = text.startsWith("preview:");
+                return (isInclude || isPreview) && isMarkdown;
+            });
+        }
+
+        function selectPreviewElements($jqcol, num_elements) {
+            function isTextNode(node) {
+                return node.nodeType === 3;
+            }
+            var count = 0;
+            var elements = [];
+            $jqcol.each(function (i, e) {
+                if (count < num_elements) {
+                    elements.push(e);
+                    if (!isTextNode(e)) count++;
+                }
+            });
+            return $(elements);
+        }
+
+        var external_links = findExternalIncludes();
+        // continue execution when all external resources are fully loaded
+        var latch = $.md.util.countDownLatch(external_links.length);
+        latch.always(function () {
+            parent_dfd.resolve();
+        });
+
+        external_links.each(function (i, e) {
+            var $el = $(e);
+            var href = $el.attr("href");
+            var text = $el.toptext();
+
+            $.ajax({
+                url: href,
+                dataType: "text",
+            })
+                .done(function (data) {
+                    var $html = $(transformMarkdown(data));
+                    if (text.startsWith("preview:")) {
+                        // only insert the selected number of paragraphs; default 3
+                        var num_preview_elements = parseInt(text.substring(8), 10) || 3;
+                        var $preview = selectPreviewElements($html, num_preview_elements);
+                        $preview.last().append('<a href="' + href + '"> ...read more &#10140;</a>');
+                        $preview.insertBefore($el.parent("p").eq(0));
+                        $el.remove();
+                    } else {
+                        $html.insertAfter($el.parents("p"));
+                        $el.remove();
+                    }
+                })
+                .always(function () {
+                    latch.countDown();
+                });
+        });
+    }
+
+    function isSpecialLink(href) {
+        if (!href) return false;
+
+        if (href.lastIndexOf("data:") >= 0) return true;
+
+        if (href.startsWith("mailto:")) return true;
+
+        if (href.startsWith("file:")) return true;
+
+        if (href.startsWith("ftp:")) return true;
+
+        // TODO capture more special links: every non-http link with : like
+        // torrent:// etc.
+    }
+
+    // modify internal links so we load them through our engine
+    function processPageLinks(domElement, baseUrl) {
+        var html = $(domElement);
+        if (baseUrl === undefined) {
+            baseUrl = "";
+        }
+        // HACK against marked: empty links will have empy href attribute
+        // we remove the href attribute from the a tag
+        html.find("a")
+            .not("#md-menu a")
+            .filter(function () {
+                var $this = $(this);
+                var attr = $this.attr("href");
+                if (!attr || attr.length === 0) $this.removeAttr("href");
+            });
+
+        html.find("a, img").each(function (i, e) {
+            var link = $(e);
+            // link must be jquery collection
+            var isImage = false;
+            var hrefAttribute = "href";
+
+            if (!link.attr(hrefAttribute)) {
+                isImage = true;
+                hrefAttribute = "src";
+            }
+            var href = link.attr(hrefAttribute);
+
+            if (href && href.lastIndexOf("#!") >= 0) return;
+
+            if (isSpecialLink(href)) return;
+
+            if (!isImage && href.startsWith("#") && !href.startsWith("#!")) {
+                // in-page link
+                link.click(function (ev) {
+                    ev.preventDefault();
+                    $.md.scrollToInPageAnchor(href);
+                });
+            }
+
+            if (!$.md.util.isRelativeUrl(href)) return;
+
+            if (isImage && !$.md.util.isRelativePath(href)) return;
+
+            if (!isImage && $.md.util.isGimmickLink(link)) return;
+
+            function build_link(url) {
+                if ($.md.util.hasMarkdownFileExtension(url)) return "#!" + url;
+                else return url;
+            }
+
+            var newHref = baseUrl + href;
+            if (isImage) link.attr(hrefAttribute, newHref);
+            else if ($.md.util.isRelativePath(href)) link.attr(hrefAttribute, build_link(newHref));
+            else link.attr(hrefAttribute, build_link(href));
+        });
+    }
+
+    var navMD = "";
+    $.md.NavigationDfd = $.Deferred();
+    var ajaxReq = {
+        url: "navigation.md",
+        dataType: "text",
+    };
+    $.ajax(ajaxReq)
+        .done(function (data) {
+            navMD = data;
+            $.md.NavigationDfd.resolve();
+        })
+        .fail(function () {
+            $.md.NavigationDfd.reject();
+        });
+
+    function registerBuildNavigation() {
+        $.md.stage("init").subscribe(function (done) {
+            $.md.NavigationDfd.done(function () {
+                done();
+            }).fail(function () {
+                done();
+            });
+        });
+
+        $.md.stage("transform").subscribe(function (done) {
+            if (navMD === "") {
+                var log = $.md.getLogger();
+                log.info("no navgiation.md found, not using a navbar");
+                done();
+                return;
+            }
+
+            var navHtml = marked(navMD);
+            // TODO why are <script> tags from navHtml APPENDED to the jqcol?
+            var $h = $("<div>" + navHtml + "</div>");
+
+            // insert <scripts> from navigation.md into the DOM
+            $h.each(function (i, e) {
+                if (e.tagName === "SCRIPT") {
+                    $("script").first().before(e);
+                }
+            });
+
+            // TODO .html() is evil!!!
+            var $navContent = $h.eq(0);
+            $navContent.find("p").each(function (i, e) {
+                var $el = $(e);
+                $el.replaceWith($el.html());
+            });
+            $("#md-menu").append($navContent.html());
+            done();
+        });
+
+        $.md.stage("bootstrap").subscribe(function (done) {
+            processPageLinks($("#md-menu"));
+            done();
+        });
+
+        $.md.stage("postgimmick").subscribe(function (done) {
+            var num_links = $("#md-menu a").length;
+            var has_header = $("#md-menu .navbar-brand").eq(0).toptext().trim().length > 0;
+            if (!has_header && num_links <= 1) $("#md-menu").hide();
+
+            done();
+        });
+    }
+
+    $.md.ConfigDfd = $.Deferred();
+    $.ajax({ url: "config.json", dataType: "text" })
+        .done(function (data) {
+            try {
+                var data_json = JSON.parse(data);
+                $.md.config = $.extend($.md.config, data_json);
+                log.info("Found a valid config.json file, using configuration");
+            } catch (err) {
+                log.error("config.json was not JSON parsable: " + err);
+            }
+            $.md.ConfigDfd.resolve();
+        })
+        .fail(function (err, textStatus) {
+            log.error("unable to retrieve config.json: " + textStatus);
+            $.md.ConfigDfd.reject();
+        });
+    function registerFetchConfig() {
+        $.md.stage("init").subscribe(function (done) {
+            // TODO 404 won't get cached, requesting it every reload is not good
+            // maybe use cookies? or disable re-loading of the page
+            //$.ajax('config.json').done(function(data){
+            $.md.ConfigDfd.done(function () {
+                done();
+            }).fail(function () {
+                var log = $.md.getLogger();
+                log.info("No config.json found, using default settings");
+                done();
+            });
+        });
+    }
+
+    function registerClearContent() {
+        $.md.stage("init").subscribe(function (done) {
+            $("#md-all").empty();
+            var skel =
+                '<div id="md-body"><div id="md-title"></div><div id="md-menu">' +
+                '</div><div id="md-content"></div></div>';
+            $("#md-all").prepend($(skel));
+            done();
+        });
+    }
+    function loadContent(href) {
+        if (href.startsWith("/")) {
+            // prevent cross-domain inclusions to prevent possible XSS
+            href = "/./" + href;
+        } else {
+            href = "./" + href;
+        }
+        $.md.mainHref = href;
+
+        registerFetchMarkdown();
+        registerClearContent();
+
+        // find out which link gimmicks we need
+        $.md.stage("ready").subscribe(function (done) {
+            $.md.initializeGimmicks();
+            $.md.registerLinkGimmicks();
+            done();
+        });
+
+        // wire up the load method of the modules
+        $.each($.md.gimmicks, function (i, module) {
+            if (module.load === undefined) {
+                return;
+            }
+            $.md.stage("load").subscribe(function (done) {
+                module.load();
+                done();
+            });
+        });
+
+        $.md.stage("ready").subscribe(function (done) {
+            $.md("createBasicSkeleton");
+            done();
+        });
+
+        $.md.stage("bootstrap").subscribe(function (done) {
+            $.mdbootstrap("bootstrapify");
+            processPageLinks($("#md-content"), $.md.baseUrl);
+            done();
+        });
+        runStages();
+    }
+
+    function runStages() {
+        // wire the stages up
+        $.md.stage("init").done(function () {
+            $.md.stage("load").run();
+        });
+        $.md.stage("load").done(function () {
+            $.md.stage("transform").run();
+        });
+        $.md.stage("transform").done(function () {
+            $.md.stage("ready").run();
+        });
+        $.md.stage("ready").done(function () {
+            $.md.stage("skel_ready").run();
+        });
+        $.md.stage("skel_ready").done(function () {
+            $.md.stage("bootstrap").run();
+        });
+        $.md.stage("bootstrap").done(function () {
+            $.md.stage("pregimmick").run();
+        });
+        $.md.stage("pregimmick").done(function () {
+            $.md.stage("gimmick").run();
+        });
+        $.md.stage("gimmick").done(function () {
+            $.md.stage("postgimmick").run();
+        });
+        $.md.stage("postgimmick").done(function () {
+            $.md.stage("all_ready").run();
+        });
+        $.md.stage("all_ready").done(function () {
+            $("html").removeClass("md-hidden-load");
+
+            // phantomjs hook when we are done
+            if (typeof window.callPhantom === "function") {
+                window.callPhantom({});
+            }
+
+            $.md.stage("final_tests").run();
+        });
+        $.md.stage("final_tests").done(function () {
+            // reset the stages for next iteration
+            resetStages();
+
+            // required by dalekjs so we can wait the element to appear
+            $("body").append('<span id="start-tests"></span>');
+            $("#start-tests").hide();
+        });
+
+        // trigger the whole process by runing the init stage
+        $.md.stage("init").run();
+        return;
+    }
+
+    function extractHashData() {
+        // first char is the # or #!
+        var href;
+        if (window.location.hash.startsWith("#!")) {
+            href = window.location.hash.substring(2);
+        } else {
+            href = window.location.hash.substring(1);
+        }
+        href = decodeURIComponent(href);
+
+        // extract possible in-page anchor
+        var ex_pos = href.indexOf("#");
+        if (ex_pos !== -1) {
+            $.md.inPageAnchor = href.substring(ex_pos + 1);
+            $.md.mainHref = href.substring(0, ex_pos);
+        } else {
+            $.md.mainHref = href;
+        }
+    }
+
+    function appendDefaultFilenameToHash() {
+        var newHashString = "";
+        var currentHashString = window.location.hash || "";
+        if (currentHashString === "" || currentHashString === "#" || currentHashString === "#!") {
+            newHashString = "#!index.md";
+        } else if (currentHashString.startsWith("#!") && currentHashString.endsWith("/")) {
+            newHashString = currentHashString + "index.md";
+        }
+        if (newHashString) window.location.hash = newHashString;
+    }
+
+    $(document).ready(function () {
+        // stage init stuff
+        registerFetchConfig();
+        registerBuildNavigation();
+        extractHashData();
+
+        appendDefaultFilenameToHash();
+
+        $(window).bind("hashchange", function () {
+            window.location.reload(false);
+        });
+
+        loadContent($.md.mainHref);
+    });
+})(jQuery);
+
+(function ($) {
+    var publicMethods = {
+        isRelativeUrl: function (url) {
+            if (url === undefined) {
+                return false;
+            }
+            // if there is :// in it, its considered absolute
+            // else its relative
+            if (url.indexOf("://") === -1) {
+                return true;
+            } else {
+                return false;
+            }
+        },
+        isRelativePath: function (path) {
+            if (path === undefined) return false;
+            if (path.startsWith("/")) return false;
+            return true;
+        },
+        isGimmickLink: function (domAnchor) {
+            if (domAnchor.toptext().indexOf("gimmick:") !== -1) {
+                return true;
+            } else {
+                return false;
+            }
+        },
+        hasMarkdownFileExtension: function (str) {
+            var markdownExtensions = [".md", ".markdown", ".mdown"];
+            var result = false;
+            var value = str.toLowerCase().split("#")[0];
+            $(markdownExtensions).each(function (i, ext) {
+                if (value.toLowerCase().endsWith(ext)) {
+                    result = true;
+                }
+            });
+            return result;
+        },
+        wait: function (time) {
+            return $.Deferred(function (dfd) {
+                setTimeout(dfd.resolve, time);
+            });
+        },
+    };
+    $.md.util = $.extend({}, $.md.util, publicMethods);
+
+    if (typeof String.prototype.startsWith !== "function") {
+        String.prototype.startsWith = function (str) {
+            return this.slice(0, str.length) === str;
+        };
+    }
+    if (typeof String.prototype.endsWith !== "function") {
+        String.prototype.endsWith = function (str) {
+            return this.slice(this.length - str.length, this.length) === str;
+        };
+    }
+
+    $.fn.extend({
+        toptext: function () {
+            return this.clone().children().remove().end().text();
+        },
+    });
+
+    // adds a :icontains selector to jQuery that is case insensitive
+    $.expr[":"].icontains = $.expr.createPseudo(function (arg) {
+        return function (elem) {
+            return $(elem).toptext().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
+        };
+    });
+
+    $.md.util.getInpageAnchorText = function (text) {
+        var subhash = text.replace(/ /g, "_");
+        // TODO remove more unwanted characters like ?/,- etc.
+        return subhash;
+    };
+    $.md.util.getInpageAnchorHref = function (text, href) {
+        href = href || $.md.mainHref;
+        var subhash = $.md.util.getInpageAnchorText(text);
+        return "#!" + href + "#" + subhash;
+    };
+
+    $.md.util.repeatUntil = function (interval, predicate, maxRepeats) {
+        maxRepeats = maxRepeats || 10;
+        var dfd = $.Deferred();
+        function recursive_repeat(interval, predicate, maxRepeats) {
+            if (maxRepeats === 0) {
+                dfd.reject();
+                return;
+            }
+            if (predicate()) {
+                dfd.resolve();
+                return;
+            } else {
+                $.md.util.wait(interval).always(function () {
+                    recursive_repeat(interval, predicate, maxRepeats - 1);
+                });
+            }
+        }
+        recursive_repeat(interval, predicate, maxRepeats);
+        return dfd;
+    };
+
+    // a count-down latch as in Java7.
+    $.md.util.countDownLatch = function (capacity, min) {
+        min = min || 0;
+        var dfd = $.Deferred();
+        if (capacity <= min) dfd.resolve();
+        dfd.capacity = capacity;
+        dfd.countDown = function () {
+            dfd.capacity--;
+            if (dfd.capacity <= min) dfd.resolve();
+        };
+        return dfd;
+    };
+})(jQuery);
+
+(function ($) {
+    "use strict";
+
+    // PUBLIC API
+    $.md.registerGimmick = function (module) {
+        $.md.gimmicks.push(module);
+        return;
+    };
+
+    // registers a script for a gimmick, that is later dynamically loaded
+    // by the core.
+    // src may be an URL or direct javascript sourcecode. When options.callback
+    // is provided, the done() function is passed to the function and needs to
+    // be called.
+    $.md.registerScript = function (module, src, options) {
+        var scriptinfo = new ScriptInfo({
+            module: module,
+            src: src,
+            options: options,
+        });
+        registeredScripts.push(scriptinfo);
+    };
+
+    // same as registerScript but for css. Note that we do not provide a
+    // callback when the load finishes
+    $.md.registerCss = function (module, url, options) {
+        var license = options.license,
+            stage = options.stage || "skel_ready",
+            callback = options.callback;
+
+        checkLicense(license, module);
+        var tag = '<link rel="stylesheet" href="' + url + '" type="text/css"></link>';
+        $.md.stage(stage).subscribe(function (done) {
+            $("head").append(tag);
+            if (callback !== undefined) {
+                callback(done);
+            } else {
+                done();
+            }
+        });
+    };
+
+    // turns hostname/path links into http://hostname/path links
+    // we need to do this because if accessed by file:///, we need a different
+    // transport scheme for external resources (like http://)
+    $.md.prepareLink = function (link, options) {
+        options = options || {};
+        var ownProtocol = window.location.protocol;
+
+        if (options.forceSSL) return "https://" + link;
+        if (options.forceHTTP) return "http://" + link;
+
+        if (ownProtocol === "file:") {
+            return "http://" + link;
+        }
+        // default: use the same as origin resource
+        return "//" + link;
+    };
+
+    // associate a link trigger for a gimmick. i.e. [gimmick:foo]() then
+    // foo is the trigger and will invoke the corresponding gimmick
+    $.md.linkGimmick = function (module, trigger, callback, stage) {
+        if (stage === undefined) {
+            stage = "gimmick";
+        }
+        var linktrigger = new LinkTrigger({
+            trigger: trigger,
+            module: module,
+            stage: stage,
+            callback: callback,
+        });
+        linkTriggers.push(linktrigger);
+    };
+
+    $.md.triggerIsActive = function (trigger) {
+        if (activeLinkTriggers.indexOf(trigger) === -1) {
+            return false;
+        } else {
+            return true;
+        }
+    };
+
+    var initialized = false;
+    // TODO combine main.js and modules.js closure
+    $.md.initializeGimmicks = function () {
+        findActiveLinkTrigger();
+        runGimmicksOnce();
+        loadRequiredScripts();
+    };
+
+    // END PUBLIC API
+
+    var log = $.md.getLogger();
+
+    // triggers that we actually found on the page
+    // array of string
+    var activeLinkTriggers = [];
+
+    // array of ScriptInfo
+    var registeredScripts = [];
+    function ScriptInfo(initial) {
+        this.module = undefined;
+        this.options = {};
+
+        // can ba an URL or javascript sourcecode
+        this.src = "";
+
+        $.extend(this, initial);
+    }
+
+    // array of linkTriggers
+    var linkTriggers = [];
+    function LinkTrigger(initial) {
+        this.trigger = undefined;
+        this.module = undefined;
+        this.callback = undefined;
+
+        $.extend(this, initial);
+    }
+
+    // jQuery does some magic when inserting inline scripts, so better
+    // use vanilla JS. See:
+    // http://stackoverflow.com/questions/610995/jquery-cant-append-script-element
+    function insertInlineScript(src) {
+        // scripts always need to go directly into the DOM
+        var script = document.createElement("script");
+        script.type = "text/javascript";
+        script.text = src;
+        document.body.appendChild(script);
+    }
+
+    // since we are GPL, we have to be cautious what other scripts we load
+    // as delivering to the browser is considered delivering a derived work
+    var licenses = [
+        "MIT",
+        "BSD",
+        "GPL",
+        "GPL2",
+        "GPL3",
+        "LGPL",
+        "LGPL2",
+        "APACHE2",
+        "PUBLICDOMAIN",
+        "EXCEPTION",
+        "OTHER",
+    ];
+    function checkLicense(license, module) {
+        if ($.inArray(license, licenses) === -1) {
+            var availLicenses = JSON.stringify(licenses);
+            log.warn("license " + license + " is not known.");
+            log.warn("Known licenses:" + availLicenses);
+        } else if (license === "OTHER") {
+            log.warn(
+                "WARNING: Module " +
+                    module.name +
+                    " uses a script" +
+                    " with unknown license. This may be a GPL license violation if" +
+                    " this website is publically available!"
+            );
+        }
+    }
+
+    // will actually schedule the script load into the DOM.
+    function loadScript(scriptinfo) {
+        var module = scriptinfo.module,
+            src = scriptinfo.src,
+            options = scriptinfo.options;
+
+        var license = options.license || "OTHER",
+            loadstage = options.loadstage || "skel_ready",
+            finishstage = options.finishstage || "pregimmick",
+            callback = options.callback;
+
+        var loadDone = $.Deferred();
+
+        checkLicense(license, module);
+        // start script loading
+        log.debug("subscribing " + module.name + " to start: " + loadstage + " end in: " + finishstage);
+        $.md.stage(loadstage).subscribe(function (done) {
+            if (src.startsWith("//") || src.startsWith("http")) {
+                $.getScript(src, function () {
+                    if (callback !== undefined) {
+                        callback(done);
+                    } else {
+                        log.debug("module" + module.name + " script load done: " + src);
+                        done();
+                    }
+                    loadDone.resolve();
+                });
+            } else {
+                // inline script that we directly insert
+                insertInlineScript(src);
+                log.debug("module" + module.name + " script inject done");
+                loadDone.resolve();
+                done();
+            }
+        });
+        // if loading is not yet finished in stage finishstage, wait
+        // for the loading to complete
+        $.md.stage(finishstage).subscribe(function (done) {
+            loadDone.done(function () {
+                done();
+            });
+        });
+    }
+
+    // finds out that kind of trigger words are acutally used on a given page
+    // this is most likely a very small subset of all available gimmicks
+    function findActiveLinkTrigger() {
+        var $gimmicks = $("a:icontains(gimmick:)");
+        $gimmicks.each(function (i, e) {
+            var parts = getGimmickLinkParts($(e));
+            if (activeLinkTriggers.indexOf(parts.trigger) === -1) {
+                activeLinkTriggers.push(parts.trigger);
+            }
+        });
+        log.debug("Scanning for required gimmick links: " + JSON.stringify(activeLinkTriggers));
+    }
+
+    function loadRequiredScripts() {
+        // find each module responsible for the link trigger
+        $.each(activeLinkTriggers, function (i, trigger) {
+            var module = findModuleByTrigger(trigger);
+            if (module === undefined) {
+                log.error('Gimmick link: "' + trigger + '" found but no suitable gimmick loaded');
+                return;
+            }
+            var scriptinfo = registeredScripts.filter(function (info) {
+                return info.module.name === module.name;
+            })[0];
+            // register to load the script
+            if (scriptinfo !== undefined) {
+                loadScript(scriptinfo);
+            }
+        });
+    }
+
+    function findModuleByTrigger(trigger) {
+        var ret;
+        $.each(linkTriggers, function (i, e) {
+            if (e.trigger === trigger) {
+                ret = e.module;
+            }
+        });
+        return ret;
+    }
+
+    function getGimmickLinkParts($link) {
+        var link_text = $.trim($link.toptext());
+        // returns linkTrigger, options, linkText
+        if (link_text.match(/gimmick:/i) === null) {
+            return null;
+        }
+        var href = $.trim($link.attr("href"));
+        var r = new RegExp(/gimmick:\s*([^(\s]*)\s*(\(\s*{?(.*)\s*}?\s*\))*/i);
+        var matches = r.exec(link_text);
+        if (matches === null || matches[1] === undefined) {
+            $.error("Error matching a gimmick: " + link_text);
+            return null;
+        }
+        var trigger = matches[1].toLowerCase();
+        var args = null;
+        // getting the parameters
+        if (matches[2] !== undefined) {
+            // remove whitespaces
+            var params = $.trim(matches[3].toString());
+            // remove the closing } if present
+            if (params.charAt(params.length - 1) === "}") {
+                params = params.substring(0, params.length - 1);
+            }
+            // add surrounding braces and paranthese
+            params = "({" + params + "})";
+            // replace any single quotes by double quotes
+            params = params.replace(/'/g, '"');
+            // finally, try if the json object is valid
+            try {
+                /*jshint -W061 */
+                args = eval(params);
+            } catch (err) {
+                log.error("error parsing argument of gimmick: " + link_text + "giving error: " + err);
+            }
+        }
+        return { trigger: trigger, options: args, href: href };
+    }
+
+    function runGimmicksOnce() {
+        // runs the once: callback for each gimmick within the init stage
+        $.each($.md.gimmicks, function (i, module) {
+            if (module.once === undefined) {
+                return;
+            }
+            module.once();
+        });
+    }
+
+    // activate all gimmicks on a page, that are contain the text gimmick:
+    // TODO make private / merge closures
+    $.md.registerLinkGimmicks = function () {
+        var $gimmick_links = $("a:icontains(gimmick:)");
+        $gimmick_links.each(function (i, e) {
+            var $link = $(e);
+            var gimmick_arguments = getGimmickLinkParts($link);
+
+            $.each(linkTriggers, function (i, linktrigger) {
+                if (gimmick_arguments.trigger === linktrigger.trigger) {
+                    subscribeLinkTrigger($link, gimmick_arguments, linktrigger);
+                }
+            });
+        });
+    };
+
+    function subscribeLinkTrigger($link, args, linktrigger) {
+        log.debug("Subscribing gimmick " + linktrigger.module.name + " to stage: " + linktrigger.stage);
+
+        $.md.stage(linktrigger.stage).subscribe(function (done) {
+            args.options = args.options || {};
+
+            // it is possible that broken modules or any other transformation removed the $link
+            // from the dom in the meantime
+            if (!jQuery.contains(document.documentElement, $link[0])) {
+                log.error("LINK IS NOT IN THE DOM ANYMORE: ");
+                console.log($link);
+            }
+
+            log.debug("Running gimmick " + linktrigger.module.name);
+            linktrigger.callback($link, args.options, args.href, done);
+
+            // if the gimmick didn't call done, we trigger it here
+            done();
+        });
+    }
+})(jQuery);
+
+(function ($) {
+    var publicMethods = {
+        createBasicSkeleton: function () {
+            setPageTitle();
+            wrapParagraphText();
+            linkImagesToSelf();
+            groupImages();
+            removeBreaks();
+            addInpageAnchors();
+
+            $.md.stage("all_ready").subscribe(function (done) {
+                if ($.md.inPageAnchor !== "") {
+                    $.md.util.wait(500).then(function () {
+                        $.md.scrollToInPageAnchor($.md.inPageAnchor);
+                    });
+                }
+                done();
+            });
+            return;
+        },
+    };
+    $.md.publicMethods = $.extend({}, $.md.publicMethods, publicMethods);
+
+    // set the page title to the browser document title, optionally picking
+    // the first h1 element as title if no title is given
+    function setPageTitle() {
+        var $pageTitle;
+        if ($.md.config.title) $("title").text($.md.config.title);
+
+        $pageTitle = $("#md-content h1").eq(0);
+        if ($.trim($pageTitle.toptext()).length > 0) {
+            $("#md-title").prepend($pageTitle);
+            var title = $pageTitle.toptext();
+            // document.title = title;
+        } else {
+            $("#md-title").remove();
+        }
+    }
+    function wrapParagraphText() {
+        // TODO is this true for marked.js?
+
+        // markdown gives us sometime paragraph that contain child tags (like img),
+        // but the containing text is not wrapped. Make sure to wrap the text in the
+        // paragraph into a <div>
+
+        // this also moves ANY child tags to the front of the paragraph!
+        $("#md-content p").each(function () {
+            var $p = $(this);
+            // nothing to do for paragraphs without text
+            if ($.trim($p.text()).length === 0) {
+                // make sure no whitespace are in the p and then exit
+                //$p.text ('');
+                return;
+            }
+            // children elements of the p
+            var children = $p.contents().filter(function () {
+                var $child = $(this);
+                // we extract images and hyperlinks with images out of the paragraph
+                if (this.tagName === "A" && $child.find("img").length > 0) {
+                    return true;
+                }
+                if (this.tagName === "IMG") {
+                    return true;
+                }
+                // else
+                return false;
+            });
+            var floatClass = getFloatClass($p);
+            $p.wrapInner('<div class="md-text" />');
+
+            // if there are no children, we are done
+            if (children.length === 0) {
+                return;
+            }
+            // move the children out of the wrapped div into the original p
+            children.prependTo($p);
+
+            // at this point, we now have a paragraph that holds text AND images
+            // we mark that paragraph to be a floating environment
+            // TODO determine floatenv left/right
+            $p.addClass("md-floatenv").addClass(floatClass);
+        });
+    }
+    function removeBreaks() {
+        // since we use non-markdown-standard line wrapping, we get lots of
+        // <br> elements we don't want.
+
+        // remove a leading <br> from floatclasses, that happen to
+        // get insertet after an image
+        $(".md-floatenv")
+            .find(".md-text")
+            .each(function () {
+                var $first = $(this).find("*").eq(0);
+                if ($first.is("br")) {
+                    $first.remove();
+                }
+            });
+
+        // remove any breaks from image groups
+        $(".md-image-group").find("br").remove();
+    }
+    function getFloatClass(par) {
+        var $p = $(par);
+        var floatClass = "";
+
+        // reduce content of the paragraph to images
+        var nonTextContents = $p.contents().filter(function () {
+            if (this.tagName === "IMG" || this.tagName === "IFRAME") {
+                return true;
+            } else if (this.tagName === "A") {
+                return $(this).find("img").length > 0;
+            } else {
+                return $.trim($(this).text()).length > 0;
+            }
+        });
+        // check the first element - if its an image or a link with image, we go left
+        var elem = nonTextContents[0];
+        if (elem !== undefined && elem !== null) {
+            if (elem.tagName === "IMG" || elem.tagName === "IFRAME") {
+                floatClass = "md-float-left";
+            } else if (elem.tagName === "A" && $(elem).find("img").length > 0) {
+                floatClass = "md-float-left";
+            } else {
+                floatClass = "md-float-right";
+            }
+        }
+        return floatClass;
+    }
+    // images are put in the same image group as long as there is
+    // not separating paragraph between them
+    function groupImages() {
+        var par = $("p img").parents("p");
+        // add an .md-image-group class to the p
+        par.addClass("md-image-group");
+    }
+
+    // takes a standard <img> tag and adds a hyperlink to the image source
+    // needed since we scale down images via css and want them to be accessible
+    // in original format
+    function linkImagesToSelf() {
+        function selectNonLinkedImages() {
+            // only select images that do not have a non-empty parent link
+            $images = $("img").filter(function (index) {
+                var $parent_link = $(this).parents("a").eq(0);
+                if ($parent_link.length === 0) return true;
+                var attr = $parent_link.attr("href");
+                return attr && attr.length === 0;
+            });
+            return $images;
+        }
+        var $images = selectNonLinkedImages();
+        return $images.each(function () {
+            var $this = $(this);
+            var img_src = $this.attr("src");
+            var img_title = $this.attr("title");
+            if (img_title === undefined) {
+                img_title = "";
+            }
+            // wrap the <img> tag in an anchor and copy the title of the image
+            $this.wrap('<a class="md-image-selfref" href="' + img_src + '" title="' + img_title + '"/> ');
+        });
+    }
+
+    function addInpageAnchors() {
+        // adds a pilcrow (paragraph) character to heading with a link for the
+        // inpage anchor
+        function addPilcrow($heading, href) {
+            var c = $.md.config.anchorCharacter;
+            var $pilcrow = $('<span class="anchor-highlight"><a>' + c + "</a></span>");
+            $pilcrow.find("a").attr("href", href);
+            $pilcrow.hide();
+
+            var mouse_entered = false;
+            $heading.mouseenter(function () {
+                mouse_entered = true;
+                $.md.util.wait(300).then(function () {
+                    if (!mouse_entered) return;
+                    $pilcrow.fadeIn(200);
+                });
+            });
+            $heading.mouseleave(function () {
+                mouse_entered = false;
+                $pilcrow.fadeOut(200);
+            });
+            $pilcrow.appendTo($heading);
+        }
+
+        // adds a link to the navigation at the top of the page
+        function addJumpLinkToTOC($heading) {
+            if ($.md.config.useSideMenu === false) return;
+            if ($heading.prop("tagName") !== "H2") return;
+
+            var c = $.md.config.tocAnchor;
+            if (c === "") return;
+
+            var $jumpLink = $('<a class="visible-xs visible-sm jumplink" href="#md-page-menu">' + c + "</a>");
+            $jumpLink.click(function (ev) {
+                ev.preventDefault();
+
+                $("body").scrollTop($("#md-page-menu").position().top);
+            });
+
+            if ($heading.parents("#md-menu").length === 0) {
+                $jumpLink.insertAfter($heading);
+            }
+        }
+
+        // adds a page inline anchor to each h1,h2,h3,h4,h5,h6 element
+        // which can be accessed by the headings text
+        $("h1,h2,h3,h4,h5,h6")
+            .not("#md-title h1")
+            .each(function () {
+                var $heading = $(this);
+                $heading.addClass("md-inpage-anchor");
+                var text = $heading.clone().children(".anchor-highlight").remove().end().text();
+                var href = $.md.util.getInpageAnchorHref(text);
+                addPilcrow($heading, href);
+
+                //add jumplink to table of contents
+                addJumpLinkToTOC($heading);
+            });
+    }
+
+    $.md.scrollToInPageAnchor = function (anchortext) {
+        if (anchortext.startsWith("#")) anchortext = anchortext.substring(1, anchortext.length);
+        // we match case insensitive
+        var doBreak = false;
+        $(".md-inpage-anchor").each(function () {
+            if (doBreak) {
+                return;
+            }
+            var $this = $(this);
+            // don't use the text of any subnode
+            var text = $this.toptext();
+            var match = $.md.util.getInpageAnchorText(text);
+            if (anchortext === match) {
+                this.scrollIntoView(true);
+                var navbar_offset = $(".navbar-collapse").height() + 5;
+                window.scrollBy(0, -navbar_offset + 5);
+                doBreak = true;
+            }
+        });
+    };
+})(jQuery);
+
+(function ($) {
+    "use strict";
+    // call the gimmick
+    $.mdbootstrap = function (method) {
+        if ($.mdbootstrap.publicMethods[method]) {
+            return $.mdbootstrap.publicMethods[method].apply(this, Array.prototype.slice.call(arguments, 1));
+        } else {
+            $.error("Method " + method + " does not exist on jquery.mdbootstrap");
+        }
+    };
+    // simple wrapper around $().bind
+    $.mdbootstrap.events = [];
+    $.mdbootstrap.bind = function (ev, func) {
+        $(document).bind(ev, func);
+        $.mdbootstrap.events.push(ev);
+    };
+    $.mdbootstrap.trigger = function (ev) {
+        $(document).trigger(ev);
+    };
+
+    var navStyle = "";
+
+    // PUBLIC API functions that are exposed
+    var publicMethods = {
+        bootstrapify: function () {
+            createPageSkeleton();
+            buildMenu();
+            changeHeading();
+            replaceImageParagraphs();
+
+            $("table").addClass("table").addClass("table-bordered");
+            //pullRightBumper ();
+
+            // remove the margin for headings h1 and h2 that are the first
+            // on page
+            //if (navStyle == "sub" || (navStyle == "top" && $('#md-title').text ().trim ().length === 0))
+            //    $(".md-first-heading").css ("margin-top", "0");
+
+            // external content should run after gimmicks were run
+            $.md.stage("pregimmick").subscribe(function (done) {
+                if ($.md.config.useSideMenu !== false) {
+                    createPageContentMenu();
+                }
+                addAdditionalFooterText();
+                done();
+            });
+            $.md.stage("postgimmick").subscribe(function (done) {
+                adjustExternalContent();
+                highlightActiveLink();
+
+                done();
+            });
+        },
+    };
+    // register the public API functions
+    $.mdbootstrap.publicMethods = $.extend({}, $.mdbootstrap.publicMethods, publicMethods);
+
+    // PRIVATE FUNCTIONS:
+
+    function buildTopNav() {
+        // replace with the navbar skeleton
+        if ($("#md-menu").length <= 0) {
+            return;
+        }
+        navStyle = "top";
+        var $menuContent = $("#md-menu").children();
+
+        // $('#md-menu').addClass ('navbar navbar-default navbar-fixed-top');
+        // var menusrc = '';
+        // menusrc += '<div id="md-menu-inner" class="container">';
+        // menusrc += '<ul id="md-menu-ul" class="nav navbar-nav">';
+        // menusrc += '</ul></div>';
+
+        var navbar = "";
+        navbar += '<div id="md-main-navbar" class="navbar navbar-default navbar-fixed-top" role="navigation">';
+        navbar += '<div class="navbar-header">';
+        navbar +=
+            '<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">';
+        navbar += '<span class="sr-only">Toggle navigation</span>';
+        navbar += '<span class="icon-bar"></span>';
+        navbar += '<span class="icon-bar"></span>';
+        navbar += '<span class="icon-bar"></span>';
+        navbar += "</button>";
+        navbar += '<a class="navbar-brand" href="#"></a>';
+        navbar += "</div>";
+
+        navbar += '<div class="collapse navbar-collapse navbar-ex1-collapse">';
+        navbar += '<ul class="nav navbar-nav" />';
+        navbar += '<ul class="nav navbar-nav navbar-right" />';
+        navbar += "</div>";
+        navbar += "</div>";
+        var $navbar = $(navbar);
+
+        $navbar.appendTo("#md-menu");
+        // .eq(0) becase we dont want navbar-right to be appended to
+        $("#md-menu ul.nav").eq(0).append($menuContent);
+
+        // the menu should be the first element in the body
+        $("#md-menu").prependTo("#md-all");
+
+        var brand_text = $("#md-menu h1").toptext();
+        $("#md-menu h1").remove();
+        $("a.navbar-brand").text(brand_text);
+
+        // initial offset
+        $("#md-body").css("margin-top", "70px");
+        $.md.stage("pregimmick").subscribe(function (done) {
+            check_offset_to_navbar();
+            done();
+        });
+    }
+    // the navbar has different height depending on theme, number of navbar entries,
+    // and window/device width. Therefore recalculate on start and upon window resize
+    function set_offset_to_navbar() {
+        var height = $("#md-main-navbar").height() + 10;
+        $("#md-body").css("margin-top", height + "px");
+    }
+    function check_offset_to_navbar() {
+        // HACK this is VERY UGLY. When an external theme is used, we don't know when the
+        // css style will be finished loading - and we can only correctly calculate
+        // the height AFTER it has completely loaded.
+        var navbar_height = 0;
+
+        var dfd1 = $.md.util.repeatUntil(
+            40,
+            function () {
+                navbar_height = $("#md-main-navbar").height();
+                return navbar_height > 35 && navbar_height < 481;
+            },
+            25
+        );
+
+        dfd1.done(function () {
+            navbar_height = $("#md-main-navbar").height();
+            set_offset_to_navbar();
+            // now bootstrap changes this maybe after a while, again watch for changes
+            var dfd2 = $.md.util.repeatUntil(
+                20,
+                function () {
+                    return navbar_height !== $("#md-main-navbar").height();
+                },
+                25
+            );
+            dfd2.done(function () {
+                // it changed, so we need to change it again
+                set_offset_to_navbar();
+            });
+            // and finally, for real slow computers, make sure it is changed if changin very late
+            $.md.util.wait(2000).done(function () {
+                set_offset_to_navbar();
+            });
+        });
+    }
+    function buildSubNav() {
+        // replace with the navbar skeleton
+        /* BROKEN CODE
+        if ($('#md-menu').length <= 0) {
+            return;
+        }
+        navStyle = 'sub';
+        var $menuContent = $('#md-menu').html ();
+
+        var menusrc = '';
+        menusrc += '<div id="md-menu-inner" class="subnav">';
+        menusrc += '<ul id="md-menu-ul" class="nav nav-pills">';
+        menusrc += $menuContent;
+        menusrc += '</ul></div>';
+        $('#md-menu').empty();
+        $('#md-menu').wrapInner($(menusrc));
+        $('#md-menu').addClass ('col-md-12');
+
+        $('#md-menu-container').insertAfter ($('#md-title-container'));
+        */
+    }
+
+    function buildMenu() {
+        if ($("#md-menu a").length === 0) {
+            return;
+        }
+        var h = $("#md-menu");
+
+        // make toplevel <a> a dropdown
+        h.find('> a[href=""]')
+            .attr("data-toggle", "dropdown")
+            .addClass("dropdown-toggle")
+            .attr("href", "")
+            .append('<b class="caret"/>');
+        h.find("ul").addClass("dropdown-menu");
+        h.find("ul li").addClass("dropdown");
+
+        // replace hr with dividers
+        $("#md-menu hr").each(function (i, e) {
+            var hr = $(e);
+            var prev = hr.prev();
+            var next = hr.next();
+            if (prev.is("ul") && prev.length >= 0) {
+                prev.append($('<li class="divider"/>'));
+                hr.remove();
+                if (next.is("ul")) {
+                    next.find("li").appendTo(prev);
+                    next.remove();
+                }
+                // next ul should now be empty
+            }
+            return;
+        });
+
+        // remove empty uls
+        $("#md-menu ul").each(function (i, e) {
+            var ul = $(e);
+            if (ul.find("li").length === 0) {
+                ul.remove();
+            }
+        });
+
+        $("#md-menu hr").replaceWith($('<li class="divider-vertical"/>'));
+
+        // wrap the toplevel links in <li>
+        $("#md-menu > a").wrap("<li />");
+        $("#md-menu ul").each(function (i, e) {
+            var ul = $(e);
+            ul.appendTo(ul.prev());
+            ul.parent("li").addClass("dropdown");
+        });
+
+        // submenu headers
+        $("#md-menu li.dropdown")
+            .find("h1, h2, h3")
+            .each(function (i, e) {
+                var $e = $(e);
+                var text = $e.toptext();
+                var header = $('<li class="dropdown-header" />');
+                header.text(text);
+                $e.replaceWith(header);
+            });
+
+        // call the user specifed menu function
+        buildTopNav();
+    }
+    function isVisibleInViewport(e) {
+        var el = $(e);
+        var top = $(window).scrollTop();
+        var bottom = top + $(window).height();
+
+        var eltop = el.offset().top;
+        var elbottom = eltop + el.height();
+
+        return elbottom <= bottom && eltop >= top;
+    }
+
+    function createPageContentMenu() {
+        // assemble the menu
+        var $headings = $("#md-content").find("h2").clone();
+        // we dont want the text of any child nodes
+        $headings.children().remove();
+
+        if ($headings.length <= 1) {
+            return;
+        }
+
+        $("#md-content").removeClass("col-md-12");
+        $("#md-content").addClass("col-md-9");
+        $("#md-content-row").prepend('<div class="col-md-3" id="md-left-column"/>');
+
+        var recalc_width = function () {
+            // if the page menu is affixed, it is not a child of the
+            // <md-left-column> anymore and therefore does not inherit
+            // its width. On every resize, change the class accordingly
+            var width_left_column = $("#md-left-column").css("width");
+            $("#md-page-menu").css("width", width_left_column);
+        };
+
+        $(window).scroll(function () {
+            recalc_width($("#md-page-menu"));
+            var $first;
+            $("*.md-inpage-anchor").each(function (i, e) {
+                if ($first === undefined) {
+                    var h = $(e);
+                    if (isVisibleInViewport(h)) {
+                        $first = h;
+                    }
+                }
+            });
+            // highlight in the right menu
+            $("#md-page-menu a").each(function (i, e) {
+                var $a = $(e);
+                if ($first && $a.toptext() === $first.toptext()) {
+                    $("#md-page-menu a.active").removeClass("active");
+                    //$a.parent('a').addClass('active');
+                    $a.addClass("active");
+                }
+            });
+        });
+
+        var affixDiv = $('<div id="md-page-menu" />');
+
+        //var top_spacing = $('#md-menu').height() + 15;
+        var top_spacing = 70;
+        affixDiv.affix({
+            //offset: affix.position() - 50,
+            offset: 130,
+        });
+        affixDiv.css("top", top_spacing);
+        //affix.css('top','-250px');
+
+        var $pannel = $('<div class="panel panel-default"><ul class="list-group"/></div>');
+        var $ul = $pannel.find("ul");
+        affixDiv.append($pannel);
+
+        $headings.each(function (i, e) {
+            var $heading = $(e);
+            var $li = $('<li class="list-group-item" />');
+            var $a = $("<a />");
+            $a.attr("href", $.md.util.getInpageAnchorHref($heading.toptext()));
+            $a.click(function (ev) {
+                ev.preventDefault();
+
+                var $this = $(this);
+                var anchortext = $.md.util.getInpageAnchorText($this.toptext());
+                $.md.scrollToInPageAnchor(anchortext);
+            });
+            $a.text($heading.toptext());
+            $li.append($a);
+            $ul.append($li);
+        });
+
+        $(window).resize(function () {
+            recalc_width($("#md-page-menu"));
+            check_offset_to_navbar();
+        });
+        $.md.stage("postgimmick").subscribe(function (done) {
+            // recalc_width();
+            done();
+        });
+
+        //menu.css('width','100%');
+        $("#md-left-column").append(affixDiv);
+    }
+
+    function createPageSkeleton() {
+        $("#md-title").wrap('<div class="container" id="md-title-container"/>');
+        $("#md-title").wrap('<div class="row" id="md-title-row"/>');
+
+        $("#md-menu").wrap('<div class="container" id="md-menu-container"/>');
+        $("#md-menu").wrap('<div class="row" id="md-menu-row"/>');
+
+        $("#md-content").wrap('<div class="container" id="md-content-container"/>');
+        $("#md-content").wrap('<div class="row" id="md-content-row"/>');
+
+        $("#md-body").wrap('<div class="container" id="md-body-container"/>');
+        $("#md-body").wrap('<div class="row" id="md-body-row"/>');
+
+        $("#md-title").addClass("col-md-12");
+        $("#md-content").addClass("col-md-12");
+    }
+    function pullRightBumper() {
+        /*     $("span.bumper").each (function () {
+			$this = $(this);
+			$this.prev().addClass ("pull-right");
+		});
+		$('span.bumper').addClass ('pull-right');
+*/
+    }
+
+    function changeHeading() {
+        // HEADING
+        var jumbo = $('<div class="page-header" />');
+        $("#md-title").wrapInner(jumbo);
+    }
+
+    function highlightActiveLink() {
+        // when no menu is used, return
+        if ($("#md-menu").find("li").length === 0) {
+            return;
+        }
+        var filename = window.location.hash;
+
+        if (filename.length === 0) {
+            filename = "#!index.md";
+        }
+        var selector = 'li:has(a[href="' + filename + '"])';
+        $("#md-menu").find(selector).addClass("active");
+    }
+
+    // replace all <p> around images with a <div class="thumbnail" >
+    function replaceImageParagraphs() {
+        // only select those paragraphs that have images in them
+        var $pars = $("p img").parents("p");
+        $pars.each(function () {
+            var $p = $(this);
+            var $images = $(this)
+                .find("img")
+                .filter(function () {
+                    // only select those images that have no parent anchor
+                    return $(this).parents("a").length === 0;
+                })
+                // add those anchors including images
+                .add($(this).find("img"))
+                .addClass("img-responsive")
+                .addClass("img-thumbnail");
+
+            // create a new url group at the fron of the paragraph
+            //$p.prepend($('<ul class="thumbnails" />'));
+            // move the images to the newly created ul
+            //$p.find('ul').eq(0).append($images);
+
+            // wrap each image with a <li> that limits their space
+            // the number of images in a paragraphs determines thei width / span
+
+            // if the image is a link, wrap around the link to avoid
+            function wrapImage($imgages, wrapElement) {
+                return $images.each(function (i, img) {
+                    var $img = $(img);
+                    var $parent_img = $img.parent("a");
+                    if ($parent_img.length > 0) $parent_img.wrap(wrapElement);
+                    else $img.wrap(wrapElement);
+                });
+            }
+
+            if ($p.hasClass("md-floatenv")) {
+                if ($images.length === 1) {
+                    wrapImage($images, '<div class="col-sm-8" />');
+                } else if ($images.length === 2) {
+                    wrapImage($images, '<div class="col-sm-4" />');
+                } else {
+                    wrapImage($images, '<div class="col-sm-2" />');
+                }
+            } else {
+                // non-float => images are on their own single paragraph, make em larger
+                // but remember, our image resizing will make them only as large as they are
+                // but do no upscaling
+                // TODO replace by calculation
+
+                if ($images.length === 1) {
+                    wrapImage($images, '<div class="col-sm-12" />');
+                } else if ($images.length === 2) {
+                    wrapImage($images, '<div class="col-sm-6" />');
+                } else if ($images.length === 3) {
+                    wrapImage($images, '<div class="col-sm-4" />');
+                } else if ($images.length === 4) {
+                    wrapImage($images, '<div class="col-sm-3" />');
+                } else {
+                    wrapImage($images, '<div class="col-sm-2" />');
+                }
+            }
+            $p.addClass("row");
+            // finally, every img gets its own wrapping thumbnail div
+            //$images.wrap('<div class="thumbnail" />');
+        });
+
+        // apply float to the ul thumbnails
+        //$('.md-floatenv.md-float-left ul').addClass ('pull-left');
+        //$('.md-floatenv.md-float-right ul').addClass ('pull-right');
+    }
+
+    function adjustExternalContent() {
+        // external content are usually iframes or divs that are integrated
+        // by gimmicks
+        // example: youtube iframes, google maps div canvas
+        // all external content are in the md-external class
+
+        $("iframe.md-external").not(".md-external-nowidth").attr("width", "450").css("width", "450px");
+
+        $("iframe.md-external").not(".md-external-noheight").attr("height", "280").css("height", "280px");
+
+        // make it appear like an image thumbnal
+        //$('.md-external').addClass('img-thumbnail');
+
+        //.wrap($("<ul class='thumbnails' />")).wrap($("<li class='col-md-6' />"));
+        $("div.md-external").not(".md-external-noheight").css("height", "280px");
+        $("div.md-external").not(".md-external-nowidth").css("width", "450px");
+
+        // // make it appear like an image thumbnal
+        // $("div.md-external").addClass("thumbnail").wrap($("<ul class='thumbnails' />")).wrap($("<li class='col-md-10' />"));
+
+        // $("div.md-external-large").css('width', "700px")
+    }
+
+    // note: the footer is part of the GPLv3 legal information
+    // and may not be removed or hidden to comply with licensing conditions.
+    function addFooter() {
+        var navbar = "";
+        navbar += '<hr><div class="scontainer">';
+        navbar += '<div class="pull-right md-copyright-footer"> ';
+        navbar += '<span id="md-footer-additional"></span>';
+        navbar += 'Website generated with <a href="http://www.mdwiki.info">MDwiki</a> ';
+        navbar += "&copy; Timo D&ouml;rr and contributors. ";
+        navbar += "</div>";
+        navbar += "</div>";
+        var $navbar = $(navbar);
+        $navbar.css("position", "relative");
+        $navbar.css("margin-top", "1em");
+        $("#md-all").append($navbar);
+    }
+
+    function addAdditionalFooterText() {
+        var text = $.md.config.additionalFooterText;
+        if (text) {
+            $(".md-copyright-footer #md-footer-additional").html(text);
+        }
+    }
+})(jQuery);
+
+(function ($) {
+    $.gimmicks = $.fn.gimmicks = function (method) {
+        if (method === undefined) {
+            return;
+        }
+        // call the gimmick
+        if ($.fn.gimmicks.methods[method]) {
+            return $.fn.gimmicks.methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
+        } else {
+            $.error("Gimmick " + method + " does not exist on jQuery.gimmicks");
+        }
+    };
+
+    // TODO underscores _ in Markdown links are not allowed! bug in our MD imlemenation
+})(jQuery);
+
+(function ($) {
+    //'use strict';
+    var alertsGimmick = {
+        name: "alerts",
+        // TODO
+        //version: $.md.version,
+        load: function () {
+            $.md.stage("bootstrap").subscribe(function (done) {
+                createAlerts();
+                done();
+            });
+        },
+    };
+    $.md.registerGimmick(alertsGimmick);
+
+    // takes a standard <img> tag and adds a hyperlink to the image source
+    // needed since we scale down images via css and want them to be accessible
+    // in original format
+    function createAlerts() {
+        var matches = $(select_paragraphs());
+        matches.each(function () {
+            var $p = $(this.p);
+            var type = this.alertType;
+            $p.addClass("alert");
+
+            if (type === "note") {
+                $p.addClass("alert-info");
+            } else if (type === "hint") {
+                $p.addClass("alert-success");
+            } else if (type === "warning") {
+                $p.addClass("alert-warning");
+            }
+        });
+    }
+
+    // picks out the paragraphs that start with a trigger word
+    function select_paragraphs() {
+        var note = ["note", "beachte"];
+        var warning = ["achtung", "attention", "warnung", "warning", "atención", "guarda", "advertimiento"];
+        var hint = ["hint", "tipp", "tip", "hinweis"];
+        var exp = note.concat(warning);
+        exp = exp.concat(hint);
+        var matches = [];
+
+        $("p").filter(function () {
+            var $par = $(this);
+            // check against each expression
+            $(exp).each(function (i, trigger) {
+                var txt = $par.text().toLowerCase();
+                // we match only paragrachps in which the 'trigger' expression
+                // is follow by a ! or :
+                var re = new RegExp(trigger + "(:|!)+.*", "i");
+                var alertType = "none";
+                if (txt.match(re) !== null) {
+                    if ($.inArray(trigger, note) >= 0) {
+                        alertType = "note";
+                    } else if ($.inArray(trigger, warning) >= 0) {
+                        alertType = "warning";
+                    } else if ($.inArray(trigger, hint) >= 0) {
+                        alertType = "hint";
+                    }
+                    matches.push({
+                        p: $par,
+                        alertType: alertType,
+                    });
+                }
+            });
+        });
+        return matches;
+    }
+})(jQuery);
+
+(function ($) {
+    // makes trouble, find out why
+    //'use strict';
+    var colorboxGimmick = {
+        name: "colorbox",
+        load: function () {
+            $.md.stage("gimmick").subscribe(function (done) {
+                $.gimmicks("colorbox");
+                done();
+            });
+        },
+    };
+    $.md.registerGimmick(colorboxGimmick);
+
+    var methods = {
+        // takes a standard <img> tag and adds a hyperlink to the image source
+        // needed since we scale down images via css and want them to be accessible
+        // in original format
+        colorbox: function () {
+            var $image_groups;
+            if (!(this instanceof jQuery)) {
+                // select the image groups of the page
+                $image_groups = $(".md-image-group");
+            } else {
+                $image_groups = $(this);
+            }
+            // operate on md-image-group, which holds one
+            // or more images that are to be colorbox'ed
+            var counter = 0;
+            return $image_groups.each(function () {
+                var $this = $(this);
+
+                // each group requires a unique name
+                var gal_group = "gallery-group-" + counter++;
+
+                // create a hyperlink around the image
+                $this
+                    .find("a.md-image-selfref img")
+                    // filter out images that already are a hyperlink
+                    // (so won't be part of the gallery)
+
+                    // apply colorbox on their parent anchors
+                    .parents("a")
+                    .colorbox({
+                        rel: gal_group,
+                        opacity: 0.75,
+                        slideshow: true,
+                        maxWidth: "95%",
+                        maxHeight: "95%",
+                        scalePhotos: true,
+                        photo: true,
+                        slideshowAuto: false,
+                    });
+            });
+        },
+    };
+    $.gimmicks.methods = $.extend({}, $.fn.gimmicks.methods, methods);
+})(jQuery);
+
+(function ($) {
+    "use strict";
+
+    var themeChooserGimmick = {
+        name: "Themes",
+        version: $.md.version,
+        once: function () {
+            $.md.linkGimmick(this, "carousel", carousel);
+        },
+    };
+    $.md.registerGimmick(themeChooserGimmick);
+
+    function carousel($link, opt, href) {
+        var $c = $('<div id="myCarousel" class="carousel slide"></div>');
+        var $d = $('<div class="carousel-inner"/>');
+        $c.append('<ol class="carousel-indicators" />');
+
+        var imageUrls = [];
+        var i = 0;
+        $.each(href.split(","), function (i, e) {
+            imageUrls.push($.trim(e));
+            $c.find("ol").append('<li data-target="#myCarousel" data-slide-to="' + i + '" class="active" /');
+            var div;
+            if (i === 0) {
+                div = '<div class="active item"/>';
+            } else {
+                div = '<div class="item"/>';
+            }
+            $d.append($(div).append('<img src="' + e + '"/>'));
+        });
+        $c.append($d);
+        $c.append('<a class="carousel-control left" href="#myCarousel" data-slide="prev">&lsaquo;</a>');
+        $c.append('<a class="carousel-control right" href="#myCarousel" data-slide="next">&rsaquo;</a>');
+        $link.replaceWith($c);
+    }
+})(jQuery);
+
+(function ($) {
+    "use strict";
+    var gistGimmick = {
+        name: "gist",
+        once: function () {
+            $.md.linkGimmick(this, "gist", gist);
+        },
+    };
+    $.md.registerGimmick(gistGimmick);
+
+    function gist($links, opt, href) {
+        $().lazygist("init");
+        return $links.each(function (i, link) {
+            var default_options = {
+                scheme: "https",
+                path: "gist.github.com/",
+            };
+            var options = $.extend(default_options, opt);
+            var $link = $(link);
+            var gistDiv = $('<div class="gist_here" data-id="' + href + '" />');
+            $link.replaceWith(gistDiv);
+            gistDiv.lazygist({
+                // we dont want a specific file so modify the url template
+                url_template: "{scheme}://{path}{id}.js"
+                    .replace(/\{scheme\}/g, options.scheme)
+                    .replace(/\{path\}/g, options.path),
+            });
+        });
+    }
+})(jQuery);
+
+/**
+ * Lazygist v0.2pre
+ *
+ * a jQuery plugin that will lazy load your gists.
+ *
+ * since jQuery 1.7.2
+ * https://github.com/tammo/jquery-lazy-gist
+ *
+ * Copyright, Tammo Pape
+ * http://tammopape.de
+ *
+ * Licensed under the MIT license.
+ */
+
+(function ($, window, document, undefined) {
+    "use strict";
+
+    //
+    // note:
+    // this plugin is not stateful
+    // and will not communicate with own instances at different elements
+    //
+
+    var pluginName = "lazygist",
+        version = "0.2pre",
+        defaults = {
+            // adding the ?file parameter to choose a file
+            url_template: "https://gist.github.com/{id}.js?file={file}",
+
+            // if these are strings, the attributes will be read from the element
+            id: "data-id",
+            file: "data-file",
+        },
+        options,
+        // will be replaced
+        /*jshint -W060 */
+        originwrite = document.write,
+        // stylesheet urls found in document.write calls
+        // they are cached to write them once to the document,
+        // not three times for three gists
+        stylesheets = [],
+        // cache gist-ids to know which are already appended to the dom
+        ids_dom = [],
+        // remember gist-ids if their javascript is already loaded
+        ids_ajax = [],
+        methods = {
+            /**
+             * Standard init function
+             * No magic here
+             */
+            init: function (options_input) {
+                // default options are default
+                options = $.extend({}, defaults, options_input);
+
+                // can be reset
+                /*jshint -W061 */
+                document.write = _write;
+
+                $.each(options, function (index, value) {
+                    if (typeof value !== "string") {
+                        throw new TypeError(value + " (" + typeof value + ") is not a string");
+                    }
+                });
+
+                return this.lazygist("load");
+            },
+
+            /**
+             * Load the gists
+             */
+            load: function () {
+                // (1) iterate over gist anchors
+                // (2) append the gist-html through the new document.write func (see _write)
+
+                // (1)
+                return this.filter("[" + options.id + "]").each(function () {
+                    var id = $(this).attr(options.id),
+                        file = $(this).attr(options.file),
+                        src;
+
+                    if (id !== undefined) {
+                        if ($.inArray(id, ids_ajax) !== -1) {
+                            // just do nothin, if gist is already ajaxed
+                            return;
+                        }
+
+                        ids_ajax.push(id);
+
+                        src = options.url_template.replace(/\{id\}/g, id).replace(/\{file\}/g, file);
+
+                        // (2) this will trigger our _write function
+                        $.getScript(src, function () {});
+                    }
+                });
+            },
+
+            /**
+             * Just reset the write function
+             */
+            reset_write: function () {
+                document.write = originwrite;
+
+                return this;
+            },
+        };
+
+    /**
+     * private special document.write function
+     *
+     * Filters the css file from github.com to add it to the head - once -
+     *
+     * It has a fallback to keep flexibility with other scripts as high as possible
+     * (create a ticket if it messes things up!)
+     *
+     * Keep in mind, that a call to this function happens after
+     * an ajax call by jQuery. One *cannot* know which gist-anchor
+     * to use. You can only read the id from the content.
+     */
+    function _write(content) {
+        var expression, // for regexp results
+            href, // from the url
+            id; // from the content
+
+        if (content.indexOf('rel="stylesheet"') !== -1) {
+            href = $(content).attr("href");
+
+            // check if stylesheet is already inserted
+            if ($.inArray(href, stylesheets) === -1) {
+                $("head").append(content);
+                stylesheets.push(href);
+            }
+        } else if (content.indexOf('id="gist') !== -1) {
+            // This is the newer gist URL style, ignoring the hostname for GitHub EE instances
+            expression = /https?:\/\/gist.*?\/.*\/(.*)#/.exec(content);
+            if (expression !== null) {
+                id = expression[1];
+            } else {
+                // This will catch older versions of GitHub EE
+                expression = /gist\/.+?\/([a-f0-9]+)\/raw/g.exec(content);
+                if (expression !== null) {
+                    id = expression[1];
+                }
+            }
+            if (id !== undefined) {
+                // test if id is already loaded
+                if ($.inArray(id, ids_dom) !== -1) {
+                    // just do nothin, if gist is already attached to the dom
+                    return;
+                }
+
+                ids_dom.push(id);
+
+                $(".gist_here[data-id=" + id + "]").append(content);
+            }
+        } else {
+            // this is a fallback for interoperability
+            originwrite.apply(document, arguments);
+        }
+    }
+
+    // method invocation - from jQuery.com
+    $.fn[pluginName] = function (method) {
+        if (methods[method]) {
+            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
+        } else if (typeof method === "object" || !method) {
+            return methods.init.apply(this, arguments);
+        } else {
+            $.error("Method " + method + " does not exist on jQuery.lazygist");
+        }
+    };
+
+    // expose version for your interest
+    $.fn[pluginName].version = version;
+})(jQuery, window, document);
+
+(function ($) {
+    "use strict";
+    var iframeGimmick = {
+        name: "iframe",
+        version: $.md.version,
+        once: function () {
+            $.md.linkGimmick(this, "iframe", create_iframe);
+        },
+    };
+    $.md.registerGimmick(iframeGimmick);
+
+    function create_iframe($links, opt, text) {
+        return $links.each(function (i, link) {
+            var $link = $(link);
+            var href = $link.attr("href");
+            var $iframe = $('<iframe class="col-md-12" style="border: 0px solid red; height: 650px;"></iframe>');
+            $iframe.attr("src", href);
+            $link.replaceWith($iframe);
+
+            if (opt.width) $iframe.css("width", opt.width);
+            if (opt.height) $iframe.css("height", opt.height);
+            else {
+                var updateSizeFn = function () {
+                    var offset = $iframe.offset();
+                    var winHeight = $(window).height();
+                    var newHeight = winHeight - offset.top - 5;
+                    $iframe.height(newHeight);
+                };
+
+                $iframe.load(function (done) {
+                    updateSizeFn();
+                });
+
+                $(window).resize(function () {
+                    updateSizeFn();
+                });
+            }
+        });
+    }
+})(jQuery);
+
+(function ($) {
+    var mathGimmick = {
+        name: "math",
+        once: function () {
+            $.md.linkGimmick(this, "math", load_mathjax);
+        },
+    };
+    $.md.registerGimmick(mathGimmick);
+
+    function load_mathjax($links, opt, ref) {
+        $links.remove();
+        var script = document.createElement("script");
+        script.type = "text/javascript";
+        script.src = $.md.prepareLink("cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML", {
+            forceSSL: true,
+        });
+        document.getElementsByTagName("head")[0].appendChild(script);
+    }
+})(jQuery);
+
+(function ($) {
+    var prismGimmick = {
+        name: "prism",
+        load: function () {
+            $.md.stage("gimmick").subscribe(function (done) {
+                prism_highlight();
+                done();
+            });
+        },
+    };
+    var supportedLangs = [
+        "abap",
+        "actionscript",
+        "apacheconf",
+        "apl",
+        "applescript",
+        "asciidoc",
+        "aspnet",
+        "autohotkey",
+        "autoit",
+        "bash",
+        "basic",
+        "batch",
+        "bison",
+        "brainfuck",
+        "c",
+        "clike",
+        "coffeescript",
+        "core",
+        "cpp",
+        "crystal",
+        "csharp",
+        "css",
+        "css",
+        "d",
+        "dart",
+        "diff",
+        "docker",
+        "eiffel",
+        "elixir",
+        "erlang",
+        "fortran",
+        "fsharp",
+        "gherkin",
+        "git",
+        "glsl",
+        "go",
+        "groovy",
+        "haml",
+        "handlebars",
+        "haskell",
+        "haxe",
+        "http",
+        "icon",
+        "inform7",
+        "ini",
+        "j",
+        "jade",
+        "java",
+        "javascript",
+        "json",
+        "jsx",
+        "julia",
+        "keyman",
+        "kotlin",
+        "latex",
+        "less",
+        "lolcode",
+        "lua",
+        "makefile",
+        "markdown",
+        "markup",
+        "matlab",
+        "mel",
+        "mizar",
+        "monkey",
+        "nasm",
+        "nginx",
+        "nim",
+        "nix",
+        "nsis",
+        "objectivec",
+        "ocaml",
+        "oz",
+        "parigp",
+        "parser",
+        "pascal",
+        "perl",
+        "php",
+        "powershell",
+        "processing",
+        "prolog",
+        "puppet",
+        "pure",
+        "python",
+        "q",
+        "qore",
+        "r",
+        "rest",
+        "rip",
+        "roboconf",
+        "ruby",
+        "rust",
+        "sas",
+        "sass",
+        "scala",
+        "scheme",
+        "scss",
+        "smalltalk",
+        "smarty",
+        "sql",
+        "stylus",
+        "svg",
+        "swift",
+        "tcl",
+        "textile",
+        "twig",
+        "typescript",
+        "verilog",
+        "vhdl",
+        "vim",
+        "wiki",
+        "xml",
+        "yaml",
+    ];
+    $.md.registerGimmick(prismGimmick);
+
+    function prism_highlight() {
+        // marked adds lang-ruby, lang-csharp etc to the <code> block like in GFM
+        var $codeblocks = $("pre code[class^=lang-]");
+        $codeblocks.each(function () {
+            var $this = $(this);
+            var classes = $this.attr("class");
+            var lang = classes.substring(5);
+            if (supportedLangs.indexOf(lang) < 0) {
+                return;
+            }
+            $this.removeClass(classes);
+            $this.addClass("language-" + lang);
+        });
+        Prism.highlightAll();
+    }
+})(jQuery);
+
+(function ($) {
+    "use strict";
+
+    var themes = [
+        { name: "bootstrap", url: "netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" },
+        { name: "cyborg", url: "netdna.bootstrapcdn.com/bootswatch/3.0.0/cyborg/bootstrap.min.css" },
+        { name: "slate", url: "netdna.bootstrapcdn.com/bootswatch/3.0.0/slate/bootstrap.min.css" },
+        { name: "darkly", url: "cdn.jsdelivr.net/npm/bootswatch@3.2.0/darkly/bootstrap.min.css" },
+    ];
+    var useChooser = false;
+    var themeChooserGimmick = {
+        name: "Themes",
+        version: $.md.version,
+        once: function () {
+            $.md.linkGimmick(this, "themechooser", themechooser, "skel_ready");
+            $.md.linkGimmick(this, "theme", apply_theme);
+        },
+    };
+    $.md.registerGimmick(themeChooserGimmick);
+
+    var log = $.md.getLogger();
+
+    var set_theme = function (theme) {
+        theme.inverse = theme.inverse || false;
+
+        if (theme.url === undefined) {
+            if (!theme.name) {
+                log.error("Theme name must be given!");
+                return;
+            }
+            var saved_theme = themes.filter(function (t) {
+                return t.name === theme.name;
+            })[0];
+            if (!saved_theme) {
+                log.error("Theme " + name + " not found, removing link");
+                return;
+            }
+            theme = $.extend(theme, saved_theme);
+        }
+
+        $('link[rel=stylesheet][href*="netdna.bootstrapcdn.com"]').remove();
+
+        // slim instance has no bootstrap hardcoded in
+        var has_default_bootstrap_css = $("style[id*=bootstrap]").length > 0;
+
+        if (theme.name !== "bootstrap" || !has_default_bootstrap_css) {
+            // in devel & fat version the style is inlined, remove it
+            $("style[id*=bootstrap]").remove();
+
+            $('<link rel="stylesheet" type="text/css">').attr("href", $.md.prepareLink(theme.url)).appendTo("head");
+        }
+
+        if (theme.inverse === true) {
+            $("#md-main-navbar").removeClass("navbar-default");
+            $("#md-main-navbar").addClass("navbar-inverse");
+        } else {
+            $("#md-main-navbar").addClass("navbar-default");
+            $("#md-main-navbar").removeClass("navbar-inverse");
+        }
+    };
+
+    var apply_theme = function ($links, opt, text) {
+        opt.name = opt.name || text;
+        $links.each(function (i, link) {
+            $.md.stage("postgimmick").subscribe(function (done) {
+                var $link = $(link);
+
+                // only set a theme if no theme from the chooser is selected,
+                // or if the chooser isn't enabled
+                if (window.localStorage.theme === undefined || !useChooser) {
+                    set_theme(opt);
+                }
+
+                done();
+            });
+        });
+        $links.remove();
+    };
+
+    var themechooser = function ($links, opt, text) {
+        useChooser = true;
+        $.md.stage("bootstrap").subscribe(function (done) {
+            restore_theme(opt);
+            done();
+        });
+
+        return $links.each(function (i, e) {
+            var $this = $(e);
+            var $chooser = $('<a href=""></a><ul></ul>');
+            $chooser.eq(0).text(text);
+
+            $.each(themes, function (i, theme) {
+                var $li = $("<li></li>");
+                $chooser.eq(1).append($li);
+                var $a = $("<a/>")
+                    .text(theme.name)
+                    .attr("href", "")
+                    .click(function (ev) {
+                        ev.preventDefault();
+                        window.localStorage.theme = theme.name;
+                        window.location.reload();
+                    })
+                    .appendTo($li);
+            });
+
+            $chooser.eq(1).append('<li class="divider" />');
+            var $li = $("<li/>");
+            var $a_use_default = $("<a>Use default</a>");
+            $a_use_default.click(function (ev) {
+                ev.preventDefault();
+                window.localStorage.removeItem("theme");
+                window.location.reload();
+            });
+            $li.append($a_use_default);
+            $chooser.eq(1).append($li);
+            $this.replaceWith($chooser);
+        });
+    };
+
+    var restore_theme = function (opt) {
+        if (window.localStorage.theme) {
+            opt = $.extend({ name: window.localStorage.theme }, opt);
+            set_theme(opt);
+        }
+    };
+})(jQuery);
+
+(function ($) {
+    //'use strict';
+    var youtubeGimmick = {
+        name: "youtube",
+        load: function () {
+            $.md.stage("gimmick").subscribe(function (done) {
+                youtubeLinkToIframe();
+                done();
+            });
+        },
+    };
+    $.md.registerGimmick(youtubeGimmick);
+
+    function youtubeLinkToIframe() {
+        var $youtube_links = $("a[href*=youtube\\.com]:empty, a[href*=youtu\\.be]:empty");
+
+        $youtube_links.each(function () {
+            var $this = $(this);
+            var href = $this.attr("href");
+            if (href !== undefined) {
+                // extract the v parameter from youtube
+                var exp = /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#\&\?]*).*/;
+                var m = href.match(exp);
+
+                if (m && m[1].length === 11) {
+                    // insert the iframe
+                    var short_handle = m[1];
+                    var frame = $('<iframe class="md-external" frameborder="0" allowfullscreen></iframe>');
+                    frame.attr("src", "http://youtube.com/embed/" + short_handle);
+                    // remove the a tag
+                    $this.replaceWith(frame);
+                }
+            }
+        });
+    }
+})(jQuery);
+
+(function ($) {
+    "use strict";
+
+    var scripturl = "//cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js";
+
+    var chartGimmick = {
+        name: "chart",
+        version: $.md.version,
+        once: function () {
+            $.md.linkGimmick(this, "chart", chart);
+
+            // load the chart js
+            $.md.registerScript(this, scripturl, {
+                license: "MIT",
+                loadstage: "skel_ready",
+                finishstage: "gimmick",
+            });
+        },
+    };
+    $.md.registerGimmick(chartGimmick);
+
+    var log = $.md.getLogger();
+
+    function chart($links, opt, text) {
+        return $links.each(function (i, link) {
+            // Get the options for this gimmick
+            //      labelColumn: This is a string the indicates the column that will be used to
+            //                   label the data points
+            //      dataColumns: This is a array of strings that indicate each column to be plotted
+            //      canvasId:    This is a ID for the given chart. Defaults to a random number
+            //                   between 1-1000.
+            //      chartOptions: This is an object that is passed to chartjs to configure its
+            //                    options.
+            //      chartType:   This string is the type of chart we want to render. Bar, Line,
+            //                   or Radar. Defaults to Line.
+            var default_options = {
+                chartType: "Line",
+                canvasId: "chartGimmick" + Math.floor(Math.random() * 1000 + 1),
+                chartOptions: {
+                    responsive: false,
+                },
+            };
+            var options = $.extend({}, default_options, opt);
+
+            var $link = $(link);
+
+            var table = $link.parents().find("table").last();
+            if (table.length === 0) {
+                log.error("Chart Gimmick: No tables found on the page.");
+                $link.remove();
+                return;
+            }
+
+            // Replace the Gimmick with the canvas that chartJS needs
+            var myHtml = $('<canvas id="' + options.canvasId + '"></canvas>');
+            myHtml.width(options.width || "450px");
+            myHtml.height(options.height || "250px");
+            $link.replaceWith(myHtml);
+
+            // This is the object that is given to the chart frame work for rendering. It will be
+            // built up by processing the html table that is found on the table.
+            var chartConfig = {
+                datasets: [],
+                labels: [],
+            };
+
+            var chartAvailableToRender = true;
+
+            // These variables hold the indices of the columns in the table we care about. They will
+            // be populated as we process the table based on the options that are given in the
+            // gimmick
+            var labelColumnIndex = -1;
+            var dataColumnIndices = [];
+
+            // Get the index of the columns that we care about for charting
+            table.find("th").each(function (index) {
+                // This is the column that labels each data point
+                if (this.textContent === options.labelColumn) {
+                    labelColumnIndex = index;
+                }
+
+                // Check if this is a data column
+                else {
+                    for (var i = 0; i < options.dataColumns.length; i++) {
+                        if (this.textContent === options.dataColumns[i]) {
+                            dataColumnIndices.push(index);
+                        }
+                    }
+                }
+            });
+
+            // Get the data
+            table.find("tr").each(function (rowIndex) {
+                $(this)
+                    .find("td")
+                    .each(function (colIndex) {
+                        if (colIndex === labelColumnIndex) {
+                            chartConfig.labels.push(this.textContent);
+                        } else {
+                            for (var i = 0; i < dataColumnIndices.length; i++) {
+                                if (colIndex === dataColumnIndices[i]) {
+                                    if (chartConfig.datasets[i] === undefined) {
+                                        chartConfig.datasets[i] = {};
+                                        chartConfig.datasets[i].data = [];
+                                    }
+
+                                    chartConfig.datasets[i].data.push(this.textContent);
+                                }
+                            }
+                        }
+                    });
+            });
+
+            // No Chart data found
+            if (chartConfig.datasets[i] === undefined) {
+                chartAvailableToRender = false;
+                log.error(
+                    "Chart Gimmick: No data was found for the chart. Make sure that there " +
+                        "is a tables on the page. Check that your " +
+                        "column headers match the chart configuration."
+                );
+            }
+
+            if (chartAvailableToRender) {
+                var canvas = document.getElementById(options.canvasId);
+                var ctx = canvas.getContext("2d");
+                $.md.stage("postgimmick").subscribe(function (done) {
+                    setTimeout(function () {
+                        new Chart(ctx)[options.chartType](chartConfig, options.chartOptions);
+                    });
+                    done();
+                });
+            }
+        });
+    }
+})(jQuery);
+
+(function ($) {
+    "use strict";
+    function yuml($link, opt, text) {
+        var default_options = {
+            type: "class" /* { class, activity, usecase } */,
+            style: "plain" /* { plain, scruffy } */,
+            direction: "LR" /* LR, TB, RL */,
+            scale: "100",
+        };
+        var options = $.extend({}, default_options, opt);
+
+        return $link.each(function (i, e) {
+            var $this = $(e);
+            var url = "http://yuml.me/diagram/";
+            var data = $this.attr("href");
+            var title = $this.attr("title");
+
+            title = title ? title : "";
+
+            /* `FOOBAR´ => (FOOBAR) */
+            data = data.replace(new RegExp("`", "g"), "(").replace(new RegExp("´", "g"), ")");
+
+            url +=
+                options.style +
+                ";dir:" +
+                options.direction +
+                ";scale:" +
+                options.scale +
+                "/" +
+                options.type +
+                "/" +
+                data;
+
+            var $img = $('<img src="' + url + '" title="' + title + '" alt="' + title + '">');
+
+            $this.replaceWith($img);
+        });
+    }
+    var yumlGimmick = {
+        name: "yuml",
+        version: $.md.version,
+        once: function () {
+            $.md.linkGimmick(this, "yuml", yuml);
+            $.md.registerScript(this, "", {
+                license: "LGPL",
+                loadstage: "postgimmick",
+                finishstage: "all_ready",
+            });
+        },
+    };
+    $.md.registerGimmick(yumlGimmick);
+})(jQuery);

+ 7 - 0
Civ14-Wiki/README.md

@@ -0,0 +1,7 @@
+# MDwiki
+
+100% static single file CMS/Wiki done purely with client-side Javascript and HTML5.
+
+## See <http://www.mdwiki.info> for more info and documentation
+
+Add articles as markdown files in the this folder or any of its subfolders.

+ 3 - 0
Civ14-Wiki/config.json

@@ -0,0 +1,3 @@
+{
+    "useSideNav": "true"
+}

File diff suppressed because it is too large
+ 8 - 0
Civ14-Wiki/extlib/css/bootstrap-3.0.0.min.css


File diff suppressed because it is too large
+ 51 - 0
Civ14-Wiki/extlib/css/colorbox.css


File diff suppressed because it is too large
+ 6 - 0
Civ14-Wiki/extlib/css/prism.1.4.1.default.min.css


File diff suppressed because it is too large
+ 5 - 0
Civ14-Wiki/extlib/js/bootstrap-3.0.0.min.js


File diff suppressed because it is too large
+ 1 - 0
Civ14-Wiki/extlib/js/jquery-1.8.3.min.js


+ 942 - 0
Civ14-Wiki/extlib/js/jquery.colorbox.js

@@ -0,0 +1,942 @@
+// ColorBox v1.3.20.1 - jQuery lightbox plugin
+// (c) 2011 Jack Moore - jacklmoore.com
+// License: http://www.opensource.org/licenses/mit-license.php
+(function ($, document, window) {
+	var
+	// Default settings object.
+	// See http://jacklmoore.com/colorbox for details.
+	defaults = {
+		transition: "elastic",
+		speed: 300,
+		width: false,
+		initialWidth: "600",
+		innerWidth: false,
+		maxWidth: false,
+		height: false,
+		initialHeight: "450",
+		innerHeight: false,
+		maxHeight: false,
+		scalePhotos: true,
+		scrolling: true,
+		inline: false,
+		html: false,
+		iframe: false,
+		fastIframe: true,
+		photo: false,
+		href: false,
+		title: false,
+		rel: false,
+		opacity: 0.9,
+		preloading: true,
+
+		current: "image {current} of {total}",
+		previous: "previous",
+		next: "next",
+		close: "close",
+		xhrError: "This content failed to load.",
+		imgError: "This image failed to load.",
+
+		open: false,
+		returnFocus: true,
+		reposition: true,
+		loop: true,
+		slideshow: false,
+		slideshowAuto: true,
+		slideshowSpeed: 2500,
+		slideshowStart: "start slideshow",
+		slideshowStop: "stop slideshow",
+		onOpen: false,
+		onLoad: false,
+		onComplete: false,
+		onCleanup: false,
+		onClosed: false,
+		overlayClose: true,
+		escKey: true,
+		arrowKey: true,
+		top: false,
+		bottom: false,
+		left: false,
+		right: false,
+		fixed: false,
+		data: undefined
+	},
+	
+	// Abstracting the HTML and event identifiers for easy rebranding
+	colorbox = 'colorbox',
+	prefix = 'cbox',
+	boxElement = prefix + 'Element',
+	
+	// Events
+	event_open = prefix + '_open',
+	event_load = prefix + '_load',
+	event_complete = prefix + '_complete',
+	event_cleanup = prefix + '_cleanup',
+	event_closed = prefix + '_closed',
+	event_purge = prefix + '_purge',
+	
+	// Special Handling for IE
+	isIE = !$.support.opacity && !$.support.style, // IE7 & IE8
+	isIE6 = isIE && !window.XMLHttpRequest, // IE6
+	event_ie6 = prefix + '_IE6',
+
+	// Cached jQuery Object Variables
+	$overlay,
+	$box,
+	$wrap,
+	$content,
+	$topBorder,
+	$leftBorder,
+	$rightBorder,
+	$bottomBorder,
+	$related,
+	$window,
+	$loaded,
+	$loadingBay,
+	$loadingOverlay,
+	$title,
+	$current,
+	$slideshow,
+	$next,
+	$prev,
+	$close,
+	$groupControls,
+	
+	// Variables for cached values or use across multiple functions
+	settings,
+	interfaceHeight,
+	interfaceWidth,
+	loadedHeight,
+	loadedWidth,
+	element,
+	index,
+	photo,
+	open,
+	active,
+	closing,
+	loadingTimer,
+	publicMethod,
+	div = "div",
+	init;
+
+	// ****************
+	// HELPER FUNCTIONS
+	// ****************
+	
+	// Convience function for creating new jQuery objects
+	function $tag(tag, id, css) {
+		var element = document.createElement(tag);
+
+		if (id) {
+			element.id = prefix + id;
+		}
+
+		if (css) {
+			element.style.cssText = css;
+		}
+
+		return $(element);
+	}
+
+	// Determine the next and previous members in a group.
+	function getIndex(increment) {
+		var
+		max = $related.length,
+		newIndex = (index + increment) % max;
+		
+		return (newIndex < 0) ? max + newIndex : newIndex;
+	}
+
+	// Convert '%' and 'px' values to integers
+	function setSize(size, dimension) {
+		return Math.round((/%/.test(size) ? ((dimension === 'x' ? winWidth() : winHeight()) / 100) : 1) * parseInt(size, 10));
+	}
+	
+	// Checks an href to see if it is a photo.
+	// There is a force photo option (photo: true) for hrefs that cannot be matched by this regex.
+	function isImage(url) {
+		return settings.photo || /\.(gif|png|jp(e|g|eg)|bmp|ico)((#|\?).*)?$/i.test(url);
+	}
+	
+	function winWidth() {
+		// $(window).width() is incorrect for some mobile browsers, but
+		// window.innerWidth is unsupported in IE8 and lower.
+		return window.innerWidth || $window.width();
+	}
+
+	function winHeight() {
+		return window.innerHeight || $window.height();
+	}
+
+	// Assigns function results to their respective properties
+	function makeSettings() {
+		var i,
+			data = $.data(element, colorbox);
+		
+		if (data == null) {
+			settings = $.extend({}, defaults);
+			if (console && console.log) {
+				console.log('Error: cboxElement missing settings object');
+			}
+		} else {
+			settings = $.extend({}, data);
+		}
+		
+		for (i in settings) {
+			if ($.isFunction(settings[i]) && i.slice(0, 2) !== 'on') { // checks to make sure the function isn't one of the callbacks, they will be handled at the appropriate time.
+				settings[i] = settings[i].call(element);
+			}
+		}
+		
+		settings.rel = settings.rel || element.rel || $(element).data('rel') || 'nofollow';
+		settings.href = settings.href || $(element).attr('href');
+		settings.title = settings.title || element.title;
+		
+		if (typeof settings.href === "string") {
+			settings.href = $.trim(settings.href);
+		}
+	}
+
+	function trigger(event, callback) {
+		$.event.trigger(event);
+		if (callback) {
+			callback.call(element);
+		}
+	}
+
+	// Slideshow functionality
+	function slideshow() {
+		var
+		timeOut,
+		className = prefix + "Slideshow_",
+		click = "click." + prefix,
+		start,
+		stop,
+		clear;
+		
+		if (settings.slideshow && $related[1]) {
+			start = function () {
+				$slideshow
+					.text(settings.slideshowStop)
+					.unbind(click)
+					.bind(event_complete, function () {
+						if (settings.loop || $related[index + 1]) {
+							timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed);
+						}
+					})
+					.bind(event_load, function () {
+						clearTimeout(timeOut);
+					})
+					.one(click + ' ' + event_cleanup, stop);
+				$box.removeClass(className + "off").addClass(className + "on");
+				timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed);
+			};
+			
+			stop = function () {
+				clearTimeout(timeOut);
+				$slideshow
+					.text(settings.slideshowStart)
+					.unbind([event_complete, event_load, event_cleanup, click].join(' '))
+					.one(click, function () {
+						publicMethod.next();
+						start();
+					});
+				$box.removeClass(className + "on").addClass(className + "off");
+			};
+			
+			if (settings.slideshowAuto) {
+				start();
+			} else {
+				stop();
+			}
+		} else {
+			$box.removeClass(className + "off " + className + "on");
+		}
+	}
+
+	function launch(target) {
+		if (!closing) {
+			
+			element = target;
+			
+			makeSettings();
+			
+			$related = $(element);
+			
+			index = 0;
+			
+			if (settings.rel !== 'nofollow') {
+				$related = $('.' + boxElement).filter(function () {
+					var data = $.data(this, colorbox),
+						relRelated;
+
+					if (data) {
+						relRelated =  $(this).data('rel') || data.rel || this.rel;
+					}
+					
+					return (relRelated === settings.rel);
+				});
+				index = $related.index(element);
+				
+				// Check direct calls to ColorBox.
+				if (index === -1) {
+					$related = $related.add(element);
+					index = $related.length - 1;
+				}
+			}
+			
+			if (!open) {
+				open = active = true; // Prevents the page-change action from queuing up if the visitor holds down the left or right keys.
+				
+				$box.show();
+				
+				if (settings.returnFocus) {
+					$(element).blur().one(event_closed, function () {
+						$(this).focus();
+					});
+				}
+				
+				// +settings.opacity avoids a problem in IE when using non-zero-prefixed-string-values, like '.5'
+				$overlay.css({"opacity": +settings.opacity, "cursor": settings.overlayClose ? "pointer" : "auto"}).show();
+				
+				// Opens inital empty ColorBox prior to content being loaded.
+				settings.w = setSize(settings.initialWidth, 'x');
+				settings.h = setSize(settings.initialHeight, 'y');
+				publicMethod.position();
+				
+				if (isIE6) {
+					$window.bind('resize.' + event_ie6 + ' scroll.' + event_ie6, function () {
+						$overlay.css({width: winWidth(), height: winHeight(), top: $window.scrollTop(), left: $window.scrollLeft()});
+					}).trigger('resize.' + event_ie6);
+				}
+				
+				trigger(event_open, settings.onOpen);
+				
+				$groupControls.add($title).hide();
+				
+				$close.html(settings.close).show();
+			}
+			
+			publicMethod.load(true);
+		}
+	}
+
+	// ColorBox's markup needs to be added to the DOM prior to being called
+	// so that the browser will go ahead and load the CSS background images.
+	function appendHTML() {
+		if (!$box && document.body) {
+			init = false;
+
+			$window = $(window);
+			$box = $tag(div).attr({id: colorbox, 'class': isIE ? prefix + (isIE6 ? 'IE6' : 'IE') : ''}).hide();
+			$overlay = $tag(div, "Overlay", isIE6 ? 'position:absolute' : '').hide();
+			$loadingOverlay = $tag(div, "LoadingOverlay").add($tag(div, "LoadingGraphic"));
+			$wrap = $tag(div, "Wrapper");
+			$content = $tag(div, "Content").append(
+				$loaded = $tag(div, "LoadedContent", 'width:0; height:0; overflow:hidden'),
+				$title = $tag(div, "Title"),
+				$current = $tag(div, "Current"),
+				$next = $tag(div, "Next"),
+				$prev = $tag(div, "Previous"),
+				$slideshow = $tag(div, "Slideshow").bind(event_open, slideshow),
+				$close = $tag(div, "Close")
+			);
+			
+			$wrap.append( // The 3x3 Grid that makes up ColorBox
+				$tag(div).append(
+					$tag(div, "TopLeft"),
+					$topBorder = $tag(div, "TopCenter"),
+					$tag(div, "TopRight")
+				),
+				$tag(div, false, 'clear:left').append(
+					$leftBorder = $tag(div, "MiddleLeft"),
+					$content,
+					$rightBorder = $tag(div, "MiddleRight")
+				),
+				$tag(div, false, 'clear:left').append(
+					$tag(div, "BottomLeft"),
+					$bottomBorder = $tag(div, "BottomCenter"),
+					$tag(div, "BottomRight")
+				)
+			).find('div div').css({'float': 'left'});
+			
+			$loadingBay = $tag(div, false, 'position:absolute; width:9999px; visibility:hidden; display:none');
+			
+			$groupControls = $next.add($prev).add($current).add($slideshow);
+
+			$(document.body).append($overlay, $box.append($wrap, $loadingBay));
+		}
+	}
+
+	// Add ColorBox's event bindings
+	function addBindings() {
+		if ($box) {
+			if (!init) {
+				init = true;
+
+				// Cache values needed for size calculations
+				interfaceHeight = $topBorder.height() + $bottomBorder.height() + $content.outerHeight(true) - $content.height();//Subtraction needed for IE6
+				interfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.outerWidth(true) - $content.width();
+				loadedHeight = $loaded.outerHeight(true);
+				loadedWidth = $loaded.outerWidth(true);
+				
+				// Setting padding to remove the need to do size conversions during the animation step.
+				$box.css({"padding-bottom": interfaceHeight, "padding-right": interfaceWidth});
+
+				// Anonymous functions here keep the public method from being cached, thereby allowing them to be redefined on the fly.
+				$next.click(function () {
+					publicMethod.next();
+				});
+				$prev.click(function () {
+					publicMethod.prev();
+				});
+				$close.click(function () {
+					publicMethod.close();
+				});
+				$overlay.click(function () {
+					if (settings.overlayClose) {
+						publicMethod.close();
+					}
+				});
+				
+				// Key Bindings
+				$(document).bind('keydown.' + prefix, function (e) {
+					var key = e.keyCode;
+					if (open && settings.escKey && key === 27) {
+						e.preventDefault();
+						publicMethod.close();
+					}
+					if (open && settings.arrowKey && $related[1]) {
+						if (key === 37) {
+							e.preventDefault();
+							$prev.click();
+						} else if (key === 39) {
+							e.preventDefault();
+							$next.click();
+						}
+					}
+				});
+
+				$('.' + boxElement, document).live('click', function (e) {
+					// ignore non-left-mouse-clicks and clicks modified with ctrl / command, shift, or alt.
+					// See: http://jacklmoore.com/notes/click-events/
+					if (!(e.which > 1 || e.shiftKey || e.altKey || e.metaKey)) {
+						e.preventDefault();
+						launch(this);
+					}
+				});
+			}
+			return true;
+		}
+		return false;
+	}
+
+	// Don't do anything if ColorBox already exists.
+	if ($.colorbox) {
+		return;
+	}
+
+	// Append the HTML when the DOM loads
+	$(appendHTML);
+
+
+	// ****************
+	// PUBLIC FUNCTIONS
+	// Usage format: $.fn.colorbox.close();
+	// Usage from within an iframe: parent.$.fn.colorbox.close();
+	// ****************
+	
+	publicMethod = $.fn[colorbox] = $[colorbox] = function (options, callback) {
+		var $this = this;
+		
+		options = options || {};
+		
+		appendHTML();
+
+		if (addBindings()) {
+			if (!$this[0]) {
+				if ($this.selector) { // if a selector was given and it didn't match any elements, go ahead and exit.
+					return $this;
+				}
+				// if no selector was given (ie. $.colorbox()), create a temporary element to work with
+				$this = $('<a/>');
+				options.open = true; // assume an immediate open
+			}
+			
+			if (callback) {
+				options.onComplete = callback;
+			}
+			
+			$this.each(function () {
+				$.data(this, colorbox, $.extend({}, $.data(this, colorbox) || defaults, options));
+			}).addClass(boxElement);
+			
+			if (($.isFunction(options.open) && options.open.call($this)) || options.open) {
+				launch($this[0]);
+			}
+		}
+		
+		return $this;
+	};
+
+	publicMethod.position = function (speed, loadedCallback) {
+		var
+		css,
+		top = 0,
+		left = 0,
+		offset = $box.offset(),
+		scrollTop,
+		scrollLeft;
+		
+		$window.unbind('resize.' + prefix);
+
+		// remove the modal so that it doesn't influence the document width/height
+		$box.css({top: -9e4, left: -9e4});
+
+		scrollTop = $window.scrollTop();
+		scrollLeft = $window.scrollLeft();
+
+		if (settings.fixed && !isIE6) {
+			offset.top -= scrollTop;
+			offset.left -= scrollLeft;
+			$box.css({position: 'fixed'});
+		} else {
+			top = scrollTop;
+			left = scrollLeft;
+			$box.css({position: 'absolute'});
+		}
+
+		// keeps the top and left positions within the browser's viewport.
+		if (settings.right !== false) {
+			left += Math.max(winWidth() - settings.w - loadedWidth - interfaceWidth - setSize(settings.right, 'x'), 0);
+		} else if (settings.left !== false) {
+			left += setSize(settings.left, 'x');
+		} else {
+			left += Math.round(Math.max(winWidth() - settings.w - loadedWidth - interfaceWidth, 0) / 2);
+		}
+		
+		if (settings.bottom !== false) {
+			top += Math.max(winHeight() - settings.h - loadedHeight - interfaceHeight - setSize(settings.bottom, 'y'), 0);
+		} else if (settings.top !== false) {
+			top += setSize(settings.top, 'y');
+		} else {
+			top += Math.round(Math.max(winHeight() - settings.h - loadedHeight - interfaceHeight, 0) / 2);
+		}
+
+		$box.css({top: offset.top, left: offset.left});
+
+		// setting the speed to 0 to reduce the delay between same-sized content.
+		speed = ($box.width() === settings.w + loadedWidth && $box.height() === settings.h + loadedHeight) ? 0 : speed || 0;
+		
+		// this gives the wrapper plenty of breathing room so it's floated contents can move around smoothly,
+		// but it has to be shrank down around the size of div#colorbox when it's done.  If not,
+		// it can invoke an obscure IE bug when using iframes.
+		$wrap[0].style.width = $wrap[0].style.height = "9999px";
+		
+		function modalDimensions(that) {
+			$topBorder[0].style.width = $bottomBorder[0].style.width = $content[0].style.width = that.style.width;
+			$content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.height = that.style.height;
+		}
+
+		css = {width: settings.w + loadedWidth, height: settings.h + loadedHeight, top: top, left: left};
+		if(speed===0){ // temporary workaround to side-step jQuery-UI 1.8 bug (http://bugs.jquery.com/ticket/12273)
+			$box.css(css);
+		}
+		$box.dequeue().animate(css, {
+			duration: speed,
+			complete: function () {
+				modalDimensions(this);
+				
+				active = false;
+				
+				// shrink the wrapper down to exactly the size of colorbox to avoid a bug in IE's iframe implementation.
+				$wrap[0].style.width = (settings.w + loadedWidth + interfaceWidth) + "px";
+				$wrap[0].style.height = (settings.h + loadedHeight + interfaceHeight) + "px";
+				
+				if (settings.reposition) {
+					setTimeout(function () {  // small delay before binding onresize due to an IE8 bug.
+						$window.bind('resize.' + prefix, publicMethod.position);
+					}, 1);
+				}
+
+				if (loadedCallback) {
+					loadedCallback();
+				}
+			},
+			step: function () {
+				modalDimensions(this);
+			}
+		});
+	};
+
+	publicMethod.resize = function (options) {
+		if (open) {
+			options = options || {};
+			
+			if (options.width) {
+				settings.w = setSize(options.width, 'x') - loadedWidth - interfaceWidth;
+			}
+			if (options.innerWidth) {
+				settings.w = setSize(options.innerWidth, 'x');
+			}
+			$loaded.css({width: settings.w});
+			
+			if (options.height) {
+				settings.h = setSize(options.height, 'y') - loadedHeight - interfaceHeight;
+			}
+			if (options.innerHeight) {
+				settings.h = setSize(options.innerHeight, 'y');
+			}
+			if (!options.innerHeight && !options.height) {
+				$loaded.css({height: "auto"});
+				settings.h = $loaded.height();
+			}
+			$loaded.css({height: settings.h});
+			
+			publicMethod.position(settings.transition === "none" ? 0 : settings.speed);
+		}
+	};
+
+	publicMethod.prep = function (object) {
+		if (!open) {
+			return;
+		}
+		
+		var callback, speed = settings.transition === "none" ? 0 : settings.speed;
+		
+		$loaded.remove();
+		$loaded = $tag(div, 'LoadedContent').append(object);
+		
+		function getWidth() {
+			settings.w = settings.w || $loaded.width();
+			settings.w = settings.mw && settings.mw < settings.w ? settings.mw : settings.w;
+			return settings.w;
+		}
+		function getHeight() {
+			settings.h = settings.h || $loaded.height();
+			settings.h = settings.mh && settings.mh < settings.h ? settings.mh : settings.h;
+			return settings.h;
+		}
+		
+		$loaded.hide()
+		.appendTo($loadingBay.show())// content has to be appended to the DOM for accurate size calculations.
+		.css({width: getWidth(), overflow: settings.scrolling ? 'auto' : 'hidden'})
+		.css({height: getHeight()})// sets the height independently from the width in case the new width influences the value of height.
+		.prependTo($content);
+		
+		$loadingBay.hide();
+		
+		// floating the IMG removes the bottom line-height and fixed a problem where IE miscalculates the width of the parent element as 100% of the document width.
+		//$(photo).css({'float': 'none', marginLeft: 'auto', marginRight: 'auto'});
+		
+		$(photo).css({'float': 'none'});
+		
+		// Hides SELECT elements in IE6 because they would otherwise sit on top of the overlay.
+		if (isIE6) {
+			$('select').not($box.find('select')).filter(function () {
+				return this.style.visibility !== 'hidden';
+			}).css({'visibility': 'hidden'}).one(event_cleanup, function () {
+				this.style.visibility = 'inherit';
+			});
+		}
+		
+		callback = function () {
+			var preload,
+				i,
+				total = $related.length,
+				iframe,
+				frameBorder = 'frameBorder',
+				allowTransparency = 'allowTransparency',
+				complete,
+				src,
+				img,
+				data;
+			
+			if (!open) {
+				return;
+			}
+			
+			function removeFilter() {
+				if (isIE) {
+					$box[0].style.removeAttribute('filter');
+				}
+			}
+			
+			complete = function () {
+				clearTimeout(loadingTimer);
+				// Detaching forces Andriod stock browser to redraw the area underneat the loading overlay.  Hiding alone isn't enough.
+				$loadingOverlay.detach().hide();
+				trigger(event_complete, settings.onComplete);
+			};
+			
+			if (isIE) {
+				//This fadeIn helps the bicubic resampling to kick-in.
+				if (photo) {
+					$loaded.fadeIn(100);
+				}
+			}
+			
+			$title.html(settings.title).add($loaded).show();
+			
+			if (total > 1) { // handle grouping
+				if (typeof settings.current === "string") {
+					$current.html(settings.current.replace('{current}', index + 1).replace('{total}', total)).show();
+				}
+				
+				$next[(settings.loop || index < total - 1) ? "show" : "hide"]().html(settings.next);
+				$prev[(settings.loop || index) ? "show" : "hide"]().html(settings.previous);
+				
+				if (settings.slideshow) {
+					$slideshow.show();
+				}
+				
+				// Preloads images within a rel group
+				if (settings.preloading) {
+					preload = [
+						getIndex(-1),
+						getIndex(1)
+					];
+					while (i = $related[preload.pop()]) {
+						data = $.data(i, colorbox);
+						
+						if (data && data.href) {
+							src = data.href;
+							if ($.isFunction(src)) {
+								src = src.call(i);
+							}
+						} else {
+							src = i.href;
+						}
+
+						if (isImage(src)) {
+							img = new Image();
+							img.src = src;
+						}
+					}
+				}
+			} else {
+				$groupControls.hide();
+			}
+			
+			if (settings.iframe) {
+				iframe = $tag('iframe')[0];
+				
+				if (frameBorder in iframe) {
+					iframe[frameBorder] = 0;
+				}
+				if (allowTransparency in iframe) {
+					iframe[allowTransparency] = "true";
+				}
+				// give the iframe a unique name to prevent caching
+				iframe.name = prefix + (+new Date());
+				if (settings.fastIframe) {
+					complete();
+				} else {
+					$(iframe).one('load', complete);
+				}
+				iframe.src = settings.href;
+				if (!settings.scrolling) {
+					iframe.scrolling = "no";
+				}
+				$(iframe).addClass(prefix + 'Iframe').appendTo($loaded).one(event_purge, function () {
+					iframe.src = "//about:blank";
+				});
+			} else {
+				complete();
+			}
+			
+			if (settings.transition === 'fade') {
+				$box.fadeTo(speed, 1, removeFilter);
+			} else {
+				removeFilter();
+			}
+		};
+		
+		if (settings.transition === 'fade') {
+			$box.fadeTo(speed, 0, function () {
+				publicMethod.position(0, callback);
+			});
+		} else {
+			publicMethod.position(speed, callback);
+		}
+	};
+
+	publicMethod.load = function (launched) {
+		var href, setResize, prep = publicMethod.prep;
+		
+		active = true;
+		
+		photo = false;
+		
+		element = $related[index];
+		
+		if (!launched) {
+			makeSettings();
+		}
+		
+		trigger(event_purge);
+		
+		trigger(event_load, settings.onLoad);
+		
+		settings.h = settings.height ?
+				setSize(settings.height, 'y') - loadedHeight - interfaceHeight :
+				settings.innerHeight && setSize(settings.innerHeight, 'y');
+		
+		settings.w = settings.width ?
+				setSize(settings.width, 'x') - loadedWidth - interfaceWidth :
+				settings.innerWidth && setSize(settings.innerWidth, 'x');
+		
+		// Sets the minimum dimensions for use in image scaling
+		settings.mw = settings.w;
+		settings.mh = settings.h;
+		
+		// Re-evaluate the minimum width and height based on maxWidth and maxHeight values.
+		// If the width or height exceed the maxWidth or maxHeight, use the maximum values instead.
+		if (settings.maxWidth) {
+			settings.mw = setSize(settings.maxWidth, 'x') - loadedWidth - interfaceWidth;
+			settings.mw = settings.w && settings.w < settings.mw ? settings.w : settings.mw;
+		}
+		if (settings.maxHeight) {
+			settings.mh = setSize(settings.maxHeight, 'y') - loadedHeight - interfaceHeight;
+			settings.mh = settings.h && settings.h < settings.mh ? settings.h : settings.mh;
+		}
+		
+		href = settings.href;
+		
+		loadingTimer = setTimeout(function () {
+			$loadingOverlay.show().appendTo($content);
+		}, 100);
+		
+		if (settings.inline) {
+			// Inserts an empty placeholder where inline content is being pulled from.
+			// An event is bound to put inline content back when ColorBox closes or loads new content.
+			$tag(div).hide().insertBefore($(href)[0]).one(event_purge, function () {
+				$(this).replaceWith($loaded.children());
+			});
+			prep($(href));
+		} else if (settings.iframe) {
+			// IFrame element won't be added to the DOM until it is ready to be displayed,
+			// to avoid problems with DOM-ready JS that might be trying to run in that iframe.
+			prep(" ");
+		} else if (settings.html) {
+			prep(settings.html);
+		} else if (isImage(href)) {
+			$(photo = new Image())
+			.addClass(prefix + 'Photo')
+			.error(function () {
+				settings.title = false;
+				prep($tag(div, 'Error').html(settings.imgError));
+			})
+			.load(function () {
+				var percent;
+				photo.onload = null; //stops animated gifs from firing the onload repeatedly.
+				
+				if (settings.scalePhotos) {
+					setResize = function () {
+						photo.height -= photo.height * percent;
+						photo.width -= photo.width * percent;
+					};
+					if (settings.mw && photo.width > settings.mw) {
+						percent = (photo.width - settings.mw) / photo.width;
+						setResize();
+					}
+					if (settings.mh && photo.height > settings.mh) {
+						percent = (photo.height - settings.mh) / photo.height;
+						setResize();
+					}
+				}
+				
+				if (settings.h) {
+					photo.style.marginTop = Math.max(settings.h - photo.height, 0) / 2 + 'px';
+				}
+				
+				if ($related[1] && (settings.loop || $related[index + 1])) {
+					photo.style.cursor = 'pointer';
+					photo.onclick = function () {
+						publicMethod.next();
+					};
+				}
+				
+				if (isIE) {
+					photo.style.msInterpolationMode = 'bicubic';
+				}
+				
+				setTimeout(function () { // A pause because Chrome will sometimes report a 0 by 0 size otherwise.
+					prep(photo);
+				}, 1);
+			});
+			
+			setTimeout(function () { // A pause because Opera 10.6+ will sometimes not run the onload function otherwise.
+				photo.src = href;
+			}, 1);
+		} else if (href) {
+			$loadingBay.load(href, settings.data, function (data, status, xhr) {
+				prep(status === 'error' ? $tag(div, 'Error').html(settings.xhrError) : $(this).contents());
+			});
+		}
+	};
+		
+	// Navigates to the next page/image in a set.
+	publicMethod.next = function () {
+		if (!active && $related[1] && (settings.loop || $related[index + 1])) {
+			index = getIndex(1);
+			publicMethod.load();
+		}
+	};
+	
+	publicMethod.prev = function () {
+		if (!active && $related[1] && (settings.loop || index)) {
+			index = getIndex(-1);
+			publicMethod.load();
+		}
+	};
+
+	// Note: to use this within an iframe use the following format: parent.$.fn.colorbox.close();
+	publicMethod.close = function () {
+		if (open && !closing) {
+			
+			closing = true;
+			
+			open = false;
+			
+			trigger(event_cleanup, settings.onCleanup);
+			
+			$window.unbind('.' + prefix + ' .' + event_ie6);
+			
+			$overlay.fadeTo(200, 0);
+			
+			$box.stop().fadeTo(300, 0, function () {
+			
+				$box.add($overlay).css({'opacity': 1, cursor: 'auto'}).hide();
+				
+				trigger(event_purge);
+				
+				$loaded.remove();
+				
+				setTimeout(function () {
+					closing = false;
+					trigger(event_closed, settings.onClosed);
+				}, 1);
+			});
+		}
+	};
+
+	// Removes changes ColorBox made to the document, but does not remove the plugin
+	// from jQuery.
+	publicMethod.remove = function () {
+		$([]).add($box).add($overlay).remove();
+		$box = null;
+		$('.' + boxElement)
+			.removeData(colorbox)
+			.removeClass(boxElement)
+			.die();
+	};
+
+	// A method for fetching the current element ColorBox is referencing.
+	// returns a jQuery object.
+	publicMethod.element = function () {
+		return $(element);
+	};
+
+	publicMethod.settings = defaults;
+
+}(jQuery, document, this));

File diff suppressed because it is too large
+ 0 - 0
Civ14-Wiki/extlib/js/jquery.colorbox.min.js


File diff suppressed because it is too large
+ 1 - 0
Civ14-Wiki/extlib/js/prism.1.4.1.min.js


BIN
Civ14-Wiki/favicon.ico


+ 3 - 0
Civ14-Wiki/gamemodes/aotd.md

@@ -0,0 +1,3 @@
+# The Art of the Deal (AOTD)
+
+**Warning: This gamemode has not been implemented yet! You can check the Civ13 guide [here](https://civ13.github.io/civ13-wiki/The_Art_of_the_Deal).**

+ 125 - 0
Civ14-Wiki/gamemodes/nomads.md

@@ -0,0 +1,125 @@
+# Nomads
+
+**Tip: If this is your first time playing, you should probably check the [starter guide](starter_guide.md) as well.**
+
+## What is the Nomads mode?
+
+In Nomads, everyone spawns without any predetermined roles or factions. The map is a complete wilderness, ready to be explored and settled. There are no prebuilt structures, except for occasional ancient ruins.
+
+You can stay factionless (a nomad), create your own faction or join an existing one. There is no predetermined goal.
+
+A map may have one or more ethnicities, each speaking its own language initially incomprehensible to a speaker of a different language. On certain maps you can choose who you spawn as, while on other maps it is random.
+
+What will each civilization desire? Military power? World domination? Scholars with advanced technology? Mass resource output and production? Commerce and trade? Raiding? It’s up to you or your leaders to decide!
+
+## Becoming Civilized
+
+Perhaps you have noticed that your ability to craft things is a bit limited in comparison to other people, and you would like to make more. ~~Only members of a faction can research new technologies and accumulate research points.~~ (Not implemented yet in Civ14).
+
+Perhaps you are finding surviving alone difficult. Perhaps you enjoy the company and roleplay opportunity that comes with engaging with other players. If those apply to you, then you should consider joining or starting a faction.
+
+The benefits of joining or assembling a faction:
+
+-   ~~Gain access to that factions research levels, which equates to more things you can craft~~ (Not implemented yet in Civ14).
+
+-   More opportunity to roleplay in a manner you want to. From becoming a towns blacksmith, simple farmer, village idiot, to village chieftain, diplomat, emperor, or anything you want to try and make happen.
+
+-   Depending on the faction, you might have access to shared resources and facilities.
+
+-   Safety in numbers. Raiders will think twice before attacking a city, whereas a loner is an easy target for burglars, thieves, pillagers, and robbers.
+
+### Factions
+
+Factions are basically "teams". Everyone in the same faction shares the same research points, and everyone in the faction contributes to everyone else when they perform research.
+
+But that also means that lazy people can take advantage of your technology and resources and not contribute a thing...
+
+A small tight-knit group of workers that contribute is often better off than a large group of slackers that just consume.
+
+Pick your members wisely\! Or cunningly use them to your advantage...
+
+Work smart, not hard!
+
+## Research
+
+Not implemented yet in Civ14. The only mode of scientific progression at the moment is the "Auto-Research" mode, where the research levels and ages progress automatically after a certain time.
+
+## Environments
+
+The environment lives and breathes and will be the single biggest factor that influences your life!
+
+Each map has either a single biome or several different ones.
+
+There are seasons of the year, effects of which are different in every biome. Some biomes have four seasons, while others have only two.
+
+On large maps with multiple biomes each biome has its own list of plants that could be grown there. Many plants also grow only in certain seasons. See the **[Guide to Farming](guide_to_farming.md)**.
+
+To determine the biome you are in, read the descriptions below and look at your surroundings. Looking at the map of **[Pangea](https://civ13.github.io/civ13-wiki/assets/images/map_pangea.png)** that has almost every biome may also help. From top to bottom: Tundra, Taiga (roughly the southern half of the snowed area, before the northern mountains), Temperate, Semi-Arid, Desert, Savanna, Jungle. The only biome missing is Sea.
+
+### Biomes and seasons
+
+#### Tundra
+
+-   Snow covers the ground all year round and does not melt during summer (unlike in Temperate).
+
+-   Trees and animals are somewhat rare here.
+
+Seasons:
+
+-   Summer: Amene temperatures, some snow melts, revealing dirt, and crops can grow. No chance of snowfall or blizzard. Wild animals respawn.
+
+-   Winter: Icy temperatures requiring coat, high chance of snowfall, chance of deadly blizzard. Crops stop growing, snow covers all land. Have a shelter ready or you probably won't survive until summer.
+
+#### Taiga
+
+Similar to Tundra in many regards, but considerably more trees.
+
+#### Temperate
+
+Plenty of trees and grassy meadows ("wild grass" tiles).
+
+Seasons:
+
+-   Spring: Amene temperatures, a little leftover snow from the winter. Sparse rains cause mud slowdowns. Snow starts melting.
+
+-   Summer: Hot temperatures, no rain. Chance of heat-waves that evaporate all puddles. All snow melts. Wild animals respawn at a faster rate.
+
+-   Fall: Cooler temperatures, sparse rain and occasional snowfall will slow you down.
+
+-   Winter: Icy temperatures can kill you without a fur coat, some lakes and rivers freeze over, allowing you to walk on them. Constant snowfall slows you down, **crops will not grow and animals won't respawn**. Chance of blizzards that cause a whiteout, and can kill you even with fur coats. Have a shelter ready\!
+
+#### Sea
+
+Smaller islands on larger maps usually have this biome. This is similar to the Temperate biome but without snow or cold winters.
+
+#### Semi-Arid
+
+Large expanses of dry dirt with occasional groves. A transition biome between Temperate and Desert. No snow during the winter.
+
+#### Desert
+
+Sand. Lots of sand.
+
+Seasons:
+
+-   Dry Season: All the water sources dry up, has a chance of sandstorms, which impair vision, but cause no other ill-effects. Heat is intense and can harm you if you stay in the sun too long.
+
+-   Wet Season: All water sources fill up, sandstorms die down. Wild animals respawn.
+
+#### Savanna
+
+Wide plains covered with sunburnt dry grass. Acacia trees are a common sight here. A drier version of the Jungle biome.
+
+#### Jungle
+
+Lush vegetation with massive jungle trees and large bushes; thick jungle grass covers the ground.
+
+Seasons:
+
+-   Dry Season: Fertile floodplains on the riverbanks are uncovered, sunny weather most of the time.
+
+-   Wet Season: Heavy rains and the arable land along the rivers is flooded.
+
+## Nomads maps
+
+Civ14 currently generates a random when a round starts. You will have to discover the map yourself!

+ 3 - 0
Civ14-Wiki/gamemodes/tdm.md

@@ -0,0 +1,3 @@
+# TDM Gamemodes
+
+Not implemented yet :(

+ 3 - 0
Civ14-Wiki/guides/guide_to_combat.md

@@ -0,0 +1,3 @@
+# Guide to Combat
+
+Coming soon!

+ 3 - 0
Civ14-Wiki/guides/guide_to_construction.md

@@ -0,0 +1,3 @@
+# Guide to Construction
+
+Coming soon!

+ 3 - 0
Civ14-Wiki/guides/guide_to_crafting.md

@@ -0,0 +1,3 @@
+# Guide to Crafting
+
+Coming soon!

+ 54 - 0
Civ14-Wiki/guides/guide_to_farming.md

@@ -0,0 +1,54 @@
+# Guide to Farming
+
+**WARNING: This guide was originally written for Civ13, and as such might not fully reflect the actual gameplay of Civ14.**
+
+Being a grower of crops is an important role. You farm both food and cash crops. Growing food is vital for a nation to increase in wealth and power.
+
+## Tools
+
+To farm, you will require some basic tools.
+
+|                                                                                       |        |                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
+| ------------------------------------------------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| ![knife](./../../Resources/Textures/Objects/Weapons/Melee/kitchen_knife.rsi/icon.png) | Knife  | Used for harvesting crops. Can be made out of lots of different materials, such as bone and stone.                                                                                                                                                                                                                                                                                                                                                         |
+| ![plough](./../../Resources/Textures/Civ14/Objects/items.rsi/plough.png)              | Plough | A plough is made out of wood and used to plough fields for farming! Used once on the grass and once on the dirt underneath the grass. You can also plough snowy dirt and flooded plains dirt (found along the jungle rivers). In case of snowy grass, you will have to shovel the snow first. Lastly, there are places where you cannot plough: infertile soil, permafrost etc. You can also make an iron plough out of iron ingots to plough land faster. |
+| ![seeds](./../../Resources/Textures/Civ14/Objects/Farming/seeds.rsi/seeds_old.png)    | Seeds  | Some sort of seeds to plant and grow. You may find seeds simply lying on the ground, but you can also collect them in the wilderness by using any type of knife on bushes and small bushes.                                                                                                                                                                                                                                                                |
+| ![hoe](./../../Resources/Textures/Objects/Tools/Hydroponics/hoe.rsi/icon.png)         | Hoe    | Helps remove those nasty weeds. Essential to prevent premature plant death.                                                                                                                                                                                                                                                                                                                                                                                |
+
+Just plough a plot of land by yourself with the **plough** tool. Add water and nutrient. Then wait for the plant to grow, keeping an eye on water and nutrient levels.
+
+## Watering
+
+Plants need water, some more, others less. Weather conditions and
+climate also affect the crops in this regard. Each crop has a maximum water level when planted.
+
+Normally, the water level decreases at the rate of approximately 15 per minute (depends on the plant), and when it reaches zero, the plants wither away.
+
+There are a few ways to provide the crops with water:
+
+-   Plough land within two tiles of fresh water, which is any water, except for the saltwater. The plants will have all the water they need without any extra labor.
+
+-   Water the plants manually. Bring the fresh water in buckets and barrels and splash it on the ploughed field (the ground, not the plant).
+
+-   Pray for the eternal rain. Rain will water the fields (at the rate of 20 per minute), but may create other inconveniences.
+
+## Soil Nutrition
+
+The soil, as in real life, has its level of nutrition. The plants that you plant in the soil will consume its nutrition little by little, until it reaches zero. This varies by plant, but is approximately 15-20 units per minute.
+
+A freshly ploughed tile will have a nutrition value of 0.
+
+**To examine the soil, stand close to it and examine it.**
+
+## Fertilizing
+
+Many kinds of animals leave manure on the ground, which could be used to fertilize a field. This is one way to restore nutrition to your soil.
+
+Fertilizer: 50 nutrition points.
+
+The **compost bin** (10 wood) also turns food scraps, plant matter (seeds, some plants) and some other unpleasant things into fertilizer. Just place it in the bin and wait for a while. Fertilizer could also be used to refuel ovens etc.
+
+## Severe weather
+
+Be aware that blizzards will freeze the plants and kill them. A
+heatwave, as noted in the Watering section, will cause the crops to consume more water than usual. Sandstorms will also destroy the plants.

+ 3 - 0
Civ14-Wiki/guides/guide_to_medical.md

@@ -0,0 +1,3 @@
+# Guide to Medical
+
+Coming soon!

+ 3 - 0
Civ14-Wiki/guides/guide_to_metallurgy.md

@@ -0,0 +1,3 @@
+# Guide to Metallurgy
+
+Coming soon!

+ 24 - 0
Civ14-Wiki/guides/playing.md

@@ -0,0 +1,24 @@
+# How to play
+
+**Note:** This article is about how to download and join the game. If you are looking for instructions on how to play once inside the game, check [the starter guide instead](starter_guide.md).
+
+## Downloading
+
+There are two options to play online: Either use SS14's launcher and hub (requires an account), or use Civ13's dedicated client (only available for Windows for now).
+
+### Civ13 Client
+
+1. Download the Civ13 client [here](https://github.com/Civ13/civ14-launcher/releases/).
+2. Run it and let it update the game files.
+3. Input the server's address (civ13.com for the official one) and press join.
+
+### SS14 Launcher
+
+1. Download the SS14 launcher [here](https://spacestation14.com/about/download/).
+2. Create an account for the SS14 hub, if you do not have one already.
+3. Look for Civilization 14 on the Hub, or use the Direct Connect option and use ss14://civ13.com for the official server.
+4. Join and wait for the launcher to update the game's files.
+
+## Playtesting / Hosting Locally
+
+If you want to play it locally to test/etc, you will need to download the source code and follow the instructions on the [github](https://github.com/Civ13/Civ14).

+ 178 - 0
Civ14-Wiki/guides/starter_guide.md

@@ -0,0 +1,178 @@
+# Starter Guide
+
+**Note:** This guide primarily focuses on survival in the sandbox [Nomads](nomads.md) game mode.
+
+## Spawning in
+
+-   You begin with only age-appropriate clothing and a torch in your pocket. If it's dark, drag the torch to your hand slot and press **Z** to activate it.
+
+    -   ![arrival](./../img/arrival.png)
+
+-   If it's **winter season** or **Ice Age** map, you also spawn with a **fur coat**. Losing this will mean cold and miserable **death** in the icy outdoors.
+
+-   Your **hunger** and **thirst** levels will start at approximately 50%. You'll receive alerts on the right side of the screen (below your health and stamina indicators) when you're hungry or thirsty. Pay close attention to these alerts.
+
+-   Your first priority is to gather flint to craft a flint axe.
+
+    -   Locate a large rock or boulder and right-click on it. You should see an option to search for flint.
+        ![boulder](./../img/boulder.png)
+    -   Click the rock repeatedly with the flint to sharpen it (you will get a message when it is sharpened).
+    -   Now go to a tree and right click on it. There should be an option to remove a branch from the tree, if there are any suitable ones available. This will pull a branch from the tree and place it on the ground.
+    -   Click the branch with an empty hand to clear the leaves.
+    -   Use the sharpened flint on the stick to sharpen the stick. Then, click the sharpened stick with the flint again to craft a flint axe, which serves as both a tool and a weapon.
+        ![flint axe crafting menu](./../img/flint_axe.png)
+
+## Crafting Basics
+
+### Crafting Menu
+
+**Tip:** Press **G** to open the crafting menu.
+
+You will need some basic things to survive. At the very start you will most likely be using **wood, leather, bone, stone, and straw** to make them.
+
+-   Hit a tree with your flint hatchet until it breaks. You will then find some **wood** on the floor.
+
+-   Hunt and butcher some animals to get **leather** and **bone**.
+
+-   Use your knife on a grass tile to gather some **straw**.
+
+-   Use your pickaxe on a rock tile to gather **stone** (see below).
+
+### Mining 101
+
+Ores are valuable crafting materials which you mine out of the rock.
+
+-   You'll need **wood** and **bone** for this. Go gather them (bones are obtained by butchering animals - click the carcass with something sharp, like a flint axe or a knife),
+-   Make a **bone pickaxe**.
+-   Find a **rock** tile.
+-   Right click on it while holding the **pickaxe** on your active hand.
+
+## Food and Water
+
+To survive, you will need to keep yourself nourished and warm. Pay attention to the alerts on the right side of the screen, they will tell you when you need to eat and drink.
+
+**Warning: Letting either hunger or thirst reach 0% will cause your body to start shutting down, leading to inevitable death!**
+
+### Hunger
+
+The easiest way to get food early on is by killing animals and eating the meat after cooking it. Also, you can eat bird eggs, even uncooked!
+
+-   Find an animal, preferably one that doesn't have fangs, claws, tusks, or poison. and kill it with any means (even bare fists work). Remember to press the **harm intent** button to enter combat mode!
+    <img src="./../../Resources/Textures/Interface/Actions/harm.png" style="width:64px;height:64px;image-rendering: pixelated;"> <img src="./../../Resources/Textures/Interface/Actions/harmOff.png" style="width:64px;height:64px;image-rendering: pixelated;">
+
+**Tip:** For now, stay away from bears, alligators, wolves, snakes, and mammoths. They will fight back and very probably kill you. Wait until you have proper equipment or a hunting party with you.
+
+-   Use your knife (flint axe works too) on the dead animal with **Harm intent** to butcher it.
+-   **Raw meat** causes **food poisoning**! You'll want to **cook** it first, but if you're starving, food poisoning is the least of your worries.
+-   To cook meat, place it on a **campfire** and click the campfire. The campfire is made with **wood logs**.
+
+Farming is another good source of food (although not an immediate one) that does not involve getting maimed by wild animals. Check the [guide to farming](guide_to_farming.md).
+
+### Thirst
+
+The easiest way to quench your thirst early on is by drinking water or milk.
+
+#### Water
+
+You can get water from **puddles**, any **water tiles (except saltwater - do not drink nor boil it!)**, or **wells**.
+
+-   To drink, you need to make a **mug** from **wood** or **drinking glass** from **glass**.
+-   **Wells** have disease-free freshwater (**however, if there are some... excrements within 4 tiles of a well, the water becomes contaminated and unsafe to drink!)**. You can build them over a **puddle** by using with **stone**... if your faction has the research levels required.
+
+#### Milk
+
+-   Find a **cow**, **sheep ewe**, or **goat ewe**.
+-   Make a **bucket** from **wood**.
+-   Use the **bucket** on **Help intent** on the animal of choice to gather milk.
+-   Pour the milk into the **mug** or **glass** and drink.
+-   You don't have to boil milk.
+
+Milk is regenerated in the animals over time, so keep them alive, and
+you'll never go thirsty.
+
+## Temperature
+
+**Tip:** Keep an eye out for the temperature alert! If it is flashing blue with a white snowflake, you are freezing! If it is red and there is sun instead, you are melting from the heat!
+
+Winter seasons can bring an icy chill that can seriously hurt and slow you down, or even kill you. Blizzards are especially deadly, and just wearing a fur coat will not cut it, so make sure you have a shelter ready before it is too late.
+
+Southern climates could be merciless in their own way, so be careful that you do not overheat to the point of a heat stroke. Resting in a roofed shelter from time to time and wearing appropriate clothing (for instance, "traditional" desert clothes) can save you from fainting and shrivelling in a sweltering heat.
+
+### Fur Clothing
+
+<img src="./../../Resources/Textures/Civ14/Clothing/exported/suits/prehistoric_fur2.rsi/icon.png" style="width:64px;height:64px;image-rendering: pixelated;"><img src="./../../Resources/Textures/Civ14/Clothing/exported/suits/fur_jacket1.rsi/icon.png" style="width:64px;height:64px;image-rendering: pixelated;">
+Fur clothing can keep you warm in the winter, but it will not save you if you are caught in a blizzard. You can make fur clothing by skinning large furry animals like **bears** and **wolves**. <sub>Yes, you can finally skin furries with no repercussions.</sub>
+
+-   Kill one of the following animals: **bear, wolf, bison, monkey, fox, sheep**.
+-   Bucher the animal by using the **knife** on **Harm Intent**.
+-   Collect enough pelts and craft **fur coat, boots, headcover and gloves** (you might need to hunt several animals for the whole set).
+
+    -   <img src="./../../Resources/Textures/Objects/Materials/materials.rsi/sheet-brownbearpelt.png" style="width:64px;height:64px;image-rendering: pixelated;"><img src="./../../Resources/Textures/Objects/Materials/materials.rsi/sheet-wolfpelt.png" style="width:64px;height:64px;image-rendering: pixelated;">
+
+## Shelter
+
+Shelter can save you from even the toughest of conditions.
+
+Any roofed area is considered a shelter.
+
+-   **Caves**: There's a reason that stone-age men were called cavemen. Look for entrances in rocks. If it has a roof, it will be darker inside. That means it will keep snow, cold, blazing sun and rain out. The easiest way of surviving inclement weather. <sub>Make sure that no bears live in the cave, though...</sub>
+-   **Building a Roof**: Target your inner Bob the Builder and build your own roof.
+
+    -   Build **walls** to prop the ceiling up. Craft floor tiles and place them to automatically build a roof overhead.
+
+    -   You can also build walls with **dirt** or **snow** by using the **shovel** directly on the ground.
+
+## Fire
+
+<img src="./../../Resources/Textures/Civ14/Objects/kitchen.rsi/fireplace_on.png" style="width:64px;height:64px;image-rendering: pixelated;">Crackling fires will keep you warm even without a coat. Both campfires and braziers are refueled by adding **wood**, **coal** and **charcoal**. The brazier could also be refueled with **paper- and cloth-based items**.
+
+-   A **campfire** warms you when you are right next to it, or within 2 tile.
+-   A **brazier** (made with **stone**) provides more heat and warms you within 3 tiles.
+
+## Dangerous animals
+
+**Warning: The world is teeming with wildlife. Most of them are pretty tame and easy prey, but steer clear of the big game unless you're a skilled hunter, otherwise you'll become minced meat yourself!**
+
+You want to avoid these, unless you're robust or need some pelts:
+
+-   ![brown bear](./../../Resources/Textures/Civ14/Mobs/animal_64.rsi/brownbear.png)Bears (can provide fur)
+-   ![white wolf](./../../Resources/Textures/Civ14/Mobs/animal.rsi/whitewolf.png)![grey wolf](./../../Resources/Textures/Civ14/Mobs/animal.rsi/greywolf.png)Wolves (can provide fur)
+-   ![mammoth](./../../Resources/Textures/Civ14/Mobs/animal_128.rsi/mammoth.png)Mammoths
+-   ![sabertooth](./../../Resources/Textures/Civ14/Mobs/animal_big.rsi/sabertoothcat_brown.png)![liom](./../../Resources/Textures/Civ14/Mobs/animal_big.rsi/lion.png)Panthers, Jaguars, Lions, and other big cats
+-   ![alligator](./../../Resources/Textures/Civ14/Mobs/animal_big.rsi/alligator.png)Alligators
+
+![cave den](./../../Resources/Textures/Civ14/Objects/animal_spawner.rsi/cave_den2.png)
+![cave den](./../../Resources/Textures/Civ14/Objects/animal_spawner.rsi/cave_den-foliage.png)
+Also keep an eye for animal dens. Dangerous animals will spawn here!
+
+## Night time
+
+You'll need a light source to see in the night and in dark indoor areas. The basic source of light is the **torch**.
+
+-   Gather some **wood**. Craft a **torch** and press **Z** to light it. Torches will last for **5 minutes** and then burn out.
+
+-   For a static source of light, you can make a **campfire**, which will also help you cook some food.
+
+-   You can also make lanterns with **iron**. Lanterns require fuel - any form of liquid fuel will do, like olive oil, fat, or petroleum.
+
+-   For a more **permanent** light source, you can build **braziers** from **stone**. You can fuel it with any organic matter like wood or clothing - simply use items on the brazier.
+
+## Medicine
+
+In the Stone age, most of the medicine you will find is restricted to bandages and medicinal herbs.
+
+![leather bandage](./../../Resources/Textures/Civ14/Objects/surgery.rsi/leatherbandage.png)![cloth bandage](./../../Resources/Textures/Civ14/Objects/surgery.rsi/bint.png) You can craft bandages from **cloth** or **leather**. They will help you stop bleeding.
+
+You can find medicinal herbs growing wild around the map. If you harvest them, you will also get some seeds so you can plant them yourself - see the [guide to farming](guide_to_farming.md).
+
+<img src="./../../Resources/Textures/Civ14/Objects/Farming/elderflower.rsi/harvest.png" style="width:64px;height:64px;image-rendering: pixelated;"><img src="./../../Resources/Textures/Civ14/Objects/Farming/elderflower.rsi/produce.png" style="width:64px;height:64px;image-rendering: pixelated;"> **Elderflower** has a long history in European folk medicine for treating colds and sinus issues. It reduces asphyxiation by clearing airways and boosting oxygen intake.
+
+<img src="./../../Resources/Textures/Civ14/Objects/Farming/yarrow.rsi/harvest.png" style="width:64px;height:64px;image-rendering: pixelated;"><img src="./../../Resources/Textures/Civ14/Objects/Farming/yarrow.rsi/produce.png" style="width:64px;height:64px;image-rendering: pixelated;"> **Yarrow** has been used since ancient times as a hemostatic (blood-clotting) agent. It’s known for its astringent properties that help staunch bleeding.
+
+<img src="./../../Resources/Textures/Objects/Specific/Hydroponics/spacemans_trumpet.rsi/harvest.png" style="width:64px;height:64px;image-rendering: pixelated;"><img src="./../../Resources/Textures/Objects/Specific/Hydroponics/spacemans_trumpet.rsi/produce.png" style="width:64px;height:64px;image-rendering: pixelated;"> **Comfrey** has been used historically to heal bruises, sprains, and fractures due to its anti-inflammatory and tissue-repair properties. Heals brute damage.
+
+<img src="./../../Resources/Textures/Objects/Specific/Hydroponics/galaxythistle.rsi/harvest.png" style="width:64px;height:64px;image-rendering: pixelated;"><img src="./../../Resources/Textures/Objects/Specific/Hydroponics/galaxythistle.rsi/produce.png" style="width:64px;height:64px;image-rendering: pixelated;"> **Milk Thistle** has long been used as a liver tonic, with silymarin compounds believed to detoxify and protect against poisons.
+
+<img src="./../../Resources/Textures/Objects/Specific/Hydroponics/poppy.rsi/harvest.png" style="width:64px;height:64px;image-rendering: pixelated;"><img src="./../../Resources/Textures/Objects/Specific/Hydroponics/poppy.rsi/produce.png" style="width:64px;height:64px;image-rendering: pixelated;"> **Poppy** is the source of opium and morphine, known for sedative and pain-relieving effects, but it can also stabilize shock in small doses by calming the nervous system. Historically, it’s been used for pain and trauma management.
+
+<img src="./../../Resources/Textures/Objects/Specific/Hydroponics/aloe.rsi/harvest.png" style="width:64px;height:64px;image-rendering: pixelated;"><img src="./../../Resources/Textures/Objects/Specific/Hydroponics/aloe.rsi/produce.png" style="width:64px;height:64px;image-rendering: pixelated;"> **Aloe vera**’s gel is a well-documented remedy for burns, soothing inflammation and promoting skin healing.

BIN
Civ14-Wiki/img/arrival.png


BIN
Civ14-Wiki/img/boulder.png


BIN
Civ14-Wiki/img/flint_axe.png


+ 137 - 0
Civ14-Wiki/index.html

@@ -0,0 +1,137 @@
+<!DOCTYPE html>
+<html>
+<!--
+   This is MDwiki v0.7.0
+   (C) 2013 by Timo Dörr and contributors. This software is licensed
+   under the terms of the GNU GPLv3 with additional terms applied.
+   See https://github.com/Dynalon/mdwiki/blob/master/LICENSE.txt for more detail.
+   See http://github.com/Dynalon/mdwiki for a copy of the source code.
+-->
+
+<head>
+    <title>Civilization 14 Wiki</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta name="fragment" content="!">
+    <link rel="shortcut icon" type="image/x-icon" href="./../Resources/Textures/Logo/icon/icon-64x64.png" />
+    <meta charset="UTF-8">
+    <style type="text/css">
+        /* hide the main content while we assemble everything */
+        .md-hidden-load {
+            display: none;
+        }
+
+        .anchor-highlight {
+            font-size: 0.7em;
+            margin-left: 0.25em;
+        }
+
+        /* for pageContentMenu */
+        #md-page-menu {
+            position: static;
+        }
+
+        #md-page-menu a.active {
+            /* background-color: rgba(0, 0, 0, 0.01); */
+            font-weight: bold;
+            padding-left: 6px;
+
+        }
+
+        @media (min-width: 992px) {
+            #md-page-menu.affix {
+                position: fixed;
+            }
+        }
+
+        @media (min-width: 768px) {
+
+            .md-float-left .col-sm-8,
+            .md-float-right .col-sm-8 {
+                max-width: 66.67%;
+            }
+
+            .md-float-left .col-sm-4,
+            .md-float-right .col-sm-4 {
+                max-width: 33.33%;
+            }
+
+            .md-float-left .col-sm-2,
+            .md-float-right .col-sm-2 {
+                max-width: 16.67%;
+            }
+
+        }
+
+        @media (max-width: 992px) {
+            a.forkmeongithub {
+                display: none;
+            }
+        }
+
+        @media (max-width: 768px) {
+
+            /* don't use floating for smaller screens */
+            .md-float-left .col-sm-8,
+            .md-float-left .col-sm-4,
+            .md-float-left .col-sm-2 {
+                width: 100%;
+                max-width: !important;
+                min-width: 100%;
+            }
+
+            .md-float-right .col-sm-8,
+            .md-float-right .col-sm-4,
+            .md-float-right .col-sm-2 {
+                width: 100%;
+                max-width: !important;
+                min-width: 100%;
+            }
+        }
+
+        .md-floatenv .md-text {
+            /* md-text is not of md-col-* but needs the spacing */
+            margin-left: 15px;
+            margin-right: 15px;
+        }
+
+        /* float images */
+        .md-float-left .col-sm-8,
+        .md-float-left .col-sm-4,
+        .md-float-left .col-sm-2 {
+            width: auto;
+        }
+
+        .md-float-right .col-sm-8,
+        .md-float-right .col-sm-4,
+        .md-float-right .col-sm-2 {
+            float: right !important;
+            width: auto;
+        }
+
+        #md-all .md-copyright-footer {
+            background-color: !important;
+            font-size: smaller;
+            padding: 1em;
+        }
+    </style>
+    <link rel="stylesheet" href="extlib/css/bootstrap-3.0.0.min.css">
+    <link rel="stylesheet" href="extlib/css/prism.1.4.1.default.min.css">
+    <script src="extlib/js/jquery-1.8.3.min.js"></script>
+    <script src="extlib/js/bootstrap-3.0.0.min.js"></script>
+    <script src="extlib/js/prism.1.4.1.min.js"></script>
+    <link rel="stylesheet" href="extlib/css/colorbox.css">
+    <script src="extlib/js/jquery.colorbox.min.js"></script>
+    <script src="MDwiki.js"></script>
+</head>
+
+<body>
+    <noscript>
+        This website requires Javascript to be enabled. Please turn on Javascript
+        and reload the page.
+    </noscript>
+
+    <div id="md-all">
+    </div>
+</body>
+
+</html>

+ 35 - 0
Civ14-Wiki/index.md

@@ -0,0 +1,35 @@
+# Civilization 14
+
+<img src="./../Resources/Textures/Logo/splash.png" height="400">
+
+Welcome!
+
+Civilization 14 (Civ14 for short) is a port of [Civilization 13](https://github.com/Civ13/civ13) from [BYOND](https://byond.com) to [Robust Toolbox](https://github.com/space-wizards/RobustToolbox), used for Space Station 14, which itself is a remake of SS13.
+
+## What is this?
+
+Civ14 is an immersive, player-driven strategy game, where history unfolds through the hands of its community. Set across vast timelines, from the dawn of civilization to the modern era, players take on roles as leaders, builders, warriors, or everyday citizens, shaping the course of their chosen society. Whether forging empires through diplomacy and trade, waging war to expand territory, or simply surviving in a dynamic, ever-evolving world, Civ14 offers a sandbox experience defined by cooperation, conflict, and creativity. With a passionate player base and a framework that rewards both individual ambition and collective storytelling, Civ13 transforms SS14 into a living tapestry of human history.
+
+## Features
+
+Features:
+
+-   **Survival focused:** You start with a loincloth and a torch. You will need to craft everything from scratch!
+
+-   **Expanded crafting system:** Thousands (!) of craftables available, from clothing to walls to decorations.
+
+-   **Long rounds:** Rounds last for days! or until the server crashes
+
+-   **Hard to master:** The world is unforgiving. Expect to die to bears, wolves, and even piranhas!
+
+-   **Randomly generated maps:** The game includes a map generator so no two rounds are the same.
+
+-   **Choose your path:** There are no pre-set roles. Be a loner or join a faction, its up to you!
+
+## Gamemodes
+
+So far, we are working on the **Nomads** gamemode. You can see a guide to this [here](gamemodes/nomads.md).
+
+## How to Play
+
+Check [How to Play](guides/playing.md) and the [Starter Guide](guides/starter_guide.md).

+ 33 - 0
Civ14-Wiki/navigation.md

@@ -0,0 +1,33 @@
+# Civ14 Wiki
+
+[Rules](rules/rules.md)
+[How to Play](guides/playing.md)
+
+[Gamemodes]()
+
+-   [Nomads](gamemodes/nomads.md)
+-   [TDM](gamemodes/tdm.md)
+-   [Art of the Deal](gamemodes/aotd.md)
+
+[Guides]()
+
+-   [Starter Guide](guides/starter_guide.md)
+-   [Farming](guides/guide_to_farming.md)
+-   [Construction](guides/guide_to_construction.md)
+-   [Crafting](guides/guide_to_crafting.md)
+-   [Metallurgy](guides/guide_to_metallurgy.md)
+-   [Medical](guides/guide_to_medical.md)
+-   [Combat](guides/guide_to_combat.md)
+
+[Links]()
+
+-   [Discord](https://discord.gg/hBEtg4x)
+-   [Github](https://github.com/civ13/civ14)
+
+<!-- set a default theme -->
+
+[gimmick:theme (inverse: false)](cyborg)
+
+<!-- show a theme chooser in the menu bar -->
+
+[gimmick:ThemeChooser](Theme)

+ 238 - 0
Civ14-Wiki/rules/rules.md

@@ -0,0 +1,238 @@
+# Rules
+
+## Core Rules
+
+These rules apply at all times, including between rounds.
+
+## 1. Admins Have Final Say
+
+These rules are not perfect. The rules attempt to clearly communicate what the admin team intends to be allowed and prohibited, but there are likely loopholes or other flaws that can be "lawyered". Don't attempt to manipulate the interpretation of the rules to suit your personal goals or to degrade the experience of other players. If you are unsure of something, follow the more restrictive option until you are able to ask an admin and get clarification.
+
+Admins can override rules if they deem it in the best interest of the current round, server, and/or community at large. Online admins are able to make final interpretations of rules during a round. Even if you disagree with how an admin interprets a rule, you must still follow the interpretation they provide for you. Admin actions and interpretations of rules can be contested through staff complaints. If admins believe that you are an overall negative impact to the community or rounds, you will be banned. Admins will be held fully accountable for their actions if they exercise this privilege.
+
+## 2. Don't Be a Dick
+
+-   Don't do anything with the goal of negatively affecting other players. Not everyone is going to enjoy every round. Killing someone is allowed in certain situations even though it might negatively affect them, but no one should be doing anything for the purpose of harming someone else's experience.
+
+-   Do not interact negatively with SSD/AFK players. Interactions to complete antagonist objectives or duties like security searches/arrests are always permitted.
+
+## 3. No Sexual Content / ERP
+
+Erotic Roleplay (commonly abbreviated as "ERP") and sexual content is not allowed. This includes direct and indirect mentions of sexual behavior or actions. Slight leeway is given to insults, but this rule is otherwise strictly enforced.
+
+In-game romantic relationships should not become the focus of the game for you and anyone else involved.
+
+Things that appear to be intended to or are likely to disturb players out of character are considered shock content and are not allowed.
+
+Allowed:
+
+-   Telling someone that they are being a dickhead.
+-   Telling someone that you are going to kill the captain, as long as it is clear that you mean it in character.
+
+Prohibited:
+
+-   Emoting sexual acts.
+-   Erotica content.
+-   Erotic or sexual memes.
+-   Memes which contain sexual content.
+-   Dedicating significant portions of rounds to romantic relationships, dating, or similar things.
+-   Emoting defecation or related acts.
+
+## 4. No Metacommunication
+
+Do not utilize any external means of communication to talk to other players who are connected to the same server, or who were connected to the same server during the current round. This is referred to as "metacomming" and includes any means of communication including text, voice, images, and video. This includes applications such as Discord, Steam, and other platforms, along with in-person communication.
+
+Even if information is not being shared or abused, it may still be considered a violation of this rule. Due to the difficulty of determining if information is being shared, it will almost always be presumed that people who message another player they are in a round with, or who are in a voice call with another player during a round are sharing round information. Due to the difficulty of determining if users are abusing information that they are sharing, it will almost always be presumed that the information is being abused.
+
+The only exemption to this rule is when **all** players are in the server lobby.
+
+## 5. No Ban Evasion
+
+Almost all bans may be appealed on our forums at forum.ss14.io in the ban appeals section. This is generally the only acceptable way to contact the administration team to discuss your ban and revise it if it is inappropriate, including if it is mistakenly applied.
+
+Any attempt to circumvent or bypass a game ban will result in a voucher ban. Attempting to evade role bans by gaining access to or working in the capacity of a job you are banned from will result in a game ban. These bans are applied even if the evasion attempt is unsuccessful.
+
+There are no exemptions for evading or attempting to evade game bans. Antagonists who impersonate or take over a role which they are banned from to aid in their goals are not considered to be evading their role ban.
+
+## 6. Use Mostly English
+
+You must be fluent in English enough to be able to not cause game issues, and to be able to communicate with game admins when necessary. You can use other languages in OOC and ingame IF the people you are talking to speak the language. If a game admin does not feel that you are fluent enough in English, they may kick you.
+
+## 7. No Exploits / Cheats
+
+The following are prohibited by this rule:
+
+-   bugs and exploits which have effects that persist beyond the current round,
+-   intentionally used bugs, exploits, and unintended behaviors which give the user an advantage over players who do not use them, even if their effects do not persist across rounds,
+-   evading or bypassing afk detection,
+-   anything which results in gaining elevated privileges, including admin permissions,
+-   external tools and client modifications, including macros, and
+-   anything which prevents another player who is not game banned from being able to play on the servers, not including in-character actions that do not persist across rounds.
+
+Both attempts and successful use are prohibited.
+
+## 8. No Multiaccounting
+
+Use of multiple accounts is referred to as "multikey". the rule applies even if the accounts are not used at the same time, including if the old account is abandoned. All accounts may be banned if this rule is violated. You are responsible for everything done on and with your account. You are just as responsible for actions taken by other people using your account as you would be had you taken the actions themselves.
+
+## 9. No AHELP Abuse
+
+Admin help, or "ahelp", is the system used by admins to communicate with specific players in the game. Only use admin help for things requiring admin attention. If you ignore messages admins send to you via ahelp, or disconnect during an ahelp, you may be banned. If you urgently need to leave during an ahelp, you may do so but will likely need to continue the ahelp on the forums. Do not admin check, be hostile/aggressive, request events, or spam. IC methods of contacting admins, like prayers, faxes, red phones, and banana phones, should be used when there is not an issue.
+
+Admins are not always online, but all ahelps are automatically relayed to discord. For various reasons, admins might not respond to an ahelp even if they've handled it. A lack of response does not necessarily mean that an ahelp was ignored.
+
+### Should I ahelp X?
+
+You can ahelp anytime you genuinely think a player is breaking a rule. Not all ahelps end up being for something that an admin needs to intervene in, but that's ok, admins would rather have people occasionally report things that turn out to not be an issue than miss reports for actual issues because someone was unsure, or get those reports late because someone waited until the end of the round to be more sure.
+
+The most common reason players give for not ahelping issues is that they don't want to waste admin time, but it only takes a few seconds for an admin to check if someone is an antagonist. If you are ahelping too many things, an admin will let you know. If you're not being told to stop reporting something or to report less things, then you can safely assume that you aren't causing any issues.
+
+### What should I include in an ahelp?
+
+At a minimum, admins need to know what the issue is to be able to address an ahelp. Don't send ahelp messages with no information about what your question or the issue is. Messages like "hello" are often considered admin checking.
+
+If you can, an ideal ahelp message includes what the issue is along with who is causing it and their character's name if possible.
+
+Appropriate uses of ahelp:
+
+-   reporting people who you think are violating rules,
+-   asking questions about rules,
+-   asking for a temporary exemption from a rule, and
+-   request a minor gimmick, like a TC trade or item spawn.
+
+Inappropriate uses of ahelp:
+
+-   checking if an admin is online, including sending messages without any information about the issue like "hello" or incomprehensible messages,
+-   being hostile or aggressive,
+-   requesting events, and
+-   spamming messages about the same issue.
+
+## 10. No AHELP threats
+
+This rule covers out-of-character (OOC) and in-character (IC) actions. Don't threaten to ahelp a player, don't tell them you are ahelping them, and don't tell them you did ahelp them. You can argue in character about Space Law, but do not argue about whether something is or is not against the rules. If you think someone is breaking a rule, ahelp them. If you don't think someone is breaking a rule, don't ahelp them. Either way, the best thing that you can do after is to continue in-character.
+
+## 11. Minimum Age 16
+
+All players must be at least 16 years old. Additionally, all players must act at least as mature as a 16 year old. Admins may ban someone who they believe is acting less mature than a 16 year old, even if the player is known to be significantly older than 16 years old.
+
+Anyone who connects to the servers is a player, even if they don't actually play in a round.
+
+## 12. Use Realistic-ish Characters
+
+-   No names of people or characters from the real world, you can do variations though.
+-   Must follow all other rules (no slurs/sexual names/etc)
+-   Usernames, objects, random characters, very "low effort" names, "meta" names, or otherwise implausible names cannot be used as names. See examples below.
+-   Admin rulings on IC names are final and disputes should be done through the forums, not by refusing to comply with an admin
+
+Bad cannot be used by any species. Acceptable names can be used by any species.
+
+Humans typically use the Firstname Lastname convention.
+
+-   Acceptable: Tom Fisher
+-   Acceptable: Spacey Chapman
+-   Acceptable: Jonald Drump
+-   Bad: Donald Trump
+-   Usernames, objects, random characters, very "low effort" names, "meta" names, or otherwise implausible names are not permitted.
+
+-   Bad: XxRobustxX
+-   Bad: SDpksSodjdfk
+-   Bad: Lkdsoisgoieun
+-   Bad: F4ith H3arth
+-   Bad: Greytide
+-   Bad: Passenger
+-   Bad: Urist McHands
+-   Bad: Admin
+-   Bad: Game-Master
+-   Bad: Joe Mamma
+-   Bad: Middle-Aged Man
+-   Bad: Operative Whiskey
+
+## 13. No IC in OOC
+
+Local Out of Character (LOOC) and Out of Character (OOC) channel are meant for things that don't relate to the current round. Using these channels to share round info is often referred to as "IC in OOC" or "ick ock".
+
+## Roleplay Rules
+
+These rules only apply during a round. A round ends only when the round summary has appeared. All of these rules apply fully until the moment that the round summary appears, even while the arrivals shuttle is in transit.
+
+**Note:** "Chad Mode" games are exempt from these rules. Roleplay rules do not apply to ghosts/spectators/observers while they are ghosts/spectators/observers. Dead chat is considered to be an in-game out of character chat channel.
+
+## 1. Roleplay a Nrmal Person
+
+-   Do not use texting/messaging acronyms (ex: "lol", "wtf", "brb", "lmao", "thx", "sgtm") or emoticons (ex: ":)", "xD") in-character.
+-   Do not mention out-of-character (OOC) concepts like game admins or developers in character.
+-   Do not use emotes to bypass muted or accented speech.
+-   Do not use extremely low effort or impossible emotes.
+
+Things you should not do:
+
+-   Say "lol did u c wat just happened" using in-character chat.
+-   Say "an admin exploded him" using in-character chat.
+-   Emote "can you give me some cheese" as a mouse.
+-   Emote "motions for you to order guns" or "asks you to order guns in sign language" as a mime.
+
+Things you could do instead:
+
+-   Say "haha did you see what just happened?"
+-   Say "god blew him up" or "centcomm must have bluespaced a bomb to him"
+-   Point at cheese
+-   Point at the cargo order console then emote "shoots finger guns"
+
+## 2. No Metagaming
+
+Something that is "shielded" cannot be known by your character during a round until the "revealing condition" happens. This also means that your character cannot do things based on "shielded" information. Knowing or acting on something that is shielded before the revealing condition is met is referred to as metagaming.
+
+Revealing conditions reveal the shielded information for the round, not for a specific instance. This means that once a revealing condition is met in a round, the shield no longer applies in any case for the remainder of the round.
+
+## 3. No Round Stalling
+
+**This applies only on gamemodes with specific roles. Does not apply on Nomads gamemodes.**
+
+Rounds are intended to end eventually. Don't hold a round hostage by preventing it from coming to a natural end. If a majority of players in a round want the round to end, don't prevent it from ending. Recalling the shuttle or preventing it from being called can contribute to round stalling, but is not always round stalling. Leaving the station with the nuclear authentication disk while nuclear operatives are trying to get it is almost always considered round stalling. Leaving the station on the evacuation shuttle is not round stalling.
+
+## 4. Respect Teams and Teamwork
+
+Do not take or enable antagonist roles that you do not want to play. Solo antagonists and team antagonists are intended to cause issues for non-antagonists or the station. Antagonists are not required to exclusively cause issues, but their net impact on non-antagonists or the station should generally be negative.
+
+Do not cause issues for your own team as a team antagonist.
+
+## 5. Listen to your team leader
+
+Captains lead all departments and other members of command. Department heads lead members of their department. Certain antagonist teams have team leaders, like nuclear operative commanders or head revolutionaries. You are not required to perfectly follow orders given to you by your leaders, but you should generally allow your leaders to lead and not interfere with their ability to. You can choose to ignore unreasonable orders, including ones which are will result in your death unless you are an antagonist with an objective that requires you to die.
+
+Team antagonists have to listen to the leader of their antagonist team. Team antagonists do not have to listen to any other leaders, including leaders of other antagonist teams. Solo antagonists do not have to listen to any leaders at all.
+
+## 6. Follow Reasonable Escalation
+
+Antagonists are fully exempt from escalation rules. Non-antagonists who are in a conflict with antagonists are not exempt. Escalation should typically follow steps or a pattern of conflict types similar to:
+
+-   Verbal
+-   Non-harmful
+-   Non-lethal
+-   Lethal
+-   Permanently lethal
+
+All new conflicts should start at the first step. A player should not escalate a conflict across steps without some escalation from the other party involved in the conflict. Players can skip steps to match the level of escalation that the other person is at, but should almost always not skip steps other than that. Players who attempt to deescalate conflicts will be given more leniency in escalating if the other party continues to escalate despite the attempt at de-escalation. You do not have to try to deescalate conflicts, but someone who watches you over the entire round, or over multiple rounds, should not feel that your goal is generally to escalate conflicts.
+
+Conflicts or escalation can be indirect. When someone steals someone else's ID, the theft is a direct part of the conflict, but if the victim becomes trapped as a result of not having their ID to open a door, that is also considered part of the conflict and escalation. Do not randomly steal IDs from people.
+
+Escalation does not have to be directed at a specific player to enter them into a conflict. Nuclear operatives who are trying to destroy the station are considered to be at the permanently lethal level of conflict with all crew on the station. Someone who kills a station pet has started some degree of conflict with all crewmembers. Someone who kills a mouse that a chef was caring for has started some degree of conflict with that chef.
+
+You will be considered to be violating this rule if you escalate a conflict based on a poor or unreasonable assumption.
+
+## 7. No Role Abandoning
+
+**This applies only on gamemodes with specific roles. Does not apply on Nomads gamemodes.**
+
+Do not join the round as a role that you don't intend to play. Do not enable antagonist roles that you don't intend to play. Abandoning a role includes not completing tasks that the role is expected to do, in addition to things like leaving the game. Members of command should almost all stay on the station until the emergency shuttle arrives. Enforcement of this rule is more strict for command and antagonist roles, and less strict for less important roles like passengers.
+
+Violations of this rule typically result in temporary or indefinite role bans. We understand that you may need to leave round early or unexpectedly. If you are in an important role (which is relayed to you in chat upon receiving your role), you should notify command members so that they know you are leaving and attempt to cryosleep if possible. Space Station 14 is a game. Do not endanger the safety of yourself or others, and do not neglect important things to avoid leaving a round early, even if you have to leave immediately without notifying anyone. Role bans for disconnecting are typically only applied if there is a pattern, and are almost always temporary.
+
+"Antag rolling" refers to a player abandoning their role if they do not get an antagonist role.
+
+## 8. Stick to Your Role
+
+**This applies only on gamemodes with specific roles. Does not apply on Nomads gamemodes.**
+Requesting job changes is not prohibited by this rule. This rule is loosened if the station is understaffed or if there is a significant threat to you.
+
+Don't perform other people's jobs, especially where the relevance to you personally is low. This also covers performing the role of security.

+ 11 - 0
CivMigrations/README.md

@@ -0,0 +1,11 @@
+# Civ13 entity migration
+
+On the json file in this folder, register all entities you create or add that have matching entities in Civ13. For example, if you create a coat called `GreenCoat` that exists in Civ13 as `/obj/clothing/coat/green`, add it to the json as:
+
+`"/obj/clothing/coat/green": "GreenCoat"`
+
+You can use an array if there are several equivalences:
+
+`["/obj/clothing/coat/green","obj/clothing/coat/greenish"]: "GreenCoat"`
+
+This will help us convert maps and such in the future.

+ 5333 - 0
CivMigrations/migrations.json

@@ -0,0 +1,5333 @@
+{
+    "/turf/floor/grass": "FloorPlanetGrass",
+    "/mob/living/human/corpse": "",
+    "/mob/living/human/corpse/bandit": "",
+    "/mob/living/human/corpse/beggar": "",
+    "/mob/living/human/corpse/beggar_f": "",
+    "/mob/living/human/corpse/british_sailor": "",
+    "/mob/living/human/corpse/chinese_ww2": "",
+    "/mob/living/human/corpse/japanese": "",
+    "/mob/living/human/corpse/japanese_ww2": "",
+    "/mob/living/human/corpse/japanese_ww2_antitank": "",
+    "/mob/living/human/corpse/japanesesgt": "",
+    "/mob/living/human/corpse/pirate": "",
+    "/mob/living/human/corpse/prisoner": "",
+    "/mob/living/human/corpse/russian": "",
+    "/mob/living/human/corpse/russian_soviet": "",
+    "/mob/living/human/corpse/russian_soviet_sgt": "",
+    "/mob/living/human/corpse/russian_soviet_tanker": "",
+    "/mob/living/human/corpse/russiansgt": "",
+    "/mob/living/human/corpse/teller/modern": "",
+    "/mob/living/human/corpse/ww1french": "",
+    "/mob/living/human/corpse/ww1german": "",
+    "/mob/living/human/corpse/ww2_american": "",
+    "/mob/living/human/corpse/ww2_american_medic": "",
+    "/mob/living/human/corpse/ww2_jap_medic": "",
+    "/mob/living/human/corpse/ww2_jap_mg": "",
+    "/mob/living/human/corpse/ww2_jap_sl": "",
+    "/mob/living/simple_animal/bison": "",
+    "/mob/living/simple_animal/bisonbull": "",
+    "/mob/living/simple_animal/blackbat": "",
+    "/mob/living/simple_animal/boar_boar": "",
+    "/mob/living/simple_animal/boar_gilt": "",
+    "/mob/living/simple_animal/camel": "",
+    "/mob/living/simple_animal/cat": "",
+    "/mob/living/simple_animal/cat/kitten": "",
+    "/mob/living/simple_animal/cat/salem": "",
+    "/mob/living/simple_animal/cattle": "",
+    "/mob/living/simple_animal/cattle/bull": "",
+    "/mob/living/simple_animal/cattle/cow": "",
+    "/mob/living/simple_animal/chick": "",
+    "/mob/living/simple_animal/chicken": "",
+    "/mob/living/simple_animal/civilian": "",
+    "/mob/living/simple_animal/civilian/afghan": "",
+    "/mob/living/simple_animal/civilian/afghan/city": "",
+    "/mob/living/simple_animal/civilian/afghan/woman": "",
+    "/mob/living/simple_animal/civilian/greenistani_ambassador": "",
+    "/mob/living/simple_animal/cockroach": "",
+    "/mob/living/simple_animal/complex_animal/dog/beagle": "",
+    "/mob/living/simple_animal/complex_animal/dog/bullterrier": "",
+    "/mob/living/simple_animal/complex_animal/dog/german_shepherd": "",
+    "/mob/living/simple_animal/complex_animal/dog/pug": "",
+    "/mob/living/simple_animal/complex_animal/dog/samoyed": "",
+    "/mob/living/simple_animal/complex_animal/dog/samoyed/russian": "",
+    "/mob/living/simple_animal/crab": "",
+    "/mob/living/simple_animal/crab/small": "",
+    "/mob/living/simple_animal/crab/small/crab_san": "",
+    "/mob/living/simple_animal/crab/small/dead": "",
+    "/mob/living/simple_animal/crab/small/trilobite": "",
+    "/mob/living/simple_animal/crow": "",
+    "/mob/living/simple_animal/deer": "",
+    "/mob/living/simple_animal/deer/dikdik/female": "",
+    "/mob/living/simple_animal/deer/dikdik/male": "",
+    "/mob/living/simple_animal/deer/elk/female": "",
+    "/mob/living/simple_animal/deer/elk/male": "",
+    "/mob/living/simple_animal/deer/female": "",
+    "/mob/living/simple_animal/deer/male": "",
+    "/mob/living/simple_animal/deer/reindeer/female": "",
+    "/mob/living/simple_animal/deer/reindeer/male": "",
+    "/mob/living/simple_animal/dog": "",
+    "/mob/living/simple_animal/fly": "",
+    "/mob/living/simple_animal/frog": "",
+    "/mob/living/simple_animal/frog/poisonous": "",
+    "/mob/living/simple_animal/goat": "",
+    "/mob/living/simple_animal/goat/female": "",
+    "/mob/living/simple_animal/goose": "",
+    "/mob/living/simple_animal/horse": "",
+    "/mob/living/simple_animal/horse/beige": "",
+    "/mob/living/simple_animal/horse/black": "",
+    "/mob/living/simple_animal/horse/white": "",
+    "/mob/living/simple_animal/hostage": "",
+    "/mob/living/simple_animal/hostile/alligator": "",
+    "/mob/living/simple_animal/hostile/bear": "",
+    "/mob/living/simple_animal/hostile/bear/boar/black": "",
+    "/mob/living/simple_animal/hostile/bear/boar/brown": "",
+    "/mob/living/simple_animal/hostile/bear/sow/black": "",
+    "/mob/living/simple_animal/hostile/bear/sow/brown": "",
+    "/mob/living/simple_animal/hostile/bear/sow/polar": "",
+    "/mob/living/simple_animal/hostile/commanded/bear": "",
+    "/mob/living/simple_animal/hostile/commanded/dog": "",
+    "/mob/living/simple_animal/hostile/dinosaur/compsognathus": "",
+    "/mob/living/simple_animal/hostile/dinosaur/dimetrodon": "",
+    "/mob/living/simple_animal/hostile/dinosaur/pachycephalosaurus": "",
+    "/mob/living/simple_animal/hostile/dinosaur/trex": "",
+    "/mob/living/simple_animal/hostile/dinosaur/velociraptor": "",
+    "/mob/living/simple_animal/hostile/fox": "",
+    "/mob/living/simple_animal/hostile/fox/arctic": "",
+    "/mob/living/simple_animal/hostile/gorilla/gigantopithecus/yeti": "",
+    "/mob/living/simple_animal/hostile/groundsloth": "",
+    "/mob/living/simple_animal/hostile/human/bandit": "",
+    "/mob/living/simple_animal/hostile/human/native": "",
+    "/mob/living/simple_animal/hostile/human/native/bigboi": "",
+    "/mob/living/simple_animal/hostile/human/native/ranged": "",
+    "/mob/living/simple_animal/hostile/human/pmc": "",
+    "/mob/living/simple_animal/hostile/human/redmenian_ng": "",
+    "/mob/living/simple_animal/hostile/human/redmenian_ng/medic": "",
+    "/mob/living/simple_animal/hostile/human/redmenian_ng/sl": "",
+    "/mob/living/simple_animal/hostile/human/rf_soldier": "",
+    "/mob/living/simple_animal/hostile/human/rf_soldier/sniper": "",
+    "/mob/living/simple_animal/hostile/human/skeleton": "",
+    "/mob/living/simple_animal/hostile/human/skeleton/attacker": "",
+    "/mob/living/simple_animal/hostile/human/skeleton/draugr": "",
+    "/mob/living/simple_animal/hostile/human/skeleton/pirate": "",
+    "/mob/living/simple_animal/hostile/human/voyage/barmaiden": "",
+    "/mob/living/simple_animal/hostile/human/voyage/british": "",
+    "/mob/living/simple_animal/hostile/human/voyage/british/ranged": "",
+    "/mob/living/simple_animal/hostile/human/voyage/civilian": "",
+    "/mob/living/simple_animal/hostile/human/voyage/civilian_f": "",
+    "/mob/living/simple_animal/hostile/human/voyage/merchant": "",
+    "/mob/living/simple_animal/hostile/human/voyage/pirate": "",
+    "/mob/living/simple_animal/hostile/human/voyage/pirate/friendly": "",
+    "/mob/living/simple_animal/hostile/human/voyage/pirate/friendly/blindman": "",
+    "/mob/living/simple_animal/hostile/human/voyage/pirate/friendly/captain": "",
+    "/mob/living/simple_animal/hostile/human/voyage/pirate/friendly/female": "",
+    "/mob/living/simple_animal/hostile/human/voyage/pirate/ranged": "",
+    "/mob/living/simple_animal/hostile/human/voyage/pirate/ranged/captain": "",
+    "/mob/living/simple_animal/hostile/human/voyage/slave": "",
+    "/mob/living/simple_animal/hostile/human/voyage/slaver": "",
+    "/mob/living/simple_animal/hostile/human/voyage/slaver/club": "",
+    "/mob/living/simple_animal/hostile/human/voyage/spanish": "",
+    "/mob/living/simple_animal/hostile/human/voyage/spanish/ranged": "",
+    "/mob/living/simple_animal/hostile/human/voyage/spanish/ranged/cpt": "",
+    "/mob/living/simple_animal/hostile/human/voyage/spanish/ranged/lt": "",
+    "/mob/living/simple_animal/hostile/human/voyage/spanish/ranged/sgt": "",
+    "/mob/living/simple_animal/hostile/human/ww2_american": "",
+    "/mob/living/simple_animal/hostile/human/ww2_american/medic": "",
+    "/mob/living/simple_animal/hostile/human/ww2_american/mg": "",
+    "/mob/living/simple_animal/hostile/human/ww2_jap": "",
+    "/mob/living/simple_animal/hostile/human/ww2_jap/mg": "",
+    "/mob/living/simple_animal/hostile/human/ww2_jap/squad_leader": "",
+    "/mob/living/simple_animal/hostile/human/ww2_jap/summer": "",
+    "/mob/living/simple_animal/hostile/human/ww2_jap/summer/medic": "",
+    "/mob/living/simple_animal/hostile/human/zombie": "",
+    "/mob/living/simple_animal/hostile/mammoth": "",
+    "/mob/living/simple_animal/hostile/mimic": "",
+    "/mob/living/simple_animal/hostile/mirelurk": "",
+    "/mob/living/simple_animal/hostile/panther": "",
+    "/mob/living/simple_animal/hostile/panther/jaguar": "",
+    "/mob/living/simple_animal/hostile/poison/snake": "",
+    "/mob/living/simple_animal/hostile/poison/snake/cobra": "",
+    "/mob/living/simple_animal/hostile/poison/snake/constrictor/python": "",
+    "/mob/living/simple_animal/hostile/sabertooth": "",
+    "/mob/living/simple_animal/hostile/sabertooth/lion": "",
+    "/mob/living/simple_animal/hostile/sabertooth/white": "",
+    "/mob/living/simple_animal/hostile/troll": "",
+    "/mob/living/simple_animal/hostile/wolf": "",
+    "/mob/living/simple_animal/hostile/wolf/female": "",
+    "/mob/living/simple_animal/hostile/wolf/white": "",
+    "/mob/living/simple_animal/hostile/wolf/white/female": "",
+    "/mob/living/simple_animal/ichthyostega": "",
+    "/mob/living/simple_animal/leech": "",
+    "/mob/living/simple_animal/lizard": "",
+    "/mob/living/simple_animal/monkey": "",
+    "/mob/living/simple_animal/monkey/kostas": "",
+    "/mob/living/simple_animal/mosquito": "",
+    "/mob/living/simple_animal/mouse": "",
+    "/mob/living/simple_animal/mouse/black": "",
+    "/mob/living/simple_animal/mouse/black/plague": "",
+    "/mob/living/simple_animal/mouse/brown": "",
+    "/mob/living/simple_animal/mouse/brown/Tom": "",
+    "/mob/living/simple_animal/mouse/gray": "",
+    "/mob/living/simple_animal/mouse/white": "",
+    "/mob/living/simple_animal/parrot": "",
+    "/mob/living/simple_animal/pelican": "",
+    "/mob/living/simple_animal/penguin": "",
+    "/mob/living/simple_animal/pig_boar": "",
+    "/mob/living/simple_animal/pig_gilt": "",
+    "/mob/living/simple_animal/rabbit": "",
+    "/mob/living/simple_animal/rooster": "",
+    "/mob/living/simple_animal/seagull": "",
+    "/mob/living/simple_animal/sheep": "",
+    "/mob/living/simple_animal/sheep/female": "",
+    "/mob/living/simple_animal/tiktaalik": "",
+    "/mob/living/simple_animal/turkey_f": "",
+    "/mob/living/simple_animal/turkey_m": "",
+    "/mob/living/simple_animal/vampirebatblack": "",
+    "/mob/new_player": "",
+    "/mob/observer/eye": "",
+    "/obj": "",
+    "/obj/covers": "",
+    "/obj/covers/brick_wall": "",
+    "/obj/covers/brick_wall/incomplete": "",
+    "/obj/covers/carpet": "",
+    "/obj/covers/carpet/arcade": "",
+    "/obj/covers/carpet/blackcarpet": "",
+    "/obj/covers/carpet/bluecarpet": "",
+    "/obj/covers/carpet/greencarpet": "",
+    "/obj/covers/carpet/orangecarpet": "",
+    "/obj/covers/carpet/purplecarpet": "",
+    "/obj/covers/carpet/redcarpet": "",
+    "/obj/covers/carpet/tealcarpet": "",
+    "/obj/covers/carpet/whitecarpet": "",
+    "/obj/covers/catwalk": "",
+    "/obj/covers/catwalk/dark": "",
+    "/obj/covers/cement_wall": "",
+    "/obj/covers/cement_wall/horizontal": "",
+    "/obj/covers/cement_wall/incomplete": "",
+    "/obj/covers/cement_wall/vertical": "",
+    "/obj/covers/clay_wall": "",
+    "/obj/covers/clay_wall/redearth_doorway": "",
+    "/obj/covers/clay_wall/sumerian": "",
+    "/obj/covers/clay_wall/sumerian/doorway": "",
+    "/obj/covers/clay_wall/sumerian/incomplete": "",
+    "/obj/covers/cobblestone": "",
+    "/obj/covers/cobblestone/stairs": "",
+    "/obj/covers/concretefloor": "",
+    "/obj/covers/decorative_marbletile": "",
+    "/obj/covers/decorative_marbletile/black": "",
+    "/obj/covers/dirt_wall": "",
+    "/obj/covers/dirt_wall/blocks": "",
+    "/obj/covers/disco": "",
+    "/obj/covers/divider_wall": "",
+    "/obj/covers/fancywood": "",
+    "/obj/covers/generic_wall": "",
+    "/obj/covers/jail": "",
+    "/obj/covers/jail/steeljail": "",
+    "/obj/covers/jail/woodjail": "",
+    "/obj/covers/marble_checkerboard": "",
+    "/obj/covers/marble_checkerboard/pink": "",
+    "/obj/covers/marble_checkerboard/pink/reverse": "",
+    "/obj/covers/marble_checkerboard/reverse": "",
+    "/obj/covers/marble_grid": "",
+    "/obj/covers/marble_wall/classic": "",
+    "/obj/covers/marble_wall/grecian": "",
+    "/obj/covers/marble_wall/grecian/archway": "",
+    "/obj/covers/marble_wall/grecian/archway/modern": "",
+    "/obj/covers/marblefloor": "",
+    "/obj/covers/marbletile": "",
+    "/obj/covers/marbletile/black": "",
+    "/obj/covers/marbletile/pink": "",
+    "/obj/covers/metal": "",
+    "/obj/covers/ornate_marbletile": "",
+    "/obj/covers/ornatemarblefloor": "",
+    "/obj/covers/ornatemarblefloor/black": "",
+    "/obj/covers/raw_marblefloor": "",
+    "/obj/covers/repairedfloor": "",
+    "/obj/covers/repairedfloor/rope": "",
+    "/obj/covers/repairedfloor/ship": "",
+    "/obj/covers/repairedfloor/ship/south": "",
+    "/obj/covers/repairedfloor/ship/three": "",
+    "/obj/covers/road": "",
+    "/obj/covers/road/whiteline": "",
+    "/obj/covers/road/yellowline": "",
+    "/obj/covers/roads": "",
+    "/obj/covers/roads/cobble": "",
+    "/obj/covers/roads/dirt": "",
+    "/obj/covers/roads/modern": "",
+    "/obj/covers/roads/roman": "",
+    "/obj/covers/roads/sandstone": "",
+    "/obj/covers/romanroad": "",
+    "/obj/covers/saloon_door": "",
+    "/obj/covers/sandstone": "",
+    "/obj/covers/sandstone/brick": "",
+    "/obj/covers/sandstone/slab": "",
+    "/obj/covers/sandstone/stairs": "",
+    "/obj/covers/sandstone/tile": "",
+    "/obj/covers/sandstone/tile/decorative": "",
+    "/obj/covers/sandstone_wall": "",
+    "/obj/covers/sandstone_wall/brick": "",
+    "/obj/covers/sandstone_wall/classic": "",
+    "/obj/covers/sandstone_wall/classic/archway": "",
+    "/obj/covers/shipwindow": "",
+    "/obj/covers/sidewalk": "",
+    "/obj/covers/slate": "",
+    "/obj/covers/slatefloor": "",
+    "/obj/covers/snow_wall": "",
+    "/obj/covers/sovietwall": "",
+    "/obj/covers/steelplating": "",
+    "/obj/covers/steelplating/white": "",
+    "/obj/covers/stone": "",
+    "/obj/covers/stone/slab/decorative": "",
+    "/obj/covers/stone_wall": "",
+    "/obj/covers/stone_wall/brick": "",
+    "/obj/covers/stone_wall/brick/archway": "",
+    "/obj/covers/stone_wall/classic": "",
+    "/obj/covers/stone_wall/classic/archway": "",
+    "/obj/covers/stone_wall/classic/archway/marble": "",
+    "/obj/covers/stone_wall/classic/villa/relief/aquila": "",
+    "/obj/covers/stone_wall/classic/villa/relief/greek": "",
+    "/obj/covers/stone_wall/fortress": "",
+    "/obj/covers/stone_wall/fortress/archway": "",
+    "/obj/covers/stone_wall/mayan": "",
+    "/obj/covers/stone_wall/roman": "",
+    "/obj/covers/stone_wall/roman/modern": "",
+    "/obj/covers/stonebrickfloor": "",
+    "/obj/covers/straw_wall": "",
+    "/obj/covers/tatami": "",
+    "/obj/covers/tatami_vertical": "",
+    "/obj/covers/tent": "",
+    "/obj/covers/thatch": "",
+    "/obj/covers/thatch2": "",
+    "/obj/covers/tiled_wall": "",
+    "/obj/covers/vault": "",
+    "/obj/covers/wood": "",
+    "/obj/covers/wood/alt": "",
+    "/obj/covers/wood/alt/eleven": "",
+    "/obj/covers/wood/alt/four": "",
+    "/obj/covers/wood/alt/nine": "",
+    "/obj/covers/wood/alt/six": "",
+    "/obj/covers/wood/alt/three": "",
+    "/obj/covers/wood/alt/two": "",
+    "/obj/covers/wood/stairs": "",
+    "/obj/covers/wood_ship": "",
+    "/obj/covers/wood_wall": "",
+    "/obj/covers/wood_wall/abashiri": "",
+    "/obj/covers/wood_wall/adjustable": "",
+    "/obj/covers/wood_wall/bamboo": "",
+    "/obj/covers/wood_wall/bamboo/door": "",
+    "/obj/covers/wood_wall/dark": "",
+    "/obj/covers/wood_wall/log": "",
+    "/obj/covers/wood_wall/log/corner": "",
+    "/obj/covers/wood_wall/medieval": "",
+    "/obj/covers/wood_wall/medieval/x": "",
+    "/obj/covers/wood_wall/medieval/y": "",
+    "/obj/covers/wood_wall/medieval/y/l": "",
+    "/obj/covers/wood_wall/medieval/y/r": "",
+    "/obj/covers/wood_wall/nordic": "",
+    "/obj/covers/wood_wall/shoji": "",
+    "/obj/covers/wood_wall/shoji_divider": "",
+    "/obj/effect/area_teleporter": "",
+    "/obj/effect/autoassembler": "",
+    "/obj/effect/bet_processor": "",
+    "/obj/effect/decal/cleanable/ash": "",
+    "/obj/effect/decal/cleanable/blood": "",
+    "/obj/effect/decal/cleanable/blood/drip": "",
+    "/obj/effect/decal/cleanable/blood/gibs": "",
+    "/obj/effect/decal/cleanable/blood/gibs/body": "",
+    "/obj/effect/decal/cleanable/blood/oil": "",
+    "/obj/effect/decal/cleanable/blood/oil/streak": "",
+    "/obj/effect/decal/cleanable/blood/splatter": "",
+    "/obj/effect/decal/cleanable/blood/tracks/footprints": "",
+    "/obj/effect/decal/cleanable/blood/writing": "",
+    "/obj/effect/decal/cleanable/cobweb": "",
+    "/obj/effect/decal/cleanable/cobweb2": "",
+    "/obj/effect/decal/cleanable/dirt": "",
+    "/obj/effect/decal/cleanable/flour": "",
+    "/obj/effect/decal/cleanable/fruit_smudge": "",
+    "/obj/effect/decal/cleanable/generic": "",
+    "/obj/effect/decal/cleanable/graffiti": "",
+    "/obj/effect/decal/cleanable/graffiti_grove": "",
+    "/obj/effect/decal/cleanable/greenglow": "",
+    "/obj/effect/decal/cleanable/molten_item": "",
+    "/obj/effect/decal/cleanable/mucus": "",
+    "/obj/effect/decal/cleanable/poo": "",
+    "/obj/effect/decal/cleanable/poo/drip": "",
+    "/obj/effect/decal/cleanable/urine": "",
+    "/obj/effect/decal/cleanable/vomit": "",
+    "/obj/effect/decal/cleanable/vomit/bloody": "",
+    "/obj/effect/decal/warning_stripes": "",
+    "/obj/effect/flooding": "",
+    "/obj/effect/floor_decal/borderfloor/full": "",
+    "/obj/effect/floor_decal/borderfloorblack/full": "",
+    "/obj/effect/floor_decal/carpet": "",
+    "/obj/effect/floor_decal/carpet/blue": "",
+    "/obj/effect/floor_decal/carpet/corners": "",
+    "/obj/effect/floor_decal/corner/black/border": "",
+    "/obj/effect/floor_decal/corner/black/diagonal": "",
+    "/obj/effect/floor_decal/corner/green/border": "",
+    "/obj/effect/floor_decal/corner/grey": "",
+    "/obj/effect/floor_decal/corner/paleblue/border": "",
+    "/obj/effect/floor_decal/corner/paleblue/bordercorner": "",
+    "/obj/effect/floor_decal/corner/red": "",
+    "/obj/effect/floor_decal/corner/red/border": "",
+    "/obj/effect/floor_decal/corner/red/bordercorner": "",
+    "/obj/effect/floor_decal/corner/red/diagonal": "",
+    "/obj/effect/floor_decal/corner/white/diagonal": "",
+    "/obj/effect/floor_decal/corner/yellow/border": "",
+    "/obj/effect/floor_decal/corner_kafel/green/diagonal": "",
+    "/obj/effect/floor_decal/corner_kafel/red/diagonal": "",
+    "/obj/effect/floor_decal/corner_kafel/white/diagonal": "",
+    "/obj/effect/floor_decal/corner_oldtile/blue/diagonal": "",
+    "/obj/effect/floor_decal/corner_oldtile/red": "",
+    "/obj/effect/floor_decal/corner_oldtile/red/diagonal": "",
+    "/obj/effect/floor_decal/corner_oldtile/red/full": "",
+    "/obj/effect/floor_decal/corner_steel_grid": "",
+    "/obj/effect/floor_decal/corner_steel_grid/diagonal": "",
+    "/obj/effect/floor_decal/corner_steel_grid/full": "",
+    "/obj/effect/floor_decal/desert_edge": "",
+    "/obj/effect/floor_decal/dirtwall": "",
+    "/obj/effect/floor_decal/dirtwall/inc33": "",
+    "/obj/effect/floor_decal/dirtwall/inc66": "",
+    "/obj/effect/floor_decal/grass_edge": "",
+    "/obj/effect/floor_decal/grass_edge/corner": "",
+    "/obj/effect/floor_decal/grass_edge/corner/dead": "",
+    "/obj/effect/floor_decal/grass_edge/dead": "",
+    "/obj/effect/floor_decal/industrial/danger": "",
+    "/obj/effect/floor_decal/industrial/danger/corner": "",
+    "/obj/effect/floor_decal/industrial/danger/full": "",
+    "/obj/effect/floor_decal/industrial/hatch": "",
+    "/obj/effect/floor_decal/industrial/hatch/yellow": "",
+    "/obj/effect/floor_decal/industrial/loading": "",
+    "/obj/effect/floor_decal/industrial/outline": "",
+    "/obj/effect/floor_decal/industrial/outline/blue": "",
+    "/obj/effect/floor_decal/industrial/outline/grey": "",
+    "/obj/effect/floor_decal/industrial/outline/yellow": "",
+    "/obj/effect/floor_decal/industrial/warning": "",
+    "/obj/effect/floor_decal/industrial/warning/cee": "",
+    "/obj/effect/floor_decal/industrial/warning/corner": "",
+    "/obj/effect/floor_decal/industrial/warning/dust": "",
+    "/obj/effect/floor_decal/industrial/warning/dust/corner": "",
+    "/obj/effect/floor_decal/industrial/warning/full": "",
+    "/obj/effect/floor_decal/plaque": "",
+    "/obj/effect/floor_decal/rust": "",
+    "/obj/effect/floor_decal/rust/color_rustedfull": "",
+    "/obj/effect/floor_decal/rust/mono_rusted3": "",
+    "/obj/effect/floor_decal/safensound": "",
+    "/obj/effect/floor_decal/sand_edge": "",
+    "/obj/effect/floor_decal/shipline": "",
+    "/obj/effect/floor_decal/spline/fancy": "",
+    "/obj/effect/floor_decal/spline/fancy/wood": "",
+    "/obj/effect/floor_decal/spline/fancy/wood/corner": "",
+    "/obj/effect/floor_decal/spline/fancy/wood/three_quarters": "",
+    "/obj/effect/floor_decal/spline/plain": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals_central1": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals_central2": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals_central3": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals_central4": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals_central5": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals_central6": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals_central7": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals10": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals2": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals3": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals4": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals5": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals6": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals7": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals8": "",
+    "/obj/effect/floor_decal/steeldecal/steel_decals9": "",
+    "/obj/effect/floor_decal/tatami": "",
+    "/obj/effect/floor_decal/tatami/angle": "",
+    "/obj/effect/floor_decal/tatami/cee": "",
+    "/obj/effect/floor_decal/tatami/corner": "",
+    "/obj/effect/floor_decal/tatami/full": "",
+    "/obj/effect/floor_decal/techfloor/hole": "",
+    "/obj/effect/floor_decal/techfloor/hole/right": "",
+    "/obj/effect/landmark": "",
+    "/obj/effect/landmark/npctarget": "",
+    "/obj/effect/landmark/npctarget/faction": "",
+    "/obj/effect/landmark/npctarget/faction/all": "",
+    "/obj/effect/landmark/npctarget/squad_spawner/japanese": "",
+    "/obj/effect/mist": "",
+    "/obj/effect/oil": "",
+    "/obj/effect/overlay/coconut": "",
+    "/obj/effect/overlay/palmtree_l": "",
+    "/obj/effect/overlay/palmtree_r": "",
+    "/obj/effect/sailing_effect": "",
+    "/obj/effect/spawner/ammospawner/arrow/bronze": "",
+    "/obj/effect/spawner/ammospawner/tomahawk": "",
+    "/obj/effect/spawner/lootdrop/ammo/industrial": "",
+    "/obj/effect/spawner/lootdrop/ammo/medieval": "",
+    "/obj/effect/spawner/lootdrop/armor/industrial": "",
+    "/obj/effect/spawner/lootdrop/armor/medieval": "",
+    "/obj/effect/spawner/lootdrop/guns/industrial": "",
+    "/obj/effect/spawner/lootdrop/guns/medieval": "",
+    "/obj/effect/spawner/lootdrop/melee": "",
+    "/obj/effect/spawner/lootdrop/melee/medieval": "",
+    "/obj/effect/spawner/mobspawner": "",
+    "/obj/effect/spawner/mobspawner/alligator": "",
+    "/obj/effect/spawner/mobspawner/attacker": "",
+    "/obj/effect/spawner/mobspawner/bat": "",
+    "/obj/effect/spawner/mobspawner/bears": "",
+    "/obj/effect/spawner/mobspawner/bears/brown": "",
+    "/obj/effect/spawner/mobspawner/bears/polar": "",
+    "/obj/effect/spawner/mobspawner/bears_f/brown": "",
+    "/obj/effect/spawner/mobspawner/boars": "",
+    "/obj/effect/spawner/mobspawner/boars_f": "",
+    "/obj/effect/spawner/mobspawner/buffalo": "",
+    "/obj/effect/spawner/mobspawner/camel": "",
+    "/obj/effect/spawner/mobspawner/cattle": "",
+    "/obj/effect/spawner/mobspawner/cattle/bull": "",
+    "/obj/effect/spawner/mobspawner/cattle/cow": "",
+    "/obj/effect/spawner/mobspawner/chicken": "",
+    "/obj/effect/spawner/mobspawner/chicken/rooster": "",
+    "/obj/effect/spawner/mobspawner/cockroach": "",
+    "/obj/effect/spawner/mobspawner/cockroach/nuclear": "",
+    "/obj/effect/spawner/mobspawner/compsognathus": "",
+    "/obj/effect/spawner/mobspawner/crab": "",
+    "/obj/effect/spawner/mobspawner/crab/trill": "",
+    "/obj/effect/spawner/mobspawner/deer": "",
+    "/obj/effect/spawner/mobspawner/deer/female": "",
+    "/obj/effect/spawner/mobspawner/deer/male": "",
+    "/obj/effect/spawner/mobspawner/dikdik_f": "",
+    "/obj/effect/spawner/mobspawner/dikdik_m": "",
+    "/obj/effect/spawner/mobspawner/dimetrodon": "",
+    "/obj/effect/spawner/mobspawner/elk_f": "",
+    "/obj/effect/spawner/mobspawner/elk_m": "",
+    "/obj/effect/spawner/mobspawner/fox": "",
+    "/obj/effect/spawner/mobspawner/fox/arctic": "",
+    "/obj/effect/spawner/mobspawner/frog": "",
+    "/obj/effect/spawner/mobspawner/frogpoisonous": "",
+    "/obj/effect/spawner/mobspawner/goats_f": "",
+    "/obj/effect/spawner/mobspawner/goats_m": "",
+    "/obj/effect/spawner/mobspawner/gorilla": "",
+    "/obj/effect/spawner/mobspawner/groundsloth": "",
+    "/obj/effect/spawner/mobspawner/horse": "",
+    "/obj/effect/spawner/mobspawner/horse/beige": "",
+    "/obj/effect/spawner/mobspawner/horse/black": "",
+    "/obj/effect/spawner/mobspawner/horse/white": "",
+    "/obj/effect/spawner/mobspawner/leech": "",
+    "/obj/effect/spawner/mobspawner/lion": "",
+    "/obj/effect/spawner/mobspawner/lizard": "",
+    "/obj/effect/spawner/mobspawner/mammoth": "",
+    "/obj/effect/spawner/mobspawner/monkeys": "",
+    "/obj/effect/spawner/mobspawner/mouse": "",
+    "/obj/effect/spawner/mobspawner/mouse/sm": "",
+    "/obj/effect/spawner/mobspawner/pachycephalosaurus": "",
+    "/obj/effect/spawner/mobspawner/panthers": "",
+    "/obj/effect/spawner/mobspawner/panthers/jaguar": "",
+    "/obj/effect/spawner/mobspawner/parrot": "",
+    "/obj/effect/spawner/mobspawner/penguins": "",
+    "/obj/effect/spawner/mobspawner/pig": "",
+    "/obj/effect/spawner/mobspawner/pig/gilt": "",
+    "/obj/effect/spawner/mobspawner/rabbits": "",
+    "/obj/effect/spawner/mobspawner/reindeer_f": "",
+    "/obj/effect/spawner/mobspawner/reindeer_m": "",
+    "/obj/effect/spawner/mobspawner/seagull": "",
+    "/obj/effect/spawner/mobspawner/sheep_f": "",
+    "/obj/effect/spawner/mobspawner/sheep_m": "",
+    "/obj/effect/spawner/mobspawner/skeletons": "",
+    "/obj/effect/spawner/mobspawner/skeletons/off": "",
+    "/obj/effect/spawner/mobspawner/snake": "",
+    "/obj/effect/spawner/mobspawner/snake/cobra": "",
+    "/obj/effect/spawner/mobspawner/snake/python": "",
+    "/obj/effect/spawner/mobspawner/townmilitia": "",
+    "/obj/effect/spawner/mobspawner/trex": "",
+    "/obj/effect/spawner/mobspawner/troll": "",
+    "/obj/effect/spawner/mobspawner/turkeys": "",
+    "/obj/effect/spawner/mobspawner/turkeys_f": "",
+    "/obj/effect/spawner/mobspawner/velociraptor": "",
+    "/obj/effect/spawner/mobspawner/velociraptor/on": "",
+    "/obj/effect/spawner/mobspawner/wolves": "",
+    "/obj/effect/spawner/mobspawner/wolves/white": "",
+    "/obj/effect/spawner/mobspawner/ww2/american": "",
+    "/obj/effect/spawner/mobspawner/ww2/american/lead": "",
+    "/obj/effect/spawner/mobspawner/ww2/american/medic": "",
+    "/obj/effect/spawner/mobspawner/ww2/american/mg": "",
+    "/obj/effect/spawner/mobspawner/zombies/many": "",
+    "/obj/effect/spawner/mobspawner/zombies/special": "",
+    "/obj/effect/spawner/objective_spawner": "",
+    "/obj/effect/spawner/objspawner/acacia": "",
+    "/obj/effect/spawner/objspawner/bamboo": "",
+    "/obj/effect/spawner/objspawner/cinchona": "",
+    "/obj/effect/spawner/objspawner/door/blue": "",
+    "/obj/effect/spawner/objspawner/door/green": "",
+    "/obj/effect/spawner/objspawner/door/police": "",
+    "/obj/effect/spawner/objspawner/door/red": "",
+    "/obj/effect/spawner/objspawner/door/yellow": "",
+    "/obj/effect/spawner/objspawner/jungle": "",
+    "/obj/effect/spawner/objspawner/m13": "",
+    "/obj/effect/spawner/objspawner/m1a1_abrams": "",
+    "/obj/effect/spawner/objspawner/medpine": "",
+    "/obj/effect/spawner/objspawner/palm": "",
+    "/obj/effect/spawner/objspawner/pine": "",
+    "/obj/effect/spawner/objspawner/pine/snow": "",
+    "/obj/effect/spawner/objspawner/tree": "",
+    "/obj/effect/spawner/objspawner/tree/snow": "",
+    "/obj/effect/spawner/orespawner": "",
+    "/obj/effect/step_trigger/goal/blue": "",
+    "/obj/effect/step_trigger/goal/red": "",
+    "/obj/effects/premadevehicles/apc/bmd2": "",
+    "/obj/effects/premadevehicles/apc/bradley/green": "",
+    "/obj/effects/premadevehicles/apc/btr80": "",
+    "/obj/effects/premadevehicles/apc/m113": "",
+    "/obj/effects/premadevehicles/apc/mtlb": "",
+    "/obj/effects/premadevehicles/asno/quattroporte": "",
+    "/obj/effects/premadevehicles/car/mercedes/mg": "",
+    "/obj/effects/premadevehicles/car/tigr/mg": "",
+    "/obj/effects/premadevehicles/isuzu/type94": "",
+    "/obj/effects/premadevehicles/kurogane/type95": "",
+    "/obj/effects/premadevehicles/smc/falcon": "",
+    "/obj/effects/premadevehicles/smc/wyoming": "",
+    "/obj/effects/premadevehicles/tank/baf1_a": "",
+    "/obj/effects/premadevehicles/tank/bmv1": "",
+    "/obj/effects/premadevehicles/tank/hago": "",
+    "/obj/effects/premadevehicles/tank/l3": "",
+    "/obj/effects/premadevehicles/tank/l3/antitank": "",
+    "/obj/effects/premadevehicles/tank/omw22_2": "",
+    "/obj/effects/premadevehicles/tank/panzeriv": "",
+    "/obj/effects/premadevehicles/tank/smf1": "",
+    "/obj/effects/premadevehicles/tank/t34": "",
+    "/obj/effects/premadevehicles/tank/t72": "",
+    "/obj/effects/premadevehicles/truck/daf": "",
+    "/obj/effects/premadevehicles/truck/kamaz": "",
+    "/obj/effects/premadevehicles/ubermacht/erstenklasse": "",
+    "/obj/effects/premadevehicles/yamasaki/kazoku": "",
+    "/obj/effects/premadevehicles/yamasaki/shinobu": "",
+    "/obj/item/ammo_casing/a44magnum": "",
+    "/obj/item/ammo_casing/a45": "",
+    "/obj/item/ammo_casing/a4570": "",
+    "/obj/item/ammo_casing/a545x39": "",
+    "/obj/item/ammo_casing/a556x45": "",
+    "/obj/item/ammo_casing/a577": "",
+    "/obj/item/ammo_casing/a762x38": "",
+    "/obj/item/ammo_casing/a762x39": "",
+    "/obj/item/ammo_casing/a8x27": "",
+    "/obj/item/ammo_casing/arrow": "",
+    "/obj/item/ammo_casing/arrow/bronze": "",
+    "/obj/item/ammo_casing/arrow/iron": "",
+    "/obj/item/ammo_casing/arrow/modern": "",
+    "/obj/item/ammo_casing/arrow/stone": "",
+    "/obj/item/ammo_casing/blunderbuss": "",
+    "/obj/item/ammo_casing/bolt/iron": "",
+    "/obj/item/ammo_casing/bolt/steel": "",
+    "/obj/item/ammo_casing/musketball": "",
+    "/obj/item/ammo_casing/musketball_pistol": "",
+    "/obj/item/ammo_casing/rocket": "",
+    "/obj/item/ammo_casing/rocket/atgm": "",
+    "/obj/item/ammo_casing/rocket/atgm/he": "",
+    "/obj/item/ammo_casing/rocket/bazooka": "",
+    "/obj/item/ammo_casing/rocket/og7v": "",
+    "/obj/item/ammo_casing/rocket/pg7v": "",
+    "/obj/item/ammo_casing/rocket/piat": "",
+    "/obj/item/ammo_casing/rocket/piat/mk3": "",
+    "/obj/item/ammo_casing/shotgun": "",
+    "/obj/item/ammo_casing/shotgun/beanbag": "",
+    "/obj/item/ammo_casing/shotgun/buckshot": "",
+    "/obj/item/ammo_casing/shotgun/slug": "",
+    "/obj/item/ammo_casing/stone": "",
+    "/obj/item/ammo_casing/stoneball": "",
+    "/obj/item/ammo_casing/webly445": "",
+    "/obj/item/ammo_magazine/a30mm_ap": "",
+    "/obj/item/ammo_magazine/a30mm_he": "",
+    "/obj/item/ammo_magazine/a45acpbox": "",
+    "/obj/item/ammo_magazine/a50cal": "",
+    "/obj/item/ammo_magazine/a50cal_can": "",
+    "/obj/item/ammo_magazine/ak47": "",
+    "/obj/item/ammo_magazine/ak47/makeshift": "",
+    "/obj/item/ammo_magazine/ak74": "",
+    "/obj/item/ammo_magazine/ak74/ak74m": "",
+    "/obj/item/ammo_magazine/ak74/box": "",
+    "/obj/item/ammo_magazine/ak74/rubber": "",
+    "/obj/item/ammo_magazine/ammo127": "",
+    "/obj/item/ammo_magazine/ammo127/box": "",
+    "/obj/item/ammo_magazine/ar10": "",
+    "/obj/item/ammo_magazine/ar12": "",
+    "/obj/item/ammo_magazine/ar15": "",
+    "/obj/item/ammo_magazine/arisaka": "",
+    "/obj/item/ammo_magazine/arisaka99": "",
+    "/obj/item/ammo_magazine/arisaka99_training": "",
+    "/obj/item/ammo_magazine/arisakabox": "",
+    "/obj/item/ammo_magazine/arisakabox99": "",
+    "/obj/item/ammo_magazine/avtomat": "",
+    "/obj/item/ammo_magazine/b762": "",
+    "/obj/item/ammo_magazine/bar": "",
+    "/obj/item/ammo_magazine/barrett": "",
+    "/obj/item/ammo_magazine/browning": "",
+    "/obj/item/ammo_magazine/browninghp": "",
+    "/obj/item/ammo_magazine/c32": "",
+    "/obj/item/ammo_magazine/c38": "",
+    "/obj/item/ammo_magazine/c43": "",
+    "/obj/item/ammo_magazine/c44": "",
+    "/obj/item/ammo_magazine/c44magnum": "",
+    "/obj/item/ammo_magazine/c45": "",
+    "/obj/item/ammo_magazine/c455": "",
+    "/obj/item/ammo_magazine/c577": "",
+    "/obj/item/ammo_magazine/c762x25_pps": "",
+    "/obj/item/ammo_magazine/c762x25_ppsh": "",
+    "/obj/item/ammo_magazine/c762x38mmR": "",
+    "/obj/item/ammo_magazine/c8mmnambu": "",
+    "/obj/item/ammo_magazine/c8x27": "",
+    "/obj/item/ammo_magazine/c8x50": "",
+    "/obj/item/ammo_magazine/c8x50_3clip": "",
+    "/obj/item/ammo_magazine/c8x50_5clip": "",
+    "/obj/item/ammo_magazine/c9mm": "",
+    "/obj/item/ammo_magazine/c9mm_jap_revolver": "",
+    "/obj/item/ammo_magazine/carcano": "",
+    "/obj/item/ammo_magazine/chemdart/mag": "",
+    "/obj/item/ammo_magazine/dp": "",
+    "/obj/item/ammo_magazine/dp/dt": "",
+    "/obj/item/ammo_magazine/emptybelt/filled_556x45": "",
+    "/obj/item/ammo_magazine/emptybelt/filled_762x54": "",
+    "/obj/item/ammo_magazine/emptyclip": "",
+    "/obj/item/ammo_magazine/emptymagazine": "",
+    "/obj/item/ammo_magazine/emptymagazine/pistol": "",
+    "/obj/item/ammo_magazine/emptymagazine/rifle/ak47/filled": "",
+    "/obj/item/ammo_magazine/emptymagazine/rifle/m16/filled": "",
+    "/obj/item/ammo_magazine/emptypouch": "",
+    "/obj/item/ammo_magazine/enfield": "",
+    "/obj/item/ammo_magazine/enfield_box": "",
+    "/obj/item/ammo_magazine/fal": "",
+    "/obj/item/ammo_magazine/fg42": "",
+    "/obj/item/ammo_magazine/fg42/small": "",
+    "/obj/item/ammo_magazine/g43": "",
+    "/obj/item/ammo_magazine/garand": "",
+    "/obj/item/ammo_magazine/gewehr71": "",
+    "/obj/item/ammo_magazine/gewehr71box": "",
+    "/obj/item/ammo_magazine/gewehr98": "",
+    "/obj/item/ammo_magazine/gewehr98box": "",
+    "/obj/item/ammo_magazine/glock17": "",
+    "/obj/item/ammo_magazine/greasegun": "",
+    "/obj/item/ammo_magazine/greasegun/box": "",
+    "/obj/item/ammo_magazine/hk": "",
+    "/obj/item/ammo_magazine/hotchkiss": "",
+    "/obj/item/ammo_magazine/jericho": "",
+    "/obj/item/ammo_magazine/luger": "",
+    "/obj/item/ammo_magazine/m14": "",
+    "/obj/item/ammo_magazine/m16": "",
+    "/obj/item/ammo_magazine/m16/box": "",
+    "/obj/item/ammo_magazine/m1911": "",
+    "/obj/item/ammo_magazine/m1911/empty": "",
+    "/obj/item/ammo_magazine/m1carbine": "",
+    "/obj/item/ammo_magazine/m1carbine/big": "",
+    "/obj/item/ammo_magazine/m1carbine/box": "",
+    "/obj/item/ammo_magazine/m24": "",
+    "/obj/item/ammo_magazine/m249": "",
+    "/obj/item/ammo_magazine/m3006box": "",
+    "/obj/item/ammo_magazine/m9beretta": "",
+    "/obj/item/ammo_magazine/mac10": "",
+    "/obj/item/ammo_magazine/madsen": "",
+    "/obj/item/ammo_magazine/madsen/box": "",
+    "/obj/item/ammo_magazine/makarov": "",
+    "/obj/item/ammo_magazine/mauser": "",
+    "/obj/item/ammo_magazine/mauser1893": "",
+    "/obj/item/ammo_magazine/mauser1893box": "",
+    "/obj/item/ammo_magazine/maxim": "",
+    "/obj/item/ammo_magazine/mg34": "",
+    "/obj/item/ammo_magazine/mg34belt": "",
+    "/obj/item/ammo_magazine/mg3belt": "",
+    "/obj/item/ammo_magazine/mk18": "",
+    "/obj/item/ammo_magazine/mosin": "",
+    "/obj/item/ammo_magazine/mosinbox": "",
+    "/obj/item/ammo_magazine/mp40": "",
+    "/obj/item/ammo_magazine/mp40/box": "",
+    "/obj/item/ammo_magazine/mp40/erma": "",
+    "/obj/item/ammo_magazine/mp40/modello38": "",
+    "/obj/item/ammo_magazine/mp40/mp5": "",
+    "/obj/item/ammo_magazine/mp443": "",
+    "/obj/item/ammo_magazine/murata": "",
+    "/obj/item/ammo_magazine/murata_box": "",
+    "/obj/item/ammo_magazine/negev": "",
+    "/obj/item/ammo_magazine/p220": "",
+    "/obj/item/ammo_magazine/p90": "",
+    "/obj/item/ammo_magazine/pkm": "",
+    "/obj/item/ammo_magazine/pkm = 8": "",
+    "/obj/item/ammo_magazine/pkm/c100": "",
+    "/obj/item/ammo_magazine/pkm/c100 = 25": "",
+    "/obj/item/ammo_magazine/ptrd_box": "",
+    "/obj/item/ammo_magazine/ptrd_box/ap": "",
+    "/obj/item/ammo_magazine/ptrd_pouch": "",
+    "/obj/item/ammo_magazine/ptrd_pouch/ap": "",
+    "/obj/item/ammo_magazine/pzb_case": "",
+    "/obj/item/ammo_magazine/pzb_case_ap": "",
+    "/obj/item/ammo_magazine/pzb_pouch": "",
+    "/obj/item/ammo_magazine/pzb_pouch_ap": "",
+    "/obj/item/ammo_magazine/rpd": "",
+    "/obj/item/ammo_magazine/rpk47": "",
+    "/obj/item/ammo_magazine/rpk74": "",
+    "/obj/item/ammo_magazine/rpk74/drum": "",
+    "/obj/item/ammo_magazine/saiga12": "",
+    "/obj/item/ammo_magazine/scarh": "",
+    "/obj/item/ammo_magazine/sharps": "",
+    "/obj/item/ammo_magazine/shellbox": "",
+    "/obj/item/ammo_magazine/shellbox/beanbag": "",
+    "/obj/item/ammo_magazine/shellbox/rubber": "",
+    "/obj/item/ammo_magazine/shellbox/slug": "",
+    "/obj/item/ammo_magazine/sks": "",
+    "/obj/item/ammo_magazine/sksm": "",
+    "/obj/item/ammo_magazine/springfield": "",
+    "/obj/item/ammo_magazine/sten2": "",
+    "/obj/item/ammo_magazine/stg": "",
+    "/obj/item/ammo_magazine/sti2011": "",
+    "/obj/item/ammo_magazine/svd": "",
+    "/obj/item/ammo_magazine/svd = 25": "",
+    "/obj/item/ammo_magazine/svt": "",
+    "/obj/item/ammo_magazine/tec9": "",
+    "/obj/item/ammo_magazine/thompson": "",
+    "/obj/item/ammo_magazine/tibannagas/dc17": "",
+    "/obj/item/ammo_magazine/tibannagas/repeating_blaster": "",
+    "/obj/item/ammo_magazine/tibannagas/westar34": "",
+    "/obj/item/ammo_magazine/tommy": "",
+    "/obj/item/ammo_magazine/tt30": "",
+    "/obj/item/ammo_magazine/tt30 = 15": "",
+    "/obj/item/ammo_magazine/tt30/empty": "",
+    "/obj/item/ammo_magazine/tt30ll/rubber": "",
+    "/obj/item/ammo_magazine/type100": "",
+    "/obj/item/ammo_magazine/type3": "",
+    "/obj/item/ammo_magazine/type92": "",
+    "/obj/item/ammo_magazine/type99": "",
+    "/obj/item/ammo_magazine/type99/type97": "",
+    "/obj/item/ammo_magazine/usas12": "",
+    "/obj/item/ammo_magazine/usas12/slug": "",
+    "/obj/item/ammo_magazine/usas12drum": "",
+    "/obj/item/ammo_magazine/usas12drum/slug": "",
+    "/obj/item/ammo_magazine/uzi": "",
+    "/obj/item/ammo_magazine/vickers": "",
+    "/obj/item/ammo_magazine/vintorez": "",
+    "/obj/item/ammo_magazine/walther": "",
+    "/obj/item/ammo_magazine/walther/empty": "",
+    "/obj/item/ammo_magazine/webly445": "",
+    "/obj/item/bag_valve_mask": "",
+    "/obj/item/blueprint/gun/ak103": "",
+    "/obj/item/blueprint/gun/arisaka": "",
+    "/obj/item/blueprint/gun/m4": "",
+    "/obj/item/bodybag": "",
+    "/obj/item/camera": "",
+    "/obj/item/camera/coldwar": "",
+    "/obj/item/camera/early": "",
+    "/obj/item/camera/earlymodern": "",
+    "/obj/item/camera_film": "",
+    "/obj/item/cannon_ball/chainshot": "",
+    "/obj/item/cannon_ball/grapeshot": "",
+    "/obj/item/cannon_ball/mortar_shell": "",
+    "/obj/item/cannon_ball/mortar_shell/incendiary": "",
+    "/obj/item/cannon_ball/mortar_shell/smoke": "",
+    "/obj/item/cannon_ball/mortar_shell/type89": "",
+    "/obj/item/cannon_ball/rocket": "",
+    "/obj/item/cannon_ball/rocket/incendiary": "",
+    "/obj/item/cannon_ball/shell": "",
+    "/obj/item/cannon_ball/shell/gas/chlorine": "",
+    "/obj/item/cannon_ball/shell/gas/mustard": "",
+    "/obj/item/cannon_ball/shell/gas/phosgene": "",
+    "/obj/item/cannon_ball/shell/gas/white_phosphorus": "",
+    "/obj/item/cannon_ball/shell/gas/xylyl_bromide": "",
+    "/obj/item/cannon_ball/shell/gas/zyklon_b": "",
+    "/obj/item/cannon_ball/shell/naval/HE150": "",
+    "/obj/item/cannon_ball/shell/naval/HE380": "",
+    "/obj/item/cannon_ball/shell/nuclear/W9": "",
+    "/obj/item/cannon_ball/shell/tank/AP100": "",
+    "/obj/item/cannon_ball/shell/tank/AP76": "",
+    "/obj/item/cannon_ball/shell/tank/AP85": "",
+    "/obj/item/cannon_ball/shell/tank/AP88": "",
+    "/obj/item/cannon_ball/shell/tank/APCR100": "",
+    "/obj/item/cannon_ball/shell/tank/APCR76": "",
+    "/obj/item/cannon_ball/shell/tank/APCR85": "",
+    "/obj/item/cannon_ball/shell/tank/APCR88": "",
+    "/obj/item/cannon_ball/shell/tank/HE100": "",
+    "/obj/item/cannon_ball/shell/tank/HE57": "",
+    "/obj/item/cannon_ball/shell/tank/HE76": "",
+    "/obj/item/cannon_ball/shell/tank/HE85": "",
+    "/obj/item/cannon_ball/shell/tank/HE88": "",
+    "/obj/item/catapult_ball": "",
+    "/obj/item/clothing/accessory/armband": "",
+    "/obj/item/clothing/accessory/armband/armbangle/gold": "",
+    "/obj/item/clothing/accessory/armband/blue_scarf": "",
+    "/obj/item/clothing/accessory/armband/british": "",
+    "/obj/item/clothing/accessory/armband/british_scarf": "",
+    "/obj/item/clothing/accessory/armband/deputy": "",
+    "/obj/item/clothing/accessory/armband/dutch": "",
+    "/obj/item/clothing/accessory/armband/french": "",
+    "/obj/item/clothing/accessory/armband/grey_scarf": "",
+    "/obj/item/clothing/accessory/armband/indian1": "",
+    "/obj/item/clothing/accessory/armband/indian2": "",
+    "/obj/item/clothing/accessory/armband/indiang": "",
+    "/obj/item/clothing/accessory/armband/indianr": "",
+    "/obj/item/clothing/accessory/armband/indianshaman": "",
+    "/obj/item/clothing/accessory/armband/japanese": "",
+    "/obj/item/clothing/accessory/armband/kenpeitai": "",
+    "/obj/item/clothing/accessory/armband/nsdap": "",
+    "/obj/item/clothing/accessory/armband/poland": "",
+    "/obj/item/clothing/accessory/armband/policebadge": "",
+    "/obj/item/clothing/accessory/armband/portuguese": "",
+    "/obj/item/clothing/accessory/armband/punk": "",
+    "/obj/item/clothing/accessory/armband/red_scarf": "",
+    "/obj/item/clothing/accessory/armband/redcross": "",
+    "/obj/item/clothing/accessory/armband/sheriff": "",
+    "/obj/item/clothing/accessory/armband/spanish": "",
+    "/obj/item/clothing/accessory/armband/talisman": "",
+    "/obj/item/clothing/accessory/armband/yellow_scarf": "",
+    "/obj/item/clothing/accessory/armor/armguards": "",
+    "/obj/item/clothing/accessory/armor/coldwar/flakjacket": "",
+    "/obj/item/clothing/accessory/armor/coldwar/flakjacket/b1": "",
+    "/obj/item/clothing/accessory/armor/coldwar/flakjacket/m1969": "",
+    "/obj/item/clothing/accessory/armor/coldwar/pasgt": "",
+    "/obj/item/clothing/accessory/armor/coldwar/pasgt/blizzard": "",
+    "/obj/item/clothing/accessory/armor/coldwar/pasgt/green": "",
+    "/obj/item/clothing/accessory/armor/coldwar/pasgt/khaki": "",
+    "/obj/item/clothing/accessory/armor/coldwar/plates/b2": "",
+    "/obj/item/clothing/accessory/armor/coldwar/plates/b3": "",
+    "/obj/item/clothing/accessory/armor/coldwar/plates/b5": "",
+    "/obj/item/clothing/accessory/armor/coldwar/plates/interceptor": "",
+    "/obj/item/clothing/accessory/armor/coldwar/plates/platecarriergreen": "",
+    "/obj/item/clothing/accessory/armor/elbow_protections": "",
+    "/obj/item/clothing/accessory/armor/knee_protections": "",
+    "/obj/item/clothing/accessory/armor/legguards": "",
+    "/obj/item/clothing/accessory/armor/modern/british": "",
+    "/obj/item/clothing/accessory/armor/modern/lightplate/black": "",
+    "/obj/item/clothing/accessory/armor/modern/lightplate/black/lead": "",
+    "/obj/item/clothing/accessory/armor/modern/lightplate/lead": "",
+    "/obj/item/clothing/accessory/armor/modern/plate": "",
+    "/obj/item/clothing/accessory/armor/nomads/baily": "",
+    "/obj/item/clothing/accessory/armor/nomads/civiliankevlar": "",
+    "/obj/item/clothing/accessory/armor/nomads/civiliankevlar/under": "",
+    "/obj/item/clothing/accessory/armor/nomads/kevlarblack": "",
+    "/obj/item/clothing/accessory/armor/nomads/pcarriertan": "",
+    "/obj/item/clothing/accessory/armor/nomads/thickcarrier": "",
+    "/obj/item/clothing/accessory/catears": "",
+    "/obj/item/clothing/accessory/custom/apron": "",
+    "/obj/item/clothing/accessory/custom/armband": "",
+    "/obj/item/clothing/accessory/custom/bowtie": "",
+    "/obj/item/clothing/accessory/custom/cape": "",
+    "/obj/item/clothing/accessory/custom/priest_band": "",
+    "/obj/item/clothing/accessory/custom/sash": "",
+    "/obj/item/clothing/accessory/custom/scarf": "",
+    "/obj/item/clothing/accessory/custom/tabard": "",
+    "/obj/item/clothing/accessory/custom/tie": "",
+    "/obj/item/clothing/accessory/holster": "",
+    "/obj/item/clothing/accessory/holster/armpit": "",
+    "/obj/item/clothing/accessory/holster/chest": "",
+    "/obj/item/clothing/accessory/holster/hip": "",
+    "/obj/item/clothing/accessory/holster/hip/double": "",
+    "/obj/item/clothing/accessory/holster/tactical": "",
+    "/obj/item/clothing/accessory/holster/waist": "",
+    "/obj/item/clothing/accessory/locket": "",
+    "/obj/item/clothing/accessory/medal/american/combat_medical_badge": "",
+    "/obj/item/clothing/accessory/medal/bronze": "",
+    "/obj/item/clothing/accessory/medal/german/ww1/iron_cross_2nd": "",
+    "/obj/item/clothing/accessory/medal/german/ww2/assault_badge": "",
+    "/obj/item/clothing/accessory/medal/german/ww2/eastern_front": "",
+    "/obj/item/clothing/accessory/medal/german/ww2/iron_cross_1st": "",
+    "/obj/item/clothing/accessory/medal/german/ww2/iron_cross_knight_oak": "",
+    "/obj/item/clothing/accessory/medal/german/ww2/nazi_pin": "",
+    "/obj/item/clothing/accessory/medal/german/ww2/nsdap_pin": "",
+    "/obj/item/clothing/accessory/medal/german/ww2/ss_sadler": "",
+    "/obj/item/clothing/accessory/medal/german/ww2/totenkopf": "",
+    "/obj/item/clothing/accessory/medal/gold": "",
+    "/obj/item/clothing/accessory/medal/pin/anarchoprimitist": "",
+    "/obj/item/clothing/accessory/medal/pin/environmentalist": "",
+    "/obj/item/clothing/accessory/medal/pin/merchant": "",
+    "/obj/item/clothing/accessory/medal/pin/worker/lumberjack": "",
+    "/obj/item/clothing/accessory/medal/pin/worker/medic": "",
+    "/obj/item/clothing/accessory/medal/silver": "",
+    "/obj/item/clothing/accessory/medal/soviet/ww2/delegate_supreme_soviet": "",
+    "/obj/item/clothing/accessory/medal/soviet/ww2/For_the_defence_of_Stalingrad": "",
+    "/obj/item/clothing/accessory/medal/soviet/ww2/Guards_Unit_Badge": "",
+    "/obj/item/clothing/accessory/medal/soviet/ww2/Hero_of_the_Soviet_Union": "",
+    "/obj/item/clothing/accessory/medal/soviet/ww2/nkvd": "",
+    "/obj/item/clothing/accessory/medal/soviet/ww2/Order_of_the_Red_Star": "",
+    "/obj/item/clothing/accessory/patch/marksman": "",
+    "/obj/item/clothing/accessory/patch/police": "",
+    "/obj/item/clothing/accessory/patch/russia": "",
+    "/obj/item/clothing/accessory/patch/security": "",
+    "/obj/item/clothing/accessory/patch/specialforce": "",
+    "/obj/item/clothing/accessory/patch/spetsgruppaa": "",
+    "/obj/item/clothing/accessory/rank/germ_obergefreiter": "",
+    "/obj/item/clothing/accessory/rank/jap_2lt": "",
+    "/obj/item/clothing/accessory/rank/jap_nitohei": "",
+    "/obj/item/clothing/accessory/rank/jap_taii": "",
+    "/obj/item/clothing/accessory/ruffle/neck": "",
+    "/obj/item/clothing/accessory/stethoscope": "",
+    "/obj/item/clothing/accessory/storage/coinpouch": "",
+    "/obj/item/clothing/accessory/storage/coinpouch/tes13": "",
+    "/obj/item/clothing/accessory/storage/passport": "",
+    "/obj/item/clothing/accessory/storage/sheath": "",
+    "/obj/item/clothing/accessory/storage/sheath/daisho": "",
+    "/obj/item/clothing/accessory/storage/sheath/katana": "",
+    "/obj/item/clothing/accessory/storage/sheath/knife": "",
+    "/obj/item/clothing/accessory/storage/sheath/longer": "",
+    "/obj/item/clothing/accessory/storage/sheath/longer/officer": "",
+    "/obj/item/clothing/accessory/storage/sheath/longsword": "",
+    "/obj/item/clothing/accessory/storage/webbing": "",
+    "/obj/item/clothing/accessory/storage/webbing/caf_tacvest": "",
+    "/obj/item/clothing/accessory/storage/webbing/civil_war": "",
+    "/obj/item/clothing/accessory/storage/webbing/civil_war/officer": "",
+    "/obj/item/clothing/accessory/storage/webbing/filipino": "",
+    "/obj/item/clothing/accessory/storage/webbing/green_webbing": "",
+    "/obj/item/clothing/accessory/storage/webbing/khaki_webbing": "",
+    "/obj/item/clothing/accessory/storage/webbing/light": "",
+    "/obj/item/clothing/accessory/storage/webbing/pouches": "",
+    "/obj/item/clothing/accessory/storage/webbing/russband": "",
+    "/obj/item/clothing/accessory/storage/webbing/russian": "",
+    "/obj/item/clothing/accessory/storage/webbing/shell40mm": "",
+    "/obj/item/clothing/accessory/storage/webbing/shotgun_bandolier": "",
+    "/obj/item/clothing/accessory/storage/webbing/shotgun_bandolier/filled_buckshot": "",
+    "/obj/item/clothing/accessory/storage/webbing/tanpouches": "",
+    "/obj/item/clothing/accessory/storage/webbing/us_bandolier": "",
+    "/obj/item/clothing/accessory/storage/webbing/us_vest": "",
+    "/obj/item/clothing/accessory/storage/webbing/us_ww2": "",
+    "/obj/item/clothing/accessory/storage/webbing/ww1": "",
+    "/obj/item/clothing/accessory/storage/webbing/ww1/british": "",
+    "/obj/item/clothing/accessory/storage/webbing/ww1/german": "",
+    "/obj/item/clothing/accessory/storage/webbing/ww1/german/ww2": "",
+    "/obj/item/clothing/accessory/storage/webbing/ww1/leather": "",
+    "/obj/item/clothing/accessory/tie": "",
+    "/obj/item/clothing/accessory/tie/blue": "",
+    "/obj/item/clothing/accessory/tie/bowtie": "",
+    "/obj/item/clothing/accessory/tie/red": "",
+    "/obj/item/clothing/ears/earmuffs": "",
+    "/obj/item/clothing/glasses/blueglasses": "",
+    "/obj/item/clothing/glasses/eyepatch": "",
+    "/obj/item/clothing/glasses/gglasses": "",
+    "/obj/item/clothing/glasses/monocle": "",
+    "/obj/item/clothing/glasses/nvg": "",
+    "/obj/item/clothing/glasses/pilot": "",
+    "/obj/item/clothing/glasses/redglasses": "",
+    "/obj/item/clothing/glasses/regular": "",
+    "/obj/item/clothing/glasses/regular/hipster": "",
+    "/obj/item/clothing/glasses/sunglasses": "",
+    "/obj/item/clothing/glasses/sunglasses/blindfold": "",
+    "/obj/item/clothing/glasses/sunglasses/large": "",
+    "/obj/item/clothing/glasses/tactical_goggles": "",
+    "/obj/item/clothing/glasses/tactical_goggles/ballistic": "",
+    "/obj/item/clothing/glasses/thermal": "",
+    "/obj/item/clothing/glasses/univisorcyan": "",
+    "/obj/item/clothing/glasses/univisorgreen": "",
+    "/obj/item/clothing/glasses/univisorred": "",
+    "/obj/item/clothing/glasses/univisorwhite": "",
+    "/obj/item/clothing/glasses/univisoryellow": "",
+    "/obj/item/clothing/glasses/yellowglasses": "",
+    "/obj/item/clothing/gloves/botanic_leather": "",
+    "/obj/item/clothing/gloves/boxing": "",
+    "/obj/item/clothing/gloves/boxing/blue": "",
+    "/obj/item/clothing/gloves/boxing/green": "",
+    "/obj/item/clothing/gloves/boxing/yellow": "",
+    "/obj/item/clothing/gloves/color": "",
+    "/obj/item/clothing/gloves/color/blue": "",
+    "/obj/item/clothing/gloves/color/brown": "",
+    "/obj/item/clothing/gloves/color/grey": "",
+    "/obj/item/clothing/gloves/color/light_brown": "",
+    "/obj/item/clothing/gloves/color/luxglove": "",
+    "/obj/item/clothing/gloves/color/red": "",
+    "/obj/item/clothing/gloves/color/white": "",
+    "/obj/item/clothing/gloves/color/yellow": "",
+    "/obj/item/clothing/gloves/fingerless": "",
+    "/obj/item/clothing/gloves/gauntlets": "",
+    "/obj/item/clothing/gloves/gauntlets/tes13/dwemmer": "",
+    "/obj/item/clothing/gloves/motorist": "",
+    "/obj/item/clothing/gloves/oven": "",
+    "/obj/item/clothing/gloves/replicantgloves": "",
+    "/obj/item/clothing/gloves/rings/silver": "",
+    "/obj/item/clothing/gloves/sterile": "",
+    "/obj/item/clothing/gloves/sterile/nitrile": "",
+    "/obj/item/clothing/gloves/sterile/nuclear": "",
+    "/obj/item/clothing/gloves/thick": "",
+    "/obj/item/clothing/gloves/thick/combat": "",
+    "/obj/item/clothing/gloves/thick/firefighter": "",
+    "/obj/item/clothing/gloves/thick/leather": "",
+    "/obj/item/clothing/gloves/thick/leather/black": "",
+    "/obj/item/clothing/gloves/thick/leather/brown": "",
+    "/obj/item/clothing/gloves/thick/leather/grey": "",
+    "/obj/item/clothing/gloves/thick/leather/white": "",
+    "/obj/item/clothing/gloves/thick/swat": "",
+    "/obj/item/clothing/gloves/toughguy": "",
+    "/obj/item/clothing/gloves/union_gloves": "",
+    "/obj/item/clothing/gloves/watch/goldwatch": "",
+    "/obj/item/clothing/gloves/watch/specialwatch": "",
+    "/obj/item/clothing/gloves/watch/watch": "",
+    "/obj/item/clothing/head/abashiri_guard": "",
+    "/obj/item/clothing/head/abashiri_prisoner": "",
+    "/obj/item/clothing/head/ainu_bandana": "",
+    "/obj/item/clothing/head/atef": "",
+    "/obj/item/clothing/head/bandana": "",
+    "/obj/item/clothing/head/bandit": "",
+    "/obj/item/clothing/head/bearpelt": "",
+    "/obj/item/clothing/head/bearpelt/white": "",
+    "/obj/item/clothing/head/beret_blugoslavia": "",
+    "/obj/item/clothing/head/beret_green": "",
+    "/obj/item/clothing/head/beret_green/insig": "",
+    "/obj/item/clothing/head/beret_red": "",
+    "/obj/item/clothing/head/beret_redmenia": "",
+    "/obj/item/clothing/head/beret_rus_vdv": "",
+    "/obj/item/clothing/head/bicorne_british_soldier": "",
+    "/obj/item/clothing/head/black_bandana": "",
+    "/obj/item/clothing/head/blackberet": "",
+    "/obj/item/clothing/head/blue_sailorberet": "",
+    "/obj/item/clothing/head/bowler_hat": "",
+    "/obj/item/clothing/head/cap/atf": "",
+    "/obj/item/clothing/head/cap/tfc": "",
+    "/obj/item/clothing/head/cap_blugoslavia": "",
+    "/obj/item/clothing/head/cap_redmenia": "",
+    "/obj/item/clothing/head/capotain": "",
+    "/obj/item/clothing/head/caubeen": "",
+    "/obj/item/clothing/head/chaplain_hood": "",
+    "/obj/item/clothing/head/chasseur_british": "",
+    "/obj/item/clothing/head/chefhat": "",
+    "/obj/item/clothing/head/chief_hat": "",
+    "/obj/item/clothing/head/chinese_ushanka": "",
+    "/obj/item/clothing/head/chinese_ushanka/down": "",
+    "/obj/item/clothing/head/coldwar/soviet_officer": "",
+    "/obj/item/clothing/head/confederatecap": "",
+    "/obj/item/clothing/head/confederatehat": "",
+    "/obj/item/clothing/head/cowboyhat": "",
+    "/obj/item/clothing/head/cowboyhat2": "",
+    "/obj/item/clothing/head/custom/customhood": "",
+    "/obj/item/clothing/head/custom/fieldcap/dra": "",
+    "/obj/item/clothing/head/custom/kippa": "",
+    "/obj/item/clothing/head/custom_hennin": "",
+    "/obj/item/clothing/head/custom_off_cap": "",
+    "/obj/item/clothing/head/feathertrilby": "",
+    "/obj/item/clothing/head/fedora": "",
+    "/obj/item/clothing/head/fez": "",
+    "/obj/item/clothing/head/flatcap1": "",
+    "/obj/item/clothing/head/flatcap2": "",
+    "/obj/item/clothing/head/flatcap3": "",
+    "/obj/item/clothing/head/foxpelt": "",
+    "/obj/item/clothing/head/furcap": "",
+    "/obj/item/clothing/head/furhat": "",
+    "/obj/item/clothing/head/furhat/bison": "",
+    "/obj/item/clothing/head/gat": "",
+    "/obj/item/clothing/head/ghillie": "",
+    "/obj/item/clothing/head/ghillie/winter": "",
+    "/obj/item/clothing/head/hairflower": "",
+    "/obj/item/clothing/head/helmet/aged_eisenbruck": "",
+    "/obj/item/clothing/head/helmet/bone": "",
+    "/obj/item/clothing/head/helmet/gladiator": "",
+    "/obj/item/clothing/head/helmet/gold_crown": "",
+    "/obj/item/clothing/head/helmet/gold_crown_diamond": "",
+    "/obj/item/clothing/head/helmet/greek": "",
+    "/obj/item/clothing/head/helmet/greek_commander": "",
+    "/obj/item/clothing/head/helmet/horned": "",
+    "/obj/item/clothing/head/helmet/kevlarhelmet": "",
+    "/obj/item/clothing/head/helmet/korean/us_medic": "",
+    "/obj/item/clothing/head/helmet/leather": "",
+    "/obj/item/clothing/head/helmet/medieval": "",
+    "/obj/item/clothing/head/helmet/medieval/arab": "",
+    "/obj/item/clothing/head/helmet/medieval/arab2": "",
+    "/obj/item/clothing/head/helmet/medieval/arab3": "",
+    "/obj/item/clothing/head/helmet/medieval/helmet1": "",
+    "/obj/item/clothing/head/helmet/medieval/helmet2": "",
+    "/obj/item/clothing/head/helmet/medieval/helmet3": "",
+    "/obj/item/clothing/head/helmet/medieval/templar": "",
+    "/obj/item/clothing/head/helmet/medieval/tes13/dwemmer": "",
+    "/obj/item/clothing/head/helmet/medieval/tes13/guard": "",
+    "/obj/item/clothing/head/helmet/medieval/viking": "",
+    "/obj/item/clothing/head/helmet/modern/a6b47": "",
+    "/obj/item/clothing/head/helmet/modern/ach/green": "",
+    "/obj/item/clothing/head/helmet/modern/cg634": "",
+    "/obj/item/clothing/head/helmet/modern/firefighter": "",
+    "/obj/item/clothing/head/helmet/modern/hardhat": "",
+    "/obj/item/clothing/head/helmet/modern/hardhat/orange": "",
+    "/obj/item/clothing/head/helmet/modern/hardhat/yellow": "",
+    "/obj/item/clothing/head/helmet/modern/pasgt": "",
+    "/obj/item/clothing/head/helmet/modern/pasgt/reddish": "",
+    "/obj/item/clothing/head/helmet/modern/pasgt/white": "",
+    "/obj/item/clothing/head/helmet/modern/pickelhaube": "",
+    "/obj/item/clothing/head/helmet/modern/sfera": "",
+    "/obj/item/clothing/head/helmet/modern/sovietfacehelmet": "",
+    "/obj/item/clothing/head/helmet/modern/ssh_68": "",
+    "/obj/item/clothing/head/helmet/modern/stahlhelm": "",
+    "/obj/item/clothing/head/helmet/modern/ushelmet": "",
+    "/obj/item/clothing/head/helmet/modern/ushelmet/camo/accessory": "",
+    "/obj/item/clothing/head/helmet/modern/ushelmet/late": "",
+    "/obj/item/clothing/head/helmet/modern/vchelmet": "",
+    "/obj/item/clothing/head/helmet/modern/vchelmet/three": "",
+    "/obj/item/clothing/head/helmet/modern/vchelmet/two": "",
+    "/obj/item/clothing/head/helmet/modern/zsh1": "",
+    "/obj/item/clothing/head/helmet/modern/zsh2": "",
+    "/obj/item/clothing/head/helmet/motorcycle": "",
+    "/obj/item/clothing/head/helmet/replicant": "",
+    "/obj/item/clothing/head/helmet/replicant/lt": "",
+    "/obj/item/clothing/head/helmet/roman": "",
+    "/obj/item/clothing/head/helmet/roman_decurion": "",
+    "/obj/item/clothing/head/helmet/samurai/red": "",
+    "/obj/item/clothing/head/helmet/scrap": "",
+    "/obj/item/clothing/head/helmet/swat": "",
+    "/obj/item/clothing/head/helmet/tactical": "",
+    "/obj/item/clothing/head/helmet/ww/adrian/m26": "",
+    "/obj/item/clothing/head/helmet/ww/adrian/medic": "",
+    "/obj/item/clothing/head/helmet/ww/adriansoviet": "",
+    "/obj/item/clothing/head/helmet/ww/mk2brodieog": "",
+    "/obj/item/clothing/head/helmet/ww/mk2brodietnet": "",
+    "/obj/item/clothing/head/helmet/ww/stahlhelm": "",
+    "/obj/item/clothing/head/helmet/ww2/gerhelm": "",
+    "/obj/item/clothing/head/helmet/ww2/gerhelm/winter": "",
+    "/obj/item/clothing/head/helmet/ww2/japhelm": "",
+    "/obj/item/clothing/head/helmet/ww2/japhelm_med": "",
+    "/obj/item/clothing/head/helmet/ww2/japhelm_tanker": "",
+    "/obj/item/clothing/head/helmet/ww2/soviet": "",
+    "/obj/item/clothing/head/helmet/ww2/soviet_medic": "",
+    "/obj/item/clothing/head/helmet/ww2/ss": "",
+    "/obj/item/clothing/head/helmet/ww2/ss/dark": "",
+    "/obj/item/clothing/head/helmet/ww2/us_1lt": "",
+    "/obj/item/clothing/head/helmet/ww2/us_cap": "",
+    "/obj/item/clothing/head/helmet/ww2/us_mar": "",
+    "/obj/item/clothing/head/helmet/ww2/usm1": "",
+    "/obj/item/clothing/head/helmet/ww2/usm1camogreen": "",
+    "/obj/item/clothing/head/helmet/ww2/usm1mpblack": "",
+    "/obj/item/clothing/head/helmet/ww2/ustannet": "",
+    "/obj/item/clothing/head/japcap": "",
+    "/obj/item/clothing/head/jungle_hat": "",
+    "/obj/item/clothing/head/kerchief": "",
+    "/obj/item/clothing/head/laurelcrown": "",
+    "/obj/item/clothing/head/leaves/crown": "",
+    "/obj/item/clothing/head/lionpelt": "",
+    "/obj/item/clothing/head/mayan_headdress": "",
+    "/obj/item/clothing/head/nbc": "",
+    "/obj/item/clothing/head/nbc/olive": "",
+    "/obj/item/clothing/head/nbc/olive/fire": "",
+    "/obj/item/clothing/head/nun_hood": "",
+    "/obj/item/clothing/head/nva_hat": "",
+    "/obj/item/clothing/head/olivebandana": "",
+    "/obj/item/clothing/head/orangebandana": "",
+    "/obj/item/clothing/head/peakyblinder": "",
+    "/obj/item/clothing/head/peakyblinderblade": "",
+    "/obj/item/clothing/head/ph_us_war/american/infantry_hat": "",
+    "/obj/item/clothing/head/ph_us_war/filipino/baliwag": "",
+    "/obj/item/clothing/head/pharoah": "",
+    "/obj/item/clothing/head/philosopher_wig": "",
+    "/obj/item/clothing/head/pirate": "",
+    "/obj/item/clothing/head/piratebandana1": "",
+    "/obj/item/clothing/head/piratehat": "",
+    "/obj/item/clothing/head/plaguedoctor": "",
+    "/obj/item/clothing/head/portuguese_army": "",
+    "/obj/item/clothing/head/powdered_wig": "",
+    "/obj/item/clothing/head/red_sailorberet": "",
+    "/obj/item/clothing/head/rice_hat": "",
+    "/obj/item/clothing/head/rusoffcap": "",
+    "/obj/item/clothing/head/sombrero": "",
+    "/obj/item/clothing/head/sov_ushanka_new": "",
+    "/obj/item/clothing/head/sov_ushanka_new/down": "",
+    "/obj/item/clothing/head/strawhat": "",
+    "/obj/item/clothing/head/surgical_cap": "",
+    "/obj/item/clothing/head/surgical_cap/blue": "",
+    "/obj/item/clothing/head/surgical_cap/darkgreen": "",
+    "/obj/item/clothing/head/surgical_cap/lightgreen": "",
+    "/obj/item/clothing/head/surgical_cap/navy": "",
+    "/obj/item/clothing/head/tarred_hat": "",
+    "/obj/item/clothing/head/top_hat": "",
+    "/obj/item/clothing/head/tophat": "",
+    "/obj/item/clothing/head/traffic_police": "",
+    "/obj/item/clothing/head/tricorne_black": "",
+    "/obj/item/clothing/head/tricorne_british_army": "",
+    "/obj/item/clothing/head/turban": "",
+    "/obj/item/clothing/head/turban/imam": "",
+    "/obj/item/clothing/head/unioncap": "",
+    "/obj/item/clothing/head/unionhat": "",
+    "/obj/item/clothing/head/unionhatlight": "",
+    "/obj/item/clothing/head/vaquerohat": "",
+    "/obj/item/clothing/head/wolfpelt": "",
+    "/obj/item/clothing/head/ww/budenovka": "",
+    "/obj/item/clothing/head/ww/germcap": "",
+    "/obj/item/clothing/head/ww/papakha": "",
+    "/obj/item/clothing/head/ww/papakha/white": "",
+    "/obj/item/clothing/head/ww2/british_hat": "",
+    "/obj/item/clothing/head/ww2/chicap": "",
+    "/obj/item/clothing/head/ww2/cra_cap": "",
+    "/obj/item/clothing/head/ww2/ger_officercap": "",
+    "/obj/item/clothing/head/ww2/german_fieldcap": "",
+    "/obj/item/clothing/head/ww2/jap_headband": "",
+    "/obj/item/clothing/head/ww2/jap_mp": "",
+    "/obj/item/clothing/head/ww2/japcap": "",
+    "/obj/item/clothing/head/ww2/japoffcap": "",
+    "/obj/item/clothing/head/ww2/nkvd_cap": "",
+    "/obj/item/clothing/head/ww2/nkvd_cap/kgb": "",
+    "/obj/item/clothing/head/ww2/sov_officercap": "",
+    "/obj/item/clothing/head/ww2/sov_pilotka": "",
+    "/obj/item/clothing/head/ww2/sov_ushanka": "",
+    "/obj/item/clothing/head/ww2/sov_ushanka/down": "",
+    "/obj/item/clothing/head/ww2/sov_ushanka/nomads": "",
+    "/obj/item/clothing/head/ww2/soviet_fieldcap": "",
+    "/obj/item/clothing/head/ww2/ss_cap": "",
+    "/obj/item/clothing/head/ww2/upa_cap": "",
+    "/obj/item/clothing/head/ww2/upa_pilotka": "",
+    "/obj/item/clothing/head/ww2/us_nco_cap": "",
+    "/obj/item/clothing/head/ww2/us_sailor_hat": "",
+    "/obj/item/clothing/mask/balaclava": "",
+    "/obj/item/clothing/mask/clown": "",
+    "/obj/item/clothing/mask/facecamo": "",
+    "/obj/item/clothing/mask/frog": "",
+    "/obj/item/clothing/mask/gas/british": "",
+    "/obj/item/clothing/mask/gas/german": "",
+    "/obj/item/clothing/mask/gas/halfmask": "",
+    "/obj/item/clothing/mask/gas/japanese": "",
+    "/obj/item/clothing/mask/gas/military": "",
+    "/obj/item/clothing/mask/gas/modern": "",
+    "/obj/item/clothing/mask/gas/modern2": "",
+    "/obj/item/clothing/mask/gas/russia": "",
+    "/obj/item/clothing/mask/gas/soviet": "",
+    "/obj/item/clothing/mask/gas/soviet/gp5": "",
+    "/obj/item/clothing/mask/gas/soviet/pmk1": "",
+    "/obj/item/clothing/mask/gas/swat": "",
+    "/obj/item/clothing/mask/muzzle": "",
+    "/obj/item/clothing/mask/necklace/christian/gold": "",
+    "/obj/item/clothing/mask/plaguedoctor": "",
+    "/obj/item/clothing/mask/sack/scarecrow": "",
+    "/obj/item/clothing/mask/samurai/red": "",
+    "/obj/item/clothing/mask/shemagh": "",
+    "/obj/item/clothing/mask/shemagh/greykerchief": "",
+    "/obj/item/clothing/mask/shemagh/redkerchief": "",
+    "/obj/item/clothing/mask/skullmask": "",
+    "/obj/item/clothing/mask/smokable/cigarette": "",
+    "/obj/item/clothing/mask/smokable/cigarette/cigar": "",
+    "/obj/item/clothing/mask/smokable/cigarette/cigar/havana": "",
+    "/obj/item/clothing/mask/smokable/cigarette/joint": "",
+    "/obj/item/clothing/mask/smokable/pipe": "",
+    "/obj/item/clothing/mask/smokable/pipe/cobpipe": "",
+    "/obj/item/clothing/mask/smokable/pipe/glass": "",
+    "/obj/item/clothing/mask/sovietbala": "",
+    "/obj/item/clothing/mask/sterile": "",
+    "/obj/item/clothing/mask/stone": "",
+    "/obj/item/clothing/mask/wooden": "",
+    "/obj/item/clothing/shoes/aztec_sandals": "",
+    "/obj/item/clothing/shoes/black": "",
+    "/obj/item/clothing/shoes/blackboots": "",
+    "/obj/item/clothing/shoes/chad": "",
+    "/obj/item/clothing/shoes/color/brown": "",
+    "/obj/item/clothing/shoes/color/orange": "",
+    "/obj/item/clothing/shoes/color/white": "",
+    "/obj/item/clothing/shoes/combat": "",
+    "/obj/item/clothing/shoes/dwemmer": "",
+    "/obj/item/clothing/shoes/football": "",
+    "/obj/item/clothing/shoes/fur/black": "",
+    "/obj/item/clothing/shoes/fur/brown": "",
+    "/obj/item/clothing/shoes/fur/grey": "",
+    "/obj/item/clothing/shoes/fur/white": "",
+    "/obj/item/clothing/shoes/gator_ankleboots": "",
+    "/obj/item/clothing/shoes/gator_laceup": "",
+    "/obj/item/clothing/shoes/geta": "",
+    "/obj/item/clothing/shoes/heavyboots": "",
+    "/obj/item/clothing/shoes/heavyboots/wrappedboots": "",
+    "/obj/item/clothing/shoes/iogboots/black": "",
+    "/obj/item/clothing/shoes/jackboots": "",
+    "/obj/item/clothing/shoes/jackboots/modern": "",
+    "/obj/item/clothing/shoes/jackboots/soviet": "",
+    "/obj/item/clothing/shoes/japboots": "",
+    "/obj/item/clothing/shoes/laceup": "",
+    "/obj/item/clothing/shoes/laceup/brown": "",
+    "/obj/item/clothing/shoes/laceup/grey": "",
+    "/obj/item/clothing/shoes/laceup/white": "",
+    "/obj/item/clothing/shoes/leather": "",
+    "/obj/item/clothing/shoes/leatherboots": "",
+    "/obj/item/clothing/shoes/lizard_laceup": "",
+    "/obj/item/clothing/shoes/medieval": "",
+    "/obj/item/clothing/shoes/medieval/arab": "",
+    "/obj/item/clothing/shoes/medieval/knight": "",
+    "/obj/item/clothing/shoes/replicantshoes": "",
+    "/obj/item/clothing/shoes/riding1": "",
+    "/obj/item/clothing/shoes/riding1/gator_cowboy": "",
+    "/obj/item/clothing/shoes/riding2": "",
+    "/obj/item/clothing/shoes/roman": "",
+    "/obj/item/clothing/shoes/sailorboots2": "",
+    "/obj/item/clothing/shoes/sandal": "",
+    "/obj/item/clothing/shoes/soldiershoes": "",
+    "/obj/item/clothing/shoes/swat": "",
+    "/obj/item/clothing/shoes/us_ww2_boots": "",
+    "/obj/item/clothing/shoes/usmc": "",
+    "/obj/item/clothing/shoes/whiteputtee": "",
+    "/obj/item/clothing/shoes/winterboots": "",
+    "/obj/item/clothing/shoes/workboots": "",
+    "/obj/item/clothing/suit/a6b28": "",
+    "/obj/item/clothing/suit/a6b45": "",
+    "/obj/item/clothing/suit/armor/ancient/aztec_harness": "",
+    "/obj/item/clothing/suit/armor/ancient/linen": "",
+    "/obj/item/clothing/suit/armor/ancient/scale": "",
+    "/obj/item/clothing/suit/armor/japmisc/japvest": "",
+    "/obj/item/clothing/suit/armor/medieval/blue": "",
+    "/obj/item/clothing/suit/armor/medieval/bronze_chestplate": "",
+    "/obj/item/clothing/suit/armor/medieval/chainmail": "",
+    "/obj/item/clothing/suit/armor/medieval/hauberk": "",
+    "/obj/item/clothing/suit/armor/medieval/iron_chestplate": "",
+    "/obj/item/clothing/suit/armor/medieval/iron_chestplate/crusader": "",
+    "/obj/item/clothing/suit/armor/medieval/iron_chestplate/red": "",
+    "/obj/item/clothing/suit/armor/medieval/leather": "",
+    "/obj/item/clothing/suit/armor/medieval/templar": "",
+    "/obj/item/clothing/suit/armor/medieval/yellow": "",
+    "/obj/item/clothing/suit/armor/replicant": "",
+    "/obj/item/clothing/suit/armor/replicant/lieutenant": "",
+    "/obj/item/clothing/suit/armor/royal": "",
+    "/obj/item/clothing/suit/armor/samurai/black": "",
+    "/obj/item/clothing/suit/armor/samurai/lord/red": "",
+    "/obj/item/clothing/suit/armor/scrap": "",
+    "/obj/item/clothing/suit/armor/tes13/dwemmer": "",
+    "/obj/item/clothing/suit/b3": "",
+    "/obj/item/clothing/suit/bx": "",
+    "/obj/item/clothing/suit/cape": "",
+    "/obj/item/clothing/suit/chef": "",
+    "/obj/item/clothing/suit/chef/tfc": "",
+    "/obj/item/clothing/suit/hairbonearmor": "",
+    "/obj/item/clothing/suit/hawaiian": "",
+    "/obj/item/clothing/suit/hawaiian/green": "",
+    "/obj/item/clothing/suit/hawaiian/orange": "",
+    "/obj/item/clothing/suit/hawaiian/purple": "",
+    "/obj/item/clothing/suit/hazmat": "",
+    "/obj/item/clothing/suit/heavyvest1": "",
+    "/obj/item/clothing/suit/lifejacket": "",
+    "/obj/item/clothing/suit/lifejacket/blue": "",
+    "/obj/item/clothing/suit/lifejacket/yellow": "",
+    "/obj/item/clothing/suit/medvest": "",
+    "/obj/item/clothing/suit/nbc": "",
+    "/obj/item/clothing/suit/nbc/olive": "",
+    "/obj/item/clothing/suit/nbc/olive/fire": "",
+    "/obj/item/clothing/suit/nbcponcho": "",
+    "/obj/item/clothing/suit/police": "",
+    "/obj/item/clothing/suit/prehistoricfurcoat/black": "",
+    "/obj/item/clothing/suit/storage/arabic_robe": "",
+    "/obj/item/clothing/suit/storage/atf": "",
+    "/obj/item/clothing/suit/storage/closechest_apron_f": "",
+    "/obj/item/clothing/suit/storage/coat/american": "",
+    "/obj/item/clothing/suit/storage/coat/britishcoat": "",
+    "/obj/item/clothing/suit/storage/coat/cheka": "",
+    "/obj/item/clothing/suit/storage/coat/chinese": "",
+    "/obj/item/clothing/suit/storage/coat/fancy_fur_coat": "",
+    "/obj/item/clothing/suit/storage/coat/firefighter": "",
+    "/obj/item/clothing/suit/storage/coat/fur": "",
+    "/obj/item/clothing/suit/storage/coat/fur/black": "",
+    "/obj/item/clothing/suit/storage/coat/fur/brown": "",
+    "/obj/item/clothing/suit/storage/coat/fur/grey": "",
+    "/obj/item/clothing/suit/storage/coat/fur/klyaksa": "",
+    "/obj/item/clothing/suit/storage/coat/fur/m05": "",
+    "/obj/item/clothing/suit/storage/coat/fur/pink": "",
+    "/obj/item/clothing/suit/storage/coat/fur/schneetarn": "",
+    "/obj/item/clothing/suit/storage/coat/fur/ukrainian": "",
+    "/obj/item/clothing/suit/storage/coat/fur/white": "",
+    "/obj/item/clothing/suit/storage/coat/gentleman": "",
+    "/obj/item/clothing/suit/storage/coat/germcoat": "",
+    "/obj/item/clothing/suit/storage/coat/japcoat2/brown": "",
+    "/obj/item/clothing/suit/storage/coat/kozhanka": "",
+    "/obj/item/clothing/suit/storage/coat/kozhanka/white": "",
+    "/obj/item/clothing/suit/storage/coat/leathercoat_black": "",
+    "/obj/item/clothing/suit/storage/coat/modern_long_black": "",
+    "/obj/item/clothing/suit/storage/coat/modern_winter": "",
+    "/obj/item/clothing/suit/storage/coat/monk_robes": "",
+    "/obj/item/clothing/suit/storage/coat/oldyjacket": "",
+    "/obj/item/clothing/suit/storage/coat/priest": "",
+    "/obj/item/clothing/suit/storage/coat/ruscoat": "",
+    "/obj/item/clothing/suit/storage/coat/ruscoat/grey": "",
+    "/obj/item/clothing/suit/storage/coat/rusoffcoat": "",
+    "/obj/item/clothing/suit/storage/coat/russian_rcw": "",
+    "/obj/item/clothing/suit/storage/coat/tes13/fine_clothing": "",
+    "/obj/item/clothing/suit/storage/coat/winter_coat": "",
+    "/obj/item/clothing/suit/storage/coat/ww1/royalcoat": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/biker": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/biker/gator_jacket": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/bomberjacketblack": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/bomberjacketbrown": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/expensivecoat": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/fancycoat": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/german": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/german/civ": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/german/winter": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/german_officer": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/japcoat_rain": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/moderncoat": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/servicejacket": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/sovcoat": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/sovcoat2": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/soviet": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/soviet_officer": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/ss_parka": "",
+    "/obj/item/clothing/suit/storage/coat/ww2/us_coat": "",
+    "/obj/item/clothing/suit/storage/fbi": "",
+    "/obj/item/clothing/suit/storage/ghillie": "",
+    "/obj/item/clothing/suit/storage/ghillie/winter": "",
+    "/obj/item/clothing/suit/storage/hazard": "",
+    "/obj/item/clothing/suit/storage/hazard/blue": "",
+    "/obj/item/clothing/suit/storage/hazard/green": "",
+    "/obj/item/clothing/suit/storage/jacket/afghanka": "",
+    "/obj/item/clothing/suit/storage/jacket/black_suit": "",
+    "/obj/item/clothing/suit/storage/jacket/blackvest": "",
+    "/obj/item/clothing/suit/storage/jacket/bluevest": "",
+    "/obj/item/clothing/suit/storage/jacket/bonearmor": "",
+    "/obj/item/clothing/suit/storage/jacket/british_captain": "",
+    "/obj/item/clothing/suit/storage/jacket/british_officer_army": "",
+    "/obj/item/clothing/suit/storage/jacket/british_soldier": "",
+    "/obj/item/clothing/suit/storage/jacket/burgundy_suit": "",
+    "/obj/item/clothing/suit/storage/jacket/chaplain": "",
+    "/obj/item/clothing/suit/storage/jacket/charcoal_suit": "",
+    "/obj/item/clothing/suit/storage/jacket/checkered_suit": "",
+    "/obj/item/clothing/suit/storage/jacket/coveralls": "",
+    "/obj/item/clothing/suit/storage/jacket/custom/blazer": "",
+    "/obj/item/clothing/suit/storage/jacket/custom/cloth_jacket": "",
+    "/obj/item/clothing/suit/storage/jacket/custom/haori_jacket": "",
+    "/obj/item/clothing/suit/storage/jacket/custom/hoodie": "",
+    "/obj/item/clothing/suit/storage/jacket/custom/poncho": "",
+    "/obj/item/clothing/suit/storage/jacket/customcolonialcoat": "",
+    "/obj/item/clothing/suit/storage/jacket/customtracksuit": "",
+    "/obj/item/clothing/suit/storage/jacket/doctor": "",
+    "/obj/item/clothing/suit/storage/jacket/highvis": "",
+    "/obj/item/clothing/suit/storage/jacket/leatherovercoat1": "",
+    "/obj/item/clothing/suit/storage/jacket/leatherovercoat2": "",
+    "/obj/item/clothing/suit/storage/jacket/motorist": "",
+    "/obj/item/clothing/suit/storage/jacket/navy_suit": "",
+    "/obj/item/clothing/suit/storage/jacket/olivevest": "",
+    "/obj/item/clothing/suit/storage/jacket/piratejacket1": "",
+    "/obj/item/clothing/suit/storage/jacket/piratejacket2": "",
+    "/obj/item/clothing/suit/storage/jacket/piratejacket3": "",
+    "/obj/item/clothing/suit/storage/jacket/piratejacket4": "",
+    "/obj/item/clothing/suit/storage/jacket/piratejacket5": "",
+    "/obj/item/clothing/suit/storage/jacket/plaguedoctor": "",
+    "/obj/item/clothing/suit/storage/jacket/portuguese_officer_army": "",
+    "/obj/item/clothing/suit/storage/jacket/really_black_suit": "",
+    "/obj/item/clothing/suit/storage/jacket/surgeon": "",
+    "/obj/item/clothing/suit/storage/jacket/texan": "",
+    "/obj/item/clothing/suit/storage/jacket/vict_tailcoat": "",
+    "/obj/item/clothing/suit/storage/us_jacket": "",
+    "/obj/item/clothing/suit/swat": "",
+    "/obj/item/clothing/suit/woodarmor": "",
+    "/obj/item/clothing/under/abashiri": "",
+    "/obj/item/clothing/under/abashiri_prisoner": "",
+    "/obj/item/clothing/under/afghanka": "",
+    "/obj/item/clothing/under/ainu": "",
+    "/obj/item/clothing/under/ainu2": "",
+    "/obj/item/clothing/under/aztec_loincloth": "",
+    "/obj/item/clothing/under/baily": "",
+    "/obj/item/clothing/under/bartender": "",
+    "/obj/item/clothing/under/blackdress": "",
+    "/obj/item/clothing/under/blackdress/short": "",
+    "/obj/item/clothing/under/blacktango": "",
+    "/obj/item/clothing/under/blue/bandbikini": "",
+    "/obj/item/clothing/under/blue/strappedbikini": "",
+    "/obj/item/clothing/under/blue/swimtrunks": "",
+    "/obj/item/clothing/under/blue_shorts": "",
+    "/obj/item/clothing/under/bodyglove": "",
+    "/obj/item/clothing/under/boomerwaffen1": "",
+    "/obj/item/clothing/under/boomerwaffen2": "",
+    "/obj/item/clothing/under/boomerwaffen3": "",
+    "/obj/item/clothing/under/caf": "",
+    "/obj/item/clothing/under/cartel": "",
+    "/obj/item/clothing/under/celtic_green": "",
+    "/obj/item/clothing/under/chad": "",
+    "/obj/item/clothing/under/chaplain": "",
+    "/obj/item/clothing/under/christian_priest": "",
+    "/obj/item/clothing/under/civ1": "",
+    "/obj/item/clothing/under/civ2": "",
+    "/obj/item/clothing/under/civ3": "",
+    "/obj/item/clothing/under/civ4": "",
+    "/obj/item/clothing/under/civ5": "",
+    "/obj/item/clothing/under/civ6": "",
+    "/obj/item/clothing/under/civf1": "",
+    "/obj/item/clothing/under/civf2": "",
+    "/obj/item/clothing/under/civf3": "",
+    "/obj/item/clothing/under/civfg": "",
+    "/obj/item/clothing/under/civfr": "",
+    "/obj/item/clothing/under/cleansuit": "",
+    "/obj/item/clothing/under/clown": "",
+    "/obj/item/clothing/under/coldwar/bowling_blue": "",
+    "/obj/item/clothing/under/coldwar/bowling_green": "",
+    "/obj/item/clothing/under/coldwar/bowling_red": "",
+    "/obj/item/clothing/under/coldwar/bowling_yellow": "",
+    "/obj/item/clothing/under/coldwar/dra/nco": "",
+    "/obj/item/clothing/under/coldwar/dra/officer": "",
+    "/obj/item/clothing/under/coldwar/dra/soldier": "",
+    "/obj/item/clothing/under/coldwar/hippie": "",
+    "/obj/item/clothing/under/combat": "",
+    "/obj/item/clothing/under/confederate_uniform": "",
+    "/obj/item/clothing/under/confederate_uniform/grey": "",
+    "/obj/item/clothing/under/confederate_uniform/grey_blue": "",
+    "/obj/item/clothing/under/cozyoldy": "",
+    "/obj/item/clothing/under/crinoline_dress": "",
+    "/obj/item/clothing/under/custom/arabictunic": "",
+    "/obj/item/clothing/under/custom/celtic": "",
+    "/obj/item/clothing/under/custom/roman": "",
+    "/obj/item/clothing/under/custom/shendyt": "",
+    "/obj/item/clothing/under/custom/spartan": "",
+    "/obj/item/clothing/under/custom/toga": "",
+    "/obj/item/clothing/under/custom/toga/purple": "",
+    "/obj/item/clothing/under/custom/tunic": "",
+    "/obj/item/clothing/under/customdress": "",
+    "/obj/item/clothing/under/customdress2": "",
+    "/obj/item/clothing/under/custompyjamas": "",
+    "/obj/item/clothing/under/customtrackpants": "",
+    "/obj/item/clothing/under/customtribalrobe": "",
+    "/obj/item/clothing/under/customuniform": "",
+    "/obj/item/clothing/under/customuniform/short": "",
+    "/obj/item/clothing/under/customuniform_modern": "",
+    "/obj/item/clothing/under/debutante/blue": "",
+    "/obj/item/clothing/under/debutante/orange": "",
+    "/obj/item/clothing/under/debutante/purple": "",
+    "/obj/item/clothing/under/debutante/red": "",
+    "/obj/item/clothing/under/debutante/yellow": "",
+    "/obj/item/clothing/under/detective2": "",
+    "/obj/item/clothing/under/engi": "",
+    "/obj/item/clothing/under/expensive": "",
+    "/obj/item/clothing/under/expensive/blue": "",
+    "/obj/item/clothing/under/expensive/red": "",
+    "/obj/item/clothing/under/farmer_outfit": "",
+    "/obj/item/clothing/under/firefighter": "",
+    "/obj/item/clothing/under/football/flamengo": "",
+    "/obj/item/clothing/under/french_sailor1": "",
+    "/obj/item/clothing/under/french_sailor2": "",
+    "/obj/item/clothing/under/french_sailor3": "",
+    "/obj/item/clothing/under/gang_leader": "",
+    "/obj/item/clothing/under/gatorpants": "",
+    "/obj/item/clothing/under/gorka": "",
+    "/obj/item/clothing/under/greek_commander": "",
+    "/obj/item/clothing/under/green/bandbikini": "",
+    "/obj/item/clothing/under/green/strappedbikini": "",
+    "/obj/item/clothing/under/green/swimtrunks": "",
+    "/obj/item/clothing/under/hanfu": "",
+    "/obj/item/clothing/under/hanfu/green": "",
+    "/obj/item/clothing/under/hanfu/light": "",
+    "/obj/item/clothing/under/indian1": "",
+    "/obj/item/clothing/under/indianchief": "",
+    "/obj/item/clothing/under/indianhuge": "",
+    "/obj/item/clothing/under/industrial1": "",
+    "/obj/item/clothing/under/industrial2": "",
+    "/obj/item/clothing/under/industrial3": "",
+    "/obj/item/clothing/under/industrial4": "",
+    "/obj/item/clothing/under/industrial5": "",
+    "/obj/item/clothing/under/insurgent_black": "",
+    "/obj/item/clothing/under/insurgent_sand": "",
+    "/obj/item/clothing/under/insurgent_sand_green": "",
+    "/obj/item/clothing/under/insurgent_sand_woodland": "",
+    "/obj/item/clothing/under/japuni": "",
+    "/obj/item/clothing/under/jester": "",
+    "/obj/item/clothing/under/leaves_skirt/long": "",
+    "/obj/item/clothing/under/lederhosen": "",
+    "/obj/item/clothing/under/loinleather": "",
+    "/obj/item/clothing/under/mafia": "",
+    "/obj/item/clothing/under/mechanic_outfit": "",
+    "/obj/item/clothing/under/medieval/arab1": "",
+    "/obj/item/clothing/under/medieval/arab2": "",
+    "/obj/item/clothing/under/medieval/arab3": "",
+    "/obj/item/clothing/under/medieval/arabic_tunic": "",
+    "/obj/item/clothing/under/medieval/beggar_clothing": "",
+    "/obj/item/clothing/under/medieval/blue": "",
+    "/obj/item/clothing/under/medieval/kilt": "",
+    "/obj/item/clothing/under/medieval/leather": "",
+    "/obj/item/clothing/under/medieval/lighttunic": "",
+    "/obj/item/clothing/under/medieval/red": "",
+    "/obj/item/clothing/under/medieval/red2": "",
+    "/obj/item/clothing/under/medieval/yellow": "",
+    "/obj/item/clothing/under/milrus_vsr93": "",
+    "/obj/item/clothing/under/milrus2": "",
+    "/obj/item/clothing/under/modern1": "",
+    "/obj/item/clothing/under/modern2": "",
+    "/obj/item/clothing/under/modern3": "",
+    "/obj/item/clothing/under/modern4": "",
+    "/obj/item/clothing/under/modern7": "",
+    "/obj/item/clothing/under/modern8": "",
+    "/obj/item/clothing/under/napoleonic/patriot": "",
+    "/obj/item/clothing/under/nightingale": "",
+    "/obj/item/clothing/under/nun": "",
+    "/obj/item/clothing/under/nva": "",
+    "/obj/item/clothing/under/nva/green": "",
+    "/obj/item/clothing/under/nva/officer": "",
+    "/obj/item/clothing/under/oldfirefighter": "",
+    "/obj/item/clothing/under/oldmansuit": "",
+    "/obj/item/clothing/under/omon": "",
+    "/obj/item/clothing/under/peakyblinder": "",
+    "/obj/item/clothing/under/ph_us_war/american/us_uni": "",
+    "/obj/item/clothing/under/ph_us_war/filipino/filuni": "",
+    "/obj/item/clothing/under/pharaoh": "",
+    "/obj/item/clothing/under/pirate1": "",
+    "/obj/item/clothing/under/pirate2": "",
+    "/obj/item/clothing/under/pirate3": "",
+    "/obj/item/clothing/under/pirate4": "",
+    "/obj/item/clothing/under/pirate5": "",
+    "/obj/item/clothing/under/police": "",
+    "/obj/item/clothing/under/portuguese_sailor1": "",
+    "/obj/item/clothing/under/portuguese_sailor2": "",
+    "/obj/item/clothing/under/portuguese_sailor3": "",
+    "/obj/item/clothing/under/portuguese_sailor4": "",
+    "/obj/item/clothing/under/prisoner": "",
+    "/obj/item/clothing/under/red/bandbikini": "",
+    "/obj/item/clothing/under/red/strappedbikini": "",
+    "/obj/item/clothing/under/red/swimtrunks": "",
+    "/obj/item/clothing/under/red_shorts": "",
+    "/obj/item/clothing/under/renaissance": "",
+    "/obj/item/clothing/under/renaissance_pontifical": "",
+    "/obj/item/clothing/under/roman": "",
+    "/obj/item/clothing/under/russian": "",
+    "/obj/item/clothing/under/rusuni_rcw": "",
+    "/obj/item/clothing/under/rusuni_ww1": "",
+    "/obj/item/clothing/under/saloondress": "",
+    "/obj/item/clothing/under/scavfit": "",
+    "/obj/item/clothing/under/scrubs": "",
+    "/obj/item/clothing/under/scrubs/blue": "",
+    "/obj/item/clothing/under/scrubs/darkgreen": "",
+    "/obj/item/clothing/under/scrubs/lightgreen": "",
+    "/obj/item/clothing/under/scrubs/navy": "",
+    "/obj/item/clothing/under/sov_klmk": "",
+    "/obj/item/clothing/under/sov_kzs": "",
+    "/obj/item/clothing/under/spanish_sailor1": "",
+    "/obj/item/clothing/under/spanish_sailor2": "",
+    "/obj/item/clothing/under/spanish_sailor3": "",
+    "/obj/item/clothing/under/sundress": "",
+    "/obj/item/clothing/under/sundress/blue": "",
+    "/obj/item/clothing/under/sundress/orange": "",
+    "/obj/item/clothing/under/sundress/purple": "",
+    "/obj/item/clothing/under/sundress/red": "",
+    "/obj/item/clothing/under/swat": "",
+    "/obj/item/clothing/under/swat_new": "",
+    "/obj/item/clothing/under/tactical1": "",
+    "/obj/item/clothing/under/tacticool_hawaiian": "",
+    "/obj/item/clothing/under/tes13/stormcloak": "",
+    "/obj/item/clothing/under/tes13/stormcloak/female": "",
+    "/obj/item/clothing/under/tes13/whiterun": "",
+    "/obj/item/clothing/under/tes13/whiterun/female": "",
+    "/obj/item/clothing/under/texan": "",
+    "/obj/item/clothing/under/toga2": "",
+    "/obj/item/clothing/under/towel": "",
+    "/obj/item/clothing/under/tradwife": "",
+    "/obj/item/clothing/under/tradwife/orange": "",
+    "/obj/item/clothing/under/tradwife/purple": "",
+    "/obj/item/clothing/under/tradwife/red": "",
+    "/obj/item/clothing/under/tradwife/yellow": "",
+    "/obj/item/clothing/under/traffic_police": "",
+    "/obj/item/clothing/under/traffic_police/supervisor": "",
+    "/obj/item/clothing/under/union_uniform": "",
+    "/obj/item/clothing/under/us_uni": "",
+    "/obj/item/clothing/under/us_uni/us_camo": "",
+    "/obj/item/clothing/under/us_uni/us_camo_ucp": "",
+    "/obj/item/clothing/under/us_uni/us_greentrousers": "",
+    "/obj/item/clothing/under/us_uni/us_lightuni": "",
+    "/obj/item/clothing/under/us_uni/us_lightuni2": "",
+    "/obj/item/clothing/under/victorian_dress/red": "",
+    "/obj/item/clothing/under/victorian_prim": "",
+    "/obj/item/clothing/under/victorian_vest": "",
+    "/obj/item/clothing/under/victorian_vest/redshirt": "",
+    "/obj/item/clothing/under/victorian_vest/redvest": "",
+    "/obj/item/clothing/under/waistcoat": "",
+    "/obj/item/clothing/under/wastelander": "",
+    "/obj/item/clothing/under/wedding": "",
+    "/obj/item/clothing/under/wise_tutor": "",
+    "/obj/item/clothing/under/ww1/british": "",
+    "/obj/item/clothing/under/ww1/french": "",
+    "/obj/item/clothing/under/ww1/german": "",
+    "/obj/item/clothing/under/ww1/trenchsuit": "",
+    "/obj/item/clothing/under/ww2/british": "",
+    "/obj/item/clothing/under/ww2/chiuni": "",
+    "/obj/item/clothing/under/ww2/civ1": "",
+    "/obj/item/clothing/under/ww2/civ2": "",
+    "/obj/item/clothing/under/ww2/cra_uni": "",
+    "/obj/item/clothing/under/ww2/finnish": "",
+    "/obj/item/clothing/under/ww2/german": "",
+    "/obj/item/clothing/under/ww2/german_doctor": "",
+    "/obj/item/clothing/under/ww2/german_officer": "",
+    "/obj/item/clothing/under/ww2/german_ss": "",
+    "/obj/item/clothing/under/ww2/german_ss_officer": "",
+    "/obj/item/clothing/under/ww2/gulag_prisoner": "",
+    "/obj/item/clothing/under/ww2/japoffuni": "",
+    "/obj/item/clothing/under/ww2/japuni": "",
+    "/obj/item/clothing/under/ww2/japuni_tanker": "",
+    "/obj/item/clothing/under/ww2/soviet": "",
+    "/obj/item/clothing/under/ww2/soviet_amoeba": "",
+    "/obj/item/clothing/under/ww2/soviet_berezka": "",
+    "/obj/item/clothing/under/ww2/soviet_nkvd": "",
+    "/obj/item/clothing/under/ww2/soviet_nkvd/kgb": "",
+    "/obj/item/clothing/under/ww2/soviet_officer": "",
+    "/obj/item/clothing/under/ww2/upa": "",
+    "/obj/item/clothing/under/ww2/us": "",
+    "/obj/item/clothing/under/ww2/us_cap": "",
+    "/obj/item/clothing/under/ww2/us_mp": "",
+    "/obj/item/clothing/under/ww2/us_navy": "",
+    "/obj/item/clothing/under/ww2/us_shirtless": "",
+    "/obj/item/clothing/under/yellow_shorts": "",
+    "/obj/item/cocktail_stuff/celery": "",
+    "/obj/item/cocktail_stuff/cocktail_olive": "",
+    "/obj/item/cocktail_stuff/maraschino_cherry": "",
+    "/obj/item/connector": "",
+    "/obj/item/cursedtreasure": "",
+    "/obj/item/drone_controller": "",
+    "/obj/item/flagmaker": "",
+    "/obj/item/flare_pouch/normal_full": "",
+    "/obj/item/flare_pouch/white_full": "",
+    "/obj/item/flashlight": "",
+    "/obj/item/flashlight/flare": "",
+    "/obj/item/flashlight/flare/alwayson": "",
+    "/obj/item/flashlight/flare/on": "",
+    "/obj/item/flashlight/flare/signal": "",
+    "/obj/item/flashlight/flare/signal/p47": "",
+    "/obj/item/flashlight/flashlight": "",
+    "/obj/item/flashlight/japflashlight": "",
+    "/obj/item/flashlight/lamp": "",
+    "/obj/item/flashlight/lamp/littlelamp": "",
+    "/obj/item/flashlight/lamp/littlelamp/desklamp": "",
+    "/obj/item/flashlight/lamp/oldlamp": "",
+    "/obj/item/flashlight/lantern": "",
+    "/obj/item/flashlight/lantern/anchored": "",
+    "/obj/item/flashlight/lantern/bronze": "",
+    "/obj/item/flashlight/lantern/on": "",
+    "/obj/item/flashlight/lantern/on/anchored": "",
+    "/obj/item/flashlight/militarylight": "",
+    "/obj/item/flashlight/militarylight/alt": "",
+    "/obj/item/flashlight/modern": "",
+    "/obj/item/flashlight/tiki_torch": "",
+    "/obj/item/flashlight/tiki_torch/on/anchor": "",
+    "/obj/item/flashlight/tiki_torch/on/anchor/unlimited": "",
+    "/obj/item/flashlight/torch": "",
+    "/obj/item/flashlight/torch/on": "",
+    "/obj/item/flashlight/torch/on/unlimited": "",
+    "/obj/item/football": "",
+    "/obj/item/garrote": "",
+    "/obj/item/glass_jar": "",
+    "/obj/item/kitchen/plate": "",
+    "/obj/item/kitchen/snack_bowl": "",
+    "/obj/item/kitchen/wood_bowl": "",
+    "/obj/item/lightbulb": "",
+    "/obj/item/lightbulb/broken": "",
+    "/obj/item/lightbulb/tube": "",
+    "/obj/item/lightbulb/tube/broken": "",
+    "/obj/item/mine/ap": "",
+    "/obj/item/mine/ap/armed": "",
+    "/obj/item/mine/at": "",
+    "/obj/item/mine/at/armed": "",
+    "/obj/item/mine/boobytrap": "",
+    "/obj/item/mine/pipe": "",
+    "/obj/item/mirror": "",
+    "/obj/item/organ/brain": "",
+    "/obj/item/organ/external/head": "",
+    "/obj/item/organ/eyes": "",
+    "/obj/item/organ/heart": "",
+    "/obj/item/organ/kidneys": "",
+    "/obj/item/organ/liver": "",
+    "/obj/item/remains": "",
+    "/obj/item/remains/human": "",
+    "/obj/item/remains/lizard": "",
+    "/obj/item/remains/mouse": "",
+    "/obj/item/roller": "",
+    "/obj/item/roller_holder": "",
+    "/obj/item/sail": "",
+    "/obj/item/shamisen": "",
+    "/obj/item/sign": "",
+    "/obj/item/stack/ammopart/bullet": "",
+    "/obj/item/stack/ammopart/casing/artillery": "",
+    "/obj/item/stack/ammopart/casing/grenade": "",
+    "/obj/item/stack/ammopart/casing/pistol": "",
+    "/obj/item/stack/ammopart/casing/rifle": "",
+    "/obj/item/stack/ammopart/casing/tank": "",
+    "/obj/item/stack/ammopart/stoneball": "",
+    "/obj/item/stack/arrowhead/vial": "",
+    "/obj/item/stack/cable_coil/random/five": "",
+    "/obj/item/stack/cable_coil/red": "",
+    "/obj/item/stack/cable_coil/white": "",
+    "/obj/item/stack/cable_coil/yellow": "",
+    "/obj/item/stack/farming/seeds/agave": "",
+    "/obj/item/stack/farming/seeds/apple": "",
+    "/obj/item/stack/farming/seeds/apricot": "",
+    "/obj/item/stack/farming/seeds/bamboo": "",
+    "/obj/item/stack/farming/seeds/banana": "",
+    "/obj/item/stack/farming/seeds/beans": "",
+    "/obj/item/stack/farming/seeds/cabbage": "",
+    "/obj/item/stack/farming/seeds/carrot": "",
+    "/obj/item/stack/farming/seeds/coca": "",
+    "/obj/item/stack/farming/seeds/coconut": "",
+    "/obj/item/stack/farming/seeds/coffee": "",
+    "/obj/item/stack/farming/seeds/corn": "",
+    "/obj/item/stack/farming/seeds/cotton": "",
+    "/obj/item/stack/farming/seeds/flax": "",
+    "/obj/item/stack/farming/seeds/grapes": "",
+    "/obj/item/stack/farming/seeds/hemp": "",
+    "/obj/item/stack/farming/seeds/lime": "",
+    "/obj/item/stack/farming/seeds/mushroom": "",
+    "/obj/item/stack/farming/seeds/mushroompsy": "",
+    "/obj/item/stack/farming/seeds/oat": "",
+    "/obj/item/stack/farming/seeds/olives": "",
+    "/obj/item/stack/farming/seeds/orange": "",
+    "/obj/item/stack/farming/seeds/peyote": "",
+    "/obj/item/stack/farming/seeds/poppy": "",
+    "/obj/item/stack/farming/seeds/potato": "",
+    "/obj/item/stack/farming/seeds/pumpkin": "",
+    "/obj/item/stack/farming/seeds/redpepper": "",
+    "/obj/item/stack/farming/seeds/rice": "",
+    "/obj/item/stack/farming/seeds/sapodilla": "",
+    "/obj/item/stack/farming/seeds/sugarcane": "",
+    "/obj/item/stack/farming/seeds/tea": "",
+    "/obj/item/stack/farming/seeds/tobacco": "",
+    "/obj/item/stack/farming/seeds/tomato": "",
+    "/obj/item/stack/farming/seeds/tree": "",
+    "/obj/item/stack/farming/seeds/watermelon": "",
+    "/obj/item/stack/farming/seeds/wheat": "",
+    "/obj/item/stack/material/barbwire": "",
+    "/obj/item/stack/material/barbwire/ten": "",
+    "/obj/item/stack/material/barbwire/twnt": "",
+    "/obj/item/stack/material/bone": "",
+    "/obj/item/stack/material/bronze": "",
+    "/obj/item/stack/material/cloth": "",
+    "/obj/item/stack/material/coca": "",
+    "/obj/item/stack/material/copper": "",
+    "/obj/item/stack/material/cotton": "",
+    "/obj/item/stack/material/diamond": "",
+    "/obj/item/stack/material/electronics": "",
+    "/obj/item/stack/material/glass": "",
+    "/obj/item/stack/material/gold": "",
+    "/obj/item/stack/material/hemp": "",
+    "/obj/item/stack/material/iron": "",
+    "/obj/item/stack/material/iron/twentyfive": "",
+    "/obj/item/stack/material/lead": "",
+    "/obj/item/stack/material/leather": "",
+    "/obj/item/stack/material/marble": "",
+    "/obj/item/stack/material/obsidian": "",
+    "/obj/item/stack/material/pelt/gatorpelt": "",
+    "/obj/item/stack/material/pelt/lionpelt": "",
+    "/obj/item/stack/material/pelt/pantherpelt": "",
+    "/obj/item/stack/material/plastic": "",
+    "/obj/item/stack/material/rags": "",
+    "/obj/item/stack/material/rope": "",
+    "/obj/item/stack/material/sandstone": "",
+    "/obj/item/stack/material/silver": "",
+    "/obj/item/stack/material/steel": "",
+    "/obj/item/stack/material/steel/twentyfive": "",
+    "/obj/item/stack/material/stone": "",
+    "/obj/item/stack/material/straw": "",
+    "/obj/item/stack/material/tin": "",
+    "/obj/item/stack/material/tobacco": "",
+    "/obj/item/stack/material/wood": "",
+    "/obj/item/stack/material/wood/twentyfive": "",
+    "/obj/item/stack/material/woodplank/twentyfive": "",
+    "/obj/item/stack/material/wool": "",
+    "/obj/item/stack/material/woolcloth": "",
+    "/obj/item/stack/medical/advanced/bruise_pack": "",
+    "/obj/item/stack/medical/advanced/herbs": "",
+    "/obj/item/stack/medical/advanced/ointment": "",
+    "/obj/item/stack/medical/advanced/sulfa": "",
+    "/obj/item/stack/medical/bruise_pack/bint": "",
+    "/obj/item/stack/medical/bruise_pack/bint/leather": "",
+    "/obj/item/stack/medical/bruise_pack/bint/medic": "",
+    "/obj/item/stack/medical/bruise_pack/gauze": "",
+    "/obj/item/stack/medical/splint": "",
+    "/obj/item/stack/money": "",
+    "/obj/item/stack/money/bitcoin": "",
+    "/obj/item/stack/money/cents": "",
+    "/obj/item/stack/money/coppercoin": "",
+    "/obj/item/stack/money/coppercoin/twohundred": "",
+    "/obj/item/stack/money/dollar": "",
+    "/obj/item/stack/money/dollar/five": "",
+    "/obj/item/stack/money/dollar/onehundy": "",
+    "/obj/item/stack/money/dollar/ten": "",
+    "/obj/item/stack/money/dollar/twenty": "",
+    "/obj/item/stack/money/doubloon": "",
+    "/obj/item/stack/money/doubloon/ten": "",
+    "/obj/item/stack/money/escudo": "",
+    "/obj/item/stack/money/escudo/ten": "",
+    "/obj/item/stack/money/gems": "",
+    "/obj/item/stack/money/goldcoin": "",
+    "/obj/item/stack/money/goldnugget": "",
+    "/obj/item/stack/money/goldvaluables": "",
+    "/obj/item/stack/money/pearls": "",
+    "/obj/item/stack/money/real": "",
+    "/obj/item/stack/money/real/fifty": "",
+    "/obj/item/stack/money/real/twenty": "",
+    "/obj/item/stack/money/rubles": "",
+    "/obj/item/stack/money/septim": "",
+    "/obj/item/stack/money/silvercoin": "",
+    "/obj/item/stack/money/silvercoin/twohundred": "",
+    "/obj/item/stack/money/yen": "",
+    "/obj/item/stack/ore/charcoal": "",
+    "/obj/item/stack/ore/coal": "",
+    "/obj/item/stack/ore/copper": "",
+    "/obj/item/stack/ore/diamond": "",
+    "/obj/item/stack/ore/fossilbone1": "",
+    "/obj/item/stack/ore/fossilleaf2": "",
+    "/obj/item/stack/ore/fossilleaf3": "",
+    "/obj/item/stack/ore/fossilshell1": "",
+    "/obj/item/stack/ore/fossilshell2": "",
+    "/obj/item/stack/ore/fossilshell3": "",
+    "/obj/item/stack/ore/fossilskull1": "",
+    "/obj/item/stack/ore/fossilskull3": "",
+    "/obj/item/stack/ore/glass": "",
+    "/obj/item/stack/ore/gold": "",
+    "/obj/item/stack/ore/iron": "",
+    "/obj/item/stack/ore/lead": "",
+    "/obj/item/stack/ore/obsidian": "",
+    "/obj/item/stack/ore/saltpeter": "",
+    "/obj/item/stack/ore/silver": "",
+    "/obj/item/stack/ore/sulphur": "",
+    "/obj/item/stack/ore/tin": "",
+    "/obj/item/stack/ore/uranium": "",
+    "/obj/item/stack/ore/uranium/random": "",
+    "/obj/item/stack/rods": "",
+    "/obj/item/stack/sausagecasing": "",
+    "/obj/item/stack/teeth/human": "",
+    "/obj/item/tape/police": "",
+    "/obj/item/taperoll/no_tape": "",
+    "/obj/item/taperoll/police": "",
+    "/obj/item/trash/candle": "",
+    "/obj/item/trash/money": "",
+    "/obj/item/trash/tray": "",
+    "/obj/item/trombone": "",
+    "/obj/item/vehicleparts/frame/bike": "",
+    "/obj/item/vehicleparts/wheel": "",
+    "/obj/item/video_camera": "",
+    "/obj/item/violin": "",
+    "/obj/item/weapon/analyser": "",
+    "/obj/item/weapon/armorplate": "",
+    "/obj/item/weapon/armorplates": "",
+    "/obj/item/weapon/attachment/bayonet": "",
+    "/obj/item/weapon/attachment/bayonet = 15": "",
+    "/obj/item/weapon/attachment/bayonet/flag": "",
+    "/obj/item/weapon/attachment/scope": "",
+    "/obj/item/weapon/attachment/scope/adjustable/binoculars": "",
+    "/obj/item/weapon/attachment/scope/adjustable/binoculars/binoculars": "",
+    "/obj/item/weapon/attachment/scope/adjustable/binoculars/laser_designator": "",
+    "/obj/item/weapon/attachment/scope/adjustable/binoculars/small": "",
+    "/obj/item/weapon/attachment/scope/adjustable/sniper_scope": "",
+    "/obj/item/weapon/attachment/silencer": "",
+    "/obj/item/weapon/attachment/silencer/oil_filter": "",
+    "/obj/item/weapon/attachment/silencer/pistol/ww2": "",
+    "/obj/item/weapon/attachment/silencer/plastic_bottle": "",
+    "/obj/item/weapon/barrier": "",
+    "/obj/item/weapon/barrier/sandbag": "",
+    "/obj/item/weapon/barrier/sandbag/empty": "",
+    "/obj/item/weapon/barstool": "",
+    "/obj/item/weapon/barstool/black": "",
+    "/obj/item/weapon/barstool/blue": "",
+    "/obj/item/weapon/barstool/brown": "",
+    "/obj/item/weapon/barstool/green": "",
+    "/obj/item/weapon/barstool/white": "",
+    "/obj/item/weapon/beartrap": "",
+    "/obj/item/weapon/beartrap/armed": "",
+    "/obj/item/weapon/bedroll": "",
+    "/obj/item/weapon/bedsheet": "",
+    "/obj/item/weapon/bedsheet/blue": "",
+    "/obj/item/weapon/bedsheet/brown": "",
+    "/obj/item/weapon/bedsheet/captain": "",
+    "/obj/item/weapon/bedsheet/ce": "",
+    "/obj/item/weapon/bedsheet/green": "",
+    "/obj/item/weapon/bedsheet/hop": "",
+    "/obj/item/weapon/bedsheet/hos": "",
+    "/obj/item/weapon/bedsheet/medical": "",
+    "/obj/item/weapon/bedsheet/mime": "",
+    "/obj/item/weapon/bedsheet/orange": "",
+    "/obj/item/weapon/bedsheet/purple": "",
+    "/obj/item/weapon/bedsheet/rd": "",
+    "/obj/item/weapon/bedsheet/red": "",
+    "/obj/item/weapon/bedsheet/yellow": "",
+    "/obj/item/weapon/berriesgatherer": "",
+    "/obj/item/weapon/book": "",
+    "/obj/item/weapon/book/holybook": "",
+    "/obj/item/weapon/book/language_book": "",
+    "/obj/item/weapon/book/manual": "",
+    "/obj/item/weapon/book/manual/aotd_law": "",
+    "/obj/item/weapon/book/manual/barman_recipes": "",
+    "/obj/item/weapon/book/manual/chef_recipes": "",
+    "/obj/item/weapon/book/research": "",
+    "/obj/item/weapon/branch/sharpened": "",
+    "/obj/item/weapon/broken_bottle": "",
+    "/obj/item/weapon/can": "",
+    "/obj/item/weapon/can/filled": "",
+    "/obj/item/weapon/can/large": "",
+    "/obj/item/weapon/can/small": "",
+    "/obj/item/weapon/cane": "",
+    "/obj/item/weapon/cell/high": "",
+    "/obj/item/weapon/chicken_carcass": "",
+    "/obj/item/weapon/chisel": "",
+    "/obj/item/weapon/chisel/metal": "",
+    "/obj/item/weapon/cigbutt": "",
+    "/obj/item/weapon/cigbutt/cigarbutt": "",
+    "/obj/item/weapon/clay/advclaybricks": "",
+    "/obj/item/weapon/clay/advclaybricks/cement": "",
+    "/obj/item/weapon/clay/advclaybricks/fired": "",
+    "/obj/item/weapon/clay/advclaybricks/fired/cement": "",
+    "/obj/item/weapon/clay/claybricks/fired": "",
+    "/obj/item/weapon/clay/mold/arrowhead/fired": "",
+    "/obj/item/weapon/clay/mold/axehead/fired": "",
+    "/obj/item/weapon/clay/mold/clayjug/fired": "",
+    "/obj/item/weapon/clay/mold/claypot/fired": "",
+    "/obj/item/weapon/clay/mold/fired": "",
+    "/obj/item/weapon/clay/mold/key/fired": "",
+    "/obj/item/weapon/clay/mold/knife": "",
+    "/obj/item/weapon/clay/mold/knife/fired": "",
+    "/obj/item/weapon/clay/mold/pickaxe/fired": "",
+    "/obj/item/weapon/clay/mold/shovel/fired": "",
+    "/obj/item/weapon/clay/mold/spearhead/fired": "",
+    "/obj/item/weapon/clay/mold/sword/fired": "",
+    "/obj/item/weapon/clay/roofing": "",
+    "/obj/item/weapon/clayshards": "",
+    "/obj/item/weapon/clipboard": "",
+    "/obj/item/weapon/clipboard/full": "",
+    "/obj/item/weapon/compass": "",
+    "/obj/item/weapon/compass/modern/tacmap": "",
+    "/obj/item/weapon/covers": "",
+    "/obj/item/weapon/crowbar": "",
+    "/obj/item/weapon/crowbar/prybar": "",
+    "/obj/item/weapon/deck/cards": "",
+    "/obj/item/weapon/deck/tarot": "",
+    "/obj/item/weapon/defibrillator": "",
+    "/obj/item/weapon/defibrillator/loaded": "",
+    "/obj/item/weapon/defibrillator/loaded/high_cap": "",
+    "/obj/item/weapon/dice": "",
+    "/obj/item/weapon/dice/d2": "",
+    "/obj/item/weapon/dice/d20": "",
+    "/obj/item/weapon/disk/os/uos94": "",
+    "/obj/item/weapon/disk/program/monkeysoftmail": "",
+    "/obj/item/weapon/disk/program/orion_trail": "",
+    "/obj/item/weapon/disk/program/squadtracker": "",
+    "/obj/item/weapon/disk/siberiad/nato": "",
+    "/obj/item/weapon/disk/siberiad/soviet": "",
+    "/obj/item/weapon/doctor_handbook": "",
+    "/obj/item/weapon/enginemaker": "",
+    "/obj/item/weapon/evidencebag": "",
+    "/obj/item/weapon/fishing": "",
+    "/obj/item/weapon/fishing/modern": "",
+    "/obj/item/weapon/fishing/net": "",
+    "/obj/item/weapon/flame/candle": "",
+    "/obj/item/weapon/flame/candle/lard": "",
+    "/obj/item/weapon/flame/candle/lard/on": "",
+    "/obj/item/weapon/flame/candle/on": "",
+    "/obj/item/weapon/flame/lighter": "",
+    "/obj/item/weapon/flame/lighter/bullet": "",
+    "/obj/item/weapon/flame/lighter/random": "",
+    "/obj/item/weapon/flame/lighter/zippo": "",
+    "/obj/item/weapon/flamethrower": "",
+    "/obj/item/weapon/flamethrower/eins": "",
+    "/obj/item/weapon/flamethrower/flammenwerfer": "",
+    "/obj/item/weapon/flamethrower/lpo": "",
+    "/obj/item/weapon/flamethrower/roks2": "",
+    "/obj/item/weapon/flamethrower/type100": "",
+    "/obj/item/weapon/flint": "",
+    "/obj/item/weapon/flint/sharpened": "",
+    "/obj/item/weapon/foldable/atgm": "",
+    "/obj/item/weapon/foldable/atgm/bgm_tow": "",
+    "/obj/item/weapon/foldable/generic": "",
+    "/obj/item/weapon/foldable/hescokit": "",
+    "/obj/item/weapon/foldable/pkm": "",
+    "/obj/item/weapon/foldable/type89_mortar": "",
+    "/obj/item/weapon/foldable_shovel/trench": "",
+    "/obj/item/weapon/foldable_shovel/trench/etool": "",
+    "/obj/item/weapon/folder": "",
+    "/obj/item/weapon/folder/black": "",
+    "/obj/item/weapon/folder/blue": "",
+    "/obj/item/weapon/folder/red": "",
+    "/obj/item/weapon/folder/sred": "",
+    "/obj/item/weapon/folder/white": "",
+    "/obj/item/weapon/folder/yellow": "",
+    "/obj/item/weapon/gavelblock": "",
+    "/obj/item/weapon/gavelhammer": "",
+    "/obj/item/weapon/geiger_counter": "",
+    "/obj/item/weapon/generic_MRE_trash": "",
+    "/obj/item/weapon/globe": "",
+    "/obj/item/weapon/goldsceptre": "",
+    "/obj/item/weapon/gongmallet": "",
+    "/obj/item/weapon/grenade": "",
+    "/obj/item/weapon/grenade/antitank": "",
+    "/obj/item/weapon/grenade/antitank/custom": "",
+    "/obj/item/weapon/grenade/antitank/n73": "",
+    "/obj/item/weapon/grenade/antitank/n74": "",
+    "/obj/item/weapon/grenade/antitank/n75": "",
+    "/obj/item/weapon/grenade/antitank/rpg40": "",
+    "/obj/item/weapon/grenade/antitank/rpg40 = 15": "",
+    "/obj/item/weapon/grenade/antitank/rpg40=10": "",
+    "/obj/item/weapon/grenade/antitank/rpg43": "",
+    "/obj/item/weapon/grenade/antitank/stg24_bundle": "",
+    "/obj/item/weapon/grenade/antitank/type99": "",
+    "/obj/item/weapon/grenade/bomb": "",
+    "/obj/item/weapon/grenade/chemical/chlorine": "",
+    "/obj/item/weapon/grenade/chemical/cs_gas/m7a2": "",
+    "/obj/item/weapon/grenade/chemical/mustard": "",
+    "/obj/item/weapon/grenade/chemical/white_phosphorus": "",
+    "/obj/item/weapon/grenade/chemical/xylyl_bromide": "",
+    "/obj/item/weapon/grenade/coldwar/m26": "",
+    "/obj/item/weapon/grenade/coldwar/m67": "",
+    "/obj/item/weapon/grenade/coldwar/nonfrag/m26": "",
+    "/obj/item/weapon/grenade/coldwar/rgd5": "",
+    "/obj/item/weapon/grenade/coldwar/rgd5=15": "",
+    "/obj/item/weapon/grenade/coldwar/stinger": "",
+    "/obj/item/weapon/grenade/dynamite": "",
+    "/obj/item/weapon/grenade/dynamite/ready": "",
+    "/obj/item/weapon/grenade/flashbang": "",
+    "/obj/item/weapon/grenade/flashbang/m84": "",
+    "/obj/item/weapon/grenade/frag/ugl/shell40mm": "",
+    "/obj/item/weapon/grenade/frag/ugl/shell40mm/teargas": "",
+    "/obj/item/weapon/grenade/frag/ugl/shell40mm/teargas = 16": "",
+    "/obj/item/weapon/grenade/frag/ugl/vog25": "",
+    "/obj/item/weapon/grenade/incendiary": "",
+    "/obj/item/weapon/grenade/incendiary/anm14": "",
+    "/obj/item/weapon/grenade/incendiary/anm14=5)}'": "",
+    "/obj/item/weapon/grenade/modern/custom": "",
+    "/obj/item/weapon/grenade/modern/f1": "",
+    "/obj/item/weapon/grenade/modern/impact/oto35": "",
+    "/obj/item/weapon/grenade/modern/impact/rgo": "",
+    "/obj/item/weapon/grenade/modern/mills": "",
+    "/obj/item/weapon/grenade/modern/stg1915": "",
+    "/obj/item/weapon/grenade/old_grenade": "",
+    "/obj/item/weapon/grenade/smokebomb": "",
+    "/obj/item/weapon/grenade/smokebomb/m18smoke": "",
+    "/obj/item/weapon/grenade/smokebomb/rdg1": "",
+    "/obj/item/weapon/grenade/smokebomb/rdg2": "",
+    "/obj/item/weapon/grenade/smokebomb/rdg2=20": "",
+    "/obj/item/weapon/grenade/smokebomb/signal": "",
+    "/obj/item/weapon/grenade/smokebomb/signal/rdg2_yellow": "",
+    "/obj/item/weapon/grenade/smokebomb/ugl/vog25": "",
+    "/obj/item/weapon/grenade/suicide_vest": "",
+    "/obj/item/weapon/grenade/ww2/mills2": "",
+    "/obj/item/weapon/grenade/ww2/mk2": "",
+    "/obj/item/weapon/grenade/ww2/rg42": "",
+    "/obj/item/weapon/grenade/ww2/rgd33": "",
+    "/obj/item/weapon/grenade/ww2/rgd33 = 15": "",
+    "/obj/item/weapon/grenade/ww2/stg1924": "",
+    "/obj/item/weapon/grenade/ww2/type91": "",
+    "/obj/item/weapon/grenade/ww2/type97": "",
+    "/obj/item/weapon/gun/launcher/grenade/standalone/m79": "",
+    "/obj/item/weapon/gun/launcher/rocket/bazooka": "",
+    "/obj/item/weapon/gun/launcher/rocket/piat": "",
+    "/obj/item/weapon/gun/launcher/rocket/rpb54": "",
+    "/obj/item/weapon/gun/launcher/rocket/rpg7": "",
+    "/obj/item/weapon/gun/launcher/rocket/single_shot/m72law": "",
+    "/obj/item/weapon/gun/launcher/rocket/single_shot/panzerfaust": "",
+    "/obj/item/weapon/gun/launcher/rocket/single_shot/rpg22": "",
+    "/obj/item/weapon/gun/projectile/ancient/arquebus": "",
+    "/obj/item/weapon/gun/projectile/ancient/firelance": "",
+    "/obj/item/weapon/gun/projectile/ancient/handcannon": "",
+    "/obj/item/weapon/gun/projectile/ancient/matchlock": "",
+    "/obj/item/weapon/gun/projectile/ancient/tanegashima": "",
+    "/obj/item/weapon/gun/projectile/automatic/bar": "",
+    "/obj/item/weapon/gun/projectile/automatic/breda30": "",
+    "/obj/item/weapon/gun/projectile/automatic/browning_lmg": "",
+    "/obj/item/weapon/gun/projectile/automatic/dp28": "",
+    "/obj/item/weapon/gun/projectile/automatic/m60": "",
+    "/obj/item/weapon/gun/projectile/automatic/madsen": "",
+    "/obj/item/weapon/gun/projectile/automatic/manual/m249": "",
+    "/obj/item/weapon/gun/projectile/automatic/manual/mg34": "",
+    "/obj/item/weapon/gun/projectile/automatic/manual/rpd": "",
+    "/obj/item/weapon/gun/projectile/automatic/mg13": "",
+    "/obj/item/weapon/gun/projectile/automatic/negev": "",
+    "/obj/item/weapon/gun/projectile/automatic/pkm": "",
+    "/obj/item/weapon/gun/projectile/automatic/pkm = 8": "",
+    "/obj/item/weapon/gun/projectile/automatic/rpk47": "",
+    "/obj/item/weapon/gun/projectile/automatic/rpk74": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/atgm": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/blugoslavia": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/browning": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/dshk": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/foldable/pkm": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/hotchkiss1914": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/laser/eweb": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/m2browning": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/maxim": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/maxim/ww2": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/mg08": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/mg34": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/nsvt": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/pkm": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/redmenia": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/type98": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/vickers": "",
+    "/obj/item/weapon/gun/projectile/automatic/stationary/vickers/type24": "",
+    "/obj/item/weapon/gun/projectile/automatic/type99": "",
+    "/obj/item/weapon/gun/projectile/boltaction/arisaka30": "",
+    "/obj/item/weapon/gun/projectile/boltaction/arisaka38": "",
+    "/obj/item/weapon/gun/projectile/boltaction/arisaka99": "",
+    "/obj/item/weapon/gun/projectile/boltaction/arisaka99/sniper": "",
+    "/obj/item/weapon/gun/projectile/boltaction/arisaka99_training": "",
+    "/obj/item/weapon/gun/projectile/boltaction/berthier/m16": "",
+    "/obj/item/weapon/gun/projectile/boltaction/carcano": "",
+    "/obj/item/weapon/gun/projectile/boltaction/enfield": "",
+    "/obj/item/weapon/gun/projectile/boltaction/gewehr71": "",
+    "/obj/item/weapon/gun/projectile/boltaction/gewehr98": "",
+    "/obj/item/weapon/gun/projectile/boltaction/gewehr98/karabiner98k": "",
+    "/obj/item/weapon/gun/projectile/boltaction/gewehr98/karabiner98k/chinese": "",
+    "/obj/item/weapon/gun/projectile/boltaction/gewehr98/karabiner98k/sniper": "",
+    "/obj/item/weapon/gun/projectile/boltaction/lebel": "",
+    "/obj/item/weapon/gun/projectile/boltaction/m24": "",
+    "/obj/item/weapon/gun/projectile/boltaction/mosin": "",
+    "/obj/item/weapon/gun/projectile/boltaction/mosin/m30": "",
+    "/obj/item/weapon/gun/projectile/boltaction/mosin/m30/sniper": "",
+    "/obj/item/weapon/gun/projectile/boltaction/mosin/obrez": "",
+    "/obj/item/weapon/gun/projectile/boltaction/murata": "",
+    "/obj/item/weapon/gun/projectile/boltaction/p14enfield": "",
+    "/obj/item/weapon/gun/projectile/boltaction/singleshot": "",
+    "/obj/item/weapon/gun/projectile/boltaction/singleshot/barrett": "",
+    "/obj/item/weapon/gun/projectile/boltaction/singleshot/makeshiftbolt": "",
+    "/obj/item/weapon/gun/projectile/boltaction/singleshot/martini_henry": "",
+    "/obj/item/weapon/gun/projectile/boltaction/singleshot/ptrd": "",
+    "/obj/item/weapon/gun/projectile/boltaction/singleshot/pzb39": "",
+    "/obj/item/weapon/gun/projectile/boltaction/singleshot/rollingblock": "",
+    "/obj/item/weapon/gun/projectile/boltaction/singleshot/rollingblock/spanish": "",
+    "/obj/item/weapon/gun/projectile/boltaction/springfield": "",
+    "/obj/item/weapon/gun/projectile/boltaction/springfield/sniper": "",
+    "/obj/item/weapon/gun/projectile/bow": "",
+    "/obj/item/weapon/gun/projectile/bow/compoundbow": "",
+    "/obj/item/weapon/gun/projectile/bow/crossbow": "",
+    "/obj/item/weapon/gun/projectile/bow/longbow": "",
+    "/obj/item/weapon/gun/projectile/bow/shortbow": "",
+    "/obj/item/weapon/gun/projectile/bow/sling": "",
+    "/obj/item/weapon/gun/projectile/capnball/dragoon": "",
+    "/obj/item/weapon/gun/projectile/capnball/walker": "",
+    "/obj/item/weapon/gun/projectile/dartgun/mag": "",
+    "/obj/item/weapon/gun/projectile/flintlock": "",
+    "/obj/item/weapon/gun/projectile/flintlock/blunderbuss": "",
+    "/obj/item/weapon/gun/projectile/flintlock/blunderbuss/pistol": "",
+    "/obj/item/weapon/gun/projectile/flintlock/brownbess": "",
+    "/obj/item/weapon/gun/projectile/flintlock/crude": "",
+    "/obj/item/weapon/gun/projectile/flintlock/duellingpistol": "",
+    "/obj/item/weapon/gun/projectile/flintlock/jezail": "",
+    "/obj/item/weapon/gun/projectile/flintlock/kabyle": "",
+    "/obj/item/weapon/gun/projectile/flintlock/m1752": "",
+    "/obj/item/weapon/gun/projectile/flintlock/musket": "",
+    "/obj/item/weapon/gun/projectile/flintlock/musketoon": "",
+    "/obj/item/weapon/gun/projectile/flintlock/pistol": "",
+    "/obj/item/weapon/gun/projectile/flintlock/pistoletmodelean1733": "",
+    "/obj/item/weapon/gun/projectile/flintlock/pistoletmodeleanxiii": "",
+    "/obj/item/weapon/gun/projectile/flintlock/plexico": "",
+    "/obj/item/weapon/gun/projectile/flintlock/springfield": "",
+    "/obj/item/weapon/gun/projectile/flintlock/springfield1795": "",
+    "/obj/item/weapon/gun/projectile/leveraction/winchesterm1873": "",
+    "/obj/item/weapon/gun/projectile/leveraction/winchesterm1873/gold": "",
+    "/obj/item/weapon/gun/projectile/leveraction/winchesterm1876": "",
+    "/obj/item/weapon/gun/projectile/pistol/blackm1911": "",
+    "/obj/item/weapon/gun/projectile/pistol/browninghp": "",
+    "/obj/item/weapon/gun/projectile/pistol/glock17": "",
+    "/obj/item/weapon/gun/projectile/pistol/glock17/standardized": "",
+    "/obj/item/weapon/gun/projectile/pistol/jericho941": "",
+    "/obj/item/weapon/gun/projectile/pistol/laser/dc17c": "",
+    "/obj/item/weapon/gun/projectile/pistol/laser/westar34": "",
+    "/obj/item/weapon/gun/projectile/pistol/luger": "",
+    "/obj/item/weapon/gun/projectile/pistol/m1911": "",
+    "/obj/item/weapon/gun/projectile/pistol/m9beretta": "",
+    "/obj/item/weapon/gun/projectile/pistol/m9beretta/silenced": "",
+    "/obj/item/weapon/gun/projectile/pistol/makarov": "",
+    "/obj/item/weapon/gun/projectile/pistol/makarov/silenced": "",
+    "/obj/item/weapon/gun/projectile/pistol/mauser": "",
+    "/obj/item/weapon/gun/projectile/pistol/mp443": "",
+    "/obj/item/weapon/gun/projectile/pistol/nambu": "",
+    "/obj/item/weapon/gun/projectile/pistol/p220": "",
+    "/obj/item/weapon/gun/projectile/pistol/sti2011": "",
+    "/obj/item/weapon/gun/projectile/pistol/tarus": "",
+    "/obj/item/weapon/gun/projectile/pistol/tt30": "",
+    "/obj/item/weapon/gun/projectile/pistol/tt30 = 15": "",
+    "/obj/item/weapon/gun/projectile/pistol/tt30/silenced": "",
+    "/obj/item/weapon/gun/projectile/pistol/waltherp38": "",
+    "/obj/item/weapon/gun/projectile/pistol/ww2/nambu": "",
+    "/obj/item/weapon/gun/projectile/revolver/colt1892": "",
+    "/obj/item/weapon/gun/projectile/revolver/coltpolicepositive": "",
+    "/obj/item/weapon/gun/projectile/revolver/frontier": "",
+    "/obj/item/weapon/gun/projectile/revolver/graysonfito12": "",
+    "/obj/item/weapon/gun/projectile/revolver/m1892": "",
+    "/obj/item/weapon/gun/projectile/revolver/magnum44": "",
+    "/obj/item/weapon/gun/projectile/revolver/nagant_revolver": "",
+    "/obj/item/weapon/gun/projectile/revolver/peacemaker": "",
+    "/obj/item/weapon/gun/projectile/revolver/smithwesson": "",
+    "/obj/item/weapon/gun/projectile/revolver/snw10": "",
+    "/obj/item/weapon/gun/projectile/revolver/sw3": "",
+    "/obj/item/weapon/gun/projectile/revolver/t26_revolver": "",
+    "/obj/item/weapon/gun/projectile/revolver/webley4": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/ar15": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/avtomat": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/barrett": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/barrett/sniper": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/g41": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/g43": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/m1carbine": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/m1garand": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/m1garand/match": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/remington11": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/sks": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/sks/chinese": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/sks/sksm": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/svd": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/svd = 4": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/svd/acog": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/svt": "",
+    "/obj/item/weapon/gun/projectile/semiautomatic/vintorez": "",
+    "/obj/item/weapon/gun/projectile/shotgun/coachgun": "",
+    "/obj/item/weapon/gun/projectile/shotgun/mts225": "",
+    "/obj/item/weapon/gun/projectile/shotgun/pump": "",
+    "/obj/item/weapon/gun/projectile/shotgun/pump/remington870": "",
+    "/obj/item/weapon/gun/projectile/shotgun/pump/remington870/brown": "",
+    "/obj/item/weapon/gun/projectile/special/ak74mtactical": "",
+    "/obj/item/weapon/gun/projectile/special/mk18": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ak101/ak103": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ak47": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ak47/akms": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ak47/chinese": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ak47/gold": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ak74": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ak74/aks74": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ak74/aks74/aks74u": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ak74/aks74/aks74u/aks74uso": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ak74/aks74/aks74u/aks74uso = 8": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ak74/grenade_launcher": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ak74/pso1": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ak74m": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ar10": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ar12": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/c7": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ermaemp": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/fal": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/fg42": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/greasegun": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/hk417": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/m14": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/m14/sniper": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/m16": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/m16/ar15": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/m16/commando/m4": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/m16/m16a2/grenade_launcher": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/m16/m16a4": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/m2carbine": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/mac10": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/makeshiftak47": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/mp40": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/mp40/blyskawica": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/mp40/modello38": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/mp40/mp38": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/mp40/mp5": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/p90": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ppd": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/pps": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/ppsh": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/saiga12": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/scarh": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/scarl": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/spas": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/sten": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/sten/stv": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/stg": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/tec9": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/thompson": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/tommy": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/type100": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/usas12": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/uzi": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/vector": "",
+    "/obj/item/weapon/gun/projectile/submachinegun/vz58": "",
+    "/obj/item/weapon/gun_cleaning_kit": "",
+    "/obj/item/weapon/haircomb": "",
+    "/obj/item/weapon/hammer": "",
+    "/obj/item/weapon/hammer/modern": "",
+    "/obj/item/weapon/hammer/tribalhammer": "",
+    "/obj/item/weapon/handbell": "",
+    "/obj/item/weapon/handcuffs": "",
+    "/obj/item/weapon/handcuffs/old": "",
+    "/obj/item/weapon/handcuffs/rope": "",
+    "/obj/item/weapon/handcuffs/strips": "",
+    "/obj/item/weapon/hiddenstash/grenade": "",
+    "/obj/item/weapon/hiddenstash/luger": "",
+    "/obj/item/weapon/hiddenstash/mp40": "",
+    "/obj/item/weapon/hiddenstash/sten": "",
+    "/obj/item/weapon/horn": "",
+    "/obj/item/weapon/key": "",
+    "/obj/item/weapon/key/american": "",
+    "/obj/item/weapon/key/ancient/roman": "",
+    "/obj/item/weapon/key/chinese": "",
+    "/obj/item/weapon/key/civ": "",
+    "/obj/item/weapon/key/civ/bank": "",
+    "/obj/item/weapon/key/civ/businessblue": "",
+    "/obj/item/weapon/key/civ/gov": "",
+    "/obj/item/weapon/key/civ/hall": "",
+    "/obj/item/weapon/key/civ/inn": "",
+    "/obj/item/weapon/key/civ/mckellen": "",
+    "/obj/item/weapon/key/civ/mechanic": "",
+    "/obj/item/weapon/key/civ/paramedics": "",
+    "/obj/item/weapon/key/civ/police": "",
+    "/obj/item/weapon/key/civ/room1": "",
+    "/obj/item/weapon/key/civ/room2": "",
+    "/obj/item/weapon/key/civ/room3": "",
+    "/obj/item/weapon/key/civ/room4": "",
+    "/obj/item/weapon/key/civ/room5": "",
+    "/obj/item/weapon/key/civ/room6": "",
+    "/obj/item/weapon/key/civ/room7": "",
+    "/obj/item/weapon/key/civ/room8": "",
+    "/obj/item/weapon/key/civ/sheriff": "",
+    "/obj/item/weapon/key/dutch": "",
+    "/obj/item/weapon/key/eft/cellar": "",
+    "/obj/item/weapon/key/eft/gate0": "",
+    "/obj/item/weapon/key/eft/medgate": "",
+    "/obj/item/weapon/key/eft/pump": "",
+    "/obj/item/weapon/key/eft/pumpalt": "",
+    "/obj/item/weapon/key/french": "",
+    "/obj/item/weapon/key/german": "",
+    "/obj/item/weapon/key/german/officer": "",
+    "/obj/item/weapon/key/insurgent": "",
+    "/obj/item/weapon/key/japanese": "",
+    "/obj/item/weapon/key/japanese_officer": "",
+    "/obj/item/weapon/key/portuguese": "",
+    "/obj/item/weapon/key/russian": "",
+    "/obj/item/weapon/key/soviet": "",
+    "/obj/item/weapon/key/soviet/guard": "",
+    "/obj/item/weapon/key/soviet/guard/max": "",
+    "/obj/item/weapon/key/tribal": "",
+    "/obj/item/weapon/leash": "",
+    "/obj/item/weapon/legcuffs": "",
+    "/obj/item/weapon/lipstick/black": "",
+    "/obj/item/weapon/lipstick/purple": "",
+    "/obj/item/weapon/lipstick/random": "",
+    "/obj/item/weapon/lockpick": "",
+    "/obj/item/weapon/lungemine": "",
+    "/obj/item/weapon/macuahuitl": "",
+    "/obj/item/weapon/map": "",
+    "/obj/item/weapon/map_tdm/abashiri": "",
+    "/obj/item/weapon/map_tdm/kandahar": "",
+    "/obj/item/weapon/matchbox": "",
+    "/obj/item/weapon/material/ashtray": "",
+    "/obj/item/weapon/material/ashtray/bronze": "",
+    "/obj/item/weapon/material/ashtray/glass": "",
+    "/obj/item/weapon/material/ashtray/marble": "",
+    "/obj/item/weapon/material/ashtray/stone": "",
+    "/obj/item/weapon/material/boarding_axe": "",
+    "/obj/item/weapon/material/classic_baton": "",
+    "/obj/item/weapon/material/classic_baton/blackjack": "",
+    "/obj/item/weapon/material/classic_baton/guard": "",
+    "/obj/item/weapon/material/classic_baton/guard/metal": "",
+    "/obj/item/weapon/material/classic_baton/nightstick": "",
+    "/obj/item/weapon/material/fancycane": "",
+    "/obj/item/weapon/material/handle": "",
+    "/obj/item/weapon/material/harpoon": "",
+    "/obj/item/weapon/material/hatchet": "",
+    "/obj/item/weapon/material/hatchet/battleaxe": "",
+    "/obj/item/weapon/material/hatchet/battleaxe/steel": "",
+    "/obj/item/weapon/material/hatchet/battleaxe/tes13": "",
+    "/obj/item/weapon/material/hatchet/battleaxe/tes13/battleaxe": "",
+    "/obj/item/weapon/material/hatchet/bone_battleaxe": "",
+    "/obj/item/weapon/material/hatchet/bronze": "",
+    "/obj/item/weapon/material/hatchet/steel": "",
+    "/obj/item/weapon/material/hatchet/tribal": "",
+    "/obj/item/weapon/material/hatchet/tribal/bone": "",
+    "/obj/item/weapon/material/hatchet/tribal/flint": "",
+    "/obj/item/weapon/material/kitchen/rollingpin": "",
+    "/obj/item/weapon/material/kitchen/utensil/chopsticks": "",
+    "/obj/item/weapon/material/kitchen/utensil/fork": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/blackknife": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/bone": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/bowie": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/bowie/iron": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/bread": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/bronze": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/butcher": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/circumcision": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/fancy": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/fish": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/hook": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/iron": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/meat": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/military": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/military/iron": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/razorblade": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/shaggers": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/shank": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/shank/iron": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/steel": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/survival": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/tanto": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/trench": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/trench/iron": "",
+    "/obj/item/weapon/material/kitchen/utensil/knife/wood": "",
+    "/obj/item/weapon/material/kitchen/utensil/spoon": "",
+    "/obj/item/weapon/material/machete": "",
+    "/obj/item/weapon/material/machete = 15": "",
+    "/obj/item/weapon/material/machete1": "",
+    "/obj/item/weapon/material/magic/wand": "",
+    "/obj/item/weapon/material/marx": "",
+    "/obj/item/weapon/material/minihoe": "",
+    "/obj/item/weapon/material/naginata": "",
+    "/obj/item/weapon/material/naginata/steel": "",
+    "/obj/item/weapon/material/pickaxe": "",
+    "/obj/item/weapon/material/pickaxe/bone": "",
+    "/obj/item/weapon/material/pickaxe/jackhammer": "",
+    "/obj/item/weapon/material/pickaxe/steel": "",
+    "/obj/item/weapon/material/pickaxe/stone": "",
+    "/obj/item/weapon/material/pike/steel": "",
+    "/obj/item/weapon/material/pilum": "",
+    "/obj/item/weapon/material/pitchfork": "",
+    "/obj/item/weapon/material/quarterstaff": "",
+    "/obj/item/weapon/material/roman_standard": "",
+    "/obj/item/weapon/material/scepter": "",
+    "/obj/item/weapon/material/scythe": "",
+    "/obj/item/weapon/material/scythe/old": "",
+    "/obj/item/weapon/material/shard": "",
+    "/obj/item/weapon/material/shard/glass": "",
+    "/obj/item/weapon/material/shard/shrapnel": "",
+    "/obj/item/weapon/material/shovel": "",
+    "/obj/item/weapon/material/shovel/bone": "",
+    "/obj/item/weapon/material/shovel/spade": "",
+    "/obj/item/weapon/material/shovel/spade/foldable": "",
+    "/obj/item/weapon/material/shovel/spade/small": "",
+    "/obj/item/weapon/material/shovel/steel": "",
+    "/obj/item/weapon/material/shovel/trench": "",
+    "/obj/item/weapon/material/shovel/trench/foldable/etool": "",
+    "/obj/item/weapon/material/spear": "",
+    "/obj/item/weapon/material/spear/dory": "",
+    "/obj/item/weapon/material/spear/halberd": "",
+    "/obj/item/weapon/material/spear/iron": "",
+    "/obj/item/weapon/material/spear/sarissa": "",
+    "/obj/item/weapon/material/spear/sarissa/pike": "",
+    "/obj/item/weapon/material/sword/arabsword": "",
+    "/obj/item/weapon/material/sword/arabsword2": "",
+    "/obj/item/weapon/material/sword/armingsword": "",
+    "/obj/item/weapon/material/sword/armingsword/iron": "",
+    "/obj/item/weapon/material/sword/bolo": "",
+    "/obj/item/weapon/material/sword/broadsword": "",
+    "/obj/item/weapon/material/sword/cutlass": "",
+    "/obj/item/weapon/material/sword/gladius/iron": "",
+    "/obj/item/weapon/material/sword/katana": "",
+    "/obj/item/weapon/material/sword/katana/iron": "",
+    "/obj/item/weapon/material/sword/kukri": "",
+    "/obj/item/weapon/material/sword/longsword": "",
+    "/obj/item/weapon/material/sword/longsword/iron": "",
+    "/obj/item/weapon/material/sword/magic/crimsonedge/lesser": "",
+    "/obj/item/weapon/material/sword/magic/elec/lesser": "",
+    "/obj/item/weapon/material/sword/magic/onoff/green": "",
+    "/obj/item/weapon/material/sword/mersksword": "",
+    "/obj/item/weapon/material/sword/rapier": "",
+    "/obj/item/weapon/material/sword/sabre": "",
+    "/obj/item/weapon/material/sword/sabre/iron": "",
+    "/obj/item/weapon/material/sword/saif": "",
+    "/obj/item/weapon/material/sword/scimitar": "",
+    "/obj/item/weapon/material/sword/shashka": "",
+    "/obj/item/weapon/material/sword/smallsword": "",
+    "/obj/item/weapon/material/sword/smallsword/iron": "",
+    "/obj/item/weapon/material/sword/spadroon": "",
+    "/obj/item/weapon/material/sword/spadroon/iron": "",
+    "/obj/item/weapon/material/sword/tes13/steel": "",
+    "/obj/item/weapon/material/sword/tes13/twohanded": "",
+    "/obj/item/weapon/material/sword/training": "",
+    "/obj/item/weapon/material/sword/vangar": "",
+    "/obj/item/weapon/material/sword/vikingsword/iron": "",
+    "/obj/item/weapon/material/sword/wakazashi": "",
+    "/obj/item/weapon/material/sword/xiphos/bronze": "",
+    "/obj/item/weapon/material/sword/zweihander": "",
+    "/obj/item/weapon/material/tes13/mace": "",
+    "/obj/item/weapon/material/thrown/star": "",
+    "/obj/item/weapon/material/thrown/throwing_axe": "",
+    "/obj/item/weapon/material/thrown/throwing_knife": "",
+    "/obj/item/weapon/material/thrown/tomahawk": "",
+    "/obj/item/weapon/material/twohanded/fireaxe": "",
+    "/obj/item/weapon/material/twohanded/sword/tes13": "",
+    "/obj/item/weapon/melee/baseball_bat": "",
+    "/obj/item/weapon/melee/baseball_bat/aluminium": "",
+    "/obj/item/weapon/melee/classic_baton": "",
+    "/obj/item/weapon/melee/classic_baton/big_club": "",
+    "/obj/item/weapon/melee/classic_baton/club": "",
+    "/obj/item/weapon/melee/classic_baton/guard": "",
+    "/obj/item/weapon/melee/classic_baton/whip": "",
+    "/obj/item/weapon/melee/mace": "",
+    "/obj/item/weapon/melee/nightbaton": "",
+    "/obj/item/weapon/melee/nightbaton = 15": "",
+    "/obj/item/weapon/mop": "",
+    "/obj/item/weapon/newspaper": "",
+    "/obj/item/weapon/package": "",
+    "/obj/item/weapon/paper": "",
+    "/obj/item/weapon/paper/Court": "",
+    "/obj/item/weapon/paper/crumpled": "",
+    "/obj/item/weapon/paper/crumpled/bloody": "",
+    "/obj/item/weapon/paper/k9_manual": "",
+    "/obj/item/weapon/paper/official": "",
+    "/obj/item/weapon/paper/official/activation_code": "",
+    "/obj/item/weapon/paper/police": "",
+    "/obj/item/weapon/paper/police/searchwarrant": "",
+    "/obj/item/weapon/paper/police/searchwarrant/drug": "",
+    "/obj/item/weapon/paper_bin": "",
+    "/obj/item/weapon/paper_bin/empty": "",
+    "/obj/item/weapon/paper_bin/police": "",
+    "/obj/item/weapon/paper_bundle": "",
+    "/obj/item/weapon/pen": "",
+    "/obj/item/weapon/pen/blue": "",
+    "/obj/item/weapon/pen/crayon": "",
+    "/obj/item/weapon/pen/fancy": "",
+    "/obj/item/weapon/pen/multi": "",
+    "/obj/item/weapon/pen/pencil": "",
+    "/obj/item/weapon/pen/reagent/paralysis": "",
+    "/obj/item/weapon/pen/reagent/sleepy": "",
+    "/obj/item/weapon/pen/red": "",
+    "/obj/item/weapon/photo": "",
+    "/obj/item/weapon/pigleg": "",
+    "/obj/item/weapon/pigleg/bloodless": "",
+    "/obj/item/weapon/pigleg/salted": "",
+    "/obj/item/weapon/pigleg/salted/dried": "",
+    "/obj/item/weapon/pigleg/salted/dried/packaged": "",
+    "/obj/item/weapon/pill_pack/adrenaline": "",
+    "/obj/item/weapon/pill_pack/antimalaria": "",
+    "/obj/item/weapon/pill_pack/antitox": "",
+    "/obj/item/weapon/pill_pack/aspirin": "",
+    "/obj/item/weapon/pill_pack/paracetamol": "",
+    "/obj/item/weapon/pill_pack/pervitin": "",
+    "/obj/item/weapon/pill_pack/potassium_iodide": "",
+    "/obj/item/weapon/pill_pack/procrit": "",
+    "/obj/item/weapon/pill_pack/sal_acid": "",
+    "/obj/item/weapon/pill_pack/tramadol": "",
+    "/obj/item/weapon/plastique/c4": "",
+    "/obj/item/weapon/plastique/russian": "",
+    "/obj/item/weapon/plough": "",
+    "/obj/item/weapon/plough/iron": "",
+    "/obj/item/weapon/poster/faction/mil1": "",
+    "/obj/item/weapon/prisoner_passport": "",
+    "/obj/item/weapon/prosthesis/pegleg": "",
+    "/obj/item/weapon/prosthesis/woodfoot": "",
+    "/obj/item/weapon/punji_sticks": "",
+    "/obj/item/weapon/radio": "",
+    "/obj/item/weapon/radio/faction1": "",
+    "/obj/item/weapon/radio/faction2": "",
+    "/obj/item/weapon/radio/walkietalkie": "",
+    "/obj/item/weapon/radio/walkietalkie/faction1": "",
+    "/obj/item/weapon/radio/walkietalkie/faction2/earradio2": "",
+    "/obj/item/weapon/radio/walkietalkie/factionmckellen": "",
+    "/obj/item/weapon/reagent_containers/blood": "",
+    "/obj/item/weapon/reagent_containers/blood/ABMinus": "",
+    "/obj/item/weapon/reagent_containers/blood/ABPlus": "",
+    "/obj/item/weapon/reagent_containers/blood/AMinus": "",
+    "/obj/item/weapon/reagent_containers/blood/APlus": "",
+    "/obj/item/weapon/reagent_containers/blood/BMinus": "",
+    "/obj/item/weapon/reagent_containers/blood/BPlus": "",
+    "/obj/item/weapon/reagent_containers/blood/empty": "",
+    "/obj/item/weapon/reagent_containers/blood/OMinus": "",
+    "/obj/item/weapon/reagent_containers/blood/OPlus": "",
+    "/obj/item/weapon/reagent_containers/blood/saline": "",
+    "/obj/item/weapon/reagent_containers/cocaineblock": "",
+    "/obj/item/weapon/reagent_containers/cocaineblock/torn": "",
+    "/obj/item/weapon/reagent_containers/cocaineblocks": "",
+    "/obj/item/weapon/reagent_containers/cocaineblocks/five": "",
+    "/obj/item/weapon/reagent_containers/cocaineblocks/four": "",
+    "/obj/item/weapon/reagent_containers/cocaineblocks/six": "",
+    "/obj/item/weapon/reagent_containers/cocaineblocks/three": "",
+    "/obj/item/weapon/reagent_containers/dropper": "",
+    "/obj/item/weapon/reagent_containers/dropper/industrial": "",
+    "/obj/item/weapon/reagent_containers/food/condiment/bsugar": "",
+    "/obj/item/weapon/reagent_containers/food/condiment/enzyme": "",
+    "/obj/item/weapon/reagent_containers/food/condiment/flour": "",
+    "/obj/item/weapon/reagent_containers/food/condiment/flour = 1)}'": "",
+    "/obj/item/weapon/reagent_containers/food/condiment/flour/barleyflour": "",
+    "/obj/item/weapon/reagent_containers/food/condiment/flour/oatflour": "",
+    "/obj/item/weapon/reagent_containers/food/condiment/flour=1)}'": "",
+    "/obj/item/weapon/reagent_containers/food/condiment/peppermill": "",
+    "/obj/item/weapon/reagent_containers/food/condiment/saltpile": "",
+    "/obj/item/weapon/reagent_containers/food/condiment/saltshaker": "",
+    "/obj/item/weapon/reagent_containers/food/condiment/sugar": "",
+    "/obj/item/weapon/reagent_containers/food/condiment/tealeaves": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/bluegoose": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/canteen": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/canteen/full": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/canteen/ww2/german": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/canteen/ww2/us": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/cognac": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/expensivewine": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/gin": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/large": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/molotov/vodka": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/palmwine": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/patron": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/plastic/large/water": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/plastic/water": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/rum": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/rum/empty": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/alto_wine": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/cola": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/healing/draught": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/healing/healing_potion": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/healing/minor": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/healing/plentiful": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/healing/vigorous": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/mead": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/sake": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/stamina/minor": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/stamina/plentiful": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/small/stamina/vigorous": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka/empty": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey/empty": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/wine": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/bottle/wine/expensivewine": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/can": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/can/cola": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/can/ice_tea": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/can/lemonade": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/can/lite": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/can/milk": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/can/monster": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/can/water": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/clay/bigclaypot": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/clay/claybowl": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/clay/claycup": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/clay/clayjug": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/clay/claypitcher": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/clay/claypot": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/clay/clayvase": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/clay/claywinecup": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/clay/largeclaypitcher": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/clay/largeclaypitcher/gold": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/clay/verysmallclaypot": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/coffee": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/amphora": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/amphora/water": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/amphora/wine": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/beermug": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/beermug_fancy": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/cocktail": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/custom": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/flute": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/lowball": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/mug": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/mug/brit": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/mug/red": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/shot": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/soda": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/tankard": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/tribalpot": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/waterskin": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/wine": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/wood": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/flask": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/flask/barflask": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/flask/barflask/vodka": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/flask/detflask": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/flask/officer/vodka": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/golden_cup": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/gunpowder": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/gunpowder/full": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/h_chocolate": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/ice": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/jar": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/plastic/carton": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/plastic/cola": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/plastic/sodacan": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/shaker": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/tea": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/tea/empty": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/teapot": "",
+    "/obj/item/weapon/reagent_containers/food/drinks/teapot/filled": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/animalfat": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/applecakeslice": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/applepie": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/appletart": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/bananabreadslice": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/bearmeat": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/beetsoup": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/boiledegg": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/boiledrice": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/boiledspagetti": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/breadslice": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/bun": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/burger": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/caldoverde": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/carrotcakeslice": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/cheeseburger": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/cheesecakeslice": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/cheesewedge": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/cherrypie": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/chicken": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/chicken = 1": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/chicken/breast": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/chicken/drumstick": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/chicken/wing": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/chicken/wing = 1)}'": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/chicken/wing=1)}'": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/chicken=1": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/chocolatebar": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/chocolatebar/pervitin": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/chocolatecakeslice": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/cockroach": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/cookie": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/cow/stomach": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/cracker": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/creamcheesebreadslice": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/csandwich": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/donut": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/donut/banana": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/donut/caramel": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/donut/cherry": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/donut/chocolate": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/donut/grenadine": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/dough": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/driedfish": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/driedmeat": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/driedmeat/minced_driedmeat": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/driedsalmon": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/driedsalmon); randbrand =": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/egg": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/fishfillet": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/fishfingers": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/fishfingers/chickenbucket": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/flatbread": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/friedegg": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/fries": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/frogegg": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grilledcheese": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/agave": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/apple": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/banana": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/banana = 1": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/banana=1": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/barley": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/beans": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/carrot": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/cherry": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/cinchona": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/coconut": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/coffee": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/corn": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/grapes": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/lemon": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/lime": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/lime = 1": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/lime=1": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/oat": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/olives": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/orange": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/peyote": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/potato": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/redpepper": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/rice": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/rice = 1": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/rice=1": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/tomato": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/watermelon": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/watermelon = 1)}'": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/watermelon=1)}'": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/grown/wheat": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/gyro": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/hardtack": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/hotdog": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/jellysandwich": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/lemoncakeslice": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/limecakeslice": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/loadedbakedpotato": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/meat": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/meat/human": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/meat/monkey": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/meat/poisonfrog": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/meat/turtle": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/meatball": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/meatballsoup": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/meatballspagetti": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/meatpie": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/meatsteak": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/mince": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/mint": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/MRE/generic": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/MRE/generic/american": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/MRE/generic/blugoslavian": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/MRE/generic/british": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/MRE/generic/german": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/MRE/generic/italian": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/MRE/generic/japanese": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/MRE/generic/pirates": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/MRE/generic/redmenian": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/MRE/generic/russian": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/MRE/generic/space": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/muffin": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/mushroomsoup": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/noodles": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/octopus": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/omelette": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/pastatomato": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/patty": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/pemmican": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/pickle": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/pickle/big": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/pink_squid": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/pizzameat": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/poo": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/poo/animal": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/poppypretzel": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/pumpkinpieslice": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/ramen": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/rawcrab": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/rawcutlet": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/rawfish/cod": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/rawfish/cod/salted": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/rawfish/salmon": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/rawlobster": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/rawschnitzel": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/rice": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/ricepudding": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sandwich": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sausage": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sausage/bratwurst": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sausage/salted": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sausage/salted/salami": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/baguette": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/bread": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/meatbread": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/pizzacheesed": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/spaghetti": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/ssicle": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/ssicle/gsicle": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/ssicle/osicle": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/stew": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/stew_wood": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/sweetroll": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/toastedsandwich": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/tofu": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/tofupie": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/tomatosoup": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/tossedsalad": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/tripe": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/twobread": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/vegetablesoup": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/waffles": "",
+    "/obj/item/weapon/reagent_containers/food/snacks/watermelonslice": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/ale": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/beer": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/ethanol": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/fat_oil": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/fueltank": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/fueltank/bike": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/fueltank/bike75": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/fueltank/smalltank": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/fueltank/smalltank/fueleddiesel": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/fueltank/smalltank/fueledgasoline": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/fueltank/tank": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/fueltank/tank/fueleddiesel": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/fueltank/tank/fueledgasoline": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/fueltank/tank/highcap/fueleddiesel": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/gunpowder": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/jerrycan": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/jerrycan/diesel": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/jerrycan/gasoline": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/modern": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/modern/bmilk": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/modern/diesel": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/modern/diesel/low": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/modern/ethanol": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/modern/gasoline": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/modern/oil": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/modern/sterilizine": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/modern/water": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/modern/yellow": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/oil": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/olive_oil": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/rum": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/tea": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/vodka": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/water": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/whiskey": "",
+    "/obj/item/weapon/reagent_containers/glass/barrel/wine": "",
+    "/obj/item/weapon/reagent_containers/glass/beaker": "",
+    "/obj/item/weapon/reagent_containers/glass/beaker/large": "",
+    "/obj/item/weapon/reagent_containers/glass/beaker/vial": "",
+    "/obj/item/weapon/reagent_containers/glass/bottle/adrenaline": "",
+    "/obj/item/weapon/reagent_containers/glass/bottle/ammonia": "",
+    "/obj/item/weapon/reagent_containers/glass/bottle/antitoxin": "",
+    "/obj/item/weapon/reagent_containers/glass/bottle/chloralhydrate": "",
+    "/obj/item/weapon/reagent_containers/glass/bottle/cyanide": "",
+    "/obj/item/weapon/reagent_containers/glass/bottle/diethylamine": "",
+    "/obj/item/weapon/reagent_containers/glass/bottle/frostoil": "",
+    "/obj/item/weapon/reagent_containers/glass/bottle/opium": "",
+    "/obj/item/weapon/reagent_containers/glass/bottle/toxin": "",
+    "/obj/item/weapon/reagent_containers/glass/bottle/urine": "",
+    "/obj/item/weapon/reagent_containers/glass/bucket": "",
+    "/obj/item/weapon/reagent_containers/glass/bucket/steel": "",
+    "/obj/item/weapon/reagent_containers/glass/extraction_kit": "",
+    "/obj/item/weapon/reagent_containers/glass/fire_extinguisher": "",
+    "/obj/item/weapon/reagent_containers/glass/fire_extinguisher/ww2": "",
+    "/obj/item/weapon/reagent_containers/glass/flamethrower/eins/filled": "",
+    "/obj/item/weapon/reagent_containers/glass/flamethrower/filled": "",
+    "/obj/item/weapon/reagent_containers/glass/flamethrower/flammenwerfer/filled": "",
+    "/obj/item/weapon/reagent_containers/glass/flamethrower/lpo/filled": "",
+    "/obj/item/weapon/reagent_containers/glass/flamethrower/roks2/filled": "",
+    "/obj/item/weapon/reagent_containers/glass/flamethrower/type100": "",
+    "/obj/item/weapon/reagent_containers/glass/flamethrower/type100/filled": "",
+    "/obj/item/weapon/reagent_containers/glass/paint/black": "",
+    "/obj/item/weapon/reagent_containers/glass/paint/blue": "",
+    "/obj/item/weapon/reagent_containers/glass/paint/red": "",
+    "/obj/item/weapon/reagent_containers/glass/paint/white": "",
+    "/obj/item/weapon/reagent_containers/glass/paint/yellow": "",
+    "/obj/item/weapon/reagent_containers/glass/rag": "",
+    "/obj/item/weapon/reagent_containers/glass/small_pot": "",
+    "/obj/item/weapon/reagent_containers/glass/small_pot/clay": "",
+    "/obj/item/weapon/reagent_containers/glass/small_pot/copper_large": "",
+    "/obj/item/weapon/reagent_containers/glass/small_pot/copper_small": "",
+    "/obj/item/weapon/reagent_containers/glass/small_pot/german_kit_lid": "",
+    "/obj/item/weapon/reagent_containers/glass/small_pot/hangou": "",
+    "/obj/item/weapon/reagent_containers/nuclear/controlrod": "",
+    "/obj/item/weapon/reagent_containers/nuclear/fuelrod": "",
+    "/obj/item/weapon/reagent_containers/nuclear/meltedsomething": "",
+    "/obj/item/weapon/reagent_containers/pill/antitox": "",
+    "/obj/item/weapon/reagent_containers/pill/citalopram": "",
+    "/obj/item/weapon/reagent_containers/pill/cocaine": "",
+    "/obj/item/weapon/reagent_containers/pill/cocaine_line": "",
+    "/obj/item/weapon/reagent_containers/pill/crack": "",
+    "/obj/item/weapon/reagent_containers/pill/dragonpowder": "",
+    "/obj/item/weapon/reagent_containers/pill/happy": "",
+    "/obj/item/weapon/reagent_containers/pill/ketamine": "",
+    "/obj/item/weapon/reagent_containers/pill/methylphenidate": "",
+    "/obj/item/weapon/reagent_containers/pill/opium": "",
+    "/obj/item/weapon/reagent_containers/pill/paracetamol": "",
+    "/obj/item/weapon/reagent_containers/pill/pervitin": "",
+    "/obj/item/weapon/reagent_containers/pill/potassium_iodide": "",
+    "/obj/item/weapon/reagent_containers/pill/tramadol": "",
+    "/obj/item/weapon/reagent_containers/spray/chemsprayer": "",
+    "/obj/item/weapon/reagent_containers/spray/chemsprayer/filled": "",
+    "/obj/item/weapon/reagent_containers/spray/cleaner": "",
+    "/obj/item/weapon/reagent_containers/spray/pepper": "",
+    "/obj/item/weapon/reagent_containers/spray/sterilizine": "",
+    "/obj/item/weapon/reagent_containers/syringe": "",
+    "/obj/item/weapon/reagent_containers/syringe/adrenaline": "",
+    "/obj/item/weapon/reagent_containers/syringe/antitoxin": "",
+    "/obj/item/weapon/reagent_containers/syringe/morphine": "",
+    "/obj/item/weapon/reagent_containers/syringe/sulfanomides": "",
+    "/obj/item/weapon/reagent_containers/syringe/thc": "",
+    "/obj/item/weapon/roofbuilder": "",
+    "/obj/item/weapon/roulette/chip": "",
+    "/obj/item/weapon/roulette/chip/red": "",
+    "/obj/item/weapon/saw": "",
+    "/obj/item/weapon/screwdriver": "",
+    "/obj/item/weapon/shears": "",
+    "/obj/item/weapon/shield": "",
+    "/obj/item/weapon/shield/aspis": "",
+    "/obj/item/weapon/shield/balistic": "",
+    "/obj/item/weapon/shield/chimalli": "",
+    "/obj/item/weapon/shield/iron": "",
+    "/obj/item/weapon/shield/iron/semioval/templar": "",
+    "/obj/item/weapon/shield/iron/semioval/templar2": "",
+    "/obj/item/weapon/shield/metal_riot": "",
+    "/obj/item/weapon/shield/nguni_shield": "",
+    "/obj/item/weapon/shield/nomads": "",
+    "/obj/item/weapon/shield/red_buckler": "",
+    "/obj/item/weapon/shield/roman": "",
+    "/obj/item/weapon/shield/roman/praetorian": "",
+    "/obj/item/weapon/shield/roman_buckler": "",
+    "/obj/item/weapon/shield/steel": "",
+    "/obj/item/weapon/shield/tes13": "",
+    "/obj/item/weapon/shield/tes13/stormcloak": "",
+    "/obj/item/weapon/shield/tes13/whiterun": "",
+    "/obj/item/weapon/siegeladder": "",
+    "/obj/item/weapon/siegeladder/metal": "",
+    "/obj/item/weapon/sledgehammer": "",
+    "/obj/item/weapon/sledgehammer/iron/sledgehammer": "",
+    "/obj/item/weapon/snowwall": "",
+    "/obj/item/weapon/soap": "",
+    "/obj/item/weapon/soap/deluxe": "",
+    "/obj/item/weapon/soap/lard": "",
+    "/obj/item/weapon/soviet_flag": "",
+    "/obj/item/weapon/stamp": "",
+    "/obj/item/weapon/stamp/approved": "",
+    "/obj/item/weapon/stamp/baily": "",
+    "/obj/item/weapon/stamp/denied": "",
+    "/obj/item/weapon/stamp/es": "",
+    "/obj/item/weapon/stamp/fr": "",
+    "/obj/item/weapon/stamp/mail": "",
+    "/obj/item/weapon/stamp/nl": "",
+    "/obj/item/weapon/stamp/pt": "",
+    "/obj/item/weapon/stamp/rd": "",
+    "/obj/item/weapon/stamp/rn": "",
+    "/obj/item/weapon/starterjar": "",
+    "/obj/item/weapon/stool": "",
+    "/obj/item/weapon/stool/padded": "",
+    "/obj/item/weapon/stool/prison": "",
+    "/obj/item/weapon/stool/wood": "",
+    "/obj/item/weapon/storage/ammo_can": "",
+    "/obj/item/weapon/storage/ammo_can/ak74": "",
+    "/obj/item/weapon/storage/ammo_can/breda30": "",
+    "/obj/item/weapon/storage/ammo_can/browning": "",
+    "/obj/item/weapon/storage/ammo_can/dp": "",
+    "/obj/item/weapon/storage/ammo_can/m16": "",
+    "/obj/item/weapon/storage/ammo_can/mg34belt": "",
+    "/obj/item/weapon/storage/ammo_can/mg34drum": "",
+    "/obj/item/weapon/storage/ammo_can/stanag": "",
+    "/obj/item/weapon/storage/backpack": "",
+    "/obj/item/weapon/storage/backpack/buttpack": "",
+    "/obj/item/weapon/storage/backpack/civbag": "",
+    "/obj/item/weapon/storage/backpack/duffel": "",
+    "/obj/item/weapon/storage/backpack/heavyrucksack/atgm": "",
+    "/obj/item/weapon/storage/backpack/paratrooper": "",
+    "/obj/item/weapon/storage/backpack/piatpack/filledearly": "",
+    "/obj/item/weapon/storage/backpack/piatpack/filledlate": "",
+    "/obj/item/weapon/storage/backpack/quiver": "",
+    "/obj/item/weapon/storage/backpack/quiver/crossbow": "",
+    "/obj/item/weapon/storage/backpack/quiver/full": "",
+    "/obj/item/weapon/storage/backpack/quiver/medieval": "",
+    "/obj/item/weapon/storage/backpack/rpg_pack/filled": "",
+    "/obj/item/weapon/storage/backpack/rpg_pack/filled_at": "",
+    "/obj/item/weapon/storage/backpack/rpg_pack/olive": "",
+    "/obj/item/weapon/storage/backpack/rpg_pack/olive/filled": "",
+    "/obj/item/weapon/storage/backpack/rpg_pack/olive/filled_at": "",
+    "/obj/item/weapon/storage/backpack/rucksack": "",
+    "/obj/item/weapon/storage/backpack/rucksack/rpg": "",
+    "/obj/item/weapon/storage/backpack/satchel": "",
+    "/obj/item/weapon/storage/backpack/satchel/black": "",
+    "/obj/item/weapon/storage/backpack/satchel/black/germanat/rpb54": "",
+    "/obj/item/weapon/storage/backpack/satchel/lizard_satchel": "",
+    "/obj/item/weapon/storage/backpack/satchel/police": "",
+    "/obj/item/weapon/storage/backpack/scavpack": "",
+    "/obj/item/weapon/storage/backpack/sovpack": "",
+    "/obj/item/weapon/storage/backpack/ww2/american": "",
+    "/obj/item/weapon/storage/backpack/ww2/german": "",
+    "/obj/item/weapon/storage/backpack/ww2/german/sapper": "",
+    "/obj/item/weapon/storage/backpack/ww2/jap": "",
+    "/obj/item/weapon/storage/backpack/ww2/jap/ammo_crate": "",
+    "/obj/item/weapon/storage/backpack/ww2/jap/ammo_crate/full96": "",
+    "/obj/item/weapon/storage/backpack/ww2/sapper": "",
+    "/obj/item/weapon/storage/backpack/ww2/sapper/german": "",
+    "/obj/item/weapon/storage/backpack/ww2/sapper/russian": "",
+    "/obj/item/weapon/storage/bag/cash": "",
+    "/obj/item/weapon/storage/bag/plasticbag": "",
+    "/obj/item/weapon/storage/bag/trash": "",
+    "/obj/item/weapon/storage/belt": "",
+    "/obj/item/weapon/storage/belt/gulagguard/filled": "",
+    "/obj/item/weapon/storage/belt/jap": "",
+    "/obj/item/weapon/storage/belt/jap/camp_guard": "",
+    "/obj/item/weapon/storage/belt/jap/camp_guard_SS": "",
+    "/obj/item/weapon/storage/belt/jap/ww2soldier100": "",
+    "/obj/item/weapon/storage/belt/keychain": "",
+    "/obj/item/weapon/storage/belt/largepouches": "",
+    "/obj/item/weapon/storage/belt/largepouches/green": "",
+    "/obj/item/weapon/storage/belt/largepouches/m249": "",
+    "/obj/item/weapon/storage/belt/largepouches/olive/m60": "",
+    "/obj/item/weapon/storage/belt/largepouches/pkm": "",
+    "/obj/item/weapon/storage/belt/leather": "",
+    "/obj/item/weapon/storage/belt/leather/shaman": "",
+    "/obj/item/weapon/storage/belt/medical/full_us": "",
+    "/obj/item/weapon/storage/belt/police/modern": "",
+    "/obj/item/weapon/storage/belt/security": "",
+    "/obj/item/weapon/storage/belt/security/tactical": "",
+    "/obj/item/weapon/storage/belt/smallpouches": "",
+    "/obj/item/weapon/storage/belt/smallpouches/green": "",
+    "/obj/item/weapon/storage/belt/smallpouches/green/sov_saiga": "",
+    "/obj/item/weapon/storage/belt/smallpouches/olive/greasegun": "",
+    "/obj/item/weapon/storage/belt/throwing/ninja": "",
+    "/obj/item/weapon/storage/belt/utility": "",
+    "/obj/item/weapon/storage/belt/utility/sapper": "",
+    "/obj/item/weapon/storage/bible": "",
+    "/obj/item/weapon/storage/bible/booze": "",
+    "/obj/item/weapon/storage/bible/orthodox": "",
+    "/obj/item/weapon/storage/bible/quran": "",
+    "/obj/item/weapon/storage/bible/talmud": "",
+    "/obj/item/weapon/storage/box": "",
+    "/obj/item/weapon/storage/box/beermug": "",
+    "/obj/item/weapon/storage/box/bloodpacks": "",
+    "/obj/item/weapon/storage/box/bodybags": "",
+    "/obj/item/weapon/storage/box/bowls": "",
+    "/obj/item/weapon/storage/box/canned": "",
+    "/obj/item/weapon/storage/box/condimentbottles": "",
+    "/obj/item/weapon/storage/box/ctail": "",
+    "/obj/item/weapon/storage/box/cups": "",
+    "/obj/item/weapon/storage/box/cutlery": "",
+    "/obj/item/weapon/storage/box/drinkingglasses": "",
+    "/obj/item/weapon/storage/box/evidence": "",
+    "/obj/item/weapon/storage/box/fingerprints": "",
+    "/obj/item/weapon/storage/box/firstaid": "",
+    "/obj/item/weapon/storage/box/flare": "",
+    "/obj/item/weapon/storage/box/handcuffs": "",
+    "/obj/item/weapon/storage/box/nood": "",
+    "/obj/item/weapon/storage/box/occinn": "",
+    "/obj/item/weapon/storage/box/pillbottles": "",
+    "/obj/item/weapon/storage/box/sandbags": "",
+    "/obj/item/weapon/storage/box/shotglass": "",
+    "/obj/item/weapon/storage/box/slides": "",
+    "/obj/item/weapon/storage/box/specialtyglass": "",
+    "/obj/item/weapon/storage/box/sterglove": "",
+    "/obj/item/weapon/storage/box/stermask": "",
+    "/obj/item/weapon/storage/box/waffle": "",
+    "/obj/item/weapon/storage/box/wheat": "",
+    "/obj/item/weapon/storage/box/wineglasses": "",
+    "/obj/item/weapon/storage/briefcase": "",
+    "/obj/item/weapon/storage/briefcase/crimekit": "",
+    "/obj/item/weapon/storage/emergencykit/base/generic": "",
+    "/obj/item/weapon/storage/envelope": "",
+    "/obj/item/weapon/storage/fancy/candle_box": "",
+    "/obj/item/weapon/storage/fancy/cigar/full": "",
+    "/obj/item/weapon/storage/fancy/cigarettes": "",
+    "/obj/item/weapon/storage/fancy/cigarettes/luckystrike": "",
+    "/obj/item/weapon/storage/fancy/cigarettes/marlboro": "",
+    "/obj/item/weapon/storage/fancy/cigarettes/papirosi": "",
+    "/obj/item/weapon/storage/fancy/cigarettes/randompack": "",
+    "/obj/item/weapon/storage/fancy/cigarettes/randompack/lighter": "",
+    "/obj/item/weapon/storage/fancy/donut_box": "",
+    "/obj/item/weapon/storage/fancy/egg_box": "",
+    "/obj/item/weapon/storage/fancy/medal/german_action": "",
+    "/obj/item/weapon/storage/fancy/medal/german_full": "",
+    "/obj/item/weapon/storage/fancy/medal/german_iron": "",
+    "/obj/item/weapon/storage/fancy/medal/japanese_china_full": "",
+    "/obj/item/weapon/storage/fancy/medal/japanese_pacific_full": "",
+    "/obj/item/weapon/storage/fancy/medal/occupation/factolabo": "",
+    "/obj/item/weapon/storage/fancy/medal/occupation/german_party": "",
+    "/obj/item/weapon/storage/fancy/medal/occupation/hospimedi": "",
+    "/obj/item/weapon/storage/fancy/medal/occupation/minefarm": "",
+    "/obj/item/weapon/storage/fancy/picklejar": "",
+    "/obj/item/weapon/storage/firstaid": "",
+    "/obj/item/weapon/storage/firstaid/adv": "",
+    "/obj/item/weapon/storage/firstaid/advsmall": "",
+    "/obj/item/weapon/storage/firstaid/combat": "",
+    "/obj/item/weapon/storage/firstaid/combat/modern": "",
+    "/obj/item/weapon/storage/firstaid/early": "",
+    "/obj/item/weapon/storage/firstaid/surgery": "",
+    "/obj/item/weapon/storage/firstaid/surgery_bronze": "",
+    "/obj/item/weapon/storage/firstaid/surgery_empty": "",
+    "/obj/item/weapon/storage/foodbox": "",
+    "/obj/item/weapon/storage/foodbox/chippack": "",
+    "/obj/item/weapon/storage/ore_collector": "",
+    "/obj/item/weapon/storage/photo_album": "",
+    "/obj/item/weapon/storage/pill_bottle/antitox": "",
+    "/obj/item/weapon/storage/pill_bottle/citalopram": "",
+    "/obj/item/weapon/storage/pill_bottle/paracetamol": "",
+    "/obj/item/weapon/storage/pill_bottle/penicillin": "",
+    "/obj/item/weapon/storage/pill_bottle/pervitin": "",
+    "/obj/item/weapon/storage/pill_bottle/potassium_iodide": "",
+    "/obj/item/weapon/storage/pill_bottle/tramadol": "",
+    "/obj/item/weapon/storage/produce_basket": "",
+    "/obj/item/weapon/storage/seed_collector": "",
+    "/obj/item/weapon/storage/toolbox": "",
+    "/obj/item/weapon/storage/toolbox/blue": "",
+    "/obj/item/weapon/storage/toolbox/electrical": "",
+    "/obj/item/weapon/storage/toolbox/emergency": "",
+    "/obj/item/weapon/storage/toolbox/mechanical": "",
+    "/obj/item/weapon/storage/toolbox/yellow": "",
+    "/obj/item/weapon/storage/ww2": "",
+    "/obj/item/weapon/storage/ww2/german": "",
+    "/obj/item/weapon/storage/ww2/shaving_kit": "",
+    "/obj/item/weapon/storage/ww2/shaving_kit/german": "",
+    "/obj/item/weapon/storage/ww2/slunch": "",
+    "/obj/item/weapon/surgery/bone_saw": "",
+    "/obj/item/weapon/surgery/bonesetter": "",
+    "/obj/item/weapon/surgery/cautery": "",
+    "/obj/item/weapon/surgery/hemostat": "",
+    "/obj/item/weapon/surgery/retractor": "",
+    "/obj/item/weapon/surgery/scalpel": "",
+    "/obj/item/weapon/surgery/surgicaldrill": "",
+    "/obj/item/weapon/swatter": "",
+    "/obj/item/weapon/swatter/modern": "",
+    "/obj/item/weapon/telephone": "",
+    "/obj/item/weapon/telephone/mobile": "",
+    "/obj/item/weapon/telephone/mobile/campaign/blue": "",
+    "/obj/item/weapon/telephone/mobile/campaign/red": "",
+    "/obj/item/weapon/telephone/mobile/faction": "",
+    "/obj/item/weapon/telephone/mobile/faction/blue": "",
+    "/obj/item/weapon/telephone/mobile/faction/green": "",
+    "/obj/item/weapon/telephone/mobile/faction/mckellen": "",
+    "/obj/item/weapon/telephone/mobile/faction/red": "",
+    "/obj/item/weapon/telephone/mobile/faction/yellow": "",
+    "/obj/item/weapon/telephone/mobile/mobilefaction/blue": "",
+    "/obj/item/weapon/telephone/mobile/mobilefaction/green": "",
+    "/obj/item/weapon/telephone/mobile/mobilefaction/red": "",
+    "/obj/item/weapon/telephone/mobile/mobilefaction/yellow": "",
+    "/obj/item/weapon/telephone/mobile/police": "",
+    "/obj/item/weapon/telephone/public": "",
+    "/obj/item/weapon/telephone/wireless": "",
+    "/obj/item/weapon/tent": "",
+    "/obj/item/weapon/trafficcone": "",
+    "/obj/item/weapon/tray": "",
+    "/obj/item/weapon/type92hmg": "",
+    "/obj/item/weapon/type92tripod": "",
+    "/obj/item/weapon/visa": "",
+    "/obj/item/weapon/watch/pocket": "",
+    "/obj/item/weapon/weldingtool": "",
+    "/obj/item/weapon/whistle": "",
+    "/obj/item/weapon/whistle/tin": "",
+    "/obj/item/weapon/wirecutters": "",
+    "/obj/item/weapon/wirecutters/boltcutters": "",
+    "/obj/item/weapon/wrench": "",
+    "/obj/item/wood_ash": "",
+    "/obj/machinery/dnaforensics": "",
+    "/obj/machinery/microscope": "",
+    "/obj/machinery/slotmachine": "",
+    "/obj/machinery/washing_machine": "",
+    "/obj/random/accessories": "",
+    "/obj/random/armor": "",
+    "/obj/random/barricade/random": "",
+    "/obj/random/explosives": "",
+    "/obj/random/gun/ak_modern": "",
+    "/obj/random/gun/ak47": "",
+    "/obj/random/gun/funny_random": "",
+    "/obj/random/gun/german_random": "",
+    "/obj/random/gun/random_ak": "",
+    "/obj/random/gun/western_random": "",
+    "/obj/random/magazine/ak47": "",
+    "/obj/random/magazine/ak74": "",
+    "/obj/random/magazine/german": "",
+    "/obj/random/magazine/western_random": "",
+    "/obj/random/medical/bandage": "",
+    "/obj/random/medical/drugs": "",
+    "/obj/random/melee": "",
+    "/obj/random/mine/ap": "",
+    "/obj/random/mine/booby": "",
+    "/obj/roof": "",
+    "/obj/roof/canopy": "",
+    "/obj/roof/clay": "",
+    "/obj/roof/clay/black": "",
+    "/obj/roof/clay/blue": "",
+    "/obj/roof/clay/kerawa": "",
+    "/obj/roof/concrete": "",
+    "/obj/roof/mayan": "",
+    "/obj/roof/palm": "",
+    "/obj/roof/sandstone": "",
+    "/obj/roof/thatch": "",
+    "/obj/roof/wood": "",
+    "/obj/structure/altar": "",
+    "/obj/structure/altar/bamboo": "",
+    "/obj/structure/altar/darkstone": "",
+    "/obj/structure/altar/darkstone/sacrifice": "",
+    "/obj/structure/altar/darkstone/unsacrifice": "",
+    "/obj/structure/altar/heads": "",
+    "/obj/structure/altar/iron": "",
+    "/obj/structure/altar/marble": "",
+    "/obj/structure/altar/sandstone": "",
+    "/obj/structure/altar/stone": "",
+    "/obj/structure/altar/stone/material": "",
+    "/obj/structure/altar/wood": "",
+    "/obj/structure/animalspawner/bearcave": "",
+    "/obj/structure/animalspawner/bearcave/full": "",
+    "/obj/structure/animalspawner/wolfcave": "",
+    "/obj/structure/animalspawner/wolfcave/full": "",
+    "/obj/structure/anthill": "",
+    "/obj/structure/ants": "",
+    "/obj/structure/anvil": "",
+    "/obj/structure/anvil/steel": "",
+    "/obj/structure/assembler/loader/blue": "",
+    "/obj/structure/assembler/loader/green": "",
+    "/obj/structure/assembler/loader/red": "",
+    "/obj/structure/assembler/loader/yellow": "",
+    "/obj/structure/assembler/processor": "",
+    "/obj/structure/assembler/unloader": "",
+    "/obj/structure/autopsy_table": "",
+    "/obj/structure/bakelizer": "",
+    "/obj/structure/banner/faction/team/team1": "",
+    "/obj/structure/banner/faction/team/team2": "",
+    "/obj/structure/barbwire": "",
+    "/obj/structure/barricade": "",
+    "/obj/structure/barricade/antitank": "",
+    "/obj/structure/barricade/car": "",
+    "/obj/structure/barricade/construction": "",
+    "/obj/structure/barricade/construction/corner": "",
+    "/obj/structure/barricade/construction/flashing": "",
+    "/obj/structure/barricade/debris": "",
+    "/obj/structure/barricade/debris/brick": "",
+    "/obj/structure/barricade/hescobastion": "",
+    "/obj/structure/barricade/horizontal": "",
+    "/obj/structure/barricade/jap": "",
+    "/obj/structure/barricade/jap_h": "",
+    "/obj/structure/barricade/jap_h_l": "",
+    "/obj/structure/barricade/jap_h_r": "",
+    "/obj/structure/barricade/jap_v": "",
+    "/obj/structure/barricade/jap_v_b": "",
+    "/obj/structure/barricade/jap_v_t": "",
+    "/obj/structure/barricade/sandstone_h": "",
+    "/obj/structure/barricade/sandstone_h/crenelated": "",
+    "/obj/structure/barricade/sandstone_v": "",
+    "/obj/structure/barricade/sandstone_v/crenelated": "",
+    "/obj/structure/barricade/ship": "",
+    "/obj/structure/barricade/ship/aport0": "",
+    "/obj/structure/barricade/ship/aport0/north": "",
+    "/obj/structure/barricade/ship/aport1": "",
+    "/obj/structure/barricade/ship/aport1/north": "",
+    "/obj/structure/barricade/ship/blue/b1": "",
+    "/obj/structure/barricade/ship/blue/b10": "",
+    "/obj/structure/barricade/ship/blue/b15": "",
+    "/obj/structure/barricade/ship/blue/b16": "",
+    "/obj/structure/barricade/ship/blue/b17": "",
+    "/obj/structure/barricade/ship/blue/b18": "",
+    "/obj/structure/barricade/ship/blue/b19": "",
+    "/obj/structure/barricade/ship/blue/b2": "",
+    "/obj/structure/barricade/ship/blue/b20": "",
+    "/obj/structure/barricade/ship/blue/b4": "",
+    "/obj/structure/barricade/ship/blue/b8": "",
+    "/obj/structure/barricade/ship/blue/b9": "",
+    "/obj/structure/barricade/ship/blue/beast": "",
+    "/obj/structure/barricade/ship/blue/beast2": "",
+    "/obj/structure/barricade/ship/blue/bwest": "",
+    "/obj/structure/barricade/ship/blue/bwest2": "",
+    "/obj/structure/barricade/ship/mast": "",
+    "/obj/structure/barricade/ship/mast/large": "",
+    "/obj/structure/barricade/ship/north/corners": "",
+    "/obj/structure/barricade/ship/wall2": "",
+    "/obj/structure/barricade/ship/wall2/doorway": "",
+    "/obj/structure/barricade/ship/wood/a1": "",
+    "/obj/structure/barricade/ship/wood/a10": "",
+    "/obj/structure/barricade/ship/wood/a12": "",
+    "/obj/structure/barricade/ship/wood/a2": "",
+    "/obj/structure/barricade/ship/wood/a3": "",
+    "/obj/structure/barricade/ship/wood/a4": "",
+    "/obj/structure/barricade/ship/wood/a5": "",
+    "/obj/structure/barricade/ship/wood/a6": "",
+    "/obj/structure/barricade/ship/wood/a7": "",
+    "/obj/structure/barricade/ship/wood/a8": "",
+    "/obj/structure/barricade/ship/wood/a9": "",
+    "/obj/structure/barricade/steel": "",
+    "/obj/structure/barricade/steel_crowd": "",
+    "/obj/structure/barricade/stone_h": "",
+    "/obj/structure/barricade/stone_h/crenelated": "",
+    "/obj/structure/barricade/stone_v": "",
+    "/obj/structure/barricade/stone_v/crenelated": "",
+    "/obj/structure/barricade/tires": "",
+    "/obj/structure/barricade/velvet_rope": "",
+    "/obj/structure/barricade/vertical": "",
+    "/obj/structure/barricade/wood_pole": "",
+    "/obj/structure/bed": "",
+    "/obj/structure/bed/bedroll": "",
+    "/obj/structure/bed/chair": "",
+    "/obj/structure/bed/chair/barber": "",
+    "/obj/structure/bed/chair/carseat/left": "",
+    "/obj/structure/bed/chair/carseat/left/dark": "",
+    "/obj/structure/bed/chair/carseat/left/type94": "",
+    "/obj/structure/bed/chair/carseat/left/type95": "",
+    "/obj/structure/bed/chair/carseat/right": "",
+    "/obj/structure/bed/chair/carseat/right/dark": "",
+    "/obj/structure/bed/chair/comfy": "",
+    "/obj/structure/bed/chair/comfy/beige": "",
+    "/obj/structure/bed/chair/comfy/black": "",
+    "/obj/structure/bed/chair/comfy/blue": "",
+    "/obj/structure/bed/chair/comfy/brown": "",
+    "/obj/structure/bed/chair/comfy/diner_booth": "",
+    "/obj/structure/bed/chair/comfy/diner_booth/l": "",
+    "/obj/structure/bed/chair/comfy/diner_booth/r": "",
+    "/obj/structure/bed/chair/comfy/fancy_sofa": "",
+    "/obj/structure/bed/chair/comfy/fancy_sofa/l": "",
+    "/obj/structure/bed/chair/comfy/fancy_sofa/r": "",
+    "/obj/structure/bed/chair/comfy/green": "",
+    "/obj/structure/bed/chair/comfy/purp": "",
+    "/obj/structure/bed/chair/comfy/red": "",
+    "/obj/structure/bed/chair/commander": "",
+    "/obj/structure/bed/chair/commander/naval": "",
+    "/obj/structure/bed/chair/drivers": "",
+    "/obj/structure/bed/chair/drivers/car": "",
+    "/obj/structure/bed/chair/drivers/car/dark": "",
+    "/obj/structure/bed/chair/drivers/car/type94": "",
+    "/obj/structure/bed/chair/drivers/car/type95": "",
+    "/obj/structure/bed/chair/drivers/tank": "",
+    "/obj/structure/bed/chair/executive": "",
+    "/obj/structure/bed/chair/gunner": "",
+    "/obj/structure/bed/chair/loader": "",
+    "/obj/structure/bed/chair/mgunner/browning_lmg": "",
+    "/obj/structure/bed/chair/mgunner/dtm28": "",
+    "/obj/structure/bed/chair/mgunner/mg34": "",
+    "/obj/structure/bed/chair/mgunner/pkm": "",
+    "/obj/structure/bed/chair/office": "",
+    "/obj/structure/bed/chair/office/dark": "",
+    "/obj/structure/bed/chair/office/light": "",
+    "/obj/structure/bed/chair/sofa": "",
+    "/obj/structure/bed/chair/sofa/left": "",
+    "/obj/structure/bed/chair/sofa/right": "",
+    "/obj/structure/bed/chair/steel": "",
+    "/obj/structure/bed/chair/steel/alt": "",
+    "/obj/structure/bed/chair/steel/alt/blue": "",
+    "/obj/structure/bed/chair/steel/alt/green": "",
+    "/obj/structure/bed/chair/steel/alt/red": "",
+    "/obj/structure/bed/chair/steel/alt/yellow": "",
+    "/obj/structure/bed/chair/stone": "",
+    "/obj/structure/bed/chair/throne": "",
+    "/obj/structure/bed/chair/wheelchair": "",
+    "/obj/structure/bed/chair/wood": "",
+    "/obj/structure/bed/chair/wood/alt": "",
+    "/obj/structure/bed/chair/wood/bleacher": "",
+    "/obj/structure/bed/chair/wood/bleacher/l": "",
+    "/obj/structure/bed/chair/wood/bleacher/r": "",
+    "/obj/structure/bed/chair/wood/red": "",
+    "/obj/structure/bed/chair/wood/wings": "",
+    "/obj/structure/bed/custsofa": "",
+    "/obj/structure/bed/custsofa/corner": "",
+    "/obj/structure/bed/custsofa/left": "",
+    "/obj/structure/bed/custsofa/right": "",
+    "/obj/structure/bed/fieldbed": "",
+    "/obj/structure/bed/hammock": "",
+    "/obj/structure/bed/padded": "",
+    "/obj/structure/bed/psych": "",
+    "/obj/structure/bed/roller": "",
+    "/obj/structure/bed/saving": "",
+    "/obj/structure/bed/sofa": "",
+    "/obj/structure/bed/sofa/left": "",
+    "/obj/structure/bed/sofa/right": "",
+    "/obj/structure/bed/wood": "",
+    "/obj/structure/bedsheetbin": "",
+    "/obj/structure/bell_stand": "",
+    "/obj/structure/bell_stand/church": "",
+    "/obj/structure/betting_box/blue": "",
+    "/obj/structure/betting_box/red": "",
+    "/obj/structure/billboard": "",
+    "/obj/structure/boat_spawn_lever/east": "",
+    "/obj/structure/boat_spawn_lever/north": "",
+    "/obj/structure/boat_spawn_lever/south": "",
+    "/obj/structure/boat_spawn_lever/west": "",
+    "/obj/structure/boiling_oil/east": "",
+    "/obj/structure/boiling_oil/north": "",
+    "/obj/structure/boiling_oil/south": "",
+    "/obj/structure/boiling_oil/west": "",
+    "/obj/structure/bookcase": "",
+    "/obj/structure/branch": "",
+    "/obj/structure/branch/cleared": "",
+    "/obj/structure/brazier": "",
+    "/obj/structure/brazier/loaded": "",
+    "/obj/structure/brazier/potbellystove": "",
+    "/obj/structure/brazier/sandstone": "",
+    "/obj/structure/brazier/stone": "",
+    "/obj/structure/broken_hind": "",
+    "/obj/structure/broken_hind_tail": "",
+    "/obj/structure/buoy": "",
+    "/obj/structure/buoy/red_white": "",
+    "/obj/structure/button/cremator": "",
+    "/obj/structure/camonet": "",
+    "/obj/structure/camp_exportbook": "",
+    "/obj/structure/canner": "",
+    "/obj/structure/cannon": "",
+    "/obj/structure/cannon/modern": "",
+    "/obj/structure/cannon/modern/naval": "",
+    "/obj/structure/cannon/modern/naval/n150": "",
+    "/obj/structure/cannon/modern/naval/n150/left": "",
+    "/obj/structure/cannon/modern/naval/n150/right": "",
+    "/obj/structure/cannon/modern/naval/n380": "",
+    "/obj/structure/cannon/modern/naval/n380/left": "",
+    "/obj/structure/cannon/modern/naval/n380/right": "",
+    "/obj/structure/cannon/modern/tank/american75": "",
+    "/obj/structure/cannon/modern/tank/baftkn75": "",
+    "/obj/structure/cannon/modern/tank/field75": "",
+    "/obj/structure/cannon/modern/tank/german75": "",
+    "/obj/structure/cannon/modern/tank/german88": "",
+    "/obj/structure/cannon/modern/tank/german88/field": "",
+    "/obj/structure/cannon/modern/tank/japanese57": "",
+    "/obj/structure/cannon/modern/tank/russian100/course": "",
+    "/obj/structure/cannon/modern/tank/russian45/field": "",
+    "/obj/structure/cannon/modern/tank/russian76": "",
+    "/obj/structure/cannon/modern/tank/russian76/americanfield": "",
+    "/obj/structure/cannon/modern/tank/russian85": "",
+    "/obj/structure/cannon/modern/tank/russian85/field": "",
+    "/obj/structure/cannon/modern/tank/voyage": "",
+    "/obj/structure/cannon/modern/tank/voyage/autofire": "",
+    "/obj/structure/cannon/mortar": "",
+    "/obj/structure/cannon/mortar/foldable/generic": "",
+    "/obj/structure/cannon/mortar/foldable/type89": "",
+    "/obj/structure/cannon/rocket": "",
+    "/obj/structure/cannon/rocket/loaded": "",
+    "/obj/structure/cargo_container": "",
+    "/obj/structure/carriage": "",
+    "/obj/structure/carriage_tdm": "",
+    "/obj/structure/catapult": "",
+    "/obj/structure/cell_tower": "",
+    "/obj/structure/centrifuge": "",
+    "/obj/structure/chem_master": "",
+    "/obj/structure/chemical_dispenser": "",
+    "/obj/structure/chemical_dispenser/alcohol": "",
+    "/obj/structure/chemical_dispenser/coffee": "",
+    "/obj/structure/chemical_dispenser/debug": "",
+    "/obj/structure/chemical_dispenser/drinks": "",
+    "/obj/structure/chemical_dispenser/drugs": "",
+    "/obj/structure/chemical_dispenser/full": "",
+    "/obj/structure/chemical_dispenser/soda": "",
+    "/obj/structure/closet": "",
+    "/obj/structure/closet/anchored": "",
+    "/obj/structure/closet/body_bag": "",
+    "/obj/structure/closet/cabinet": "",
+    "/obj/structure/closet/cabinet/ceiling": "",
+    "/obj/structure/closet/cabinet/ceiling/liquer": "",
+    "/obj/structure/closet/cabinet/defibrillator": "",
+    "/obj/structure/closet/cabinet/extinguisher_cabinet": "",
+    "/obj/structure/closet/cabinet/first_aid": "",
+    "/obj/structure/closet/chemical": "",
+    "/obj/structure/closet/coffin": "",
+    "/obj/structure/closet/coffin/anchored": "",
+    "/obj/structure/closet/coffin/generic": "",
+    "/obj/structure/closet/crate": "",
+    "/obj/structure/closet/crate/airdrops/food": "",
+    "/obj/structure/closet/crate/airdrops/medicine": "",
+    "/obj/structure/closet/crate/airdrops/military": "",
+    "/obj/structure/closet/crate/airdrops/soviet/pkm": "",
+    "/obj/structure/closet/crate/airdrops/supplies": "",
+    "/obj/structure/closet/crate/airdrops/weapons": "",
+    "/obj/structure/closet/crate/arrows/bronze": "",
+    "/obj/structure/closet/crate/arrows/iron": "",
+    "/obj/structure/closet/crate/arrows/steel": "",
+    "/obj/structure/closet/crate/arrows/stone": "",
+    "/obj/structure/closet/crate/bayonets": "",
+    "/obj/structure/closet/crate/bin": "",
+    "/obj/structure/closet/crate/blunderbuss_ammo": "",
+    "/obj/structure/closet/crate/blunderbusses": "",
+    "/obj/structure/closet/crate/bolts/iron": "",
+    "/obj/structure/closet/crate/brick": "",
+    "/obj/structure/closet/crate/cannonball": "",
+    "/obj/structure/closet/crate/cannonball/chainshot": "",
+    "/obj/structure/closet/crate/cannonball/grapeshot": "",
+    "/obj/structure/closet/crate/cart": "",
+    "/obj/structure/closet/crate/cart/bronze": "",
+    "/obj/structure/closet/crate/cart/copper": "",
+    "/obj/structure/closet/crate/cart/steel": "",
+    "/obj/structure/closet/crate/cart/stone": "",
+    "/obj/structure/closet/crate/cart/wooden": "",
+    "/obj/structure/closet/crate/cash_register": "",
+    "/obj/structure/closet/crate/cash_register/germ": "",
+    "/obj/structure/closet/crate/cash_register/inn": "",
+    "/obj/structure/closet/crate/chest": "",
+    "/obj/structure/closet/crate/chest/treasury": "",
+    "/obj/structure/closet/crate/chest/treasury/ship": "",
+    "/obj/structure/closet/crate/coldwar": "",
+    "/obj/structure/closet/crate/coldwar/m18": "",
+    "/obj/structure/closet/crate/coldwar/m26": "",
+    "/obj/structure/closet/crate/dumpster": "",
+    "/obj/structure/closet/crate/empty": "",
+    "/obj/structure/closet/crate/empty/large": "",
+    "/obj/structure/closet/crate/equipment": "",
+    "/obj/structure/closet/crate/equipment/knight_armor": "",
+    "/obj/structure/closet/crate/equipment/mamluk_armor": "",
+    "/obj/structure/closet/crate/equipment/sayaf": "",
+    "/obj/structure/closet/crate/footlocker": "",
+    "/obj/structure/closet/crate/freezer": "",
+    "/obj/structure/closet/crate/glass": "",
+    "/obj/structure/closet/crate/grenades": "",
+    "/obj/structure/closet/crate/iron": "",
+    "/obj/structure/closet/crate/large": "",
+    "/obj/structure/closet/crate/lead": "",
+    "/obj/structure/closet/crate/musketball": "",
+    "/obj/structure/closet/crate/musketball_pistol": "",
+    "/obj/structure/closet/crate/musketoons": "",
+    "/obj/structure/closet/crate/muskets": "",
+    "/obj/structure/closet/crate/pistols": "",
+    "/obj/structure/closet/crate/rations": "",
+    "/obj/structure/closet/crate/rations/ale": "",
+    "/obj/structure/closet/crate/rations/beer": "",
+    "/obj/structure/closet/crate/rations/biscuits": "",
+    "/obj/structure/closet/crate/rations/fruits": "",
+    "/obj/structure/closet/crate/rations/meat": "",
+    "/obj/structure/closet/crate/rations/sake": "",
+    "/obj/structure/closet/crate/rations/seeds": "",
+    "/obj/structure/closet/crate/rations/seeds/cashcrops": "",
+    "/obj/structure/closet/crate/rations/seeds/cereals": "",
+    "/obj/structure/closet/crate/rations/seeds/medicinal": "",
+    "/obj/structure/closet/crate/rations/seeds/trees": "",
+    "/obj/structure/closet/crate/rations/seeds/vegetables": "",
+    "/obj/structure/closet/crate/rations/vegetables": "",
+    "/obj/structure/closet/crate/sandbags": "",
+    "/obj/structure/closet/crate/steel": "",
+    "/obj/structure/closet/crate/stone": "",
+    "/obj/structure/closet/crate/treasurechest": "",
+    "/obj/structure/closet/crate/urn": "",
+    "/obj/structure/closet/crate/urn/stand": "",
+    "/obj/structure/closet/crate/wall_mailbox": "",
+    "/obj/structure/closet/crate/wall_mailbox/wood_mailbox": "",
+    "/obj/structure/closet/crate/webbings": "",
+    "/obj/structure/closet/crate/wood": "",
+    "/obj/structure/closet/crate/ww1": "",
+    "/obj/structure/closet/crate/ww1/ammo_hotchkiss": "",
+    "/obj/structure/closet/crate/ww1/ammo_maxim": "",
+    "/obj/structure/closet/crate/ww1/ammo_mg08": "",
+    "/obj/structure/closet/crate/ww1/ammo_vickers": "",
+    "/obj/structure/closet/crate/ww1/grenades_british": "",
+    "/obj/structure/closet/crate/ww1/grenades_french": "",
+    "/obj/structure/closet/crate/ww1/grenades_german": "",
+    "/obj/structure/closet/crate/ww2": "",
+    "/obj/structure/closet/crate/ww2/airdrops/ap": "",
+    "/obj/structure/closet/crate/ww2/airdrops/engineering": "",
+    "/obj/structure/closet/crate/ww2/ammo_mg34": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/AP57": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/AP75": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/AP76": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/AP85": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/AP88": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/APCR57": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/APCR75": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/APCR76": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/APCR85": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/APCR88": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/HE57": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/HE75": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/HE76": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/HE85": "",
+    "/obj/structure/closet/crate/ww2/artillery_shells/HE88": "",
+    "/obj/structure/closet/crate/ww2/atmines": "",
+    "/obj/structure/closet/crate/ww2/g43": "",
+    "/obj/structure/closet/crate/ww2/mk2": "",
+    "/obj/structure/closet/crate/ww2/mortar_shells": "",
+    "/obj/structure/closet/crate/ww2/mosin": "",
+    "/obj/structure/closet/crate/ww2/mosin_ammo": "",
+    "/obj/structure/closet/crate/ww2/mosin_old": "",
+    "/obj/structure/closet/crate/ww2/mp40": "",
+    "/obj/structure/closet/crate/ww2/panzerfaust": "",
+    "/obj/structure/closet/crate/ww2/pps": "",
+    "/obj/structure/closet/crate/ww2/ppsh": "",
+    "/obj/structure/closet/crate/ww2/rgd33": "",
+    "/obj/structure/closet/crate/ww2/rpg40": "",
+    "/obj/structure/closet/crate/ww2/russian/ammo": "",
+    "/obj/structure/closet/crate/ww2/stg": "",
+    "/obj/structure/closet/crate/ww2/stg1924": "",
+    "/obj/structure/closet/crate/ww2/svt": "",
+    "/obj/structure/closet/crate/ww2/un/ammo": "",
+    "/obj/structure/closet/crate/ww2/un/ammoboxes": "",
+    "/obj/structure/closet/crate/ww2/un/ap": "",
+    "/obj/structure/closet/crate/ww2/un/explosives": "",
+    "/obj/structure/closet/crate/ww2/un/falammoboxes": "",
+    "/obj/structure/closet/crate/ww2/un/m16ammo": "",
+    "/obj/structure/closet/crate/ww2/un/m16ammoboxes": "",
+    "/obj/structure/closet/crate/ww2/un/meals": "",
+    "/obj/structure/closet/crate/ww2/un/vickersboxes": "",
+    "/obj/structure/closet/crate/ww2/vietnam/us_ammo": "",
+    "/obj/structure/closet/crate/ww2/vietnam/us_engineering": "",
+    "/obj/structure/closet/crate/ww2/vietnam/us_explosives": "",
+    "/obj/structure/closet/crate/ww2/vietnam/us_medical": "",
+    "/obj/structure/closet/fridge": "",
+    "/obj/structure/closet/fridge/icebox": "",
+    "/obj/structure/closet/fridge/icecreamcooler": "",
+    "/obj/structure/closet/hideout": "",
+    "/obj/structure/closet/hideout/autumn": "",
+    "/obj/structure/closet/hideout/beach": "",
+    "/obj/structure/closet/hideout/pine": "",
+    "/obj/structure/closet/safe": "",
+    "/obj/structure/closet/safe/blue": "",
+    "/obj/structure/closet/safe/green": "",
+    "/obj/structure/closet/safe/red": "",
+    "/obj/structure/closet/safe/yellow": "",
+    "/obj/structure/closet/wardrobe": "",
+    "/obj/structure/compost": "",
+    "/obj/structure/computer": "",
+    "/obj/structure/computer/nopower": "",
+    "/obj/structure/computer/nopower/aotd/blue": "",
+    "/obj/structure/computer/nopower/aotd/civilian": "",
+    "/obj/structure/computer/nopower/aotd/green": "",
+    "/obj/structure/computer/nopower/aotd/red": "",
+    "/obj/structure/computer/nopower/aotd/yellow": "",
+    "/obj/structure/computer/nopower/carsales": "",
+    "/obj/structure/computer/nopower/carspawn": "",
+    "/obj/structure/computer/nopower/platoontracker": "",
+    "/obj/structure/computer/nopower/police": "",
+    "/obj/structure/computer/nopower/police/inside": "",
+    "/obj/structure/converter/retting_trough": "",
+    "/obj/structure/converter/tanning": "",
+    "/obj/structure/coolingfan": "",
+    "/obj/structure/cremator": "",
+    "/obj/structure/cross": "",
+    "/obj/structure/curtain": "",
+    "/obj/structure/curtain/black": "",
+    "/obj/structure/curtain/closed": "",
+    "/obj/structure/curtain/closed/blue": "",
+    "/obj/structure/curtain/closed/green": "",
+    "/obj/structure/curtain/closed/red": "",
+    "/obj/structure/curtain/closed/yellow": "",
+    "/obj/structure/curtain/leather": "",
+    "/obj/structure/curtain/leather/open": "",
+    "/obj/structure/curtain/medical": "",
+    "/obj/structure/curtain/open": "",
+    "/obj/structure/curtain/open/bed": "",
+    "/obj/structure/curtain/open/black": "",
+    "/obj/structure/curtain/open/blue": "",
+    "/obj/structure/curtain/open/green": "",
+    "/obj/structure/curtain/open/privacy": "",
+    "/obj/structure/curtain/open/red": "",
+    "/obj/structure/curtain/open/shower": "",
+    "/obj/structure/curtain/open/shower/engineering": "",
+    "/obj/structure/curtain/open/shower/security": "",
+    "/obj/structure/curtain/open/yellow": "",
+    "/obj/structure/cutting_board": "",
+    "/obj/structure/dehydrator": "",
+    "/obj/structure/distillery": "",
+    "/obj/structure/drone/flying/grenade": "",
+    "/obj/structure/drying_rack": "",
+    "/obj/structure/elevator_button": "",
+    "/obj/structure/emergency_lights": "",
+    "/obj/structure/emergency_lights/ambulance": "",
+    "/obj/structure/engine/external/steam": "",
+    "/obj/structure/engine/internal/diesel": "",
+    "/obj/structure/engine/internal/diesel/premade": "",
+    "/obj/structure/engine/internal/diesel/premade/bmd2": "",
+    "/obj/structure/engine/internal/diesel/premade/erstenklasse": "",
+    "/obj/structure/engine/internal/diesel/premade/mtlb": "",
+    "/obj/structure/engine/internal/diesel/premade/v12": "",
+    "/obj/structure/engine/internal/diesel/premade/v6": "",
+    "/obj/structure/engine/internal/gasoline": "",
+    "/obj/structure/engine/internal/gasoline/premade/falcon": "",
+    "/obj/structure/engine/internal/gasoline/premade/panzeriv": "",
+    "/obj/structure/engine/internal/gasoline/premade/type94": "",
+    "/obj/structure/engine/internal/gasoline/premade/type95": "",
+    "/obj/structure/engine/internal/gasoline/premade/v6": "",
+    "/obj/structure/engine/internal/hesselman": "",
+    "/obj/structure/engine/internal/turbine": "",
+    "/obj/structure/exportbook": "",
+    "/obj/structure/farming/plant/banana": "",
+    "/obj/structure/farming/plant/beans": "",
+    "/obj/structure/farming/plant/carrot": "",
+    "/obj/structure/farming/plant/corn": "",
+    "/obj/structure/farming/plant/cotton": "",
+    "/obj/structure/farming/plant/hemp": "",
+    "/obj/structure/farming/plant/mushroom": "",
+    "/obj/structure/farming/plant/oat": "",
+    "/obj/structure/farming/plant/orange": "",
+    "/obj/structure/farming/plant/poppy": "",
+    "/obj/structure/farming/plant/potato": "",
+    "/obj/structure/farming/plant/rice": "",
+    "/obj/structure/farming/plant/sugarcane": "",
+    "/obj/structure/farming/plant/tea": "",
+    "/obj/structure/farming/plant/tomato": "",
+    "/obj/structure/farming/plant/wheat": "",
+    "/obj/structure/filingcabinet": "",
+    "/obj/structure/filingcabinet/chestdrawer": "",
+    "/obj/structure/filingcabinet/filingcabinet": "",
+    "/obj/structure/fish": "",
+    "/obj/structure/fish/cod": "",
+    "/obj/structure/fish/salmon": "",
+    "/obj/structure/fishing_cage": "",
+    "/obj/structure/fitness/punchingbag": "",
+    "/obj/structure/fitness/weightlifter": "",
+    "/obj/structure/flag/black": "",
+    "/obj/structure/flag/blugoslavia": "",
+    "/obj/structure/flag/british": "",
+    "/obj/structure/flag/campaign/blugoslavia": "",
+    "/obj/structure/flag/campaign/redmenia": "",
+    "/obj/structure/flag/chinese": "",
+    "/obj/structure/flag/confed": "",
+    "/obj/structure/flag/dutch": "",
+    "/obj/structure/flag/dutch_old": "",
+    "/obj/structure/flag/filipino_war": "",
+    "/obj/structure/flag/french": "",
+    "/obj/structure/flag/french_modern": "",
+    "/obj/structure/flag/german": "",
+    "/obj/structure/flag/german_modern": "",
+    "/obj/structure/flag/italian": "",
+    "/obj/structure/flag/japanese": "",
+    "/obj/structure/flag/nva": "",
+    "/obj/structure/flag/objective/four": "",
+    "/obj/structure/flag/objective/one": "",
+    "/obj/structure/flag/objective/three": "",
+    "/obj/structure/flag/objective/two": "",
+    "/obj/structure/flag/pirates": "",
+    "/obj/structure/flag/pole": "",
+    "/obj/structure/flag/portuguese": "",
+    "/obj/structure/flag/redmenia": "",
+    "/obj/structure/flag/reich": "",
+    "/obj/structure/flag/russian": "",
+    "/obj/structure/flag/soviet": "",
+    "/obj/structure/flag/spanish": "",
+    "/obj/structure/flag/us": "",
+    "/obj/structure/flag/vietcong": "",
+    "/obj/structure/flag/white": "",
+    "/obj/structure/floodlight": "",
+    "/obj/structure/floodlight/on": "",
+    "/obj/structure/fountain": "",
+    "/obj/structure/fountain/no_bottom": "",
+    "/obj/structure/fuelpump": "",
+    "/obj/structure/fuelpump/premade": "",
+    "/obj/structure/fuelpump/premade/diesel": "",
+    "/obj/structure/fuelpump/premade/gasoline": "",
+    "/obj/structure/fuelpump/premade/yamaha/diesel": "",
+    "/obj/structure/fuelpump/premade/yamaha/gasoline": "",
+    "/obj/structure/functions/clean_arena1": "",
+    "/obj/structure/furnace": "",
+    "/obj/structure/furnace/blast_furnace": "",
+    "/obj/structure/furnace/kiln": "",
+    "/obj/structure/furnace/kiln/sandstone": "",
+    "/obj/structure/furnace/kiln/stone": "",
+    "/obj/structure/gallows": "",
+    "/obj/structure/gate": "",
+    "/obj/structure/gate/barrier": "",
+    "/obj/structure/gate/barrier/vertical": "",
+    "/obj/structure/gate/blast": "",
+    "/obj/structure/gate/blast/garage": "",
+    "/obj/structure/gate/blast/garage/open": "",
+    "/obj/structure/gate/blast/open": "",
+    "/obj/structure/gate/elevator_door": "",
+    "/obj/structure/gate/open": "",
+    "/obj/structure/gate/sandstone": "",
+    "/obj/structure/gate/sandstone/open": "",
+    "/obj/structure/gate/whiterun/l": "",
+    "/obj/structure/gate/whiterun/r": "",
+    "/obj/structure/gatecontrol": "",
+    "/obj/structure/gatecontrol/blastcontrol": "",
+    "/obj/structure/gatecontrol/blastcontrol/garage": "",
+    "/obj/structure/gatecontrol/elevator_door": "",
+    "/obj/structure/gatecontrol/sandstone": "",
+    "/obj/structure/gatecontrol/whiterun": "",
+    "/obj/structure/gladiator_control": "",
+    "/obj/structure/gladiator_control/ranged": "",
+    "/obj/structure/gladiator_control/wrestling": "",
+    "/obj/structure/gladiator_ledger": "",
+    "/obj/structure/goalpost": "",
+    "/obj/structure/goalpost/inner": "",
+    "/obj/structure/gong": "",
+    "/obj/structure/grapplehook": "",
+    "/obj/structure/grapplehook/auto": "",
+    "/obj/structure/grille": "",
+    "/obj/structure/grille/broken": "",
+    "/obj/structure/grille/chainlinkfence": "",
+    "/obj/structure/grille/chainlinkfence/corner": "",
+    "/obj/structure/grille/chainlinkfence/cut/larger": "",
+    "/obj/structure/grille/chainlinkfence/cut/larger/complete": "",
+    "/obj/structure/grille/chainlinkfence/door": "",
+    "/obj/structure/grille/chainlinkfence/door/opened": "",
+    "/obj/structure/grille/fence": "",
+    "/obj/structure/grille/fence/picket": "",
+    "/obj/structure/grille/ironfence": "",
+    "/obj/structure/grille/logfence": "",
+    "/obj/structure/grille/metalsheetfence": "",
+    "/obj/structure/grille/metalsheetfence/blue": "",
+    "/obj/structure/grille/metalsheetfence/corner": "",
+    "/obj/structure/grille/metalsheetfence/corner/blue": "",
+    "/obj/structure/grille/metalsheetfence/corner/red": "",
+    "/obj/structure/grille/metalsheetfence/green": "",
+    "/obj/structure/grille/metalsheetfence/red": "",
+    "/obj/structure/grille/metalsheetfence/yellow": "",
+    "/obj/structure/gunbench": "",
+    "/obj/structure/heatsource": "",
+    "/obj/structure/iv_drip": "",
+    "/obj/structure/katana_stand/full": "",
+    "/obj/structure/kitchenspike": "",
+    "/obj/structure/lab_distillery": "",
+    "/obj/structure/lamp": "",
+    "/obj/structure/lamp/lamp_big": "",
+    "/obj/structure/lamp/lamp_big/alwayson": "",
+    "/obj/structure/lamp/lamp_big/alwayson/white": "",
+    "/obj/structure/lamp/lamp_big/broken": "",
+    "/obj/structure/lamp/lamp_small": "",
+    "/obj/structure/lamp/lamp_small/alwayson": "",
+    "/obj/structure/lamp/lamp_small/alwayson/red": "",
+    "/obj/structure/lamp/lamp_small/alwayson/white": "",
+    "/obj/structure/lamp/lamp_small/broken": "",
+    "/obj/structure/lamp/lamp_small/tank": "",
+    "/obj/structure/lamp/lamp_small/tank/blue/police": "",
+    "/obj/structure/lamp/lamp_small/tank/red": "",
+    "/obj/structure/lamp/lamp_small/tank/red/police": "",
+    "/obj/structure/lamp/lamppost_small": "",
+    "/obj/structure/lamp/lamppost_small/alwayson": "",
+    "/obj/structure/lamp/streetlight": "",
+    "/obj/structure/lamp/streetlight/alwayson": "",
+    "/obj/structure/largecrate": "",
+    "/obj/structure/largecrate/animal/dog/german": "",
+    "/obj/structure/loom": "",
+    "/obj/structure/machinery/construction_crane": "",
+    "/obj/structure/machinery/construction_crane/excavator": "",
+    "/obj/structure/machinery/factory/coinsmelter": "",
+    "/obj/structure/machinery/forklift": "",
+    "/obj/structure/machinery/water_pump": "",
+    "/obj/structure/mailbox": "",
+    "/obj/structure/mailbox/british": "",
+    "/obj/structure/mailbox/french": "",
+    "/obj/structure/mailbox/portuguese": "",
+    "/obj/structure/mailbox/processor": "",
+    "/obj/structure/mailbox/received": "",
+    "/obj/structure/mailbox/spanish": "",
+    "/obj/structure/meat_grinder": "",
+    "/obj/structure/medical_divider": "",
+    "/obj/structure/medical_divider/full": "",
+    "/obj/structure/medicalbed": "",
+    "/obj/structure/metal_detector": "",
+    "/obj/structure/mill": "",
+    "/obj/structure/mill/large": "",
+    "/obj/structure/mine_support": "",
+    "/obj/structure/mine_support/stone": "",
+    "/obj/structure/mine_support/stone/aztec": "",
+    "/obj/structure/mine_support/stone/aztec/sandstone": "",
+    "/obj/structure/mine_support/stone/concrete": "",
+    "/obj/structure/mine_support/stone/ionic": "",
+    "/obj/structure/mine_support/stone/ionic/rock": "",
+    "/obj/structure/mine_support/stone/ionic/sandstone": "",
+    "/obj/structure/mine_support/stone/marble": "",
+    "/obj/structure/mine_support/stone/sandstone": "",
+    "/obj/structure/mine_support/stone/solomonic/sandstone": "",
+    "/obj/structure/mine_support/stone/solomonic/thick/rock": "",
+    "/obj/structure/mirror": "",
+    "/obj/structure/money_bag": "",
+    "/obj/structure/morgue": "",
+    "/obj/structure/multiz/ladder": "",
+    "/obj/structure/multiz/ladder/up": "",
+    "/obj/structure/multiz/ladder/ww2": "",
+    "/obj/structure/multiz/ladder/ww2/manhole": "",
+    "/obj/structure/multiz/ladder/ww2/manhole/bank_robbery": "",
+    "/obj/structure/multiz/ladder/ww2/manhole/chech": "",
+    "/obj/structure/multiz/ladder/ww2/stairsdown": "",
+    "/obj/structure/multiz/ladder/ww2/stairsup": "",
+    "/obj/structure/multiz/ladder/ww2/teleporter": "",
+    "/obj/structure/multiz/ladder/ww2/teleporter/five": "",
+    "/obj/structure/multiz/ladder/ww2/teleporter/four": "",
+    "/obj/structure/multiz/ladder/ww2/teleporter/one": "",
+    "/obj/structure/multiz/ladder/ww2/teleporter/three": "",
+    "/obj/structure/multiz/ladder/ww2/teleporter/two": "",
+    "/obj/structure/multiz/ladder/ww2/teleporter/up": "",
+    "/obj/structure/multiz/ladder/ww2/teleporter/up/five": "",
+    "/obj/structure/multiz/ladder/ww2/teleporter/up/four": "",
+    "/obj/structure/multiz/ladder/ww2/teleporter/up/one": "",
+    "/obj/structure/multiz/ladder/ww2/teleporter/up/three": "",
+    "/obj/structure/multiz/ladder/ww2/teleporter/up/two": "",
+    "/obj/structure/multiz/ladder/ww2/tunnelbottom": "",
+    "/obj/structure/multiz/ladder/ww2/tunnelbottom/retreat": "",
+    "/obj/structure/multiz/ladder/ww2/tunnelbottom/vietcong": "",
+    "/obj/structure/multiz/ladder/ww2/tunneltop": "",
+    "/obj/structure/multiz/ladder/ww2/tunneltop/retreat": "",
+    "/obj/structure/multiz/ladder/ww2/tunneltop/vietcong": "",
+    "/obj/structure/multiz/ladder/ww2/up": "",
+    "/obj/structure/multiz/ladder/ww2/up/manhole": "",
+    "/obj/structure/multiz/ladder/ww2/up/manhole/bank_robbery": "",
+    "/obj/structure/multiz/ladder/ww2/up/manhole/chech": "",
+    "/obj/structure/multiz/stairs": "",
+    "/obj/structure/multiz/stairs_wood": "",
+    "/obj/structure/naval_cannon_control": "",
+    "/obj/structure/noose": "",
+    "/obj/structure/noticeboard": "",
+    "/obj/structure/npc_vendor/big_lenny": "",
+    "/obj/structure/npc_vendor/biker": "",
+    "/obj/structure/npc_vendor/bouncer": "",
+    "/obj/structure/npc_vendor/cartel": "",
+    "/obj/structure/npc_vendor/fed": "",
+    "/obj/structure/npc_vendor/smuggler": "",
+    "/obj/structure/npc_vendor/walter": "",
+    "/obj/structure/nuclear_missile": "",
+    "/obj/structure/oil_spring": "",
+    "/obj/structure/oilwell": "",
+    "/obj/structure/optable": "",
+    "/obj/structure/oven": "",
+    "/obj/structure/oven/fireplace": "",
+    "/obj/structure/oven/fireplace/pit": "",
+    "/obj/structure/oven/fryer": "",
+    "/obj/structure/oven/griddle": "",
+    "/obj/structure/oven/grill": "",
+    "/obj/structure/oven/grill/gas": "",
+    "/obj/structure/oven/stove": "",
+    "/obj/structure/oven/stove/old": "",
+    "/obj/structure/oven/woodstove": "",
+    "/obj/structure/pepelsibirsk_radio/export_radio": "",
+    "/obj/structure/pepelsibirsk_radio/supply_radio": "",
+    "/obj/structure/pepelsibirsk_radio/supply_radio/no_scam": "",
+    "/obj/structure/phonecable": "",
+    "/obj/structure/phonecable/horizontal": "",
+    "/obj/structure/phonecable/vertical": "",
+    "/obj/structure/phonecable/vertical/v2": "",
+    "/obj/structure/phoneline": "",
+    "/obj/structure/piano": "",
+    "/obj/structure/pillory": "",
+    "/obj/structure/piranha": "",
+    "/obj/structure/plant_pot/clay/light": "",
+    "/obj/structure/plant_pot/clay/light/filled": "",
+    "/obj/structure/post_execution": "",
+    "/obj/structure/poster/faction": "",
+    "/obj/structure/poster/faction/blue/mil1": "",
+    "/obj/structure/poster/faction/blue/mil2": "",
+    "/obj/structure/poster/faction/red/lead": "",
+    "/obj/structure/poster/faction/red/mil1": "",
+    "/obj/structure/poster/faction/red/mil2": "",
+    "/obj/structure/poster/faction/red/work": "",
+    "/obj/structure/pot": "",
+    "/obj/structure/potted_plant": "",
+    "/obj/structure/practice_dummy": "",
+    "/obj/structure/practice_dummy/indestructible": "",
+    "/obj/structure/practice_dummy/target": "",
+    "/obj/structure/practice_dummy/target/human": "",
+    "/obj/structure/practice_dummy/target/human/indestructible": "",
+    "/obj/structure/printingpress": "",
+    "/obj/structure/props/afghan/druglord": "",
+    "/obj/structure/props/barrel": "",
+    "/obj/structure/props/bathtub": "",
+    "/obj/structure/props/bike": "",
+    "/obj/structure/props/car_wreck": "",
+    "/obj/structure/props/car_wreck/truck": "",
+    "/obj/structure/props/car_wreck/van": "",
+    "/obj/structure/props/car_wreck/van/alt": "",
+    "/obj/structure/props/coatrack": "",
+    "/obj/structure/props/computerprops": "",
+    "/obj/structure/props/computerprops/enclave": "",
+    "/obj/structure/props/computerprops/info_panel": "",
+    "/obj/structure/props/computerprops/lab": "",
+    "/obj/structure/props/computerprops/lunar": "",
+    "/obj/structure/props/computerprops/lunar2": "",
+    "/obj/structure/props/computerprops/machine": "",
+    "/obj/structure/props/computerprops/modern": "",
+    "/obj/structure/props/computerprops/modern/a10": "",
+    "/obj/structure/props/computerprops/modern/a11": "",
+    "/obj/structure/props/computerprops/modern/a9": "",
+    "/obj/structure/props/computerprops/modern/smes2": "",
+    "/obj/structure/props/computerprops/modern/synth2": "",
+    "/obj/structure/props/computerprops/research": "",
+    "/obj/structure/props/computerprops/terminal": "",
+    "/obj/structure/props/computerprops/tracking": "",
+    "/obj/structure/props/computerprops/tracking/siberiad": "",
+    "/obj/structure/props/engineprops": "",
+    "/obj/structure/props/engineprops/big": "",
+    "/obj/structure/props/engineprops/diesel": "",
+    "/obj/structure/props/engineprops/dieselgeni": "",
+    "/obj/structure/props/engineprops/frunace": "",
+    "/obj/structure/props/engineprops/gas": "",
+    "/obj/structure/props/engineprops/reactor": "",
+    "/obj/structure/props/engineprops/steam": "",
+    "/obj/structure/props/engineprops/turbine": "",
+    "/obj/structure/props/engineprops/waterpump": "",
+    "/obj/structure/props/fueltank": "",
+    "/obj/structure/props/hookah": "",
+    "/obj/structure/props/junk": "",
+    "/obj/structure/props/keyboard": "",
+    "/obj/structure/props/machineprops/refinery": "",
+    "/obj/structure/props/marketstall": "",
+    "/obj/structure/props/piping/broken_pipe": "",
+    "/obj/structure/props/piping/pipe": "",
+    "/obj/structure/props/piping/pipe/under": "",
+    "/obj/structure/props/piping/pipe_up/under": "",
+    "/obj/structure/props/piping/small/pipe": "",
+    "/obj/structure/props/piping/small/pipe/under": "",
+    "/obj/structure/props/piping/small/pipel/under": "",
+    "/obj/structure/props/power_transformer": "",
+    "/obj/structure/props/radiator": "",
+    "/obj/structure/props/random/container": "",
+    "/obj/structure/props/random/container/five": "",
+    "/obj/structure/props/random/container/four": "",
+    "/obj/structure/props/random/container/three": "",
+    "/obj/structure/props/random/container/two": "",
+    "/obj/structure/props/random/podlock": "",
+    "/obj/structure/props/server": "",
+    "/obj/structure/props/server/comm": "",
+    "/obj/structure/props/server/controller": "",
+    "/obj/structure/props/server/processor": "",
+    "/obj/structure/props/slot_machine": "",
+    "/obj/structure/props/sofa": "",
+    "/obj/structure/props/sofa/p2": "",
+    "/obj/structure/props/stove": "",
+    "/obj/structure/props/stove/old": "",
+    "/obj/structure/radio": "",
+    "/obj/structure/radio/faction1": "",
+    "/obj/structure/radio/faction2": "",
+    "/obj/structure/radio/receiver": "",
+    "/obj/structure/radio/receiver/loudspeaker": "",
+    "/obj/structure/radio/receiver/loudspeaker/faction1": "",
+    "/obj/structure/radio/receiver/loudspeaker/faction2": "",
+    "/obj/structure/radio/transmitter": "",
+    "/obj/structure/radio/transmitter/nopower": "",
+    "/obj/structure/radio/transmitter_receiver": "",
+    "/obj/structure/radio/transmitter_receiver/nopower": "",
+    "/obj/structure/radio/transmitter_receiver/nopower/faction1": "",
+    "/obj/structure/radio/transmitter_receiver/nopower/faction2": "",
+    "/obj/structure/radio/transmitter_receiver/nopower/tank/faction1": "",
+    "/obj/structure/radio/transmitter_receiver/nopower/tank/faction2": "",
+    "/obj/structure/radiorecorder": "",
+    "/obj/structure/radome": "",
+    "/obj/structure/railing": "",
+    "/obj/structure/railing/steel": "",
+    "/obj/structure/rails": "",
+    "/obj/structure/rails/corner": "",
+    "/obj/structure/rails/end": "",
+    "/obj/structure/rails/regular": "",
+    "/obj/structure/rails/regular/horizontal": "",
+    "/obj/structure/rails/rotate": "",
+    "/obj/structure/rails/split": "",
+    "/obj/structure/rails/split/switcher": "",
+    "/obj/structure/rails/split/switcher/right": "",
+    "/obj/structure/rails/turn": "",
+    "/obj/structure/rails/turn/right": "",
+    "/obj/structure/rails/wide": "",
+    "/obj/structure/reagent_dispensers/fountain": "",
+    "/obj/structure/reagent_dispensers/largebarrel": "",
+    "/obj/structure/reagent_dispensers/largebarrel/ale": "",
+    "/obj/structure/reagent_dispensers/largebarrel/beer": "",
+    "/obj/structure/reagent_dispensers/largebarrel/water": "",
+    "/obj/structure/reagent_dispensers/peppertank": "",
+    "/obj/structure/redmailbox": "",
+    "/obj/structure/refinery": "",
+    "/obj/structure/religious/angel": "",
+    "/obj/structure/religious/animal_statue": "",
+    "/obj/structure/religious/aztec_statue": "",
+    "/obj/structure/religious/gargoyle": "",
+    "/obj/structure/religious/grave": "",
+    "/obj/structure/religious/gravestone": "",
+    "/obj/structure/religious/impaledskull": "",
+    "/obj/structure/religious/moai": "",
+    "/obj/structure/religious/moai/long": "",
+    "/obj/structure/religious/monument/cultist/cthulu": "",
+    "/obj/structure/religious/monument/cultist/moloch": "",
+    "/obj/structure/religious/monument/cultist/outsider": "",
+    "/obj/structure/religious/monument/cultist/sauron": "",
+    "/obj/structure/religious/monument/cultist/sauron/reverse": "",
+    "/obj/structure/religious/monument/karl_marx": "",
+    "/obj/structure/religious/monument/liberty": "",
+    "/obj/structure/religious/monument/megalith": "",
+    "/obj/structure/religious/monument/monk/quangshi": "",
+    "/obj/structure/religious/monument/pillar_monument": "",
+    "/obj/structure/religious/monument/priesthood/saint": "",
+    "/obj/structure/religious/monument/venus": "",
+    "/obj/structure/religious/olmec_head": "",
+    "/obj/structure/religious/remains": "",
+    "/obj/structure/religious/statue": "",
+    "/obj/structure/religious/statue/king": "",
+    "/obj/structure/religious/statue/king/sandstone": "",
+    "/obj/structure/religious/tiki_statue": "",
+    "/obj/structure/religious/tiki_statue/small": "",
+    "/obj/structure/religious/totem": "",
+    "/obj/structure/religious/totem_pole": "",
+    "/obj/structure/religious/tribalmask": "",
+    "/obj/structure/religious/woodcross1": "",
+    "/obj/structure/religious/woodcross2": "",
+    "/obj/structure/repair": "",
+    "/obj/structure/repair/grindstone": "",
+    "/obj/structure/repair/gun": "",
+    "/obj/structure/repair/workbench": "",
+    "/obj/structure/researchdesk": "",
+    "/obj/structure/roof_support": "",
+    "/obj/structure/roof_support/admin": "",
+    "/obj/structure/roof_support/bamboo": "",
+    "/obj/structure/roof_support/nordic": "",
+    "/obj/structure/roulette": "",
+    "/obj/structure/safe": "",
+    "/obj/structure/safe/floor": "",
+    "/obj/structure/salting_container": "",
+    "/obj/structure/sawmill/large": "",
+    "/obj/structure/sawmill/powered": "",
+    "/obj/structure/shelf": "",
+    "/obj/structure/shelf/palette": "",
+    "/obj/structure/shellrack": "",
+    "/obj/structure/shellrack/autoloader/full100": "",
+    "/obj/structure/shellrack/autoloader/full125": "",
+    "/obj/structure/shellrack/full100modern": "",
+    "/obj/structure/shellrack/full100ww2": "",
+    "/obj/structure/shellrack/full125": "",
+    "/obj/structure/shellrack/full204": "",
+    "/obj/structure/shellrack/full45": "",
+    "/obj/structure/shellrack/full57": "",
+    "/obj/structure/shellrack/full75": "",
+    "/obj/structure/shellrack/full75/american": "",
+    "/obj/structure/shellrack/full76": "",
+    "/obj/structure/shellrack/full85": "",
+    "/obj/structure/shellrack/full88": "",
+    "/obj/structure/shellrack/fullrocket": "",
+    "/obj/structure/ship_bow": "",
+    "/obj/structure/shopping_cart": "",
+    "/obj/structure/shower": "",
+    "/obj/structure/shower/bathtub": "",
+    "/obj/structure/shower/bathtub/big/steel": "",
+    "/obj/structure/shower/bathtub/big/stone": "",
+    "/obj/structure/shower/bathtub/bronze": "",
+    "/obj/structure/shower/bathtub/steel": "",
+    "/obj/structure/shower/bathtub/stone": "",
+    "/obj/structure/shower/coldshower": "",
+    "/obj/structure/sign/abashiri": "",
+    "/obj/structure/sign/abashiri/solitary": "",
+    "/obj/structure/sign/abashiri/wing1": "",
+    "/obj/structure/sign/abashiri/wing2": "",
+    "/obj/structure/sign/abashiri/wing3": "",
+    "/obj/structure/sign/anatomy": "",
+    "/obj/structure/sign/armory": "",
+    "/obj/structure/sign/baily": "",
+    "/obj/structure/sign/baily2": "",
+    "/obj/structure/sign/bank": "",
+    "/obj/structure/sign/bar": "",
+    "/obj/structure/sign/barbershop": "",
+    "/obj/structure/sign/cafe_ru": "",
+    "/obj/structure/sign/casino": "",
+    "/obj/structure/sign/clock": "",
+    "/obj/structure/sign/court": "",
+    "/obj/structure/sign/custom": "",
+    "/obj/structure/sign/custom/golden": "",
+    "/obj/structure/sign/custom/metallic": "",
+    "/obj/structure/sign/custom/plaque": "",
+    "/obj/structure/sign/deer_trophy": "",
+    "/obj/structure/sign/donut_shop": "",
+    "/obj/structure/sign/exit": "",
+    "/obj/structure/sign/flag/afghan/dra": "",
+    "/obj/structure/sign/flag/arstotzka": "",
+    "/obj/structure/sign/flag/blue": "",
+    "/obj/structure/sign/flag/blue2": "",
+    "/obj/structure/sign/flag/blugoslavia": "",
+    "/obj/structure/sign/flag/chechen": "",
+    "/obj/structure/sign/flag/chetnik": "",
+    "/obj/structure/sign/flag/chinese": "",
+    "/obj/structure/sign/flag/chinese/prc": "",
+    "/obj/structure/sign/flag/colombia": "",
+    "/obj/structure/sign/flag/cuba": "",
+    "/obj/structure/sign/flag/custom": "",
+    "/obj/structure/sign/flag/czech": "",
+    "/obj/structure/sign/flag/denmark": "",
+    "/obj/structure/sign/flag/dutch": "",
+    "/obj/structure/sign/flag/finland": "",
+    "/obj/structure/sign/flag/firstcav": "",
+    "/obj/structure/sign/flag/french": "",
+    "/obj/structure/sign/flag/gadsen": "",
+    "/obj/structure/sign/flag/gb/imperial": "",
+    "/obj/structure/sign/flag/gb/pysker": "",
+    "/obj/structure/sign/flag/gb/rebel": "",
+    "/obj/structure/sign/flag/german": "",
+    "/obj/structure/sign/flag/german/east": "",
+    "/obj/structure/sign/flag/german/modern": "",
+    "/obj/structure/sign/flag/gns": "",
+    "/obj/structure/sign/flag/green": "",
+    "/obj/structure/sign/flag/hezbollah": "",
+    "/obj/structure/sign/flag/ireland": "",
+    "/obj/structure/sign/flag/isis": "",
+    "/obj/structure/sign/flag/israel": "",
+    "/obj/structure/sign/flag/italy": "",
+    "/obj/structure/sign/flag/japanese": "",
+    "/obj/structure/sign/flag/japanese/modern": "",
+    "/obj/structure/sign/flag/jihad1": "",
+    "/obj/structure/sign/flag/jihad2": "",
+    "/obj/structure/sign/flag/jihad3": "",
+    "/obj/structure/sign/flag/jihad4": "",
+    "/obj/structure/sign/flag/medical": "",
+    "/obj/structure/sign/flag/medical/crescent": "",
+    "/obj/structure/sign/flag/mexico": "",
+    "/obj/structure/sign/flag/nato": "",
+    "/obj/structure/sign/flag/nazi": "",
+    "/obj/structure/sign/flag/philippine_war": "",
+    "/obj/structure/sign/flag/pirate": "",
+    "/obj/structure/sign/flag/poland": "",
+    "/obj/structure/sign/flag/red": "",
+    "/obj/structure/sign/flag/red2": "",
+    "/obj/structure/sign/flag/redmenia": "",
+    "/obj/structure/sign/flag/reich": "",
+    "/obj/structure/sign/flag/russia": "",
+    "/obj/structure/sign/flag/russia/rsfsr": "",
+    "/obj/structure/sign/flag/russia/wagner": "",
+    "/obj/structure/sign/flag/serbia": "",
+    "/obj/structure/sign/flag/sov": "",
+    "/obj/structure/sign/flag/sov/border": "",
+    "/obj/structure/sign/flag/sov/vdv": "",
+    "/obj/structure/sign/flag/spain": "",
+    "/obj/structure/sign/flag/spain/nationalist": "",
+    "/obj/structure/sign/flag/ssg": "",
+    "/obj/structure/sign/flag/syria": "",
+    "/obj/structure/sign/flag/syria/fsa": "",
+    "/obj/structure/sign/flag/taliban": "",
+    "/obj/structure/sign/flag/templar1": "",
+    "/obj/structure/sign/flag/templar2": "",
+    "/obj/structure/sign/flag/uk": "",
+    "/obj/structure/sign/flag/ukraine": "",
+    "/obj/structure/sign/flag/ukraine/upa": "",
+    "/obj/structure/sign/flag/un": "",
+    "/obj/structure/sign/flag/usa": "",
+    "/obj/structure/sign/flag/usa_confed": "",
+    "/obj/structure/sign/flag/usa_union": "",
+    "/obj/structure/sign/flag/vietcong": "",
+    "/obj/structure/sign/flag/vietnam": "",
+    "/obj/structure/sign/flag/warpact": "",
+    "/obj/structure/sign/flag/warpact/alt": "",
+    "/obj/structure/sign/flag/yugoslavia": "",
+    "/obj/structure/sign/flag/yugoslavia/partisan": "",
+    "/obj/structure/sign/galacticbattles/care": "",
+    "/obj/structure/sign/galacticbattles/repair": "",
+    "/obj/structure/sign/galacticbattles/unite": "",
+    "/obj/structure/sign/gas": "",
+    "/obj/structure/sign/goldenplaque": "",
+    "/obj/structure/sign/greencross": "",
+    "/obj/structure/sign/guns": "",
+    "/obj/structure/sign/japsign": "",
+    "/obj/structure/sign/justice": "",
+    "/obj/structure/sign/kiddieplaque": "",
+    "/obj/structure/sign/logo/blue": "",
+    "/obj/structure/sign/logo/green": "",
+    "/obj/structure/sign/logo/red": "",
+    "/obj/structure/sign/logo/yellow": "",
+    "/obj/structure/sign/map": "",
+    "/obj/structure/sign/map_board": "",
+    "/obj/structure/sign/mcd": "",
+    "/obj/structure/sign/mcd/menu": "",
+    "/obj/structure/sign/mcd/pole": "",
+    "/obj/structure/sign/mckellens": "",
+    "/obj/structure/sign/medal": "",
+    "/obj/structure/sign/minefield": "",
+    "/obj/structure/sign/mugshot": "",
+    "/obj/structure/sign/n1": "",
+    "/obj/structure/sign/n2": "",
+    "/obj/structure/sign/n3": "",
+    "/obj/structure/sign/n4": "",
+    "/obj/structure/sign/n5": "",
+    "/obj/structure/sign/n6": "",
+    "/obj/structure/sign/nosmoking": "",
+    "/obj/structure/sign/nosmoking2": "",
+    "/obj/structure/sign/ogoldenplaque": "",
+    "/obj/structure/sign/open": "",
+    "/obj/structure/sign/painting1": "",
+    "/obj/structure/sign/painting10": "",
+    "/obj/structure/sign/painting11": "",
+    "/obj/structure/sign/painting12": "",
+    "/obj/structure/sign/painting13": "",
+    "/obj/structure/sign/painting2": "",
+    "/obj/structure/sign/painting3": "",
+    "/obj/structure/sign/painting4": "",
+    "/obj/structure/sign/painting5": "",
+    "/obj/structure/sign/painting6": "",
+    "/obj/structure/sign/painting7": "",
+    "/obj/structure/sign/painting8": "",
+    "/obj/structure/sign/painting9": "",
+    "/obj/structure/sign/periodic": "",
+    "/obj/structure/sign/portrait/brezhnev": "",
+    "/obj/structure/sign/portrait/hirohito": "",
+    "/obj/structure/sign/portrait/hitler": "",
+    "/obj/structure/sign/portrait/karmal": "",
+    "/obj/structure/sign/portrait/kinggeorge": "",
+    "/obj/structure/sign/portrait/lenin": "",
+    "/obj/structure/sign/portrait/sokolov": "",
+    "/obj/structure/sign/portrait/stalin": "",
+    "/obj/structure/sign/radiation": "",
+    "/obj/structure/sign/redcross": "",
+    "/obj/structure/sign/rent": "",
+    "/obj/structure/sign/restroom": "",
+    "/obj/structure/sign/restroom/female": "",
+    "/obj/structure/sign/restroom/male": "",
+    "/obj/structure/sign/sale": "",
+    "/obj/structure/sign/securearea": "",
+    "/obj/structure/sign/sheriff": "",
+    "/obj/structure/sign/signpost": "",
+    "/obj/structure/sign/signpost/everywhere": "",
+    "/obj/structure/sign/sovafghan_poster": "",
+    "/obj/structure/sign/sovafghan_poster/alt": "",
+    "/obj/structure/sign/torii": "",
+    "/obj/structure/sign/townhall": "",
+    "/obj/structure/sign/traffic": "",
+    "/obj/structure/sign/traffic/cafe": "",
+    "/obj/structure/sign/traffic/central": "",
+    "/obj/structure/sign/traffic/crossing": "",
+    "/obj/structure/sign/traffic/gas": "",
+    "/obj/structure/sign/traffic/noentry": "",
+    "/obj/structure/sign/traffic/parking": "",
+    "/obj/structure/sign/traffic/semicircle": "",
+    "/obj/structure/sign/traffic/semicircle/largest": "",
+    "/obj/structure/sign/traffic/side": "",
+    "/obj/structure/sign/traffic/stop": "",
+    "/obj/structure/sign/traffic/waysign": "",
+    "/obj/structure/sign/traffic/yeld": "",
+    "/obj/structure/sign/traffic/zebracrossing": "",
+    "/obj/structure/sign/wide/carpet": "",
+    "/obj/structure/sign/wide/carpet/green": "",
+    "/obj/structure/sign/wide/carpet/purple": "",
+    "/obj/structure/sign/wide/carpet/red": "",
+    "/obj/structure/sign/wide/grestin": "",
+    "/obj/structure/sign/wide/kandahar": "",
+    "/obj/structure/sign/xray": "",
+    "/obj/structure/simple_door": "",
+    "/obj/structure/simple_door/cell": "",
+    "/obj/structure/simple_door/fence": "",
+    "/obj/structure/simple_door/fence/picket": "",
+    "/obj/structure/simple_door/gold": "",
+    "/obj/structure/simple_door/iron": "",
+    "/obj/structure/simple_door/key_door": "",
+    "/obj/structure/simple_door/key_door/abashiri": "",
+    "/obj/structure/simple_door/key_door/abashiri/head": "",
+    "/obj/structure/simple_door/key_door/american": "",
+    "/obj/structure/simple_door/key_door/ancient/roman": "",
+    "/obj/structure/simple_door/key_door/anyone": "",
+    "/obj/structure/simple_door/key_door/anyone/blast": "",
+    "/obj/structure/simple_door/key_door/anyone/doubledoor": "",
+    "/obj/structure/simple_door/key_door/anyone/doubledoor/bamboo": "",
+    "/obj/structure/simple_door/key_door/anyone/doubledoor/gold": "",
+    "/obj/structure/simple_door/key_door/anyone/doubledoor/iron": "",
+    "/obj/structure/simple_door/key_door/anyone/doubledoor/lead": "",
+    "/obj/structure/simple_door/key_door/anyone/doubledoor/marble": "",
+    "/obj/structure/simple_door/key_door/anyone/doubledoor/silver": "",
+    "/obj/structure/simple_door/key_door/anyone/doubledoor/steel": "",
+    "/obj/structure/simple_door/key_door/anyone/doubledoor/steel/store_door": "",
+    "/obj/structure/simple_door/key_door/anyone/doubledoor/stone": "",
+    "/obj/structure/simple_door/key_door/anyone/doubledoor/wood": "",
+    "/obj/structure/simple_door/key_door/anyone/high_sec": "",
+    "/obj/structure/simple_door/key_door/anyone/nordic": "",
+    "/obj/structure/simple_door/key_door/anyone/roman": "",
+    "/obj/structure/simple_door/key_door/anyone/rustic": "",
+    "/obj/structure/simple_door/key_door/anyone/ship": "",
+    "/obj/structure/simple_door/key_door/anyone/shoji": "",
+    "/obj/structure/simple_door/key_door/anyone/singledoor": "",
+    "/obj/structure/simple_door/key_door/anyone/singledoor/housedoor": "",
+    "/obj/structure/simple_door/key_door/anyone/singledoor/privacy": "",
+    "/obj/structure/simple_door/key_door/anyone/wood": "",
+    "/obj/structure/simple_door/key_door/chinese": "",
+    "/obj/structure/simple_door/key_door/civ/bank": "",
+    "/obj/structure/simple_door/key_door/civ/businessblue": "",
+    "/obj/structure/simple_door/key_door/civ/businessgreen": "",
+    "/obj/structure/simple_door/key_door/civ/businessgreen/ceo": "",
+    "/obj/structure/simple_door/key_door/civ/businessred": "",
+    "/obj/structure/simple_door/key_door/civ/businessred/ceo": "",
+    "/obj/structure/simple_door/key_door/civ/businessyellow": "",
+    "/obj/structure/simple_door/key_door/civ/gov": "",
+    "/obj/structure/simple_door/key_door/civ/hall": "",
+    "/obj/structure/simple_door/key_door/civ/inn": "",
+    "/obj/structure/simple_door/key_door/civ/mckellen": "",
+    "/obj/structure/simple_door/key_door/civ/mckellen/manager": "",
+    "/obj/structure/simple_door/key_door/civ/mechanic": "",
+    "/obj/structure/simple_door/key_door/civ/paramedics": "",
+    "/obj/structure/simple_door/key_door/civ/police": "",
+    "/obj/structure/simple_door/key_door/civ/police/chief": "",
+    "/obj/structure/simple_door/key_door/civ/room1": "",
+    "/obj/structure/simple_door/key_door/civ/room2": "",
+    "/obj/structure/simple_door/key_door/civ/room3": "",
+    "/obj/structure/simple_door/key_door/civ/room4": "",
+    "/obj/structure/simple_door/key_door/civ/room5": "",
+    "/obj/structure/simple_door/key_door/civ/room6": "",
+    "/obj/structure/simple_door/key_door/civ/room7": "",
+    "/obj/structure/simple_door/key_door/civ/room8": "",
+    "/obj/structure/simple_door/key_door/civ/sherif": "",
+    "/obj/structure/simple_door/key_door/custom": "",
+    "/obj/structure/simple_door/key_door/custom/doubledoor/marble": "",
+    "/obj/structure/simple_door/key_door/custom/doubledoor/steel": "",
+    "/obj/structure/simple_door/key_door/custom/doubledoor/stone": "",
+    "/obj/structure/simple_door/key_door/custom/jail": "",
+    "/obj/structure/simple_door/key_door/custom/jail/steeljail": "",
+    "/obj/structure/simple_door/key_door/custom/jail/steeljail/german": "",
+    "/obj/structure/simple_door/key_door/custom/jail/steeljail/guard": "",
+    "/obj/structure/simple_door/key_door/custom/jail/steeljail/guard/max": "",
+    "/obj/structure/simple_door/key_door/custom/jail/steeljail/guard/max/command": "",
+    "/obj/structure/simple_door/key_door/custom/jail/steeljail/guard/open": "",
+    "/obj/structure/simple_door/key_door/custom/jail/steeljail/inn": "",
+    "/obj/structure/simple_door/key_door/custom/jail/steeljail/police": "",
+    "/obj/structure/simple_door/key_door/custom/jail/woodjail": "",
+    "/obj/structure/simple_door/key_door/custom/jail/woodjail/abashiri": "",
+    "/obj/structure/simple_door/key_door/custom/jail/woodjail/tribal": "",
+    "/obj/structure/simple_door/key_door/custom/singledoor/privacy": "",
+    "/obj/structure/simple_door/key_door/dutch": "",
+    "/obj/structure/simple_door/key_door/eft/cellar": "",
+    "/obj/structure/simple_door/key_door/eft/gate0": "",
+    "/obj/structure/simple_door/key_door/eft/medgate": "",
+    "/obj/structure/simple_door/key_door/eft/pump": "",
+    "/obj/structure/simple_door/key_door/eft/pumpalt": "",
+    "/obj/structure/simple_door/key_door/french": "",
+    "/obj/structure/simple_door/key_door/german": "",
+    "/obj/structure/simple_door/key_door/german/officer": "",
+    "/obj/structure/simple_door/key_door/insurgent": "",
+    "/obj/structure/simple_door/key_door/japanese": "",
+    "/obj/structure/simple_door/key_door/japanese_officer": "",
+    "/obj/structure/simple_door/key_door/portuguese": "",
+    "/obj/structure/simple_door/key_door/russian": "",
+    "/obj/structure/simple_door/key_door/soviet": "",
+    "/obj/structure/simple_door/key_door/soviet/guard": "",
+    "/obj/structure/simple_door/key_door/soviet/guard/chainlink": "",
+    "/obj/structure/simple_door/key_door/soviet/guard/max": "",
+    "/obj/structure/simple_door/key_door/vietnamese": "",
+    "/obj/structure/simple_door/key_door/wood": "",
+    "/obj/structure/simple_door/sandstone": "",
+    "/obj/structure/simple_door/silver": "",
+    "/obj/structure/simple_door/stone": "",
+    "/obj/structure/simple_door/wood": "",
+    "/obj/structure/simple_door/wood2": "",
+    "/obj/structure/sink": "",
+    "/obj/structure/sink/kitchen": "",
+    "/obj/structure/sink/puddle": "",
+    "/obj/structure/sink/puddle/nomosquitoes": "",
+    "/obj/structure/sink/well": "",
+    "/obj/structure/sink/well/marble": "",
+    "/obj/structure/sink/well/sandstone": "",
+    "/obj/structure/skeleton_activator": "",
+    "/obj/structure/skeleton_configurator": "",
+    "/obj/structure/skeleton_deactivator": "",
+    "/obj/structure/stockmarket": "",
+    "/obj/structure/submitter": "",
+    "/obj/structure/supplybook": "",
+    "/obj/structure/table": "",
+    "/obj/structure/table/carboot": "",
+    "/obj/structure/table/fancy": "",
+    "/obj/structure/table/glass": "",
+    "/obj/structure/table/marble": "",
+    "/obj/structure/table/modern": "",
+    "/obj/structure/table/modern/billiard": "",
+    "/obj/structure/table/modern/flipped": "",
+    "/obj/structure/table/modern/retable": "",
+    "/obj/structure/table/modern/retable/flipped": "",
+    "/obj/structure/table/modern/table": "",
+    "/obj/structure/table/modern/table/flipped": "",
+    "/obj/structure/table/nightstand": "",
+    "/obj/structure/table/nightstand/alt": "",
+    "/obj/structure/table/nightstand/small": "",
+    "/obj/structure/table/rack": "",
+    "/obj/structure/table/rack/coatrack": "",
+    "/obj/structure/table/rack/shelf": "",
+    "/obj/structure/table/rack/shelf/store": "",
+    "/obj/structure/table/rack/shelf/wooden": "",
+    "/obj/structure/table/wood": "",
+    "/obj/structure/table/wood/flipped": "",
+    "/obj/structure/table/wood/poker": "",
+    "/obj/structure/table_frame": "",
+    "/obj/structure/table_frame/wood": "",
+    "/obj/structure/telegraph": "",
+    "/obj/structure/teleprinter": "",
+    "/obj/structure/tent": "",
+    "/obj/structure/toilet": "",
+    "/obj/structure/toilet/outhouse": "",
+    "/obj/structure/toilet/outhouse/female": "",
+    "/obj/structure/toilet/outhouse/male": "",
+    "/obj/structure/toilet/pit_latrine": "",
+    "/obj/structure/toilet/pit_latrine/floorgrate": "",
+    "/obj/structure/torch_stand": "",
+    "/obj/structure/torch_stand/full": "",
+    "/obj/structure/torch_stand/lantern": "",
+    "/obj/structure/townmilitia_activator": "",
+    "/obj/structure/townmilitia_configurator": "",
+    "/obj/structure/townmilitia_deactivator": "",
+    "/obj/structure/train_lever": "",
+    "/obj/structure/trains/locomotive/coal": "",
+    "/obj/structure/trains/storage/closed": "",
+    "/obj/structure/trains/storage/miningcart": "",
+    "/obj/structure/trains/storage/tender": "",
+    "/obj/structure/trains/transport/cabin": "",
+    "/obj/structure/trains/transport/flatbed": "",
+    "/obj/structure/transformer": "",
+    "/obj/structure/transport_lever": "",
+    "/obj/structure/truck": "",
+    "/obj/structure/turret/bmd2": "",
+    "/obj/structure/turret/chiha": "",
+    "/obj/structure/turret/course/su100": "",
+    "/obj/structure/turret/course/su85m": "",
+    "/obj/structure/turret/mtlb": "",
+    "/obj/structure/turret/pziv": "",
+    "/obj/structure/turret/pzvi": "",
+    "/obj/structure/turret/sherman": "",
+    "/obj/structure/turret/t34": "",
+    "/obj/structure/turret/t3485": "",
+    "/obj/structure/turret/t55": "",
+    "/obj/structure/turret/t72": "",
+    "/obj/structure/turret/technical_dshk": "",
+    "/obj/structure/TV": "",
+    "/obj/structure/TV/active": "",
+    "/obj/structure/TV/grandfather": "",
+    "/obj/structure/TV/grandfather/inactive": "",
+    "/obj/structure/TV/television": "",
+    "/obj/structure/TV/television/active": "",
+    "/obj/structure/urinal": "",
+    "/obj/structure/vehicle/boat/b400": "",
+    "/obj/structure/vehicle/boat/rhib/premade": "",
+    "/obj/structure/vehicle/boat/sailboat": "",
+    "/obj/structure/vehicle/carriage": "",
+    "/obj/structure/vehicle/motorcycle/m125": "",
+    "/obj/structure/vehicle/motorcycle/m125/full": "",
+    "/obj/structure/vehicle/raft": "",
+    "/obj/structure/vehicleparts/axis/car": "",
+    "/obj/structure/vehicleparts/axis/car/ba64": "",
+    "/obj/structure/vehicleparts/axis/car/erstenklasse": "",
+    "/obj/structure/vehicleparts/axis/car/falcon": "",
+    "/obj/structure/vehicleparts/axis/car/falcon/police": "",
+    "/obj/structure/vehicleparts/axis/car/shinobu/police": "",
+    "/obj/structure/vehicleparts/axis/car/t20komsomoletstractor": "",
+    "/obj/structure/vehicleparts/axis/car/type94": "",
+    "/obj/structure/vehicleparts/axis/car/type95": "",
+    "/obj/structure/vehicleparts/axis/car/unattr": "",
+    "/obj/structure/vehicleparts/axis/car/volle/ambulance": "",
+    "/obj/structure/vehicleparts/axis/heavy": "",
+    "/obj/structure/vehicleparts/axis/heavy/bmd2": "",
+    "/obj/structure/vehicleparts/axis/heavy/chi_ha": "",
+    "/obj/structure/vehicleparts/axis/heavy/i_go": "",
+    "/obj/structure/vehicleparts/axis/heavy/kv1a": "",
+    "/obj/structure/vehicleparts/axis/heavy/m4": "",
+    "/obj/structure/vehicleparts/axis/heavy/mtlb": "",
+    "/obj/structure/vehicleparts/axis/heavy/omw22_2": "",
+    "/obj/structure/vehicleparts/axis/heavy/panzeriv": "",
+    "/obj/structure/vehicleparts/axis/heavy/panzervi": "",
+    "/obj/structure/vehicleparts/axis/heavy/su100": "",
+    "/obj/structure/vehicleparts/axis/heavy/su100/su85m": "",
+    "/obj/structure/vehicleparts/axis/heavy/t34": "",
+    "/obj/structure/vehicleparts/axis/heavy/t34/t3485": "",
+    "/obj/structure/vehicleparts/axis/heavy/t72": "",
+    "/obj/structure/vehicleparts/axis/ship/heavy": "",
+    "/obj/structure/vehicleparts/frame": "",
+    "/obj/structure/vehicleparts/frame/bmd2/lb": "",
+    "/obj/structure/vehicleparts/frame/bmd2/lc": "",
+    "/obj/structure/vehicleparts/frame/bmd2/lf": "",
+    "/obj/structure/vehicleparts/frame/bmd2/rb": "",
+    "/obj/structure/vehicleparts/frame/bmd2/rc": "",
+    "/obj/structure/vehicleparts/frame/bmd2/rf": "",
+    "/obj/structure/vehicleparts/frame/car/falcon/lb": "",
+    "/obj/structure/vehicleparts/frame/car/falcon/lbc": "",
+    "/obj/structure/vehicleparts/frame/car/falcon/lf": "",
+    "/obj/structure/vehicleparts/frame/car/falcon/lfc": "",
+    "/obj/structure/vehicleparts/frame/car/falcon/rb": "",
+    "/obj/structure/vehicleparts/frame/car/falcon/rbc": "",
+    "/obj/structure/vehicleparts/frame/car/falcon/rf": "",
+    "/obj/structure/vehicleparts/frame/car/falcon/rfc": "",
+    "/obj/structure/vehicleparts/frame/car/lb": "",
+    "/obj/structure/vehicleparts/frame/car/lb/armored": "",
+    "/obj/structure/vehicleparts/frame/car/left": "",
+    "/obj/structure/vehicleparts/frame/car/left/armored": "",
+    "/obj/structure/vehicleparts/frame/car/left/metal": "",
+    "/obj/structure/vehicleparts/frame/car/left/metalreinforced": "",
+    "/obj/structure/vehicleparts/frame/car/lf": "",
+    "/obj/structure/vehicleparts/frame/car/lf/armored": "",
+    "/obj/structure/vehicleparts/frame/car/lf/truck": "",
+    "/obj/structure/vehicleparts/frame/car/lf/truck/armored": "",
+    "/obj/structure/vehicleparts/frame/car/rb": "",
+    "/obj/structure/vehicleparts/frame/car/rb/armored": "",
+    "/obj/structure/vehicleparts/frame/car/rf": "",
+    "/obj/structure/vehicleparts/frame/car/rf/armored": "",
+    "/obj/structure/vehicleparts/frame/car/rf/truck": "",
+    "/obj/structure/vehicleparts/frame/car/rf/truck/armored": "",
+    "/obj/structure/vehicleparts/frame/car/right": "",
+    "/obj/structure/vehicleparts/frame/car/right/armored": "",
+    "/obj/structure/vehicleparts/frame/car/right/metal": "",
+    "/obj/structure/vehicleparts/frame/car/shinobu/lb": "",
+    "/obj/structure/vehicleparts/frame/car/shinobu/lbc": "",
+    "/obj/structure/vehicleparts/frame/car/shinobu/lcf": "",
+    "/obj/structure/vehicleparts/frame/car/shinobu/lf": "",
+    "/obj/structure/vehicleparts/frame/car/shinobu/rb": "",
+    "/obj/structure/vehicleparts/frame/car/shinobu/rbc": "",
+    "/obj/structure/vehicleparts/frame/car/shinobu/rcf": "",
+    "/obj/structure/vehicleparts/frame/car/shinobu/rf": "",
+    "/obj/structure/vehicleparts/frame/car/type94/lc": "",
+    "/obj/structure/vehicleparts/frame/car/type94/lf": "",
+    "/obj/structure/vehicleparts/frame/car/type94/rc": "",
+    "/obj/structure/vehicleparts/frame/car/type94/rf": "",
+    "/obj/structure/vehicleparts/frame/car/type95/lb": "",
+    "/obj/structure/vehicleparts/frame/car/type95/lc": "",
+    "/obj/structure/vehicleparts/frame/car/type95/lf": "",
+    "/obj/structure/vehicleparts/frame/car/type95/rb": "",
+    "/obj/structure/vehicleparts/frame/car/type95/rc": "",
+    "/obj/structure/vehicleparts/frame/car/type95/rf": "",
+    "/obj/structure/vehicleparts/frame/car/umek/lb": "",
+    "/obj/structure/vehicleparts/frame/car/umek/lbc": "",
+    "/obj/structure/vehicleparts/frame/car/umek/lf": "",
+    "/obj/structure/vehicleparts/frame/car/umek/lfc": "",
+    "/obj/structure/vehicleparts/frame/car/umek/rb": "",
+    "/obj/structure/vehicleparts/frame/car/umek/rbc": "",
+    "/obj/structure/vehicleparts/frame/car/umek/rf": "",
+    "/obj/structure/vehicleparts/frame/car/umek/rfc": "",
+    "/obj/structure/vehicleparts/frame/car/van/lb": "",
+    "/obj/structure/vehicleparts/frame/car/van/lf": "",
+    "/obj/structure/vehicleparts/frame/car/van/lfc": "",
+    "/obj/structure/vehicleparts/frame/car/van/rb": "",
+    "/obj/structure/vehicleparts/frame/car/van/rf": "",
+    "/obj/structure/vehicleparts/frame/car/van/rfc": "",
+    "/obj/structure/vehicleparts/frame/chi_ha": "",
+    "/obj/structure/vehicleparts/frame/chi_ha/back": "",
+    "/obj/structure/vehicleparts/frame/chi_ha/front": "",
+    "/obj/structure/vehicleparts/frame/chi_ha/lb": "",
+    "/obj/structure/vehicleparts/frame/chi_ha/left": "",
+    "/obj/structure/vehicleparts/frame/chi_ha/left/door": "",
+    "/obj/structure/vehicleparts/frame/chi_ha/lf": "",
+    "/obj/structure/vehicleparts/frame/chi_ha/rb": "",
+    "/obj/structure/vehicleparts/frame/chi_ha/rf": "",
+    "/obj/structure/vehicleparts/frame/chi_ha/right": "",
+    "/obj/structure/vehicleparts/frame/chi_ha/right/door": "",
+    "/obj/structure/vehicleparts/frame/defaultarmored/bdoor": "",
+    "/obj/structure/vehicleparts/frame/defaultarmored/lb": "",
+    "/obj/structure/vehicleparts/frame/defaultarmored/lf/armored": "",
+    "/obj/structure/vehicleparts/frame/defaultarmored/lwall/armored": "",
+    "/obj/structure/vehicleparts/frame/defaultarmored/rb": "",
+    "/obj/structure/vehicleparts/frame/defaultarmored/rf/armored": "",
+    "/obj/structure/vehicleparts/frame/defaultarmored/rwall/armored": "",
+    "/obj/structure/vehicleparts/frame/i_go": "",
+    "/obj/structure/vehicleparts/frame/i_go/back": "",
+    "/obj/structure/vehicleparts/frame/i_go/front": "",
+    "/obj/structure/vehicleparts/frame/i_go/lb": "",
+    "/obj/structure/vehicleparts/frame/i_go/left": "",
+    "/obj/structure/vehicleparts/frame/i_go/left/door": "",
+    "/obj/structure/vehicleparts/frame/i_go/lf": "",
+    "/obj/structure/vehicleparts/frame/i_go/rb": "",
+    "/obj/structure/vehicleparts/frame/i_go/rf": "",
+    "/obj/structure/vehicleparts/frame/i_go/right": "",
+    "/obj/structure/vehicleparts/frame/i_go/right/door": "",
+    "/obj/structure/vehicleparts/frame/kv1": "",
+    "/obj/structure/vehicleparts/frame/kv1/back": "",
+    "/obj/structure/vehicleparts/frame/kv1/front": "",
+    "/obj/structure/vehicleparts/frame/kv1/lb": "",
+    "/obj/structure/vehicleparts/frame/kv1/left": "",
+    "/obj/structure/vehicleparts/frame/kv1/left/door": "",
+    "/obj/structure/vehicleparts/frame/kv1/lf": "",
+    "/obj/structure/vehicleparts/frame/kv1/rb": "",
+    "/obj/structure/vehicleparts/frame/kv1/rf": "",
+    "/obj/structure/vehicleparts/frame/kv1/right": "",
+    "/obj/structure/vehicleparts/frame/kv1/right/door": "",
+    "/obj/structure/vehicleparts/frame/m4": "",
+    "/obj/structure/vehicleparts/frame/m4/back": "",
+    "/obj/structure/vehicleparts/frame/m4/front": "",
+    "/obj/structure/vehicleparts/frame/m4/lb": "",
+    "/obj/structure/vehicleparts/frame/m4/left": "",
+    "/obj/structure/vehicleparts/frame/m4/left/door": "",
+    "/obj/structure/vehicleparts/frame/m4/lf": "",
+    "/obj/structure/vehicleparts/frame/m4/rb": "",
+    "/obj/structure/vehicleparts/frame/m4/rf": "",
+    "/obj/structure/vehicleparts/frame/m4/right": "",
+    "/obj/structure/vehicleparts/frame/m4/right/door": "",
+    "/obj/structure/vehicleparts/frame/mtlb/lb": "",
+    "/obj/structure/vehicleparts/frame/mtlb/lbc": "",
+    "/obj/structure/vehicleparts/frame/mtlb/lf": "",
+    "/obj/structure/vehicleparts/frame/mtlb/lfc": "",
+    "/obj/structure/vehicleparts/frame/mtlb/rb": "",
+    "/obj/structure/vehicleparts/frame/mtlb/rbc": "",
+    "/obj/structure/vehicleparts/frame/mtlb/rf": "",
+    "/obj/structure/vehicleparts/frame/mtlb/rfc": "",
+    "/obj/structure/vehicleparts/frame/omw22_2": "",
+    "/obj/structure/vehicleparts/frame/omw22_2/back": "",
+    "/obj/structure/vehicleparts/frame/omw22_2/front": "",
+    "/obj/structure/vehicleparts/frame/omw22_2/lb": "",
+    "/obj/structure/vehicleparts/frame/omw22_2/left": "",
+    "/obj/structure/vehicleparts/frame/omw22_2/lf": "",
+    "/obj/structure/vehicleparts/frame/omw22_2/rb": "",
+    "/obj/structure/vehicleparts/frame/omw22_2/right": "",
+    "/obj/structure/vehicleparts/frame/omw22_2/right/door": "",
+    "/obj/structure/vehicleparts/frame/panzeriv": "",
+    "/obj/structure/vehicleparts/frame/panzeriv/back": "",
+    "/obj/structure/vehicleparts/frame/panzeriv/front": "",
+    "/obj/structure/vehicleparts/frame/panzeriv/lb": "",
+    "/obj/structure/vehicleparts/frame/panzeriv/left": "",
+    "/obj/structure/vehicleparts/frame/panzeriv/left/door": "",
+    "/obj/structure/vehicleparts/frame/panzeriv/lf": "",
+    "/obj/structure/vehicleparts/frame/panzeriv/rb": "",
+    "/obj/structure/vehicleparts/frame/panzeriv/rf": "",
+    "/obj/structure/vehicleparts/frame/panzeriv/right": "",
+    "/obj/structure/vehicleparts/frame/panzeriv/right/door": "",
+    "/obj/structure/vehicleparts/frame/panzervi": "",
+    "/obj/structure/vehicleparts/frame/panzervi/back/door": "",
+    "/obj/structure/vehicleparts/frame/panzervi/front": "",
+    "/obj/structure/vehicleparts/frame/panzervi/lb": "",
+    "/obj/structure/vehicleparts/frame/panzervi/left": "",
+    "/obj/structure/vehicleparts/frame/panzervi/lf": "",
+    "/obj/structure/vehicleparts/frame/panzervi/rb": "",
+    "/obj/structure/vehicleparts/frame/panzervi/rf": "",
+    "/obj/structure/vehicleparts/frame/panzervi/right": "",
+    "/obj/structure/vehicleparts/frame/sdfkzfront/lf": "",
+    "/obj/structure/vehicleparts/frame/sdfkzfront/rf": "",
+    "/obj/structure/vehicleparts/frame/sdfkzfront/right/door": "",
+    "/obj/structure/vehicleparts/frame/ship": "",
+    "/obj/structure/vehicleparts/frame/ship/back": "",
+    "/obj/structure/vehicleparts/frame/ship/bl": "",
+    "/obj/structure/vehicleparts/frame/ship/br": "",
+    "/obj/structure/vehicleparts/frame/ship/fl": "",
+    "/obj/structure/vehicleparts/frame/ship/fr": "",
+    "/obj/structure/vehicleparts/frame/ship/front": "",
+    "/obj/structure/vehicleparts/frame/ship/lwall": "",
+    "/obj/structure/vehicleparts/frame/ship/rwall": "",
+    "/obj/structure/vehicleparts/frame/su100/back": "",
+    "/obj/structure/vehicleparts/frame/su100/bc": "",
+    "/obj/structure/vehicleparts/frame/su100/fc": "",
+    "/obj/structure/vehicleparts/frame/su100/front": "",
+    "/obj/structure/vehicleparts/frame/su100/lb": "",
+    "/obj/structure/vehicleparts/frame/su100/lbc": "",
+    "/obj/structure/vehicleparts/frame/su100/lf": "",
+    "/obj/structure/vehicleparts/frame/su100/lfc": "",
+    "/obj/structure/vehicleparts/frame/su100/rb": "",
+    "/obj/structure/vehicleparts/frame/su100/rbc": "",
+    "/obj/structure/vehicleparts/frame/su100/rf": "",
+    "/obj/structure/vehicleparts/frame/su100/rfc": "",
+    "/obj/structure/vehicleparts/frame/su85/lf": "",
+    "/obj/structure/vehicleparts/frame/su85/rf": "",
+    "/obj/structure/vehicleparts/frame/su85/right/door": "",
+    "/obj/structure/vehicleparts/frame/t20/backl": "",
+    "/obj/structure/vehicleparts/frame/t20/backr": "",
+    "/obj/structure/vehicleparts/frame/t20/frontlback": "",
+    "/obj/structure/vehicleparts/frame/t20/frontrback": "",
+    "/obj/structure/vehicleparts/frame/t20/leftm": "",
+    "/obj/structure/vehicleparts/frame/t20/lf": "",
+    "/obj/structure/vehicleparts/frame/t20/rf": "",
+    "/obj/structure/vehicleparts/frame/t20/rightm": "",
+    "/obj/structure/vehicleparts/frame/t34": "",
+    "/obj/structure/vehicleparts/frame/t34/back": "",
+    "/obj/structure/vehicleparts/frame/t34/bc": "",
+    "/obj/structure/vehicleparts/frame/t34/fc": "",
+    "/obj/structure/vehicleparts/frame/t34/front": "",
+    "/obj/structure/vehicleparts/frame/t34/lb": "",
+    "/obj/structure/vehicleparts/frame/t34/left": "",
+    "/obj/structure/vehicleparts/frame/t34/left/door": "",
+    "/obj/structure/vehicleparts/frame/t34/lf": "",
+    "/obj/structure/vehicleparts/frame/t34/rb": "",
+    "/obj/structure/vehicleparts/frame/t34/rf": "",
+    "/obj/structure/vehicleparts/frame/t34/right": "",
+    "/obj/structure/vehicleparts/frame/t34/right/door": "",
+    "/obj/structure/vehicleparts/frame/t72": "",
+    "/obj/structure/vehicleparts/frame/t72/back": "",
+    "/obj/structure/vehicleparts/frame/t72/front": "",
+    "/obj/structure/vehicleparts/frame/t72/lb": "",
+    "/obj/structure/vehicleparts/frame/t72/left": "",
+    "/obj/structure/vehicleparts/frame/t72/lf": "",
+    "/obj/structure/vehicleparts/frame/t72/rb": "",
+    "/obj/structure/vehicleparts/frame/t72/rf": "",
+    "/obj/structure/vehicleparts/frame/t72/right": "",
+    "/obj/structure/vehicleparts/frame/t72/right/door": "",
+    "/obj/structure/vehicleparts/frame/unattr/backl": "",
+    "/obj/structure/vehicleparts/frame/unattr/backr": "",
+    "/obj/structure/vehicleparts/frame/unattr/frontlback": "",
+    "/obj/structure/vehicleparts/frame/unattr/frontrback": "",
+    "/obj/structure/vehicleparts/frame/unattr/leftm": "",
+    "/obj/structure/vehicleparts/frame/unattr/lf": "",
+    "/obj/structure/vehicleparts/frame/unattr/rf": "",
+    "/obj/structure/vehicleparts/frame/unattr/rightm": "",
+    "/obj/structure/vehicleparts/license_plate/eu": "",
+    "/obj/structure/vehicleparts/license_plate/nl": "",
+    "/obj/structure/vehicleparts/license_plate/us": "",
+    "/obj/structure/vehicleparts/license_plate/us/centered": "",
+    "/obj/structure/vehicleparts/license_plate/us/centered/front": "",
+    "/obj/structure/vehicleparts/movement": "",
+    "/obj/structure/vehicleparts/movement/armored": "",
+    "/obj/structure/vehicleparts/movement/armored/reversed": "",
+    "/obj/structure/vehicleparts/movement/reversed": "",
+    "/obj/structure/vehicleparts/movement/sail": "",
+    "/obj/structure/vehicleparts/movement/sail/premade": "",
+    "/obj/structure/vehicleparts/movement/tracks": "",
+    "/obj/structure/vehicleparts/movement/tracks/bmd2new/left_back": "",
+    "/obj/structure/vehicleparts/movement/tracks/bmd2new/left_front": "",
+    "/obj/structure/vehicleparts/movement/tracks/bmd2new/right_back": "",
+    "/obj/structure/vehicleparts/movement/tracks/bmd2new/right_front": "",
+    "/obj/structure/vehicleparts/movement/tracks/left": "",
+    "/obj/structure/vehicleparts/movement/tracks/left/reversed": "",
+    "/obj/structure/vehicleparts/movement/tracks/mtlb/left_back": "",
+    "/obj/structure/vehicleparts/movement/tracks/mtlb/left_front": "",
+    "/obj/structure/vehicleparts/movement/tracks/mtlb/right_back": "",
+    "/obj/structure/vehicleparts/movement/tracks/mtlb/right_front": "",
+    "/obj/structure/vehicleparts/movement/tracks/reversed": "",
+    "/obj/structure/vehicleparts/movement/tracks/right": "",
+    "/obj/structure/vehicleparts/movement/tracks/right/reversed": "",
+    "/obj/structure/vehicleparts/movement/tracks/su100/left_back": "",
+    "/obj/structure/vehicleparts/movement/tracks/su100/left_front": "",
+    "/obj/structure/vehicleparts/movement/tracks/su100/right_back": "",
+    "/obj/structure/vehicleparts/movement/tracks/su100/right_front": "",
+    "/obj/structure/vehicleparts/movement/tracks/t34/left_back": "",
+    "/obj/structure/vehicleparts/movement/tracks/t34/left_front": "",
+    "/obj/structure/vehicleparts/movement/tracks/t34/right_back": "",
+    "/obj/structure/vehicleparts/movement/tracks/t34/right_front": "",
+    "/obj/structure/vehicleparts/shipwheel": "",
+    "/obj/structure/vending/britishapparel": "",
+    "/obj/structure/vending/business_apparel": "",
+    "/obj/structure/vending/capnball": "",
+    "/obj/structure/vending/chineseapparel": "",
+    "/obj/structure/vending/chineseapparel/early": "",
+    "/obj/structure/vending/chineseapparel_korean_war": "",
+    "/obj/structure/vending/chineseweapons": "",
+    "/obj/structure/vending/chineseweapons_korean_war": "",
+    "/obj/structure/vending/coldwar/soviet/apparel": "",
+    "/obj/structure/vending/confederate_apparel": "",
+    "/obj/structure/vending/craftable/rifles": "",
+    "/obj/structure/vending/craftable/rifles/wood": "",
+    "/obj/structure/vending/craftable/rifles/wood/filled_lebel": "",
+    "/obj/structure/vending/craftable/rifles/wood/filled_musket": "",
+    "/obj/structure/vending/craftable/rifles/wood/filled_musket_british": "",
+    "/obj/structure/vending/craftable/rifles/wood/filled_musket_french": "",
+    "/obj/structure/vending/craftable/rifles/wood/filled_musket_spanish": "",
+    "/obj/structure/vending/craftable/rifles/wood/filled_musketoon": "",
+    "/obj/structure/vending/flintlock": "",
+    "/obj/structure/vending/grenade_crate": "",
+    "/obj/structure/vending/grenade_crate/alt": "",
+    "/obj/structure/vending/hezammo": "",
+    "/obj/structure/vending/idfammo": "",
+    "/obj/structure/vending/japaneseapparel": "",
+    "/obj/structure/vending/japaneseapparel_ww2": "",
+    "/obj/structure/vending/japaneseapparel_ww2_navy": "",
+    "/obj/structure/vending/japaneseapparel_ww2_snlf": "",
+    "/obj/structure/vending/japweapons": "",
+    "/obj/structure/vending/japweapons_ww2": "",
+    "/obj/structure/vending/muskets": "",
+    "/obj/structure/vending/muskets/english": "",
+    "/obj/structure/vending/muskets/french": "",
+    "/obj/structure/vending/muskets/spanish": "",
+    "/obj/structure/vending/oldrussianweapons": "",
+    "/obj/structure/vending/piratesapparel": "",
+    "/obj/structure/vending/police_equipment": "",
+    "/obj/structure/vending/police_weapons": "",
+    "/obj/structure/vending/police_weapons/ltl": "",
+    "/obj/structure/vending/rednikovapparel": "",
+    "/obj/structure/vending/rednikovweapons": "",
+    "/obj/structure/vending/russianapparel": "",
+    "/obj/structure/vending/rusweapons": "",
+    "/obj/structure/vending/sales/business_weapons": "",
+    "/obj/structure/vending/sales/cia_agent": "",
+    "/obj/structure/vending/sales/cigarettes": "",
+    "/obj/structure/vending/sales/drinks": "",
+    "/obj/structure/vending/sales/drinks/cola": "",
+    "/obj/structure/vending/sales/drinks/hot": "",
+    "/obj/structure/vending/sales/drinks/soviet": "",
+    "/obj/structure/vending/sales/food": "",
+    "/obj/structure/vending/sales/food/hot": "",
+    "/obj/structure/vending/sales/food/snacks": "",
+    "/obj/structure/vending/sales/market_stall/prepared/gulag": "",
+    "/obj/structure/vending/sales/market_stall/prepared/gulag/consumables": "",
+    "/obj/structure/vending/sales/market_stall/prepared/gulag/food": "",
+    "/obj/structure/vending/sales/menu/donuts": "",
+    "/obj/structure/vending/sales/menu/mcd": "",
+    "/obj/structure/vending/sales/menu/pizza": "",
+    "/obj/structure/vending/sales/menu/ramen": "",
+    "/obj/structure/vending/sales/moneycounter": "",
+    "/obj/structure/vending/sales/vending": "",
+    "/obj/structure/vending/sixties/china/apparel": "",
+    "/obj/structure/vending/sixties/china/weapons": "",
+    "/obj/structure/vending/sixties/soviet/apparel": "",
+    "/obj/structure/vending/sixties/soviet/weapons": "",
+    "/obj/structure/vending/sofammo": "",
+    "/obj/structure/vending/sofapparel": "",
+    "/obj/structure/vending/sofweapons": "",
+    "/obj/structure/vending/sovafghan/dra/ammo": "",
+    "/obj/structure/vending/sovafghan/dra/apparel": "",
+    "/obj/structure/vending/sovafghan/dra/weapons": "",
+    "/obj/structure/vending/sovafghan/soviet/ammo": "",
+    "/obj/structure/vending/sovafghan/soviet/apparel": "",
+    "/obj/structure/vending/sovafghan/soviet/weapons": "",
+    "/obj/structure/vending/sovietammo": "",
+    "/obj/structure/vending/sovietapparel": "",
+    "/obj/structure/vending/sovietweapons": "",
+    "/obj/structure/vending/sovietweaponsassault": "",
+    "/obj/structure/vending/ss_officerapparel": "",
+    "/obj/structure/vending/ss_weaponsassaultlatewar": "",
+    "/obj/structure/vending/ssapparel": "",
+    "/obj/structure/vending/starwars/gonk/gcw": "",
+    "/obj/structure/vending/starwars/imperial/apparel": "",
+    "/obj/structure/vending/starwars/imperial/weapons": "",
+    "/obj/structure/vending/starwars/rebel/apparel": "",
+    "/obj/structure/vending/starwars/rebel/weapons": "",
+    "/obj/structure/vending/syria/ammogov": "",
+    "/obj/structure/vending/syria/armorgov": "",
+    "/obj/structure/vending/syria/fsa/ammoreb": "",
+    "/obj/structure/vending/syria/fsa/armorreb": "",
+    "/obj/structure/vending/syria/fsa/gunreb": "",
+    "/obj/structure/vending/syria/gungov": "",
+    "/obj/structure/vending/undercover_apparel": "",
+    "/obj/structure/vending/union_apparel": "",
+    "/obj/structure/vending/usa_apparel_coldwar": "",
+    "/obj/structure/vending/usa_apparel_korean_war": "",
+    "/obj/structure/vending/usa_apparel_modern": "",
+    "/obj/structure/vending/usa_apparel_ww2": "",
+    "/obj/structure/vending/usa_equipment_coldwar": "",
+    "/obj/structure/vending/usa_equipment_modern": "",
+    "/obj/structure/vending/usa_equipment_ww2": "",
+    "/obj/structure/vending/wehrmachtammo": "",
+    "/obj/structure/vending/wehrmachtapparel": "",
+    "/obj/structure/vending/wehrmachtweapons": "",
+    "/obj/structure/vending/ww1britapparel": "",
+    "/obj/structure/vending/ww1britweapons": "",
+    "/obj/structure/vending/ww1frenchapparel": "",
+    "/obj/structure/vending/ww1frenchweapons": "",
+    "/obj/structure/vending/ww1gerapparel": "",
+    "/obj/structure/vending/ww1gerweapons": "",
+    "/obj/structure/vending/yakuza": "",
+    "/obj/structure/vending/yakuza/equipment": "",
+    "/obj/structure/vending/yeltsinammo": "",
+    "/obj/structure/vending/yeltsinapparel": "",
+    "/obj/structure/vending/yeltsinweapons": "",
+    "/obj/structure/voting": "",
+    "/obj/structure/voting/civa": "",
+    "/obj/structure/voting/civb": "",
+    "/obj/structure/voting/civc": "",
+    "/obj/structure/voting/civilain": "",
+    "/obj/structure/voting/pirates": "",
+    "/obj/structure/voyage/anchor": "",
+    "/obj/structure/voyage/anchor_capstan": "",
+    "/obj/structure/voyage/boatswain_book": "",
+    "/obj/structure/voyage/grid": "",
+    "/obj/structure/voyage/grid/middle": "",
+    "/obj/structure/voyage/lever": "",
+    "/obj/structure/voyage/quartermaster_book": "",
+    "/obj/structure/voyage/ropeladder": "",
+    "/obj/structure/voyage/ropeladder/thin": "",
+    "/obj/structure/voyage/sextant": "",
+    "/obj/structure/voyage/shipbell": "",
+    "/obj/structure/voyage/shipwheel": "",
+    "/obj/structure/voyage/tablemap": "",
+    "/obj/structure/voyage/voicepipe/cannons": "",
+    "/obj/structure/voyage/voicepipe/kitchen": "",
+    "/obj/structure/voyage/voicepipe/medical": "",
+    "/obj/structure/voyage/voicepipe/prow": "",
+    "/obj/structure/voyage/voicepipe/upper": "",
+    "/obj/structure/wallclock": "",
+    "/obj/structure/warehouse_book": "",
+    "/obj/structure/wild": "",
+    "/obj/structure/wild/bamboo": "",
+    "/obj/structure/wild/berrybush": "",
+    "/obj/structure/wild/berrybush/amar": "",
+    "/obj/structure/wild/berrybush/azul": "",
+    "/obj/structure/wild/berrybush/corcairghorm": "",
+    "/obj/structure/wild/berrybush/majo": "",
+    "/obj/structure/wild/berrybush/marron": "",
+    "/obj/structure/wild/berrybush/narco": "",
+    "/obj/structure/wild/berrybush/tinto": "",
+    "/obj/structure/wild/berrybush/zelenyy": "",
+    "/obj/structure/wild/burnedbush": "",
+    "/obj/structure/wild/burnedtree": "",
+    "/obj/structure/wild/bush": "",
+    "/obj/structure/wild/bush/big": "",
+    "/obj/structure/wild/flowers": "",
+    "/obj/structure/wild/jungle": "",
+    "/obj/structure/wild/jungle/acacia": "",
+    "/obj/structure/wild/jungle/acacia/dead": "",
+    "/obj/structure/wild/jungle/cherry": "",
+    "/obj/structure/wild/jungle/medpine": "",
+    "/obj/structure/wild/jungle/medpine/dead": "",
+    "/obj/structure/wild/junglebush": "",
+    "/obj/structure/wild/junglebush/cinchona": "",
+    "/obj/structure/wild/largejungle": "",
+    "/obj/structure/wild/palm": "",
+    "/obj/structure/wild/rock": "",
+    "/obj/structure/wild/rock/basalt": "",
+    "/obj/structure/wild/smallbush": "",
+    "/obj/structure/wild/smallbush/winter": "",
+    "/obj/structure/wild/tallgrass": "",
+    "/obj/structure/wild/tallgrass2": "",
+    "/obj/structure/wild/tree": "",
+    "/obj/structure/wild/tree/anchored": "",
+    "/obj/structure/wild/tree/cactus": "",
+    "/obj/structure/wild/tree/dead_tree": "",
+    "/obj/structure/wild/tree/dead_tree/destroyed": "",
+    "/obj/structure/wild/tree/live_tree": "",
+    "/obj/structure/wild/tree/live_tree/pine": "",
+    "/obj/structure/wild/tree/live_tree/pine/snow": "",
+    "/obj/structure/wild/tree/live_tree/snow": "",
+    "/obj/structure/wild/tree_stump": "",
+    "/obj/structure/window": "",
+    "/obj/structure/window/barrier": "",
+    "/obj/structure/window/barrier/concrete": "",
+    "/obj/structure/window/barrier/incomplete": "",
+    "/obj/structure/window/barrier/jersey": "",
+    "/obj/structure/window/barrier/jersey/alt": "",
+    "/obj/structure/window/barrier/palisade": "",
+    "/obj/structure/window/barrier/railing": "",
+    "/obj/structure/window/barrier/railing/brick": "",
+    "/obj/structure/window/barrier/railing/stone": "",
+    "/obj/structure/window/barrier/rock": "",
+    "/obj/structure/window/barrier/sandbag": "",
+    "/obj/structure/window/barrier/sandbag/incomplete": "",
+    "/obj/structure/window/barrier/sandstone": "",
+    "/obj/structure/window/barrier/ship/blue/bport_10": "",
+    "/obj/structure/window/barrier/ship/blue/bport_10/corner": "",
+    "/obj/structure/window/barrier/ship/blue/bport_6/corner": "",
+    "/obj/structure/window/barrier/ship/blue/bport_north": "",
+    "/obj/structure/window/barrier/ship/blue/bport0": "",
+    "/obj/structure/window/barrier/ship/blue/bport0/south": "",
+    "/obj/structure/window/barrier/ship/blue/bport3": "",
+    "/obj/structure/window/barrier/ship/blue/bport3/south": "",
+    "/obj/structure/window/barrier/ship/blue/bport5": "",
+    "/obj/structure/window/barrier/ship/blue/bport5/corner": "",
+    "/obj/structure/window/barrier/ship/blue/bport9": "",
+    "/obj/structure/window/barrier/ship/wood/port0": "",
+    "/obj/structure/window/barrier/ship/wood/port2": "",
+    "/obj/structure/window/barrier/ship/wood/portl1": "",
+    "/obj/structure/window/barrier/ship/wood/portl2": "",
+    "/obj/structure/window/barrier/snowwall": "",
+    "/obj/structure/window/barrier/snowwall/incomplete": "",
+    "/obj/structure/window/classic": "",
+    "/obj/structure/window/classic/abashiri": "",
+    "/obj/structure/window/classic/bamboo": "",
+    "/obj/structure/window/classic/brick": "",
+    "/obj/structure/window/classic/brickfull": "",
+    "/obj/structure/window/classic/marble": "",
+    "/obj/structure/window/classic/marblefull": "",
+    "/obj/structure/window/classic/medieval": "",
+    "/obj/structure/window/classic/metal": "",
+    "/obj/structure/window/classic/portholefull": "",
+    "/obj/structure/window/classic/reinforced": "",
+    "/obj/structure/window/classic/sandstone": "",
+    "/obj/structure/window/classic/sandstonefull": "",
+    "/obj/structure/window/classic/shoji": "",
+    "/obj/structure/window/classic/stone": "",
+    "/obj/structure/window/classic/stonefull": "",
+    "/obj/structure/window/classic/sumerian": "",
+    "/obj/structure/window/clean": "",
+    "/obj/structure/window/clean/reinforced": "",
+    "/obj/structure/window/clean/reinforced/bank_glass": "",
+    "/obj/structure/window/clean/reinforced/metal": "",
+    "/obj/structure/window_frame": "",
+    "/obj/structure/window_frame/bamboo": "",
+    "/obj/structure/window_frame/brickfull": "",
+    "/obj/structure/window_frame/marble": "",
+    "/obj/structure/window_frame/metal": "",
+    "/obj/structure/window_frame/portholefull": "",
+    "/obj/structure/window_frame/shoji": "",
+    "/obj/structure/window_frame/stone": "",
+    "/turf/floor": "FloorPlanetGrass",
+    "/turf/floor/beach": "FloorSand",
+    "/turf/floor/beach/sand": "FloorSand",
+    "/turf/floor/beach/sand/dark": "FloorDesert",
+    "/turf/floor/beach/sand/desert": "FloorDesert",
+    "/turf/floor/beach/water": "",
+    "/turf/floor/beach/water/coastwater": "",
+    "/turf/floor/beach/water/coastwater/corner": "",
+    "/turf/floor/beach/water/coastwater/layer": "",
+    "/turf/floor/beach/water/deep": "",
+    "/turf/floor/beach/water/deep/jungle": "",
+    "/turf/floor/beach/water/deep/saltwater": "",
+    "/turf/floor/beach/water/deep/saltwater/shipline": "",
+    "/turf/floor/beach/water/deep/saltwater/underwater": "",
+    "/turf/floor/beach/water/deep/swamp": "",
+    "/turf/floor/beach/water/flooded": "",
+    "/turf/floor/beach/water/ice": "",
+    "/turf/floor/beach/water/ice/salty": "",
+    "/turf/floor/beach/water/jungle": "",
+    "/turf/floor/beach/water/shallowsaltwater": "",
+    "/turf/floor/beach/water/swamp": "",
+    "/turf/floor/blackslateroof": "",
+    "/turf/floor/broken_floor": "",
+    "/turf/floor/broken_floor/sky": "",
+    "/turf/floor/carpet": "",
+    "/turf/floor/carpet/blackcarpet": "",
+    "/turf/floor/carpet/bluecarpet": "",
+    "/turf/floor/carpet/greencarpet": "",
+    "/turf/floor/carpet/orangecarpet": "",
+    "/turf/floor/carpet/pinkcarpet": "",
+    "/turf/floor/carpet/purplecarpet": "",
+    "/turf/floor/carpet/redcarpet": "",
+    "/turf/floor/carpet/tealcarpet": "",
+    "/turf/floor/carpet/whitecarpet": "",
+    "/turf/floor/delivery": "",
+    "/turf/floor/dirt": "",
+    "/turf/floor/dirt/burned": "",
+    "/turf/floor/dirt/dark_dirt": "",
+    "/turf/floor/dirt/dry_lava": "",
+    "/turf/floor/dirt/dust": "",
+    "/turf/floor/dirt/flooded": "",
+    "/turf/floor/dirt/jungledirt": "",
+    "/turf/floor/dirt/ploughed": "",
+    "/turf/floor/dirt/ploughed/flooded": "",
+    "/turf/floor/dirt/ploughed/medium_fertile": "",
+    "/turf/floor/dirt/underground": "",
+    "/turf/floor/dirt/underground/empty": "",
+    "/turf/floor/dirt/underground/icy": "",
+    "/turf/floor/dirt/underground/icy/rock": "",
+    "/turf/floor/dirt/underground/sandy": "",
+    "/turf/floor/dirt/winter": "",
+    "/turf/floor/grass/jungle": "",
+    "/turf/floor/grass/jungle/savanna": "",
+    "/turf/floor/lava/permanent": "",
+    "/turf/floor/mining": "",
+    "/turf/floor/plating": "",
+    "/turf/floor/plating/cobblestone": "",
+    "/turf/floor/plating/cobblestone/dark": "",
+    "/turf/floor/plating/cobblestone/vertical": "",
+    "/turf/floor/plating/cobblestone/vertical/dark": "",
+    "/turf/floor/plating/concrete": "",
+    "/turf/floor/plating/dark": "",
+    "/turf/floor/plating/ironsand": "",
+    "/turf/floor/plating/marble": "",
+    "/turf/floor/plating/marble/black": "",
+    "/turf/floor/plating/marble/decorative_tile": "",
+    "/turf/floor/plating/marble/grid": "",
+    "/turf/floor/plating/marble/ornate": "",
+    "/turf/floor/plating/marble/raw": "",
+    "/turf/floor/plating/marble/tile": "",
+    "/turf/floor/plating/metro": "",
+    "/turf/floor/plating/metroline": "",
+    "/turf/floor/plating/road": "",
+    "/turf/floor/plating/road/whiteline": "",
+    "/turf/floor/plating/road/yellowline": "",
+    "/turf/floor/plating/road/yellowline_center": "",
+    "/turf/floor/plating/steel": "",
+    "/turf/floor/plating/stone_old": "",
+    "/turf/floor/plating/tiled": "",
+    "/turf/floor/plating/tiled/dark": "",
+    "/turf/floor/plating/tiled/darker": "",
+    "/turf/floor/plating/tiled/woodh": "",
+    "/turf/floor/plating/tiled/woodv": "",
+    "/turf/floor/plating/white": "",
+    "/turf/floor/ship": "",
+    "/turf/floor/ship/wood_ship": "",
+    "/turf/floor/ship/wood_ship/south": "",
+    "/turf/floor/space": "",
+    "/turf/floor/trench": "",
+    "/turf/floor/trench/flooded": "",
+    "/turf/floor/winter": "",
+    "/turf/floor/winter/grass": "",
+    "/turf/floor/wood": "",
+    "/turf/floor/wood/alt": "",
+    "/turf/floor/wood/alt/eleven": "",
+    "/turf/floor/wood/alt/five": "",
+    "/turf/floor/wood/alt/four": "",
+    "/turf/floor/wood/alt/seven": "",
+    "/turf/floor/wood/alt/three": "",
+    "/turf/floor/wood/alt/two": "",
+    "/turf/floor/wood/fancywood": "",
+    "/turf/floor/wood/ship": "",
+    "/turf/floor/wood_broken": "",
+    "/turf/sky": "",
+    "/turf/wall": "",
+    "/turf/wall/abashiri": "",
+    "/turf/wall/brick": "",
+    "/turf/wall/cement": "",
+    "/turf/wall/concrete_blocks": "",
+    "/turf/wall/concrete_blocks/vertical": "",
+    "/turf/wall/fortress": "",
+    "/turf/wall/generic_wall": "",
+    "/turf/wall/gold": "",
+    "/turf/wall/indestructable": "",
+    "/turf/wall/indestructable/black": "",
+    "/turf/wall/iron": "",
+    "/turf/wall/iron/low": "",
+    "/turf/wall/old_stone": "",
+    "/turf/wall/rockwall": "",
+    "/turf/wall/rockwall/lavaspawner": "",
+    "/turf/wall/sandstone": "",
+    "/turf/wall/stone": "",
+    "/turf/wall/stone/marble": "",
+    "/turf/wall/stone/stonebrick": "",
+    "/turf/wall/tiles": "",
+    "/turf/wall/void": "",
+    "/turf/wall/wood": "",
+    "/turf/wall/wood/low": "",
+    "/turf/wall/wood/soft": ""
+}

+ 1 - 1
Content.Benchmarks/MapLoadBenchmark.cs

@@ -47,7 +47,7 @@ public async Task Cleanup()
         PoolManager.Shutdown();
         PoolManager.Shutdown();
     }
     }
 
 
-    public static readonly string[] MapsSource = { "Empty", "Satlern", "Box", "Bagel", "Dev", "CentComm", "Core", "TestTeg", "Packed", "Omega", "Reach", "Meta", "Marathon", "MeteorArena", "Fland", "Oasis", "Convex"};
+    public static readonly string[] MapsSource = { "Nomads"};
 
 
     [ParamsSource(nameof(MapsSource))]
     [ParamsSource(nameof(MapsSource))]
     public string Map;
     public string Map;

+ 2 - 2
Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml

@@ -2,14 +2,14 @@
     xmlns="https://spacestation14.io"
     xmlns="https://spacestation14.io"
     xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls">
     xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls">
     <PanelContainer StyleClasses="BackgroundDark">
     <PanelContainer StyleClasses="BackgroundDark">
-        <SplitContainer Orientation="Vertical">
+        <SplitContainer Orientation="Vertical" ResizeMode="NotResizable">
             <SplitContainer Orientation="Horizontal" VerticalExpand="True">
             <SplitContainer Orientation="Horizontal" VerticalExpand="True">
                 <cc:PlayerListControl Access="Public" Name="ChannelSelector" HorizontalExpand="True" SizeFlagsStretchRatio="2" />
                 <cc:PlayerListControl Access="Public" Name="ChannelSelector" HorizontalExpand="True" SizeFlagsStretchRatio="2" />
                 <BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="2">
                 <BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="2">
                     <BoxContainer Access="Public" Name="BwoinkArea" VerticalExpand="True" />
                     <BoxContainer Access="Public" Name="BwoinkArea" VerticalExpand="True" />
                 </BoxContainer>
                 </BoxContainer>
             </SplitContainer>
             </SplitContainer>
-            <BoxContainer Orientation="Horizontal" HorizontalExpand="True">
+            <BoxContainer Orientation="Horizontal" SetHeight="30" >
                 <CheckBox Name="AdminOnly" Access="Public" Text="{Loc 'admin-ahelp-admin-only'}" ToolTip="{Loc 'admin-ahelp-admin-only-tooltip'}" />
                 <CheckBox Name="AdminOnly" Access="Public" Text="{Loc 'admin-ahelp-admin-only'}" ToolTip="{Loc 'admin-ahelp-admin-only-tooltip'}" />
                 <Control HorizontalExpand="True" MinWidth="5" />
                 <Control HorizontalExpand="True" MinWidth="5" />
                 <CheckBox Name="PlaySound" Access="Public" Text="{Loc 'admin-bwoink-play-sound'}" Pressed="True" />
                 <CheckBox Name="PlaySound" Access="Public" Text="{Loc 'admin-bwoink-play-sound'}" Pressed="True" />

+ 5 - 0
Content.Client/CartridgeLoader/Cartridges/NanoTaskCartridgeSystem.cs

@@ -0,0 +1,5 @@
+using Content.Shared.CartridgeLoader.Cartridges;
+
+namespace Content.Client.CartridgeLoader.Cartridges;
+
+public sealed class NanoTaskCartridgeSystem : SharedNanoTaskCartridgeSystem;

+ 32 - 0
Content.Client/CartridgeLoader/Cartridges/NanoTaskItemControl.xaml

@@ -0,0 +1,32 @@
+<Control xmlns="https://spacestation14.io" xmlns:system="clr-namespace:System;assembly=System.Runtime">
+    <BoxContainer Name="MainContainer"
+                  Orientation="Horizontal"
+                  SetWidth="250">
+        <Button Name="MainButton"
+                HorizontalExpand="True"
+                VerticalExpand="True"
+                StyleClasses="ButtonSquare"
+                Margin="-1 0 0 0">
+            <BoxContainer Orientation="Horizontal" HorizontalExpand="True">
+                <BoxContainer Orientation="Vertical"
+                              VerticalExpand="True"
+                              HorizontalExpand="True"
+                              Margin="-5 0 0 0">
+                    <Label Name="TaskLabel"
+                           StyleClasses="LabelSubText" />
+                    <Label Name="TaskForLabel"
+                           StyleClasses="LabelSubText"
+                           Margin="0 -5 0 0" />
+                </BoxContainer>
+            </BoxContainer>
+        </Button>
+        <Button Name="DoneButton"
+                VerticalExpand="True"
+                Text="{Loc 'nano-task-ui-done'}">
+            <Button.StyleClasses>
+                <system:String>ButtonSmall</system:String>
+                <system:String>OpenLeft</system:String>
+            </Button.StyleClasses>
+        </Button>
+    </BoxContainer>
+</Control>

+ 33 - 0
Content.Client/CartridgeLoader/Cartridges/NanoTaskItemControl.xaml.cs

@@ -0,0 +1,33 @@
+using Robust.Client.AutoGenerated;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Maths;
+using Content.Shared.CartridgeLoader.Cartridges;
+
+namespace Content.Client.CartridgeLoader.Cartridges;
+
+/// <summary>
+///     Represents a single control for a single NanoTask item
+/// </summary>
+[GenerateTypedNameReferences]
+public sealed partial class NanoTaskItemControl : Control
+{
+    public Action<int>? OnMainPressed;
+    public Action<int>? OnDonePressed;
+
+    public NanoTaskItemControl(NanoTaskItemAndId item)
+    {
+        RobustXamlLoader.Load(this);
+
+        TaskLabel.Text = item.Data.Description;
+        TaskLabel.FontColorOverride = Color.White;
+        TaskForLabel.Text = item.Data.TaskIsFor;
+
+        MainButton.OnPressed += _ => OnMainPressed?.Invoke(item.Id);
+        DoneButton.OnPressed += _ => OnDonePressed?.Invoke(item.Id);
+
+        MainButton.Disabled = item.Data.IsTaskDone;
+        DoneButton.Text = item.Data.IsTaskDone ? Loc.GetString("nano-task-ui-revert-done") : Loc.GetString("nano-task-ui-done");
+    }
+}

+ 67 - 0
Content.Client/CartridgeLoader/Cartridges/NanoTaskItemPopup.xaml

@@ -0,0 +1,67 @@
+<DefaultWindow xmlns="https://spacestation14.io"
+               Title="{Loc nano-task-ui-item-title}"
+               MinSize="300 300">
+    <PanelContainer StyleClasses="AngleRect">
+        <BoxContainer Orientation="Vertical" Margin="4">
+            <!-- Task Description Input -->
+            <BoxContainer Orientation="Vertical" Margin="0 4">
+                <Label Text="{Loc nano-task-ui-description-label}"
+                       StyleClasses="LabelHeading" />
+                <PanelContainer StyleClasses="ButtonSquare">
+                    <LineEdit Name="DescriptionInput"
+                              PlaceHolder="{Loc nano-task-ui-description-placeholder}" />
+                </PanelContainer>
+            </BoxContainer>
+
+            <!-- Task Requester Input -->
+            <BoxContainer Orientation="Vertical" Margin="0 4">
+                <Label Text="{Loc nano-task-ui-requester-label}"
+                       StyleClasses="LabelHeading" />
+                <PanelContainer StyleClasses="ButtonSquare">
+                    <LineEdit Name="RequesterInput"
+                              PlaceHolder="{Loc nano-task-ui-requester-placeholder}" />
+                </PanelContainer>
+            </BoxContainer>
+
+            <!-- Severity Buttons -->
+            <BoxContainer Orientation="Horizontal"
+                          HorizontalAlignment="Center"
+                          Margin="0 8 0 0">
+                <Button Name="LowButton"
+                        Text="{Loc nano-task-ui-priority-low}"
+                        StyleClasses="OpenRight"
+                        MinSize="60 0" />
+                <Button Name="MediumButton"
+                        Text="{Loc nano-task-ui-priority-medium}"
+                        StyleClasses="ButtonSquare"
+                        MinSize="60 0" />
+                <Button Name="HighButton"
+                        Text="{Loc nano-task-ui-priority-high}"
+                        StyleClasses="OpenLeft"
+                        MinSize="60 0" />
+            </BoxContainer>
+
+            <!-- Verb Buttons -->
+            <BoxContainer Orientation="Horizontal"
+                          HorizontalAlignment="Right"
+                          Margin="0 8 0 0">
+                <Button Name="CancelButton"
+                        Text="{Loc nano-task-ui-cancel}"
+                        StyleClasses="OpenRight"
+                        MinSize="60 0" />
+                <Button Name="DeleteButton"
+                        Text="{Loc nano-task-ui-delete}"
+                        StyleClasses="ButtonSquare"
+                        MinSize="60 0" />
+                <Button Name="PrintButton"
+                        Text="{Loc nano-task-ui-print}"
+                        StyleClasses="ButtonSquare"
+                        MinSize="60 0" />
+                <Button Name="SaveButton"
+                        Text="{Loc nano-task-ui-save}"
+                        StyleClasses="OpenLeft"
+                        MinSize="60 0" />
+            </BoxContainer>
+        </BoxContainer>
+    </PanelContainer>
+</DefaultWindow>

+ 109 - 0
Content.Client/CartridgeLoader/Cartridges/NanoTaskItemPopup.xaml.cs

@@ -0,0 +1,109 @@
+using System.Linq;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.CustomControls;
+using Robust.Client.UserInterface.XAML;
+using Robust.Client.UserInterface.Controls;
+using Content.Shared.CartridgeLoader.Cartridges;
+
+namespace Content.Client.CartridgeLoader.Cartridges;
+
+/// <summary>
+///     Popup displayed to edit a NanoTask item
+/// </summary>
+[GenerateTypedNameReferences]
+public sealed partial class NanoTaskItemPopup : DefaultWindow
+{
+    private readonly ButtonGroup _priorityGroup = new();
+    private int? _editingTaskId = null;
+
+    public Action<int, NanoTaskItem>? TaskSaved;
+    public Action<int>? TaskDeleted;
+    public Action<NanoTaskItem>? TaskCreated;
+    public Action<NanoTaskItem>? TaskPrinted;
+
+    private NanoTaskItem MakeItem()
+    {
+        return new(
+            description: DescriptionInput.Text,
+            taskIsFor: RequesterInput.Text,
+            isTaskDone: false,
+            priority: _priorityGroup.Pressed switch {
+                var item when item == LowButton => NanoTaskPriority.Low,
+                var item when item == MediumButton => NanoTaskPriority.Medium,
+                var item when item == HighButton => NanoTaskPriority.High,
+                _ => NanoTaskPriority.Medium,
+            }
+        );
+    }
+
+    public NanoTaskItemPopup()
+    {
+        RobustXamlLoader.Load(this);
+
+        LowButton.Group = _priorityGroup;
+        MediumButton.Group = _priorityGroup;
+        HighButton.Group = _priorityGroup;
+
+        CancelButton.OnPressed += _ => Close();
+        DeleteButton.OnPressed += _ =>
+        {
+            if (_editingTaskId is int id)
+            {
+                TaskDeleted?.Invoke(id);
+            }
+        };
+        PrintButton.OnPressed += _ =>
+        {
+            TaskPrinted?.Invoke(MakeItem());
+        };
+        SaveButton.OnPressed += _ =>
+        {
+            if (_editingTaskId is int id)
+            {
+                TaskSaved?.Invoke(id, MakeItem());
+            }
+            else
+            {
+                TaskCreated?.Invoke(MakeItem());
+            }
+        };
+
+        DescriptionInput.OnTextChanged += args =>
+        {
+            if (args.Text.Length > NanoTaskItem.MaximumStringLength)
+                DescriptionInput.Text = args.Text[..NanoTaskItem.MaximumStringLength];
+        };
+        RequesterInput.OnTextChanged += args =>
+        {
+            if (args.Text.Length > NanoTaskItem.MaximumStringLength)
+                RequesterInput.Text = args.Text[..NanoTaskItem.MaximumStringLength];
+        };
+    }
+
+    public void SetEditingTaskId(int? id)
+    {
+        _editingTaskId = id;
+        DeleteButton.Visible = id is not null;
+    }
+
+    public void ResetInputs(NanoTaskItem? item)
+    {
+        if (item is NanoTaskItem task)
+        {
+            var button = task.Priority switch {
+                NanoTaskPriority.High => HighButton,
+                NanoTaskPriority.Medium => MediumButton,
+                NanoTaskPriority.Low => LowButton,
+            };
+            button.Pressed = true;
+            DescriptionInput.Text = task.Description;
+            RequesterInput.Text = task.TaskIsFor;
+        }
+        else
+        {
+            MediumButton.Pressed = true;
+            DescriptionInput.Text = "";
+            RequesterInput.Text = "";
+        }
+    }
+}

+ 82 - 0
Content.Client/CartridgeLoader/Cartridges/NanoTaskUi.cs

@@ -0,0 +1,82 @@
+using System.Linq;
+using Content.Client.UserInterface.Fragments;
+using Content.Shared.CartridgeLoader;
+using Content.Shared.CartridgeLoader.Cartridges;
+using Robust.Client.GameObjects;
+using Robust.Client.UserInterface;
+
+namespace Content.Client.CartridgeLoader.Cartridges;
+
+/// <summary>
+///     UI fragment responsible for displaying NanoTask controls in a PDA and coordinating with the NanoTaskCartridgeSystem for state
+/// </summary>
+public sealed partial class NanoTaskUi : UIFragment
+{
+    private NanoTaskUiFragment? _fragment;
+    private NanoTaskItemPopup? _popup;
+
+    public override Control GetUIFragmentRoot()
+    {
+        return _fragment!;
+    }
+
+    public override void Setup(BoundUserInterface userInterface, EntityUid? fragmentOwner)
+    {
+        _fragment = new NanoTaskUiFragment();
+        _popup = new NanoTaskItemPopup();
+        _fragment.NewTask += () =>
+        {
+            _popup.ResetInputs(null);
+            _popup.SetEditingTaskId(null);
+            _popup.OpenCentered();
+        };
+        _fragment.OpenTask += id =>
+        {
+            if (_fragment.Tasks.Find(task => task.Id == id) is not NanoTaskItemAndId task)
+                return;
+
+            _popup.ResetInputs(task.Data);
+            _popup.SetEditingTaskId(task.Id);
+            _popup.OpenCentered();
+        };
+        _fragment.ToggleTaskCompletion += id =>
+        {
+            if (_fragment.Tasks.Find(task => task.Id == id) is not NanoTaskItemAndId task)
+                return;
+
+            userInterface.SendMessage(new CartridgeUiMessage(new NanoTaskUiMessageEvent(new NanoTaskUpdateTask(new(id, new(
+                description: task.Data.Description,
+                taskIsFor: task.Data.TaskIsFor,
+                isTaskDone: !task.Data.IsTaskDone,
+                priority: task.Data.Priority
+            ))))));
+        };
+        _popup.TaskSaved += (id, data) =>
+        {
+            userInterface.SendMessage(new CartridgeUiMessage(new NanoTaskUiMessageEvent(new NanoTaskUpdateTask(new(id, data)))));
+            _popup.Close();
+        };
+        _popup.TaskDeleted += id =>
+        {
+            userInterface.SendMessage(new CartridgeUiMessage(new NanoTaskUiMessageEvent(new NanoTaskDeleteTask(id))));
+            _popup.Close();
+        };
+        _popup.TaskCreated += data =>
+        {
+            userInterface.SendMessage(new CartridgeUiMessage(new NanoTaskUiMessageEvent(new NanoTaskAddTask(data))));
+            _popup.Close();
+        };
+        _popup.TaskPrinted += data =>
+        {
+            userInterface.SendMessage(new CartridgeUiMessage(new NanoTaskUiMessageEvent(new NanoTaskPrintTask(data))));
+        };
+    }
+
+    public override void UpdateState(BoundUserInterfaceState state)
+    {
+        if (state is not NanoTaskUiState nanoTaskState)
+            return;
+
+        _fragment?.UpdateState(nanoTaskState.Tasks);
+    }
+}

+ 58 - 0
Content.Client/CartridgeLoader/Cartridges/NanoTaskUiFragment.xaml

@@ -0,0 +1,58 @@
+<cartridges:NanoTaskUiFragment xmlns:cartridges="clr-namespace:Content.Client.CartridgeLoader.Cartridges"
+                               xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
+                               xmlns="https://spacestation14.io" Margin="1 0 2 0">
+
+    <PanelContainer StyleClasses="BackgroundDark"></PanelContainer>
+    <BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
+        <ScrollContainer HorizontalExpand="True" VerticalExpand="True">
+            <BoxContainer HorizontalExpand="True" VerticalExpand="True" Orientation="Vertical" Margin="8" SeparationOverride="8">
+                <!-- Heading for High Priority Items -->
+                <BoxContainer Orientation="Horizontal">
+                    <PanelContainer SetWidth="7" Margin="0 0 8 0">
+                        <PanelContainer.PanelOverride>
+                            <gfx:StyleBoxFlat BackgroundColor="#e93d58"/>
+                        </PanelContainer.PanelOverride>
+                    </PanelContainer>
+                    <Label Name="HighPriority" StyleClasses="LabelHeading"/>
+                </BoxContainer>
+                <!-- Location for High Priority Items -->
+                <GridContainer Name="HighContainer"
+                               HorizontalExpand="True"
+                               Access="Public"
+                               Columns="2" />
+
+                <!-- Heading for Medium Priority Items -->
+                <BoxContainer Orientation="Horizontal">
+                    <PanelContainer SetWidth="7" Margin="0 0 8 0">
+                        <PanelContainer.PanelOverride>
+                            <gfx:StyleBoxFlat BackgroundColor="#ef973c"/>
+                        </PanelContainer.PanelOverride>
+                    </PanelContainer>
+                    <Label Name="MediumPriority" StyleClasses="LabelHeading"/>
+                </BoxContainer>
+                <!-- Location for Medium Priority Items -->
+                <GridContainer Name="MediumContainer"
+                               HorizontalExpand="True"
+                               Access="Public"
+                               Columns="2" />
+
+                <!-- Location for Low Priority Items -->
+                <BoxContainer Orientation="Horizontal">
+                    <PanelContainer SetWidth="7" Margin="0 0 8 0">
+                        <PanelContainer.PanelOverride>
+                            <gfx:StyleBoxFlat BackgroundColor="#3dd425"/>
+                        </PanelContainer.PanelOverride>
+                    </PanelContainer>
+                    <Label Name="LowPriority" StyleClasses="LabelHeading"/>
+                </BoxContainer>
+                <!-- Location for Low Priority Items -->
+                <GridContainer Name="LowContainer"
+                               HorizontalExpand="True"
+                               Access="Public"
+                               Columns="2" />
+
+                <Button Name="NewTaskButton" Text="{Loc 'nano-task-ui-new-task'}" HorizontalAlignment="Right"/>
+            </BoxContainer>
+        </ScrollContainer>
+    </BoxContainer>
+</cartridges:NanoTaskUiFragment>

+ 52 - 0
Content.Client/CartridgeLoader/Cartridges/NanoTaskUiFragment.xaml.cs

@@ -0,0 +1,52 @@
+using System.Linq;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+using Content.Shared.CartridgeLoader.Cartridges;
+
+namespace Content.Client.CartridgeLoader.Cartridges;
+
+/// <summary>
+///     Class displaying the main UI of NanoTask
+/// </summary>
+[GenerateTypedNameReferences]
+public sealed partial class NanoTaskUiFragment : BoxContainer
+{
+    public Action<int>? OpenTask;
+    public Action<int>? ToggleTaskCompletion;
+    public Action? NewTask;
+    public List<NanoTaskItemAndId> Tasks = new();
+
+    public NanoTaskUiFragment()
+    {
+        RobustXamlLoader.Load(this);
+        Orientation = LayoutOrientation.Vertical;
+        HorizontalExpand = true;
+        VerticalExpand = true;
+        NewTaskButton.OnPressed += _ => NewTask?.Invoke();
+    }
+    public void UpdateState(List<NanoTaskItemAndId> tasks)
+    {
+        Tasks = tasks;
+        HighContainer.RemoveAllChildren();
+        MediumContainer.RemoveAllChildren();
+        LowContainer.RemoveAllChildren();
+
+        HighPriority.Text = Loc.GetString("nano-task-ui-heading-high-priority-tasks", ("amount", tasks.Count(task => task.Data.Priority == NanoTaskPriority.High)));
+        MediumPriority.Text = Loc.GetString("nano-task-ui-heading-medium-priority-tasks", ("amount", tasks.Count(task => task.Data.Priority == NanoTaskPriority.Medium)));
+        LowPriority.Text = Loc.GetString("nano-task-ui-heading-low-priority-tasks", ("amount", tasks.Count(task => task.Data.Priority == NanoTaskPriority.Low)));
+
+        foreach (var task in tasks)
+        {
+            var container = task.Data.Priority switch {
+                NanoTaskPriority.High => HighContainer,
+                NanoTaskPriority.Medium => MediumContainer,
+                NanoTaskPriority.Low => LowContainer,
+            };
+            var control = new NanoTaskItemControl(task);
+            container.AddChild(control);
+            control.OnMainPressed += id => OpenTask?.Invoke(id);
+            control.OnDonePressed += id => ToggleTaskCompletion?.Invoke(id);
+        }
+    }
+}

+ 1 - 1
Content.Client/Clothing/ClientClothingSystem.cs

@@ -162,7 +162,7 @@ private void OnGetVisuals(EntityUid uid, ClothingComponent item, GetEquipmentVis
 
 
         var state = $"equipped-{correctedSlot}";
         var state = $"equipped-{correctedSlot}";
 
 
-        if (clothing.EquippedPrefix != null)
+        if (!string.IsNullOrEmpty(clothing.EquippedPrefix))
             state = $"{clothing.EquippedPrefix}-equipped-{correctedSlot}";
             state = $"{clothing.EquippedPrefix}-equipped-{correctedSlot}";
 
 
         if (clothing.EquippedState != null)
         if (clothing.EquippedState != null)

+ 4 - 3
Content.Client/Construction/UI/ConstructionMenuPresenter.cs

@@ -167,7 +167,7 @@ private void OnGridViewRecipeSelected(object? sender, ConstructionPrototype? rec
             PopulateInfo(_selected);
             PopulateInfo(_selected);
         }
         }
 
 
-        private void OnViewPopulateRecipes(object? sender, (string search, string catagory) args)
+        private void OnViewPopulateRecipes(object? sender, (string search, string category) args)
         {
         {
             var (search, category) = args;
             var (search, category) = args;
 
 
@@ -179,12 +179,13 @@ private void OnViewPopulateRecipes(object? sender, (string search, string catago
                 _selectedCategory = string.Empty;
                 _selectedCategory = string.Empty;
             else
             else
                 _selectedCategory = category;
                 _selectedCategory = category;
-
             foreach (var recipe in _prototypeManager.EnumeratePrototypes<ConstructionPrototype>())
             foreach (var recipe in _prototypeManager.EnumeratePrototypes<ConstructionPrototype>())
             {
             {
+                var CurrentAge = 0; //hardcoded for now
                 if (recipe.Hide)
                 if (recipe.Hide)
                     continue;
                     continue;
-
+                if (CurrentAge < recipe.AgeMin || CurrentAge > recipe.AgeMax)
+                    continue;
                 if (_playerManager.LocalSession == null
                 if (_playerManager.LocalSession == null
                 || _playerManager.LocalEntity == null
                 || _playerManager.LocalEntity == null
                 || _whitelistSystem.IsWhitelistFail(recipe.EntityWhitelist, _playerManager.LocalEntity.Value))
                 || _whitelistSystem.IsWhitelistFail(recipe.EntityWhitelist, _playerManager.LocalEntity.Value))

+ 4 - 3
Content.Client/CriminalRecords/CriminalRecordsConsoleWindow.xaml.cs

@@ -3,6 +3,7 @@
 using Content.Shared.Administration;
 using Content.Shared.Administration;
 using Content.Shared.CriminalRecords;
 using Content.Shared.CriminalRecords;
 using Content.Shared.Dataset;
 using Content.Shared.Dataset;
+using Content.Shared.Random.Helpers;
 using Content.Shared.Security;
 using Content.Shared.Security;
 using Content.Shared.StationRecords;
 using Content.Shared.StationRecords;
 using Robust.Client.AutoGenerated;
 using Robust.Client.AutoGenerated;
@@ -32,7 +33,7 @@ public sealed partial class CriminalRecordsConsoleWindow : FancyWindow
 
 
     public readonly EntityUid Console;
     public readonly EntityUid Console;
 
 
-    [ValidatePrototypeId<DatasetPrototype>]
+    [ValidatePrototypeId<LocalizedDatasetPrototype>]
     private const string ReasonPlaceholders = "CriminalRecordsWantedReasonPlaceholders";
     private const string ReasonPlaceholders = "CriminalRecordsWantedReasonPlaceholders";
 
 
     public Action<uint?>? OnKeySelected;
     public Action<uint?>? OnKeySelected;
@@ -333,8 +334,8 @@ private void GetReason(SecurityStatus status)
 
 
         var field = "reason";
         var field = "reason";
         var title = Loc.GetString("criminal-records-status-" + status.ToString().ToLower());
         var title = Loc.GetString("criminal-records-status-" + status.ToString().ToLower());
-        var placeholders = _proto.Index<DatasetPrototype>(ReasonPlaceholders);
-        var placeholder = Loc.GetString("criminal-records-console-reason-placeholder", ("placeholder", _random.Pick(placeholders.Values))); // just funny it doesn't actually get used
+        var placeholders = _proto.Index<LocalizedDatasetPrototype>(ReasonPlaceholders);
+        var placeholder = Loc.GetString("criminal-records-console-reason-placeholder", ("placeholder", _random.Pick(placeholders))); // just funny it doesn't actually get used
         var prompt = Loc.GetString("criminal-records-console-reason");
         var prompt = Loc.GetString("criminal-records-console-reason");
         var entry = new QuickDialogEntry(field, QuickDialogEntryType.LongText, prompt, placeholder);
         var entry = new QuickDialogEntry(field, QuickDialogEntryType.LongText, prompt, placeholder);
         var entries = new List<QuickDialogEntry>() { entry };
         var entries = new List<QuickDialogEntry>() { entry };

+ 4 - 4
Content.Client/Entry/EntryPoint.cs

@@ -79,7 +79,7 @@ public override void Init()
 
 
             foreach (var callback in TestingCallbacks)
             foreach (var callback in TestingCallbacks)
             {
             {
-                var cast = (ClientModuleTestingCallbacks) callback;
+                var cast = (ClientModuleTestingCallbacks)callback;
                 cast.ClientBeforeIoC?.Invoke();
                 cast.ClientBeforeIoC?.Invoke();
             }
             }
 
 
@@ -164,7 +164,7 @@ public override void PostInit()
             _clientPreferencesManager.Initialize();
             _clientPreferencesManager.Initialize();
             _euiManager.Initialize();
             _euiManager.Initialize();
             _voteManager.Initialize();
             _voteManager.Initialize();
-            _userInterfaceManager.SetDefaultTheme("SS14DefaultTheme");
+            _userInterfaceManager.SetDefaultTheme("SS14CivTheme");
             _userInterfaceManager.SetActiveTheme(_configManager.GetCVar(CVars.InterfaceTheme));
             _userInterfaceManager.SetActiveTheme(_configManager.GetCVar(CVars.InterfaceTheme));
             _documentParsingManager.Initialize();
             _documentParsingManager.Initialize();
             _titleWindowManager.Initialize();
             _titleWindowManager.Initialize();
@@ -205,7 +205,7 @@ private void SwitchToDefaultState(bool disconnected = false)
             else if (_gameController.LaunchState.FromLauncher)
             else if (_gameController.LaunchState.FromLauncher)
             {
             {
                 _stateManager.RequestStateChange<LauncherConnecting>();
                 _stateManager.RequestStateChange<LauncherConnecting>();
-                var state = (LauncherConnecting) _stateManager.CurrentState;
+                var state = (LauncherConnecting)_stateManager.CurrentState;
 
 
                 if (disconnected)
                 if (disconnected)
                 {
                 {
@@ -226,4 +226,4 @@ public override void Update(ModUpdateLevel level, FrameEventArgs frameEventArgs)
             }
             }
         }
         }
     }
     }
-}
+}

+ 6 - 1
Content.Client/Hands/Systems/HandsSystem.cs

@@ -349,7 +349,12 @@ private void UpdateHandVisuals(EntityUid uid, EntityUid held, Hand hand, HandsCo
                 sprite.LayerSetData(index, layerData);
                 sprite.LayerSetData(index, layerData);
 
 
                 //Add displacement maps
                 //Add displacement maps
-                if (handComp.HandDisplacement is not null)
+                if (hand.Location == HandLocation.Left && handComp.LeftHandDisplacement is not null)
+                    _displacement.TryAddDisplacement(handComp.LeftHandDisplacement, sprite, index, key, revealedLayers);
+                else if (hand.Location == HandLocation.Right && handComp.RightHandDisplacement is not null)
+                    _displacement.TryAddDisplacement(handComp.RightHandDisplacement, sprite, index, key, revealedLayers);
+                //Fallback to default displacement map
+                else if (handComp.HandDisplacement is not null)
                     _displacement.TryAddDisplacement(handComp.HandDisplacement, sprite, index, key, revealedLayers);
                     _displacement.TryAddDisplacement(handComp.HandDisplacement, sprite, index, key, revealedLayers);
             }
             }
 
 

+ 12 - 12
Content.Client/Humanoid/HumanoidAppearanceSystem.cs

@@ -2,6 +2,7 @@
 using Content.Shared.Humanoid;
 using Content.Shared.Humanoid;
 using Content.Shared.Humanoid.Markings;
 using Content.Shared.Humanoid.Markings;
 using Content.Shared.Humanoid.Prototypes;
 using Content.Shared.Humanoid.Prototypes;
+using Content.Shared.Inventory;
 using Content.Shared.Preferences;
 using Content.Shared.Preferences;
 using Robust.Client.GameObjects;
 using Robust.Client.GameObjects;
 using Robust.Shared.Configuration;
 using Robust.Shared.Configuration;
@@ -48,7 +49,7 @@ private void UpdateSprite(HumanoidAppearanceComponent component, SpriteComponent
     }
     }
 
 
     private static bool IsHidden(HumanoidAppearanceComponent humanoid, HumanoidVisualLayers layer)
     private static bool IsHidden(HumanoidAppearanceComponent humanoid, HumanoidVisualLayers layer)
-        => humanoid.HiddenLayers.Contains(layer) || humanoid.PermanentlyHidden.Contains(layer);
+        => humanoid.HiddenLayers.ContainsKey(layer) || humanoid.PermanentlyHidden.Contains(layer);
 
 
     private void UpdateLayers(HumanoidAppearanceComponent component, SpriteComponent sprite)
     private void UpdateLayers(HumanoidAppearanceComponent component, SpriteComponent sprite)
     {
     {
@@ -203,7 +204,7 @@ public override void LoadProfile(EntityUid uid, HumanoidCharacterProfile? profil
 
 
         humanoid.MarkingSet = markings;
         humanoid.MarkingSet = markings;
         humanoid.PermanentlyHidden = new HashSet<HumanoidVisualLayers>();
         humanoid.PermanentlyHidden = new HashSet<HumanoidVisualLayers>();
-        humanoid.HiddenLayers = new HashSet<HumanoidVisualLayers>();
+        humanoid.HiddenLayers = new Dictionary<HumanoidVisualLayers, SlotFlags>();
         humanoid.CustomBaseLayers = customBaseLayers;
         humanoid.CustomBaseLayers = customBaseLayers;
         humanoid.Sex = profile.Sex;
         humanoid.Sex = profile.Sex;
         humanoid.Gender = profile.Gender;
         humanoid.Gender = profile.Gender;
@@ -391,23 +392,21 @@ public override void SetSkinColor(EntityUid uid, Color skinColor, bool sync = tr
         }
         }
     }
     }
 
 
-    protected override void SetLayerVisibility(
-        EntityUid uid,
-        HumanoidAppearanceComponent humanoid,
+    public override void SetLayerVisibility(
+        Entity<HumanoidAppearanceComponent> ent,
         HumanoidVisualLayers layer,
         HumanoidVisualLayers layer,
         bool visible,
         bool visible,
-        bool permanent,
+        SlotFlags? slot,
         ref bool dirty)
         ref bool dirty)
     {
     {
-        base.SetLayerVisibility(uid, humanoid, layer, visible, permanent, ref dirty);
+        base.SetLayerVisibility(ent, layer, visible, slot, ref dirty);
 
 
-        var sprite = Comp<SpriteComponent>(uid);
+        var sprite = Comp<SpriteComponent>(ent);
         if (!sprite.LayerMapTryGet(layer, out var index))
         if (!sprite.LayerMapTryGet(layer, out var index))
         {
         {
             if (!visible)
             if (!visible)
                 return;
                 return;
-            else
-                index = sprite.LayerMapReserveBlank(layer);
+            index = sprite.LayerMapReserveBlank(layer);
         }
         }
 
 
         var spriteLayer = sprite[index];
         var spriteLayer = sprite[index];
@@ -417,13 +416,14 @@ public override void SetSkinColor(EntityUid uid, Color skinColor, bool sync = tr
         spriteLayer.Visible = visible;
         spriteLayer.Visible = visible;
 
 
         // I fucking hate this. I'll get around to refactoring sprite layers eventually I swear
         // I fucking hate this. I'll get around to refactoring sprite layers eventually I swear
+        // Just a week away...
 
 
-        foreach (var markingList in humanoid.MarkingSet.Markings.Values)
+        foreach (var markingList in ent.Comp.MarkingSet.Markings.Values)
         {
         {
             foreach (var marking in markingList)
             foreach (var marking in markingList)
             {
             {
                 if (_markingManager.TryGetMarking(marking, out var markingPrototype) && markingPrototype.BodyPart == layer)
                 if (_markingManager.TryGetMarking(marking, out var markingPrototype) && markingPrototype.BodyPart == layer)
-                    ApplyMarking(markingPrototype, marking.MarkingColors, marking.Visible, humanoid, sprite);
+                    ApplyMarking(markingPrototype, marking.MarkingColors, marking.Visible, ent, sprite);
             }
             }
         }
         }
     }
     }

+ 6 - 0
Content.Client/IconSmoothing/IconSmoothComponent.cs

@@ -26,6 +26,12 @@ public sealed partial class IconSmoothComponent : Component
         [ViewVariables(VVAccess.ReadWrite), DataField("key")]
         [ViewVariables(VVAccess.ReadWrite), DataField("key")]
         public string? SmoothKey { get; private set; }
         public string? SmoothKey { get; private set; }
 
 
+        /// <summary>
+        ///     Additional keys to smooth with.
+        /// </summary>
+        [DataField]
+        public List<string> AdditionalKeys = new();
+
         /// <summary>
         /// <summary>
         ///     Prepended to the RSI state.
         ///     Prepended to the RSI state.
         /// </summary>
         /// </summary>

+ 2 - 1
Content.Client/IconSmoothing/IconSmoothSystem.cs

@@ -376,7 +376,8 @@ private bool MatchingEntity(IconSmoothComponent smooth, AnchoredEntitiesEnumerat
             while (candidates.MoveNext(out var entity))
             while (candidates.MoveNext(out var entity))
             {
             {
                 if (smoothQuery.TryGetComponent(entity, out var other) &&
                 if (smoothQuery.TryGetComponent(entity, out var other) &&
-                    other.SmoothKey == smooth.SmoothKey &&
+                    other.SmoothKey != null &&
+                    (other.SmoothKey == smooth.SmoothKey || smooth.AdditionalKeys.Contains(other.SmoothKey)) &&
                     other.Enabled)
                     other.Enabled)
                 {
                 {
                     return true;
                     return true;

+ 0 - 6
Content.Client/Kitchen/UI/MicrowaveMenu.xaml

@@ -97,12 +97,6 @@
          <!-- Footer -->
          <!-- Footer -->
         <BoxContainer Orientation="Vertical">
         <BoxContainer Orientation="Vertical">
             <PanelContainer StyleClasses="LowDivider" />
             <PanelContainer StyleClasses="LowDivider" />
-            <BoxContainer Orientation="Horizontal" Margin="10 2 5 0" VerticalAlignment="Bottom">
-                <Label Text="{Loc 'microwave-menu-footer-flavor-left'}" StyleClasses="WindowFooterText" />
-                <Label Text="{Loc 'microwave-menu-footer-flavor-right'}" StyleClasses="WindowFooterText"
-                       HorizontalAlignment="Right" HorizontalExpand="True"  Margin="0 0 5 0" />
-                <TextureRect StyleClasses="NTLogoDark" Stretch="KeepAspectCentered" VerticalAlignment="Center" HorizontalAlignment="Right" SetSize="19 19"/>
-            </BoxContainer>
         </BoxContainer>
         </BoxContainer>
     </BoxContainer>
     </BoxContainer>
     <PanelContainer Name="DisableCookingPanelOverlay" MouseFilter="Stop">
     <PanelContainer Name="DisableCookingPanelOverlay" MouseFilter="Stop">

+ 1 - 1
Content.Client/Parallax/Data/ParallaxPrototype.cs

@@ -5,7 +5,7 @@ namespace Content.Client.Parallax.Data;
 /// <summary>
 /// <summary>
 /// Prototype data for a parallax.
 /// Prototype data for a parallax.
 /// </summary>
 /// </summary>
-[Prototype("parallax")]
+[Prototype]
 public sealed partial class ParallaxPrototype : IPrototype
 public sealed partial class ParallaxPrototype : IPrototype
 {
 {
     /// <inheritdoc/>
     /// <inheritdoc/>

+ 1 - 1
Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml.cs

@@ -26,7 +26,7 @@ public sealed partial class BorgSelectTypeMenu : FancyWindow
     public event Action<ProtoId<BorgTypePrototype>>? ConfirmedBorgType;
     public event Action<ProtoId<BorgTypePrototype>>? ConfirmedBorgType;
 
 
     [ValidatePrototypeId<GuideEntryPrototype>]
     [ValidatePrototypeId<GuideEntryPrototype>]
-    private static readonly List<ProtoId<GuideEntryPrototype>> GuidebookEntries = new() { "Cyborgs", "Robotics" };
+    private static readonly List<ProtoId<GuideEntryPrototype>> GuidebookEntries = new() { };
 
 
     public BorgSelectTypeMenu()
     public BorgSelectTypeMenu()
     {
     {

+ 24 - 2
Content.Client/SubFloor/SubFloorHideSystem.cs

@@ -1,12 +1,15 @@
-using Content.Shared.DrawDepth;
+using Content.Client.UserInterface.Systems.Sandbox;
 using Content.Shared.SubFloor;
 using Content.Shared.SubFloor;
 using Robust.Client.GameObjects;
 using Robust.Client.GameObjects;
+using Robust.Client.UserInterface;
+using Robust.Shared.Player;
 
 
 namespace Content.Client.SubFloor;
 namespace Content.Client.SubFloor;
 
 
 public sealed class SubFloorHideSystem : SharedSubFloorHideSystem
 public sealed class SubFloorHideSystem : SharedSubFloorHideSystem
 {
 {
     [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
     [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
+    [Dependency] private readonly IUserInterfaceManager _ui = default!;
 
 
     private bool _showAll;
     private bool _showAll;
 
 
@@ -18,8 +21,13 @@ public bool ShowAll
         {
         {
             if (_showAll == value) return;
             if (_showAll == value) return;
             _showAll = value;
             _showAll = value;
+            _ui.GetUIController<SandboxUIController>().SetToggleSubfloors(value);
 
 
-            UpdateAll();
+            var ev = new ShowSubfloorRequestEvent()
+            {
+                Value = value,
+            };
+            RaiseNetworkEvent(ev);
         }
         }
     }
     }
 
 
@@ -28,6 +36,20 @@ public override void Initialize()
         base.Initialize();
         base.Initialize();
 
 
         SubscribeLocalEvent<SubFloorHideComponent, AppearanceChangeEvent>(OnAppearanceChanged);
         SubscribeLocalEvent<SubFloorHideComponent, AppearanceChangeEvent>(OnAppearanceChanged);
+        SubscribeNetworkEvent<ShowSubfloorRequestEvent>(OnRequestReceived);
+        SubscribeLocalEvent<LocalPlayerDetachedEvent>(OnPlayerDetached);
+    }
+
+    private void OnPlayerDetached(LocalPlayerDetachedEvent ev)
+    {
+        // Vismask resets so need to reset this.
+        ShowAll = false;
+    }
+
+    private void OnRequestReceived(ShowSubfloorRequestEvent ev)
+    {
+        // When client receives request Queue an update on all vis.
+        UpdateAll();
     }
     }
 
 
     private void OnAppearanceChanged(EntityUid uid, SubFloorHideComponent component, ref AppearanceChangeEvent args)
     private void OnAppearanceChanged(EntityUid uid, SubFloorHideComponent component, ref AppearanceChangeEvent args)

+ 14 - 2
Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs

@@ -39,7 +39,6 @@ public sealed class SandboxUIController : UIController, IOnStateChanged<Gameplay
     [UISystemDependency] private readonly DebugPhysicsSystem _debugPhysics = default!;
     [UISystemDependency] private readonly DebugPhysicsSystem _debugPhysics = default!;
     [UISystemDependency] private readonly MarkerSystem _marker = default!;
     [UISystemDependency] private readonly MarkerSystem _marker = default!;
     [UISystemDependency] private readonly SandboxSystem _sandbox = default!;
     [UISystemDependency] private readonly SandboxSystem _sandbox = default!;
-    [UISystemDependency] private readonly SubFloorHideSystem _subfloorHide = default!;
 
 
     private SandboxWindow? _window;
     private SandboxWindow? _window;
 
 
@@ -117,10 +116,11 @@ private void EnsureWindow()
 
 
         _window.OnOpen += () => { SandboxButton!.Pressed = true; };
         _window.OnOpen += () => { SandboxButton!.Pressed = true; };
         _window.OnClose += () => { SandboxButton!.Pressed = false; };
         _window.OnClose += () => { SandboxButton!.Pressed = false; };
+
+        // TODO: These need moving to opened so at least if they're not synced properly on open they work.
         _window.ToggleLightButton.Pressed = !_light.Enabled;
         _window.ToggleLightButton.Pressed = !_light.Enabled;
         _window.ToggleFovButton.Pressed = !_eye.CurrentEye.DrawFov;
         _window.ToggleFovButton.Pressed = !_eye.CurrentEye.DrawFov;
         _window.ToggleShadowsButton.Pressed = !_light.DrawShadows;
         _window.ToggleShadowsButton.Pressed = !_light.DrawShadows;
-        _window.ToggleSubfloorButton.Pressed = _subfloorHide.ShowAll;
         _window.ShowMarkersButton.Pressed = _marker.MarkersVisible;
         _window.ShowMarkersButton.Pressed = _marker.MarkersVisible;
         _window.ShowBbButton.Pressed = (_debugPhysics.Flags & PhysicsDebugFlags.Shapes) != 0x0;
         _window.ShowBbButton.Pressed = (_debugPhysics.Flags & PhysicsDebugFlags.Shapes) != 0x0;
 
 
@@ -219,4 +219,16 @@ private void ToggleWindow()
             _window.Close();
             _window.Close();
         }
         }
     }
     }
+
+    #region Buttons
+
+    public void SetToggleSubfloors(bool value)
+    {
+        if (_window == null)
+            return;
+
+        _window.ToggleSubfloorButton.Pressed = value;
+    }
+
+    #endregion
 }
 }

+ 12 - 1
Content.Client/UserInterface/Systems/Sandbox/Windows/SandboxWindow.xaml.cs

@@ -1,4 +1,5 @@
-using Robust.Client.AutoGenerated;
+using Content.Client.SubFloor;
+using Robust.Client.AutoGenerated;
 using Robust.Client.UserInterface.CustomControls;
 using Robust.Client.UserInterface.CustomControls;
 using Robust.Client.UserInterface.XAML;
 using Robust.Client.UserInterface.XAML;
 
 
@@ -7,8 +8,18 @@ namespace Content.Client.UserInterface.Systems.Sandbox.Windows;
 [GenerateTypedNameReferences]
 [GenerateTypedNameReferences]
 public sealed partial class SandboxWindow : DefaultWindow
 public sealed partial class SandboxWindow : DefaultWindow
 {
 {
+    [Dependency] private readonly IEntityManager _entManager = null!;
+
     public SandboxWindow()
     public SandboxWindow()
     {
     {
         RobustXamlLoader.Load(this);
         RobustXamlLoader.Load(this);
+        IoCManager.InjectDependencies(this);
+    }
+
+    protected override void Opened()
+    {
+        base.Opened();
+        // Make sure state is up to date.
+        ToggleSubfloorButton.Pressed = _entManager.System<SubFloorHideSystem>().ShowAll;
     }
     }
 }
 }

+ 0 - 1
Content.Docfx/articles/example-article.md

@@ -1 +0,0 @@
-# Add your introductions here!

+ 0 - 2
Content.Docfx/articles/toc.yml

@@ -1,2 +0,0 @@
-- name: Example-article
-  href: example-article.md

+ 0 - 134
Content.Docfx/docfx.json

@@ -1,134 +0,0 @@
-{
-  "metadata": [
-    {
-      "src":
-      [
-        {
-          "files": [
-            "**.csproj"
-          ],
-          "exclude": [
-            "**/bin/**",
-            "**/obj/**",
-            "_site/**",
-            "**.xaml"
-          ],
-          "src": "../Content.Client"
-        }
-      ],
-      "disableGitFeatures": false,
-      "disableDefaultFilter": false,
-      "dest": "api/Content.Client"
-    },
-    {
-      "src":
-      [
-        {
-          "files": [
-            "**.csproj"
-          ],
-          "exclude": [
-            "**/bin/**",
-            "**/obj/**",
-            "_site/**",
-            "**.xaml"
-          ],
-          "src": "../Content.Server"
-        }
-      ],
-      "disableGitFeatures": false,
-      "disableDefaultFilter": false,
-      "dest": "api/Content.Server"
-    },
-    {
-      "src":
-      [
-        {
-          "files": [
-            "**.csproj"
-          ],
-          "exclude": [
-            "**/bin/**",
-            "**/obj/**",
-            "_site/**",
-            "**.xaml"
-          ],
-          "src": "../Content.Shared"
-        }
-      ],
-      "disableGitFeatures": false,
-      "disableDefaultFilter": false,
-      "dest": "api/Content.Shared"
-    },
-    {
-      "src":
-      [
-        {
-          "files": [
-            "**.csproj"
-          ],
-          "exclude": [
-            "**/bin/**",
-            "**/obj/**",
-            "_site/**",
-            "**.xaml"
-          ],
-          "src": "../Content.Tests"
-        }
-      ],
-      "disableGitFeatures": false,
-      "disableDefaultFilter": false,
-      "dest": "api/Content.Tests"
-    }
-  ],
-  "build": {
-    "content": [
-      {
-        "files": [
-          "api/**/**.yml"
-        ]
-      },
-      {
-        "files": [
-          "articles/**.md",
-          "articles/**/toc.yml",
-          "toc.yml",
-          "*.md"
-        ]
-      }
-    ],
-    "resource": [
-      {
-        "files": [
-          "images/**",
-          "favicon.ico",
-          "icon.svg"          
-        ]
-      }
-    ],
-    "overwrite": [
-      {
-        "files": [
-          "apidoc/**.md"
-        ],
-        "exclude": [
-          "obj/**",
-          "_site/**"
-        ]
-      }
-    ],
-    "dest": "_content-site",
-    "globalMetadataFiles": [],
-    "fileMetadataFiles": [],
-    "template": [
-      "default",
-      "templates/darkfx"
-    ],
-    "postProcessors": [],
-    "markdownEngineName": "markdig",
-    "noLangKeyword": false,
-    "keepFileLink": false,
-    "cleanupCacheHistory": false,
-    "disableGitFeatures": false
-  }
-}

+ 0 - 9
Content.Docfx/index.md

@@ -1,9 +0,0 @@
-# Space Station 14 DocFX
-![](https://i.imgur.com/0h6VoRZ.png)
-
-## Welcome to the Space Station 14 DocFX instance.
-### Click one of the tabs above to see documentation for that particular project/namespace
-
-## Links
-
-[Website](https://spacestation14.io/) | [Discord](https://discord.gg/t2jac3p) | [Forum](https://forum.spacestation14.io/) | [Steam](https://store.steampowered.com/app/1255460/Space_Station_14/) | [Standalone Download](https://spacestation14.io/about/nightlies/)

+ 0 - 21
Content.Docfx/templates/darkfx/LICENSE.txt

@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2021 Steffen Wilke
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.

+ 0 - 40
Content.Docfx/templates/darkfx/partials/affix.tmpl.partial

@@ -1,40 +0,0 @@
-{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
-
-<div class="hidden-sm col-md-2" role="complementary">
-  <div class="sideaffix">
-    {{^_disableContribution}}
-    <div class="contribution">
-      <ul class="nav">
-        {{#docurl}}
-        <li>
-          <a href="{{docurl}}" class="contribution-link">{{__global.improveThisDoc}}</a>
-        </li>
-        {{/docurl}}
-        {{#sourceurl}}
-        <li>
-          <a href="{{sourceurl}}" class="contribution-link">{{__global.viewSource}}</a>
-        </li>
-        {{/sourceurl}}
-      </ul>
-    </div>
-    {{/_disableContribution}}
-    <div class="toggle-mode">
-      <div class="icon">
-        <i aria-hidden="true">☀</i>
-      </div>
-      <label class="switch">
-        <input type="checkbox" id="switch-style">
-        <span class="slider round"></span>
-      </label>
-      <div class="icon">
-        <i aria-hidden="true">☾</i>
-      </div>
-    </div>
-
-    <nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
-    <h5>{{__global.inThisArticle}}</h5>
-    <div></div>
-    <!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
-    </nav>
-  </div>
-</div>

+ 0 - 108
Content.Docfx/templates/darkfx/partials/class.header.tmpl.partial

@@ -1,108 +0,0 @@
-{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
-
-<h1 id="{{id}}" data-uid="{{uid}}" class="text-break">{{>partials/title}}</h1>
-<div class="markdown level0 summary">{{{summary}}}</div>
-<div class="markdown level0 conceptual">{{{conceptual}}}</div>
-{{#inClass}}
-<div class="inheritance">
-  <h5>{{__global.inheritance}}</h5>
-  {{#inheritance}}
-  <div class="level{{index}}">{{{specName.0.value}}}</div>
-  {{/inheritance}}
-  <div class="level{{level}}"><span class="xref">{{name.0.value}}</span></div>
-  {{#derivedClasses}}
-    <div class="level{{index}}">{{{specName.0.value}}}</div>
-  {{/derivedClasses}}
-</div>
-{{/inClass}}
-{{#implements.0}}
-<div classs="implements">
-  <h5>{{__global.implements}}</h5>
-{{/implements.0}}
-{{#implements}}
-  <div>{{{specName.0.value}}}</div>
-{{/implements}}
-{{#implements.0}}
-</div>
-{{/implements.0}}
-{{#inheritedMembers.0}}
-<div class="inheritedMembers">
-</div>
-{{/inheritedMembers.0}}
-<h6><strong>{{__global.namespace}}</strong>: {{{namespace.specName.0.value}}}</h6>
-<h6><strong>{{__global.assembly}}</strong>: {{assemblies.0}}.dll</h6>
-<h5 id="{{id}}_syntax">{{__global.syntax}}</h5>
-<div class="codewrapper">
-  <pre><code class="lang-{{_lang}} hljs">{{syntax.content.0.value}}</code></pre>
-</div>
-{{#syntax.parameters.0}}
-<h5 class="parameters">{{__global.parameters}}</h5>
-<table class="table table-bordered table-striped table-condensed">
-  <thead>
-    <tr>
-      <th>{{__global.type}}</th>
-      <th>{{__global.name}}</th>
-      <th>{{__global.description}}</th>
-    </tr>
-  </thead>
-  <tbody>
-{{/syntax.parameters.0}}
-{{#syntax.parameters}}
-    <tr>
-      <td>{{{type.specName.0.value}}}</td>
-      <td><span class="parametername">{{{id}}}</span></td>
-      <td>{{{description}}}</td>
-    </tr>
-{{/syntax.parameters}}
-{{#syntax.parameters.0}}
-  </tbody>
-</table>
-{{/syntax.parameters.0}}
-{{#syntax.return}}
-<h5 class="returns">{{__global.returns}}</h5>
-<table class="table table-bordered table-striped table-condensed">
-  <thead>
-    <tr>
-      <th>{{__global.type}}</th>
-      <th>{{__global.description}}</th>
-    </tr>
-  </thead>
-  <tbody>
-    <tr>
-      <td>{{{type.specName.0.value}}}</td>
-      <td>{{{description}}}</td>
-    </tr>
-  </tbody>
-</table>
-{{/syntax.return}}
-{{#syntax.typeParameters.0}}
-<h5 class="typeParameters">{{__global.typeParameters}}</h5>
-<table class="table table-bordered table-striped table-condensed">
-  <thead>
-    <tr>
-      <th>{{__global.name}}</th>
-      <th>{{__global.description}}</th>
-    </tr>
-  </thead>
-  <tbody>
-{{/syntax.typeParameters.0}}
-{{#syntax.typeParameters}}
-    <tr>
-      <td><span class="parametername">{{{id}}}</span></td>
-      <td>{{{description}}}</td>
-    </tr>
-{{/syntax.typeParameters}}
-{{#syntax.typeParameters.0}}
-  </tbody>
-</table>
-{{/syntax.typeParameters.0}}
-{{#remarks}}
-<h5 id="{{id}}_remarks"><strong>{{__global.remarks}}</strong></h5>
-<div class="markdown level0 remarks">{{{remarks}}}</div>
-{{/remarks}}
-{{#example.0}}
-<h5 id="{{id}}_examples"><strong>{{__global.examples}}</strong></h5>
-{{/example.0}}
-{{#example}}
-{{{.}}}
-{{/example}}

+ 0 - 29
Content.Docfx/templates/darkfx/partials/footer.tmpl.partial

@@ -1,29 +0,0 @@
-{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
-
-<footer>
-  <div class="grad-bottom"></div>
-  <div class="footer">
-    <div class="container">
-      <span class="pull-right">
-        <a href="#top">Back to top</a>
-      </span>
-      <div class="pull-left">
-        {{{_appFooter}}}
-        {{^_appFooter}}<span>Generated by <strong>DocFX</strong></span>{{/_appFooter}}
-      </div>
-      <div class="toggle-mode pull-right visible-sm visible-xs">
-        <div class="icon">
-          <i aria-hidden="true">☀</i>
-        </div>
-        <label class="switch">
-          <input type="checkbox" id="switch-style-m">
-          <span class="slider round"></span>
-        </label>
-        <div class="icon">
-          <i aria-hidden="true">☾</i>
-        </div>
-      </div>
-    </div>
-  </div>
-  <script type="text/javascript" src="{{_rel}}styles/toggle-theme.js"></script>
-</footer>

+ 0 - 20
Content.Docfx/templates/darkfx/partials/head.tmpl.partial

@@ -1,20 +0,0 @@
-{{!Copyright (c) Oscar Vasquez. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
-
-<head>
-  <meta charset="utf-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-  <title>{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}</title>
-  <meta name="viewport" content="width=device-width">
-  <meta name="title" content="{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}">
-  <meta name="generator" content="docfx {{_docfxVersion}}">
-  {{#_description}}<meta name="description" content="{{_description}}">{{/_description}}
-  <link rel="shortcut icon" href="{{_rel}}{{{_appFaviconPath}}}{{^_appFaviconPath}}favicon.ico{{/_appFaviconPath}}">
-  <link rel="stylesheet" href="{{_rel}}styles/docfx.vendor.css">
-  <link rel="stylesheet" href="{{_rel}}styles/docfx.css">
-  <link rel="stylesheet" href="{{_rel}}styles/main.css">
-  <meta property="docfx:navrel" content="{{_navRel}}">
-  <meta property="docfx:tocrel" content="{{_tocRel}}">
-  {{#_noindex}}<meta name="searchOption" content="noindex">{{/_noindex}}
-  {{#_enableSearch}}<meta property="docfx:rel" content="{{_rel}}">{{/_enableSearch}}
-  {{#_enableNewTab}}<meta property="docfx:newtab" content="true">{{/_enableNewTab}}
-</head>

+ 0 - 470
Content.Docfx/templates/darkfx/styles/main.css

@@ -1,470 +0,0 @@
-:root, body.dark-theme {
-  --color-foreground: #ccd5dc;
-  --color-navbar: #66666d;
-  --color-breadcrumb: #999;
-  --color-underline: #ddd;
-  --color-toc-hover: #fff;
-  --color-background: #2d2d30;
-  --color-background-subnav: #333337;
-  --color-background-dark: #1e1e1e;
-  --color-background-table-alt: #212123;
-  --color-background-quote: #69696e;
-}
-
-body.light-theme {
-  --color-foreground: #171717;
-  --color-breadcrumb: #4a4a4a;
-  --color-toc-hover: #4c4c4c;
-  --color-background: #ffffff;
-  --color-background-subnav: #f5f5f5;
-  --color-background-dark: #ddd;
-  --color-background-table-alt: #f9f9f9;
-}
-
-body {
-  color: var(--color-foreground);
-  line-height: 1.5;
-  font-size: 14px;
-  -ms-text-size-adjust: 100%;
-  -webkit-text-size-adjust: 100%;
-  word-wrap: break-word;
-  background-color: var(--color-background);
-}
-
-.btn.focus, .btn:focus, .btn:hover {
-  color: var(--color-foreground);
-}
-
-h1 {
-  font-weight: 600;
-  font-size: 32px;
-}
-
-h2 {
-  font-weight: 600;
-  font-size: 24px;
-  line-height: 1.8;
-}
-
-h3 {
-  font-weight: 600;
-  font-size: 20px;
-  line-height: 1.8;
-}
-
-h5 {
-  font-size: 14px;
-  padding: 10px 0px;
-}
-
-article h1, article h2, article h3, article h4 {
-  margin-top: 35px;
-  margin-bottom: 15px;
-}
-
-article h4 {
-  padding-bottom: 8px;
-  border-bottom: 2px solid var(--color-underline);
-}
-
-.navbar-brand>img {
-  color: var(--color-background);
-}
-
-.navbar {
-  border: none;
-}
-
-.subnav {
-  border-top: 1px solid var(--color-underline);
-  background-color: var(--color-background-subnav);
-}
-
-.sidenav, .fixed_header, .toc {
-  background-color: var(--color-background);
-}
-
-.navbar-inverse {
-  background-color: var(--color-background-dark);
-  z-index: 100;
-}
-
-.navbar-inverse .navbar-nav>li>a, .navbar-inverse .navbar-text {
-  color: var(--color-navbar);
-  background-color: var(--color-background-dark);
-  border-bottom: 3px solid transparent;
-  padding-bottom: 12px;
-}
-
-.navbar-inverse .navbar-nav>li>a:focus, .navbar-inverse .navbar-nav>li>a:hover {
-  color: var(--color-foreground);
-  background-color: var(--color-background-dark);
-  border-bottom: 3px solid var(--color-background-subnav);
-  transition: all ease 0.25s;
-}
-
-.navbar-inverse .navbar-nav>.active>a, .navbar-inverse .navbar-nav>.active>a:focus, .navbar-inverse .navbar-nav>.active>a:hover {
-  color: var(--color-foreground);
-  background-color: var(--color-background-dark);
-  border-bottom: 3px solid var(--color-foreground);
-  transition: all ease 0.25s;
-}
-
-.navbar-form .form-control {
-  border: none;
-  border-radius: 0;
-}
-
-.light-theme .navbar-brand svg {
-  filter: brightness(20%);
-}
-
-.toc .level1>li {
-  font-weight: 400;
-}
-
-.toc .nav>li>a {
-  color: var(--color-foreground);
-}
-
-.sidefilter {
-  background-color: var(--color-background);
-  border-left: none;
-  border-right: none;
-}
-
-.sidefilter {
-  background-color: var(--color-background);
-  border-left: none;
-  border-right: none;
-}
-
-.toc-filter {
-  padding: 10px;
-  margin: 0;
-  background-color: var(--color-background);
-}
-
-.toc-filter>input {
-  border: none;
-  border-radius: unset;
-  background-color: var(--color-background-subnav);
-  padding: 5px 0 5px 20px;
-  font-size: 90%
-}
-
-.toc-filter>.clear-icon {
-  position: absolute;
-  top: 17px;
-  right: 15px;
-}
-
-.toc-filter>input:focus {
-  color: var(--color-foreground);
-  transition: all ease 0.25s;
-}
-
-.toc-filter>.filter-icon {
-  display: none;
-}
-
-.sidetoc>.toc {
-  background-color: var(--color-background);
-  overflow-x: hidden;
-}
-
-.sidetoc {
-  background-color: var(--color-background);
-  border: none;
-}
-
-.alert {
-  background-color: inherit;
-  border: none;
-  padding: 10px 0;
-  border-radius: 0;
-}
-
-.alert>p {
-  margin-bottom: 0;
-  padding: 5px 10px;
-  border-bottom: 1px solid;
-  background-color: var(--color-background-dark);
-}
-
-.alert>h5 {
-  padding: 10px 15px;
-  margin-top: 0;
-  margin-bottom: 0;
-  text-transform: uppercase;
-  font-weight: bold;
-  border-top: 2px solid;
-  background-color: var(--color-background-dark);
-  border-radius: none;
-}
-
-.alert>ul {
-  margin-bottom: 0;
-  padding: 5px 40px;
-}
-
-.alert-info {
-  color: #1976d2;
-}
-
-.alert-warning {
-  color: #f57f17;
-}
-
-.alert-danger {
-  color: #d32f2f;
-}
-
-pre {
-  padding: 9.5px;
-  margin: 0 0 10px;
-  font-size: 13px;
-  word-break: break-all;
-  word-wrap: break-word;
-  background-color: var(--color-background-dark);
-  border-radius: 0;
-  border: none;
-}
-
-code {
-  background: var(--color-background-dark) !important;
-  border-radius: 2px;
-}
-
-.hljs {
-  color: var(--color-foreground);
-}
-
-.toc .nav>li.active>.expand-stub::before, .toc .nav>li.in>.expand-stub::before, .toc .nav>li.in.active>.expand-stub::before, .toc .nav>li.filtered>.expand-stub::before {
-  content: "▾";
-}
-
-.toc .nav>li>.expand-stub::before, .toc .nav>li.active>.expand-stub::before {
-  content: "▸";
-}
-
-.affix ul ul>li>a:before {
-  content: "|";
-}
-
-.breadcrumb {
-  background-color: var(--color-background-subnav);
-}
-
-.breadcrumb .label.label-primary {
-  background: #444;
-  border-radius: 0;
-  font-weight: normal;
-  font-size: 100%;
-}
-
-#breadcrumb .breadcrumb>li a {
-  border-radius: 0;
-  font-weight: normal;
-  font-size: 85%;
-  display: inline;
-  padding: 0 .6em 0;
-  line-height: 1;
-  text-align: center;
-  white-space: nowrap;
-  vertical-align: baseline;
-  color: var(--color-breadcrumb);
-}
-
-#breadcrumb .breadcrumb>li a:hover {
-  color: var(--color-foreground);
-  transition: all ease 0.25s;
-}
-
-.breadcrumb>li+li:before {
-  content: "⯈";
-  font-size: 75%;
-  color: var(--color-background-dark);
-  padding: 0;
-}
-
-.light-theme .breadcrumb>li+li:before {
-  color: var(--color-foreground)
- }
-
-.toc .level1>li {
-  font-weight: 600;
-  font-size: 130%;
-  padding-left: 5px;
-}
-
-.footer {
-  border-top: none;
-  background-color: var(--color-background-dark);
-  padding: 15px 0;
-  font-size: 90%;
-}
-
-.toc .nav>li>a:hover, .toc .nav>li>a:focus {
-  color: var(--color-toc-hover);
-  transition: all ease 0.1s;
-}
-
-.form-control {
-  background-color: var(--color-background-subnav);
-  border: none;
-  border-radius: 0;
-  -webkit-box-shadow: none;
-  box-shadow: none;
-}
-
-.form-control:focus {
-  border-color: #66afe9;
-  outline: 0;
-  -webkit-box-shadow: none;
-  box-shadow: none;
-}
-
-input#search-query:focus {
-  color: var(--color-foreground);
-}
-
-.table-bordered, .table-bordered>tbody>tr>td, .table-bordered>tbody>tr>th, .table-bordered>tfoot>tr>td, .table-bordered>tfoot>tr>th, .table-bordered>thead>tr>td, .table-bordered>thead>tr>th {
-  border: 1px solid var(--color-background-dark);
-}
-
-.table-striped>tbody>tr:nth-of-type(odd) {
-  background-color: var(--color-background-table-alt);
-}
-
-blockquote {
-  padding: 10px 20px;
-  margin: 0 0 10px;
-  font-size: 110%;
-  border-left: 5px solid var(--color-background-quote);
-  color: var(--color-background-quote);
-}
-
-.pagination>.disabled>a, .pagination>.disabled>a:focus, .pagination>.disabled>a:hover, .pagination>.disabled>span, .pagination>.disabled>span:focus, .pagination>.disabled>span:hover {
-  background-color: var(--color-background-subnav);
-  border-color: var(--color-background-subnav);
-}
-
-.breadcrumb>li, .pagination {
-  display: inline;
-}
-
-.tabGroup a[role="tab"] {
-  border-bottom: 2px solid var(--color-background-dark);
-}
-
-.tabGroup a[role="tab"][aria-selected="true"] {
-  color: var(--color-foreground);
-}
-
-.tabGroup section[role="tabpanel"] {
-  border: 1px solid var(--color-background-dark);
-}
-
-.sideaffix > div.contribution > ul > li > a.contribution-link:hover {
-  background-color: var(--color-background);
-}
-
-.switch {
-  position: relative;
-  display: inline-block;
-  width: 40px;
-  height: 20px;
-}
-
-.switch input { 
-  opacity: 0;
-  width: 0;
-  height: 0;
-}
-
-.slider {
-  position: absolute;
-  cursor: pointer;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background-color: #ccc;
-  -webkit-transition: .4s;
-  transition: .4s;
-}
-
-.slider:before {
-  position: absolute;
-  content: "";
-  height: 14px;
-  width: 14px;
-  left: 4px;
-  bottom: 3px;
-  background-color: white;
-  -webkit-transition: .4s;
-  transition: .4s;
-}
-
-input:checked + .slider {
-  background-color: #337ab7;
-}
-
-input:focus + .slider {
-  box-shadow: 0 0 1px #337ab7;
-}
-
-input:checked + .slider:before {
-  -webkit-transform: translateX(19px);
-  -ms-transform: translateX(19px);
-  transform: translateX(19px);
-}
-
-/* Rounded sliders */
-.slider.round {
-  border-radius: 20px;
-}
-
-.slider.round:before {
-  border-radius: 50%;
-}
-.toggle-mode .icon {
-  display: inline-block;
-}
-
-.toggle-mode .icon i {
-  font-style: normal;
-  font-size: 17px;
-  display: inline-block;
-  padding-right: 7px;
-  padding-left: 7px;
-  vertical-align: middle;
-}
-
-@media (min-width: 1600px) {
-  .container {
-    width: 100%;
-  }
-  .sidefilter {
-    width: 18%;
-  }
-  .sidetoc {
-    width: 18%;
-  }
-  .article.grid-right {
-    margin-left: 19%;
-  }
-  .sideaffix {
-    width: 11.5%;
-  }
-  .affix ul>li.active>a {
-    white-space: initial;
-  }
-  .affix ul>li>a {
-    width: 99%;
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-  }
-}

+ 0 - 35
Content.Docfx/templates/darkfx/styles/toggle-theme.js

@@ -1,35 +0,0 @@
-const sw = document.getElementById("switch-style"), sw_mobile = document.getElementById("switch-style-m"), b = document.body;
-if (b) {
-  function toggleTheme(target, dark) {
-    target.classList.toggle("dark-theme", dark)
-    target.classList.toggle("light-theme", !dark)
-  }
-
-  function switchEventListener() {
-    toggleTheme(b, this.checked);
-    if (window.localStorage) {
-      this.checked ? localStorage.setItem("theme", "dark-theme") : localStorage.setItem("theme", "light-theme")
-    }
-  }
-
-  var isDarkTheme = !window.localStorage || !window.localStorage.getItem("theme") || window.localStorage && localStorage.getItem("theme") === "dark-theme";
-
-  if(sw && sw_mobile){
-    sw.checked = isDarkTheme;
-    sw_mobile.checked = isDarkTheme;
-
-    sw.addEventListener("change", switchEventListener);
-    sw_mobile.addEventListener("change", switchEventListener);
-    
-    // sync state between switches
-    sw.addEventListener("change", function() {
-      sw_mobile.checked = this.checked;
-    });
-
-    sw_mobile.addEventListener("change", function() {
-      sw.checked = this.checked;
-    });
-  }
-
-  toggleTheme(b, isDarkTheme);
-}

+ 0 - 18
Content.Docfx/toc.yml

@@ -1,18 +0,0 @@
-- name: Articles
-  href: articles/
-  
-# Client 
-- name: Content.Client 
-  href: api/Content.Client/
-
-# Server
-- name: Content.Server
-  href: api/Content.Server/
-
-# Shared 
-- name: Content.Shared
-  href: api/Content.Shared/
-  
-# Unit testing
-- name: Content.Tests
-  href: api/Content.Tests/

+ 1 - 1
Content.IntegrationTests/PoolManager.cs

@@ -30,7 +30,7 @@ namespace Content.IntegrationTests;
 /// </summary>
 /// </summary>
 public static partial class PoolManager
 public static partial class PoolManager
 {
 {
-    public const string TestMap = "Empty";
+    public const string TestMap = "Nomads";
     private static int _pairId;
     private static int _pairId;
     private static readonly object PairLock = new();
     private static readonly object PairLock = new();
     private static bool _initialized;
     private static bool _initialized;

+ 7 - 7
Content.IntegrationTests/Tests/Commands/ForceMapTest.cs

@@ -8,7 +8,7 @@ namespace Content.IntegrationTests.Tests.Commands;
 [TestFixture]
 [TestFixture]
 public sealed class ForceMapTest
 public sealed class ForceMapTest
 {
 {
-    private const string DefaultMapName = "Empty";
+    private const string DefaultMapName = "Nomads";
     private const string BadMapName = "asdf_asd-fa__sdfAsd_f"; // Hopefully no one ever names a map this...
     private const string BadMapName = "asdf_asd-fa__sdfAsd_f"; // Hopefully no one ever names a map this...
     private const string TestMapEligibleName = "ForceMapTestEligible";
     private const string TestMapEligibleName = "ForceMapTestEligible";
     private const string TestMapIneligibleName = "ForceMapTestIneligible";
     private const string TestMapIneligibleName = "ForceMapTestIneligible";
@@ -18,27 +18,27 @@ public sealed class ForceMapTest
 - type: gameMap
 - type: gameMap
   id: {TestMapIneligibleName}
   id: {TestMapIneligibleName}
   mapName: {TestMapIneligibleName}
   mapName: {TestMapIneligibleName}
-  mapPath: /Maps/Test/empty.yml
+  mapPath: /Maps/civ/nomads.yml
   minPlayers: 20
   minPlayers: 20
   maxPlayers: 80
   maxPlayers: 80
   stations:
   stations:
     Empty:
     Empty:
-      stationProto: StandardNanotrasenStation
+      stationProto: StandardStationArena
       components:
       components:
         - type: StationNameSetup
         - type: StationNameSetup
-          mapNameTemplate: ""Empty""
+          mapNameTemplate: ""Nomads Test""
 
 
 - type: gameMap
 - type: gameMap
   id: {TestMapEligibleName}
   id: {TestMapEligibleName}
   mapName: {TestMapEligibleName}
   mapName: {TestMapEligibleName}
-  mapPath: /Maps/Test/empty.yml
+  mapPath: /Maps/civ/nomads.yml
   minPlayers: 0
   minPlayers: 0
   stations:
   stations:
     Empty:
     Empty:
-      stationProto: StandardNanotrasenStation
+      stationProto: StandardStationArena
       components:
       components:
         - type: StationNameSetup
         - type: StationNameSetup
-          mapNameTemplate: ""Empty""
+          mapNameTemplate: ""Nomads Test""
 ";
 ";
 
 
     [Test]
     [Test]

+ 0 - 124
Content.IntegrationTests/Tests/Construction/ConstructionActionValid.cs

@@ -1,124 +0,0 @@
-using System.Text;
-using Content.Server.Construction.Completions;
-using Content.Shared.Construction;
-using Content.Shared.Construction.Prototypes;
-using Robust.Shared.Prototypes;
-
-namespace Content.IntegrationTests.Tests.Construction
-{
-    [TestFixture]
-    public sealed class ConstructionActionValid
-    {
-        private bool IsValid(IGraphAction action, IPrototypeManager protoMan, out string prototype)
-        {
-            switch (action)
-            {
-                case SpawnPrototype spawn:
-                    prototype = spawn.Prototype;
-                    return protoMan.TryIndex<EntityPrototype>(spawn.Prototype, out _);
-                case SpawnPrototypeAtContainer spawn:
-                    prototype = spawn.Prototype;
-                    return protoMan.TryIndex<EntityPrototype>(spawn.Prototype, out _);
-                case ConditionalAction conditional:
-                    var valid = IsValid(conditional.Action, protoMan, out var protoA) & IsValid(conditional.Else, protoMan, out var protoB);
-
-                    if (!string.IsNullOrEmpty(protoA) && string.IsNullOrEmpty(protoB))
-                    {
-                        prototype = protoA;
-                    }
-
-                    else if (string.IsNullOrEmpty(protoA) && !string.IsNullOrEmpty(protoB))
-                    {
-                        prototype = protoB;
-                    }
-
-                    else
-                    {
-                        prototype = $"{protoA}, {protoB}";
-                    }
-
-                    return valid;
-                default:
-                    prototype = string.Empty;
-                    return true;
-            }
-        }
-
-        [Test]
-        public async Task ConstructionGraphSpawnPrototypeValid()
-        {
-            await using var pair = await PoolManager.GetServerClient();
-            var server = pair.Server;
-
-            var protoMan = server.ResolveDependency<IPrototypeManager>();
-
-            var valid = true;
-            var message = new StringBuilder();
-
-            await server.WaitPost(() =>
-            {
-                foreach (var graph in protoMan.EnumeratePrototypes<ConstructionGraphPrototype>())
-                {
-                    foreach (var node in graph.Nodes.Values)
-                    {
-                        foreach (var action in node.Actions)
-                        {
-                            if (IsValid(action, protoMan, out var prototype)) continue;
-
-                            valid = false;
-                            message.Append($"Invalid entity prototype \"{prototype}\" on graph action in node \"{node.Name}\" of graph \"{graph.ID}\"\n");
-                        }
-
-                        foreach (var edge in node.Edges)
-                        {
-                            foreach (var action in edge.Completed)
-                            {
-                                if (IsValid(action, protoMan, out var prototype)) continue;
-
-                                valid = false;
-                                message.Append($"Invalid entity prototype \"{prototype}\" on graph action in edge \"{edge.Target}\" of node \"{node.Name}\" of graph \"{graph.ID}\"\n");
-                            }
-                        }
-                    }
-                }
-            });
-
-            Assert.That(valid, Is.True, $"One or more SpawnPrototype actions specified invalid entity prototypes!\n{message}");
-            await pair.CleanReturnAsync();
-        }
-
-        [Test]
-        public async Task ConstructionGraphEdgeValid()
-        {
-            await using var pair = await PoolManager.GetServerClient();
-            var server = pair.Server;
-
-            var protoMan = server.ResolveDependency<IPrototypeManager>();
-
-            var valid = true;
-            var message = new StringBuilder();
-
-            await server.WaitPost(() =>
-            {
-                foreach (var graph in protoMan.EnumeratePrototypes<ConstructionGraphPrototype>())
-                {
-                    foreach (var node in graph.Nodes.Values)
-                    {
-                        foreach (var edge in node.Edges)
-                        {
-                            if (graph.Nodes.ContainsKey(edge.Target))
-                                continue;
-
-                            valid = false;
-                            message.Append(
-                                $"Invalid target \"{edge.Target}\" in edge on node \"{node.Name}\" of graph \"{graph.ID}\"\n");
-                        }
-                    }
-                }
-            });
-
-            Assert.That(valid, Is.True, $"One or more edges specified invalid node targets!\n{message}");
-            await pair.CleanReturnAsync();
-        }
-    }
-}

+ 0 - 164
Content.IntegrationTests/Tests/Construction/ConstructionPrototypeTest.cs

@@ -1,164 +0,0 @@
-using System.Numerics;
-using Content.Server.Construction.Components;
-using Content.Shared.Construction.Prototypes;
-using Robust.Shared.GameObjects;
-using Robust.Shared.Map;
-using Robust.Shared.Maths;
-using Robust.Shared.Prototypes;
-
-namespace Content.IntegrationTests.Tests.Construction
-{
-    [TestFixture]
-    public sealed class ConstructionPrototypeTest
-    {
-        // discount linter for construction graphs
-        // TODO: Create serialization validators for these?
-        // Top test definitely can be but writing a serializer takes ages.
-
-        /// <summary>
-        /// Checks every entity prototype with a construction component has a valid start node.
-        /// </summary>
-        [Test]
-        public async Task TestStartNodeValid()
-        {
-            await using var pair = await PoolManager.GetServerClient();
-            var server = pair.Server;
-
-            var entMan = server.ResolveDependency<IEntityManager>();
-            var protoMan = server.ResolveDependency<IPrototypeManager>();
-
-            var map = await pair.CreateTestMap();
-
-            await server.WaitAssertion(() =>
-            {
-                foreach (var proto in protoMan.EnumeratePrototypes<EntityPrototype>())
-                {
-                    if (!proto.Components.ContainsKey("Construction"))
-                        continue;
-
-                    var ent = entMan.SpawnEntity(proto.ID, new MapCoordinates(Vector2.Zero, map.MapId));
-                    var construction = entMan.GetComponent<ConstructionComponent>(ent);
-
-                    var graph = protoMan.Index<ConstructionGraphPrototype>(construction.Graph);
-                    entMan.DeleteEntity(ent);
-
-                    Assert.That(graph.Nodes.ContainsKey(construction.Node),
-                        $"Found no startNode \"{construction.Node}\" on graph \"{graph.ID}\" for entity \"{proto.ID}\"!");
-                }
-            });
-
-            await pair.CleanReturnAsync();
-        }
-
-        [Test]
-        public async Task TestStartIsValid()
-        {
-            await using var pair = await PoolManager.GetServerClient();
-            var server = pair.Server;
-
-            var protoMan = server.ResolveDependency<IPrototypeManager>();
-
-            await server.WaitAssertion(() =>
-            {
-                foreach (var proto in protoMan.EnumeratePrototypes<ConstructionPrototype>())
-                {
-                    var start = proto.StartNode;
-                    var graph = protoMan.Index<ConstructionGraphPrototype>(proto.Graph);
-
-                    Assert.That(graph.Nodes.ContainsKey(start),
-                        $"Found no startNode \"{start}\" on graph \"{graph.ID}\" for construction prototype \"{proto.ID}\"!");
-                }
-            });
-            await pair.CleanReturnAsync();
-        }
-
-        [Test]
-        public async Task TestTargetIsValid()
-        {
-            await using var pair = await PoolManager.GetServerClient();
-            var server = pair.Server;
-
-            var protoMan = server.ResolveDependency<IPrototypeManager>();
-
-            await server.WaitAssertion(() =>
-            {
-                foreach (var proto in protoMan.EnumeratePrototypes<ConstructionPrototype>())
-                {
-                    var target = proto.TargetNode;
-                    var graph = protoMan.Index<ConstructionGraphPrototype>(proto.Graph);
-
-                    Assert.That(graph.Nodes.ContainsKey(target),
-                        $"Found no targetNode \"{target}\" on graph \"{graph.ID}\" for construction prototype \"{proto.ID}\"!");
-                }
-            });
-            await pair.CleanReturnAsync();
-        }
-
-        [Test]
-        public async Task DeconstructionIsValid()
-        {
-            await using var pair = await PoolManager.GetServerClient();
-            var server = pair.Server;
-
-            var protoMan = server.ResolveDependency<IPrototypeManager>();
-            var compFact = server.ResolveDependency<IComponentFactory>();
-
-            var name = compFact.GetComponentName(typeof(ConstructionComponent));
-            Assert.Multiple(() =>
-            {
-                foreach (var proto in protoMan.EnumeratePrototypes<EntityPrototype>())
-                {
-                    if (proto.Abstract || pair.IsTestPrototype(proto) || !proto.Components.TryGetValue(name, out var reg))
-                        continue;
-
-                    var comp = (ConstructionComponent) reg.Component;
-                    var target = comp.DeconstructionNode;
-                    if (target == null)
-                        continue;
-
-                    var graph = protoMan.Index<ConstructionGraphPrototype>(comp.Graph);
-                    Assert.That(graph.Nodes.ContainsKey(target), $"Invalid deconstruction node \"{target}\" on graph \"{graph.ID}\" for construction entity \"{proto.ID}\"!");
-                }
-            });
-
-            await pair.CleanReturnAsync();
-        }
-
-        [Test]
-        public async Task TestStartReachesValidTarget()
-        {
-            await using var pair = await PoolManager.GetServerClient();
-            var server = pair.Server;
-
-            var protoMan = server.ResolveDependency<IPrototypeManager>();
-            var entMan = server.ResolveDependency<IEntityManager>();
-
-            await server.WaitAssertion(() =>
-            {
-                foreach (var proto in protoMan.EnumeratePrototypes<ConstructionPrototype>())
-                {
-                    var start = proto.StartNode;
-                    var target = proto.TargetNode;
-                    var graph = protoMan.Index<ConstructionGraphPrototype>(proto.Graph);
-
-#pragma warning disable NUnit2045 // Interdependent assertions.
-                    Assert.That(graph.TryPath(start, target, out var path),
-                        $"Unable to find path from \"{start}\" to \"{target}\" on graph \"{graph.ID}\"");
-                    Assert.That(path, Has.Length.GreaterThanOrEqualTo(1),
-                        $"Unable to find path from \"{start}\" to \"{target}\" on graph \"{graph.ID}\".");
-                    var next = path[0];
-                    var nextId = next.Entity.GetId(null, null, new(entMan));
-                    Assert.That(nextId, Is.Not.Null,
-                        $"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) must specify an entity! Graph: {graph.ID}");
-                    Assert.That(protoMan.TryIndex(nextId, out EntityPrototype entity),
-                        $"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) specified an invalid entity prototype ({nextId} [{next.Entity}])");
-                    Assert.That(entity.Components.ContainsKey("Construction"),
-                        $"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) specified an entity prototype ({next.Entity}) without a ConstructionComponent.");
-#pragma warning restore NUnit2045
-                }
-            });
-
-            await pair.CleanReturnAsync();
-        }
-    }
-}

+ 0 - 97
Content.IntegrationTests/Tests/Construction/Interaction/ComputerContruction.cs

@@ -1,97 +0,0 @@
-using Content.IntegrationTests.Tests.Interaction;
-
-namespace Content.IntegrationTests.Tests.Construction.Interaction;
-
-public sealed class ComputerConstruction : InteractionTest
-{
-    private const string Computer = "Computer";
-    private const string ComputerId = "ComputerId";
-    private const string ComputerFrame = "ComputerFrame";
-    private const string IdBoard = "IDComputerCircuitboard";
-
-    [Test]
-    public async Task ConstructComputer()
-    {
-        // Place ghost
-        await StartConstruction(Computer);
-
-        // Initial interaction (ghost turns into real entity)
-        await InteractUsing(Steel, 5);
-        ClientAssertPrototype(ComputerFrame, Target);
-
-        // Perform construction steps
-        await Interact(
-            Wrench,
-            IdBoard,
-            Screw,
-            (Cable, 5),
-            (Glass, 2),
-            Screw);
-
-        // Construction finished, target entity was replaced with a new one:
-        AssertPrototype(ComputerId, Target);
-    }
-
-    [Test]
-    public async Task DeconstructComputer()
-    {
-        // Spawn initial entity
-        await StartDeconstruction(ComputerId);
-
-        // Initial interaction turns id computer into generic computer
-        await InteractUsing(Pry);
-        AssertPrototype(ComputerFrame);
-
-        // Perform deconstruction steps
-        await Interact(
-            Pry,
-            Cut,
-            Screw,
-            Pry,
-            Wrench,
-            Screw);
-
-        // construction finished, entity no longer exists.
-        AssertDeleted();
-
-        // Check expected entities were dropped.
-        await AssertEntityLookup(
-            IdBoard,
-            (Cable, 5),
-            (Steel, 5),
-            (Glass, 2));
-    }
-
-    [Test]
-    public async Task ChangeComputer()
-    {
-        // Spawn initial entity
-        await SpawnTarget(ComputerId);
-
-        // Initial interaction turns id computer into generic computer
-        await InteractUsing(Pry);
-        AssertPrototype(ComputerFrame);
-
-        // Perform partial deconstruction steps
-        await Interact(
-            Pry,
-            Cut,
-            Screw,
-            Pry);
-
-        // Entity should still exist
-        AssertPrototype(ComputerFrame);
-
-        // Begin re-constructing with a new circuit board
-        await Interact(
-            "CargoRequestComputerCircuitboard",
-            Screw,
-            (Cable, 5),
-            (Glass, 2),
-            Screw);
-
-        // Construction finished, target entity was replaced with a new one:
-        AssertPrototype("ComputerCargoOrders");
-    }
-}
-

+ 0 - 131
Content.IntegrationTests/Tests/Construction/Interaction/CraftingTests.cs

@@ -1,131 +0,0 @@
-using System.Linq;
-using Content.IntegrationTests.Tests.Interaction;
-using Content.Shared.DoAfter;
-using Content.Shared.Stacks;
-using Robust.Shared.Containers;
-
-namespace Content.IntegrationTests.Tests.Construction.Interaction;
-
-public sealed class CraftingTests : InteractionTest
-{
-    public const string ShardGlass = "ShardGlass";
-    public const string Spear = "Spear";
-
-    /// <summary>
-    /// Craft a simple instant recipe
-    /// </summary>
-    [Test]
-    public async Task CraftRods()
-    {
-        await PlaceInHands(Steel);
-        await CraftItem(Rod);
-        await FindEntity((Rod, 2));
-    }
-
-    /// <summary>
-    /// Craft a simple recipe with a DoAfter
-    /// </summary>
-    [Test]
-    public async Task CraftGrenade()
-    {
-        await PlaceInHands(Steel, 5);
-        await CraftItem("ModularGrenadeRecipe");
-        await FindEntity("ModularGrenade");
-    }
-
-    /// <summary>
-    /// Craft a complex recipe (more than one ingredient).
-    /// </summary>
-    [Test]
-    public async Task CraftSpear()
-    {
-        // Spawn a full tack of rods in the user's hands.
-        await PlaceInHands(Rod, 10);
-        await SpawnEntity((Cable, 10), SEntMan.GetCoordinates(PlayerCoords));
-
-        // Attempt (and fail) to craft without glass.
-        await CraftItem(Spear, shouldSucceed: false);
-        await FindEntity(Spear, shouldSucceed: false);
-
-        // Spawn three shards of glass and finish crafting (only one is needed).
-        await SpawnTarget(ShardGlass);
-        await SpawnTarget(ShardGlass);
-        await SpawnTarget(ShardGlass);
-        await CraftItem(Spear);
-        await FindEntity(Spear);
-
-        // Reset target because entitylookup will dump this.
-        Target = null;
-
-        // Player's hands should be full of the remaining rods, except those dropped during the failed crafting attempt.
-        // Spear and left over stacks should be on the floor.
-        await AssertEntityLookup((Rod, 2), (Cable, 7), (ShardGlass, 2), (Spear, 1));
-    }
-
-    /// <summary>
-    /// Cancel crafting a complex recipe.
-    /// </summary>
-    [Test]
-    public async Task CancelCraft()
-    {
-        var serverTargetCoords = SEntMan.GetCoordinates(TargetCoords);
-        var rods = await SpawnEntity((Rod, 10), serverTargetCoords);
-        var wires = await SpawnEntity((Cable, 10), serverTargetCoords);
-        var shard = await SpawnEntity(ShardGlass, serverTargetCoords);
-
-        var rodStack = SEntMan.GetComponent<StackComponent>(rods);
-        var wireStack = SEntMan.GetComponent<StackComponent>(wires);
-
-        await RunTicks(5);
-        var sys = SEntMan.System<SharedContainerSystem>();
-        Assert.Multiple(() =>
-        {
-            Assert.That(sys.IsEntityInContainer(rods), Is.False);
-            Assert.That(sys.IsEntityInContainer(wires), Is.False);
-            Assert.That(sys.IsEntityInContainer(shard), Is.False);
-        });
-
-#pragma warning disable CS4014 // Legacy construction code uses DoAfterAwait. If we await it we will be waiting forever.
-        await Server.WaitPost(() => SConstruction.TryStartItemConstruction(Spear, SEntMan.GetEntity(Player)));
-#pragma warning restore CS4014
-        await RunTicks(1);
-
-        // DoAfter is in progress. Entity not spawned, stacks have been split and someingredients are in a container.
-        Assert.That(ActiveDoAfters.Count(), Is.EqualTo(1));
-        Assert.That(sys.IsEntityInContainer(shard), Is.True);
-        Assert.That(sys.IsEntityInContainer(rods), Is.False);
-        Assert.That(sys.IsEntityInContainer(wires), Is.False);
-        Assert.That(rodStack, Has.Count.EqualTo(8));
-        Assert.That(wireStack, Has.Count.EqualTo(7));
-
-        await FindEntity(Spear, shouldSucceed: false);
-
-        // Cancel the DoAfter. Should drop ingredients to the floor.
-        await CancelDoAfters();
-        Assert.That(sys.IsEntityInContainer(rods), Is.False);
-        Assert.That(sys.IsEntityInContainer(wires), Is.False);
-        Assert.That(sys.IsEntityInContainer(shard), Is.False);
-        await FindEntity(Spear, shouldSucceed: false);
-        await AssertEntityLookup((Rod, 10), (Cable, 10), (ShardGlass, 1));
-
-        // Re-attempt the do-after
-#pragma warning disable CS4014 // Legacy construction code uses DoAfterAwait. See above.
-        await Server.WaitPost(() => SConstruction.TryStartItemConstruction(Spear, SEntMan.GetEntity(Player)));
-#pragma warning restore CS4014
-        await RunTicks(1);
-
-        // DoAfter is in progress. Entity not spawned, ingredients are in a container.
-        Assert.That(ActiveDoAfters.Count(), Is.EqualTo(1));
-        Assert.That(sys.IsEntityInContainer(shard), Is.True);
-        await FindEntity(Spear, shouldSucceed: false);
-
-        // Finish the DoAfter
-        await AwaitDoAfters();
-
-        // Spear has been crafted. Rods and wires are no longer contained. Glass has been consumed.
-        await FindEntity(Spear);
-        Assert.That(sys.IsEntityInContainer(rods), Is.False);
-        Assert.That(sys.IsEntityInContainer(wires), Is.False);
-        Assert.That(SEntMan.Deleted(shard));
-    }
-}

+ 0 - 56
Content.IntegrationTests/Tests/Construction/Interaction/GrilleWindowConstruction.cs

@@ -1,56 +0,0 @@
-using Content.IntegrationTests.Tests.Interaction;
-using Content.Shared.Construction.Prototypes;
-using Robust.Shared.Maths;
-
-namespace Content.IntegrationTests.Tests.Construction.Interaction;
-
-/// <summary>
-///     Check that we can build grilles on top of windows, but not the other way around.
-/// </summary>
-public sealed class GrilleWindowConstruction : InteractionTest
-{
-    private const string Grille = "Grille";
-    private const string Window = "Window";
-
-    [Test]
-    public async Task WindowOnGrille()
-    {
-        // Construct Grille
-        await StartConstruction(Grille);
-        await InteractUsing(Rod, 10);
-        ClientAssertPrototype(Grille, Target);
-        var grille = Target;
-
-        // Construct Window
-        await StartConstruction(Window);
-        await InteractUsing(Glass, 10);
-        ClientAssertPrototype(Window, Target);
-
-        // Deconstruct Window
-        await Interact(Screw, Wrench);
-        AssertDeleted();
-
-        // Deconstruct Grille
-        Target = grille;
-        await InteractUsing(Cut);
-        AssertDeleted();
-    }
-
-    [Test]
-    [TestCase(Grille, Grille)]
-    [TestCase(Window, Grille)]
-    [TestCase(Window, Window)]
-    public async Task ConstructionBlocker(string first, string second)
-    {
-        // Spawn blocking entity
-        await SpawnTarget(first);
-
-        // Further construction attempts fail - blocked by first entity interaction.
-        await Client.WaitPost(() =>
-        {
-            var proto = ProtoMan.Index<ConstructionPrototype>(second);
-            Assert.That(CConSys.TrySpawnGhost(proto, CEntMan.GetCoordinates(TargetCoords), Direction.South, out _), Is.False);
-        });
-    }
-}
-

+ 0 - 59
Content.IntegrationTests/Tests/Construction/Interaction/MachineConstruction.cs

@@ -1,59 +0,0 @@
-using Content.IntegrationTests.Tests.Interaction;
-
-namespace Content.IntegrationTests.Tests.Construction.Interaction;
-
-public sealed class MachineConstruction : InteractionTest
-{
-    private const string MachineFrame = "MachineFrame";
-    private const string Unfinished = "UnfinishedMachineFrame";
-    private const string ProtolatheBoard = "ProtolatheMachineCircuitboard";
-    private const string Protolathe = "Protolathe";
-    private const string Beaker = "Beaker";
-
-    [Test]
-    public async Task ConstructProtolathe()
-    {
-        await StartConstruction(MachineFrame);
-        await InteractUsing(Steel, 5);
-        ClientAssertPrototype(Unfinished, Target);
-        await Interact(Wrench, Cable);
-        AssertPrototype(MachineFrame);
-        await Interact(ProtolatheBoard, Bin1, Bin1, Manipulator1, Manipulator1, Beaker, Beaker, Screw);
-        AssertPrototype(Protolathe);
-    }
-
-    [Test]
-    public async Task DeconstructProtolathe()
-    {
-        await StartDeconstruction(Protolathe);
-        await Interact(Screw, Pry);
-        AssertPrototype(MachineFrame);
-        await Interact(Pry, Cut);
-        AssertPrototype(Unfinished);
-        await Interact(Wrench, Screw);
-        AssertDeleted();
-        await AssertEntityLookup(
-            (Steel, 5),
-            (Cable, 1),
-            (Beaker, 2),
-            (Manipulator1, 2),
-            (Bin1, 2),
-            (ProtolatheBoard, 1));
-    }
-
-    [Test]
-    public async Task ChangeMachine()
-    {
-        // Partially deconstruct a protolathe.
-        await SpawnTarget(Protolathe);
-        await Interact(Screw, Pry, Pry);
-        AssertPrototype(MachineFrame);
-
-        // Change it into an autolathe
-        await InteractUsing("AutolatheMachineCircuitboard");
-        AssertPrototype(MachineFrame);
-        await Interact(Bin1, Bin1, Bin1, Manipulator1, Glass, Screw);
-        AssertPrototype("Autolathe");
-    }
-}
-

+ 0 - 40
Content.IntegrationTests/Tests/Construction/Interaction/PanelScrewing.cs

@@ -1,40 +0,0 @@
-using System.Linq;
-using Content.IntegrationTests.Tests.Interaction;
-using Content.Shared.DoAfter;
-using Content.Shared.Wires;
-
-namespace Content.IntegrationTests.Tests.Construction.Interaction;
-
-public sealed class PanelScrewing : InteractionTest
-{
-    // Test wires panel on both airlocks & tcomms servers. These both use the same component, but comms may have
-    // conflicting interactions due to encryption key removal interactions.
-    [Test]
-    [TestCase("Airlock")]
-    [TestCase("TelecomServerFilled")]
-    public async Task WiresPanelScrewing(string prototype)
-    {
-        await SpawnTarget(prototype);
-        var comp = Comp<WiresPanelComponent>();
-
-        // Open & close panel
-        Assert.That(comp.Open, Is.False);
-        await InteractUsing(Screw);
-        Assert.That(comp.Open, Is.True);
-        await InteractUsing(Screw);
-        Assert.That(comp.Open, Is.False);
-
-        // Interrupted DoAfters
-        await InteractUsing(Screw, awaitDoAfters: false);
-        await CancelDoAfters();
-        Assert.That(comp.Open, Is.False);
-        await InteractUsing(Screw);
-        Assert.That(comp.Open, Is.True);
-        await InteractUsing(Screw, awaitDoAfters: false);
-        await CancelDoAfters();
-        Assert.That(comp.Open, Is.True);
-        await InteractUsing(Screw);
-        Assert.That(comp.Open, Is.False);
-    }
-}
-

+ 0 - 23
Content.IntegrationTests/Tests/Construction/Interaction/PlaceableDeconstruction.cs

@@ -1,23 +0,0 @@
-using Content.IntegrationTests.Tests.Interaction;
-using Content.Shared.Placeable;
-
-namespace Content.IntegrationTests.Tests.Construction.Interaction;
-
-public sealed class PlaceableDeconstruction : InteractionTest
-{
-    /// <summary>
-    /// Checks that you can deconstruct placeable surfaces (i.e., placing a wrench on a table does not take priority).
-    /// </summary>
-    [Test]
-    public async Task DeconstructTable()
-    {
-        await StartDeconstruction("Table");
-        Assert.That(Comp<PlaceableSurfaceComponent>().IsPlaceable);
-        await InteractUsing(Wrench);
-        AssertPrototype("TableFrame");
-        await InteractUsing(Wrench);
-        AssertDeleted();
-        await AssertEntityLookup((Steel, 1), (Rod, 2));
-    }
-}
-

+ 0 - 33
Content.IntegrationTests/Tests/Construction/Interaction/WallConstruction.cs

@@ -1,33 +0,0 @@
-using Content.IntegrationTests.Tests.Interaction;
-
-namespace Content.IntegrationTests.Tests.Construction.Interaction;
-
-public sealed class WallConstruction : InteractionTest
-{
-    public const string Girder = "Girder";
-    public const string WallSolid = "WallSolid";
-    public const string Wall = "Wall";
-
-    [Test]
-    public async Task ConstructWall()
-    {
-        await StartConstruction(Wall);
-        await InteractUsing(Steel, 2);
-        Assert.That(Hands.ActiveHandEntity, Is.Null);
-        ClientAssertPrototype(Girder, Target);
-        await InteractUsing(Steel, 2);
-        Assert.That(Hands.ActiveHandEntity, Is.Null);
-        AssertPrototype(WallSolid);
-    }
-
-    [Test]
-    public async Task DeconstructWall()
-    {
-        await StartDeconstruction(WallSolid);
-        await InteractUsing(Weld);
-        AssertPrototype(Girder);
-        await Interact(Wrench, Screw);
-        AssertDeleted();
-        await AssertEntityLookup((Steel, 4));
-    }
-}

+ 0 - 50
Content.IntegrationTests/Tests/Construction/Interaction/WindowConstruction.cs

@@ -1,50 +0,0 @@
-using Content.IntegrationTests.Tests.Interaction;
-
-namespace Content.IntegrationTests.Tests.Construction.Interaction;
-
-public sealed class WindowConstruction : InteractionTest
-{
-    private const string Window = "Window";
-    private const string RWindow = "ReinforcedWindow";
-
-    [Test]
-    public async Task ConstructWindow()
-    {
-        await StartConstruction(Window);
-        await InteractUsing(Glass, 5);
-        ClientAssertPrototype(Window, Target);
-    }
-
-    [Test]
-    public async Task DeconstructWindow()
-    {
-        await StartDeconstruction(Window);
-        await Interact(Screw, Wrench);
-        AssertDeleted();
-        await AssertEntityLookup((Glass, 2));
-    }
-
-    [Test]
-    public async Task ConstructReinforcedWindow()
-    {
-        await StartConstruction(RWindow);
-        await InteractUsing(RGlass, 5);
-        ClientAssertPrototype(RWindow, Target);
-    }
-
-    [Test]
-    public async Task DeonstructReinforcedWindow()
-    {
-        await StartDeconstruction(RWindow);
-        await Interact(
-            Weld,
-            Screw,
-            Pry,
-            Weld,
-            Screw,
-            Wrench);
-        AssertDeleted();
-        await AssertEntityLookup((RGlass, 2));
-    }
-}
-

+ 0 - 42
Content.IntegrationTests/Tests/Construction/Interaction/WindowRepair.cs

@@ -1,42 +0,0 @@
-using Content.IntegrationTests.Tests.Interaction;
-using Content.Shared.Damage;
-using Content.Shared.Damage.Prototypes;
-using Content.Shared.FixedPoint;
-using Robust.Shared.Prototypes;
-
-namespace Content.IntegrationTests.Tests.Construction.Interaction;
-
-public sealed class WindowRepair : InteractionTest
-{
-    [Test]
-    public async Task RepairReinforcedWindow()
-    {
-        await SpawnTarget("ReinforcedWindow");
-
-        // Damage the entity.
-        var sys = SEntMan.System<DamageableSystem>();
-        var comp = Comp<DamageableComponent>();
-        var damageType = Server.ResolveDependency<IPrototypeManager>().Index<DamageTypePrototype>("Blunt");
-        var damage = new DamageSpecifier(damageType, FixedPoint2.New(10));
-        Assert.That(comp.Damage.GetTotal(), Is.EqualTo(FixedPoint2.Zero));
-        await Server.WaitPost(() => sys.TryChangeDamage(SEntMan.GetEntity(Target), damage, ignoreResistances: true));
-        await RunTicks(5);
-        Assert.That(comp.Damage.GetTotal(), Is.GreaterThan(FixedPoint2.Zero));
-
-        // Repair the entity
-        await InteractUsing(Weld);
-        Assert.That(comp.Damage.GetTotal(), Is.EqualTo(FixedPoint2.Zero));
-
-        // Validate that we can still deconstruct the entity (i.e., that welding deconstruction is not blocked).
-        await Interact(
-            Weld,
-            Screw,
-            Pry,
-            Weld,
-            Screw,
-            Wrench);
-        AssertDeleted();
-        await AssertEntityLookup((RGlass, 2));
-    }
-}
-

+ 4 - 0
Content.IntegrationTests/Tests/Destructible/DestructibleTestPrototypes.cs

@@ -22,6 +22,10 @@ public static class DestructibleTestPrototypes
   id: TestPiercing
   id: TestPiercing
   name: damage-type-piercing
   name: damage-type-piercing
 
 
+- type: damageType
+  id: TestArrow
+  name: damage-type-arrow
+
 - type: damageType
 - type: damageType
   id: TestHeat
   id: TestHeat
   name: damage-type-heat
   name: damage-type-heat

+ 94 - 0
Content.IntegrationTests/Tests/DeviceLinking/DeviceLinkingTest.cs

@@ -0,0 +1,94 @@
+using System.Collections.Generic;
+using System.Linq;
+using Content.Server.DeviceLinking.Systems;
+using Content.Shared.DeviceLinking;
+using Content.Shared.Prototypes;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Map;
+using Robust.Shared.Maths;
+using Robust.Shared.Prototypes;
+
+namespace Content.IntegrationTests.Tests.DeviceLinking;
+
+public sealed class DeviceLinkingTest
+{
+    private const string PortTesterProtoId = "DeviceLinkingSinkPortTester";
+
+    [TestPrototypes]
+    private const string Prototypes = $@"
+- type: entity
+  id: {PortTesterProtoId}
+  components:
+  - type: DeviceLinkSource
+    ports:
+    - Output
+";
+
+    /// <summary>
+    /// Spawns every entity that has a <see cref="DeviceLinkSinkComponent"/>
+    /// and sends a signal to every port to make sure nothing causes an error.
+    /// </summary>
+    [Test]
+    public async Task AllDeviceLinkSinksWorkTest()
+    {
+        await using var pair = await PoolManager.GetServerClient();
+        var server = pair.Server;
+        var compFact = server.ResolveDependency<IComponentFactory>();
+        var mapMan = server.ResolveDependency<IMapManager>();
+        var mapSys = server.System<SharedMapSystem>();
+        var deviceLinkSys = server.System<DeviceLinkSystem>();
+
+        var prototypes = server.ProtoMan.EnumeratePrototypes<EntityPrototype>();
+
+        await server.WaitAssertion(() =>
+        {
+            Assert.Multiple(() =>
+            {
+                foreach (var proto in prototypes)
+                {
+                    if (proto.Abstract || pair.IsTestPrototype(proto))
+                        continue;
+
+                    if (!proto.TryGetComponent<DeviceLinkSinkComponent>(out var protoSinkComp, compFact))
+                        continue;
+
+                    foreach (var port in protoSinkComp.Ports)
+                    {
+                        // Create a map for each entity/port combo so they can't interfere
+                        mapSys.CreateMap(out var mapId);
+                        var grid = mapMan.CreateGridEntity(mapId);
+                        mapSys.SetTile(grid.Owner, grid.Comp, Vector2i.Zero, new Tile(1));
+                        var coord = new EntityCoordinates(grid.Owner, 0, 0);
+
+                        // Spawn the sink entity
+                        var sinkEnt = server.EntMan.SpawnEntity(proto.ID, coord);
+                        // Get the actual sink component, since the one we got from the prototype doesn't have its owner set up
+                        Assert.That(server.EntMan.TryGetComponent<DeviceLinkSinkComponent>(sinkEnt, out var sinkComp),
+                            $"Tester prototype does not have a DeviceLinkSourceComponent!");
+
+                        // Spawn the tester
+                        var sourceEnt = server.EntMan.SpawnEntity(PortTesterProtoId, coord);
+                        Assert.That(server.EntMan.TryGetComponent<DeviceLinkSourceComponent>(sourceEnt, out var sourceComp),
+                            $"Tester prototype does not have a DeviceLinkSourceComponent!");
+
+                        // Create a link from the tester's output to the target port on the sink
+                        deviceLinkSys.SaveLinks(null,
+                            sourceEnt,
+                            sinkEnt,
+                            [("Output", port.Id)],
+                            sourceComp,
+                            sinkComp);
+
+                        // Send a signal to the port
+                        Assert.DoesNotThrow(() => { deviceLinkSys.InvokePort(sourceEnt, "Output", null, sourceComp); },
+                            $"Exception thrown while triggering port {port.Id} of sink device {proto.ID}");
+
+                        mapSys.DeleteMap(mapId);
+                    }
+                }
+            });
+        });
+
+        await pair.CleanReturnAsync();
+    }
+}

+ 0 - 150
Content.IntegrationTests/Tests/DoAfter/DoAfterCancellationTests.cs

@@ -1,150 +0,0 @@
-using System.Linq;
-using Content.IntegrationTests.Tests.Construction.Interaction;
-using Content.IntegrationTests.Tests.Interaction;
-using Content.IntegrationTests.Tests.Weldable;
-using Content.Shared.Tools.Components;
-
-namespace Content.IntegrationTests.Tests.DoAfter;
-
-/// <summary>
-/// This class has various tests that verify that cancelled DoAfters do not complete construction or other interactions.
-/// It also checks that cancellation of a DoAfter does not block future DoAfters.
-/// </summary>
-public sealed class DoAfterCancellationTests : InteractionTest
-{
-    [Test]
-    public async Task CancelWallDeconstruct()
-    {
-        await StartDeconstruction(WallConstruction.WallSolid);
-        await InteractUsing(Weld, awaitDoAfters: false);
-
-        // Failed do-after has no effect
-        await CancelDoAfters();
-        AssertPrototype(WallConstruction.WallSolid);
-
-        // Second attempt works fine
-        await InteractUsing(Weld);
-        AssertPrototype(WallConstruction.Girder);
-
-        // Repeat for wrenching interaction
-        AssertAnchored();
-        await InteractUsing(Wrench, awaitDoAfters: false);
-        await CancelDoAfters();
-        AssertAnchored();
-        AssertPrototype(WallConstruction.Girder);
-        await InteractUsing(Wrench);
-        AssertAnchored(false);
-
-        // Repeat for screwdriver interaction.
-        AssertExists();
-        await InteractUsing(Screw, awaitDoAfters: false);
-        await CancelDoAfters();
-        AssertExists();
-        await InteractUsing(Screw);
-        AssertDeleted();
-    }
-
-    [Test]
-    public async Task CancelWallConstruct()
-    {
-        await StartConstruction(WallConstruction.Wall);
-        await InteractUsing(Steel, 5, awaitDoAfters: false);
-        await CancelDoAfters();
-
-        await InteractUsing(Steel, 5);
-        ClientAssertPrototype(WallConstruction.Girder, Target);
-        await InteractUsing(Steel, 5, awaitDoAfters: false);
-        await CancelDoAfters();
-        AssertPrototype(WallConstruction.Girder);
-
-        await InteractUsing(Steel, 5);
-        AssertPrototype(WallConstruction.WallSolid);
-    }
-
-    [Test]
-    public async Task CancelTilePry()
-    {
-        await SetTile(Floor);
-        await InteractUsing(Pry, awaitDoAfters: false);
-        await CancelDoAfters();
-        await AssertTile(Floor);
-
-        await InteractUsing(Pry);
-        await AssertTile(Plating);
-    }
-
-    [Test]
-    public async Task CancelRepeatedTilePry()
-    {
-        await SetTile(Floor);
-        await InteractUsing(Pry, awaitDoAfters: false);
-        await RunTicks(1);
-        Assert.That(ActiveDoAfters.Count(), Is.EqualTo(1));
-        await AssertTile(Floor);
-
-        // Second DoAfter cancels the first.
-        await Server.WaitPost(() => InteractSys.UserInteraction(SEntMan.GetEntity(Player), SEntMan.GetCoordinates(TargetCoords), SEntMan.GetEntity(Target)));
-        Assert.That(ActiveDoAfters.Count(), Is.EqualTo(0));
-        await AssertTile(Floor);
-
-        // Third do after will work fine
-        await InteractUsing(Pry);
-        Assert.That(ActiveDoAfters.Count(), Is.EqualTo(0));
-        await AssertTile(Plating);
-    }
-
-    [Test]
-    public async Task CancelRepeatedWeld()
-    {
-        await SpawnTarget(WeldableTests.Locker);
-        var comp = Comp<WeldableComponent>();
-
-        Assert.That(comp.IsWelded, Is.False);
-
-        await InteractUsing(Weld, awaitDoAfters: false);
-        await RunTicks(1);
-        Assert.Multiple(() =>
-        {
-            Assert.That(ActiveDoAfters.Count(), Is.EqualTo(1));
-            Assert.That(comp.IsWelded, Is.False);
-        });
-
-        // Second DoAfter cancels the first.
-        // Not using helper, because it runs too many ticks & causes the do-after to finish.
-        await Server.WaitPost(() => InteractSys.UserInteraction(SEntMan.GetEntity(Player), SEntMan.GetCoordinates(TargetCoords), SEntMan.GetEntity(Target)));
-        Assert.Multiple(() =>
-        {
-            Assert.That(ActiveDoAfters.Count(), Is.EqualTo(0));
-            Assert.That(comp.IsWelded, Is.False);
-        });
-
-        // Third do after will work fine
-        await InteractUsing(Weld);
-        Assert.Multiple(() =>
-        {
-            Assert.That(ActiveDoAfters.Count(), Is.EqualTo(0));
-            Assert.That(comp.IsWelded, Is.True);
-        });
-
-        // Repeat test for un-welding
-        await InteractUsing(Weld, awaitDoAfters: false);
-        await RunTicks(1);
-        Assert.Multiple(() =>
-        {
-            Assert.That(ActiveDoAfters.Count(), Is.EqualTo(1));
-            Assert.That(comp.IsWelded, Is.True);
-        });
-        await Server.WaitPost(() => InteractSys.UserInteraction(SEntMan.GetEntity(Player), SEntMan.GetCoordinates(TargetCoords), SEntMan.GetEntity(Target)));
-        Assert.Multiple(() =>
-        {
-            Assert.That(ActiveDoAfters.Count(), Is.EqualTo(0));
-            Assert.That(comp.IsWelded, Is.True);
-        });
-        await InteractUsing(Weld);
-        Assert.Multiple(() =>
-        {
-            Assert.That(ActiveDoAfters.Count(), Is.EqualTo(0));
-            Assert.That(comp.IsWelded, Is.False);
-        });
-    }
-}

+ 5 - 1
Content.IntegrationTests/Tests/GameRules/NukeOpsTest.cs

@@ -152,10 +152,14 @@ void CheckDummy(int i)
             Assert.That(roleSys.MindGetAllRoleInfo(mindCrew).Any(x => nukeroles.Contains(x.Prototype)), Is.False);
             Assert.That(roleSys.MindGetAllRoleInfo(mindCrew).Any(x => nukeroles.Contains(x.Prototype)), Is.False);
         }
         }
 
 
+        var ruleGridComps = entMan.AllComponents<RuleGridsComponent>();
+        Assert.That(ruleGridComps, Has.Length.EqualTo(1),
+            $"Unexpected RuleGrid(s) detected! {string.Join(',', ruleGridComps.Select(e => server.EntMan.ToPrettyString(e.Uid)))}");
+
         // The game rule exists, and all the stations/shuttles/maps are properly initialized
         // The game rule exists, and all the stations/shuttles/maps are properly initialized
         var rule = entMan.AllComponents<NukeopsRuleComponent>().Single();
         var rule = entMan.AllComponents<NukeopsRuleComponent>().Single();
         var ruleComp = rule.Component;
         var ruleComp = rule.Component;
-        var gridsRule = entMan.AllComponents<RuleGridsComponent>().Single().Component;
+        var gridsRule = ruleGridComps.Single().Component;
         foreach (var grid in gridsRule.MapGrids)
         foreach (var grid in gridsRule.MapGrids)
         {
         {
             Assert.That(entMan.EntityExists(grid));
             Assert.That(entMan.EntityExists(grid));

+ 10 - 7
Content.IntegrationTests/Tests/Localization/LocalizedDatasetPrototypeTest.cs

@@ -19,16 +19,19 @@ public async Task ValidProtoIdsTest()
 
 
         var protos = protoMan.EnumeratePrototypes<LocalizedDatasetPrototype>().OrderBy(p => p.ID);
         var protos = protoMan.EnumeratePrototypes<LocalizedDatasetPrototype>().OrderBy(p => p.ID);
 
 
-        // Check each prototype
-        foreach (var proto in protos)
+        Assert.Multiple(() =>
         {
         {
-            // Check each value in the prototype
-            foreach (var locId in proto.Values)
+            // Check each prototype
+            foreach (var proto in protos)
             {
             {
-                // Make sure the localization manager has a string for the LocId
-                Assert.That(localizationMan.HasString(locId), $"LocalizedDataset {proto.ID} with prefix \"{proto.Values.Prefix}\" specifies {proto.Values.Count} entries, but no localized string was found matching {locId}!");
+                // Check each value in the prototype
+                foreach (var locId in proto.Values)
+                {
+                    // Make sure the localization manager has a string for the LocId
+                    Assert.That(localizationMan.HasString(locId), $"LocalizedDataset {proto.ID} with prefix \"{proto.Values.Prefix}\" specifies {proto.Values.Count} entries, but no localized string was found matching {locId}!");
+                }
             }
             }
-        }
+        });
 
 
         await pair.CleanReturnAsync();
         await pair.CleanReturnAsync();
     }
     }

+ 3 - 34
Content.IntegrationTests/Tests/PostMapInitTest.cs

@@ -45,42 +45,11 @@ public sealed class PostMapInitTest
 
 
         private static readonly string[] DoNotMapWhitelist =
         private static readonly string[] DoNotMapWhitelist =
         {
         {
-            "/Maps/centcomm.yml",
-            "/Maps/bagel.yml", // Contains mime's rubber stamp --> Either fix this, remove the category, or remove this comment if intentional.
-            "/Maps/gate.yml", // Contains positronic brain and LSE-1200c "Perforator"
-            "/Maps/meta.yml", // Contains warden's rubber stamp
-            "/Maps/reach.yml", // Contains handheld crew monitor
-            "/Maps/Shuttles/ShuttleEvent/cruiser.yml", // Contains LSE-1200c "Perforator"
-            "/Maps/Shuttles/ShuttleEvent/honki.yml", // Contains golden honker, clown's rubber stamp
-            "/Maps/Shuttles/ShuttleEvent/instigator.yml", // Contains EXP-320g "Friendship"
-            "/Maps/Shuttles/ShuttleEvent/syndie_evacpod.yml", // Contains syndicate rubber stamp
         };
         };
 
 
         private static readonly string[] GameMaps =
         private static readonly string[] GameMaps =
         {
         {
-            "Dev",
-            "TestTeg",
-            "Fland",
-            "Meta",
-            "Packed",
-            "Omega",
-            "Bagel",
-            "CentComm",
-            "Box",
-            "Core",
-            "Marathon",
-            "MeteorArena",
-            "Saltern",
-            "Reach",
-            "Train",
-            "Oasis",
-            "Gate",
-            "Amber",
-            "Loop",
-            "Plasma",
-            "Elkridge",
-            "Convex",
-            "Relic"
+            "Nomads"
         };
         };
 
 
         /// <summary>
         /// <summary>
@@ -325,7 +294,7 @@ public async Task GameMapsLoadableTest(string mapProto)
                 MapId mapId;
                 MapId mapId;
                 try
                 try
                 {
                 {
-                    var opts = DeserializationOptions.Default with {InitializeMaps = true};
+                    var opts = DeserializationOptions.Default with { InitializeMaps = true };
                     ticker.LoadGameMap(protoManager.Index<GameMapPrototype>(mapProto), out mapId, opts);
                     ticker.LoadGameMap(protoManager.Index<GameMapPrototype>(mapProto), out mapId, opts);
                 }
                 }
                 catch (Exception ex)
                 catch (Exception ex)
@@ -432,7 +401,7 @@ private static int GetCountLateSpawn<T>(List<EntityUid> gridUids, IEntityManager
 #nullable enable
 #nullable enable
             while (queryPoint.MoveNext(out T? comp, out var xform))
             while (queryPoint.MoveNext(out T? comp, out var xform))
             {
             {
-                var spawner = (ISpawnPoint) comp;
+                var spawner = (ISpawnPoint)comp;
 
 
                 if (spawner.SpawnType is not SpawnPointType.LateJoin
                 if (spawner.SpawnType is not SpawnPointType.LateJoin
                 || xform.GridUid == null
                 || xform.GridUid == null

+ 0 - 1
Content.IntegrationTests/Tests/PrototypeSaveTest.cs

@@ -35,7 +35,6 @@ public async Task UninitializedSaveTest()
         await using var pair = await PoolManager.GetServerClient();
         await using var pair = await PoolManager.GetServerClient();
         var server = pair.Server;
         var server = pair.Server;
 
 
-        var mapManager = server.ResolveDependency<IMapManager>();
         var entityMan = server.ResolveDependency<IEntityManager>();
         var entityMan = server.ResolveDependency<IEntityManager>();
         var prototypeMan = server.ResolveDependency<IPrototypeManager>();
         var prototypeMan = server.ResolveDependency<IPrototypeManager>();
         var seriMan = server.ResolveDependency<ISerializationManager>();
         var seriMan = server.ResolveDependency<ISerializationManager>();

Some files were not shown because too many files changed in this diff