diff --git a/TypeScript/10ScopesAndTypes/types/callbacks/LocationCallbacks.d.ts b/TypeScript/10ScopesAndTypes/types/callbacks/LocationCallbacks.d.ts
index cc69369..6e0b538 100644
--- a/TypeScript/10ScopesAndTypes/types/callbacks/LocationCallbacks.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/callbacks/LocationCallbacks.d.ts
@@ -11,4 +11,5 @@ export declare class LocationCallbacks {
     constructor(httpResponse: HttpResponseUtil, locationController: LocationController);
     getLocationData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<ILocationsGenerateAllResponse>;
     getLocation(url: string, info: IGetLocationRequestData, sessionID: string): IGetBodyResponseData<ILocationBase>;
+    getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): string;
 }
diff --git a/TypeScript/10ScopesAndTypes/types/callbacks/ProfileCallbacks.d.ts b/TypeScript/10ScopesAndTypes/types/callbacks/ProfileCallbacks.d.ts
index 6a86fc0..183bb0a 100644
--- a/TypeScript/10ScopesAndTypes/types/callbacks/ProfileCallbacks.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/callbacks/ProfileCallbacks.d.ts
@@ -1,5 +1,6 @@
 import { ProfileController } from "../controllers/ProfileController";
 import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData";
+import { IPmcData } from "../models/eft/common/IPmcData";
 import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData";
 import { INullResponseData } from "../models/eft/httpResponse/INullResponseData";
 import { IGetMiniProfileRequestData } from "../models/eft/launcher/IGetMiniProfileRequestData";
@@ -12,20 +13,51 @@ import { ISearchFriendResponse } from "../models/eft/profile/ISearchFriendRespon
 import { IValidateNicknameRequestData } from "../models/eft/profile/IValidateNicknameRequestData";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/** Handle profile related client events */
 export declare class ProfileCallbacks {
     protected httpResponse: HttpResponseUtil;
     protected timeUtil: TimeUtil;
     protected profileController: ProfileController;
     constructor(httpResponse: HttpResponseUtil, timeUtil: TimeUtil, profileController: ProfileController);
     createProfile(url: string, info: IProfileCreateRequestData, sessionID: string): IGetBodyResponseData<any>;
-    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
-    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
+    /**
+     * Get the complete player profile (scav + pmc character)
+     * @param url
+     * @param info Empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle the creation of a scav profile for player
+     * Occurs post-raid and when profile first created immediately after character details are confirmed by player
+     * @param url
+     * @param info empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle client/game/profile/voice/change event
+     * @param url
+     * @param info Change voice request object
+     * @param sessionID Session id
+     * @returns Client response
+     */
     changeVoice(url: string, info: IProfileChangeVoiceRequestData, sessionID: string): INullResponseData;
+    /**
+     * Handle client/game/profile/nickname/change event
+     * Client allows player to adjust their profile name
+     * @param url
+     * @param info Change nickname request object
+     * @param sessionID Session id
+     * @returns client response
+     */
     changeNickname(url: string, info: IProfileChangeNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     validateNickname(url: string, info: IValidateNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     getReservedNickname(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<string>;
     /**
-     * Called when creating a character, when you choose a character face/voice
+     * Called when creating a character when choosing a character face/voice
      * @param url
      * @param info response (empty)
      * @param sessionID
diff --git a/TypeScript/10ScopesAndTypes/types/callbacks/RagfairCallbacks.d.ts b/TypeScript/10ScopesAndTypes/types/callbacks/RagfairCallbacks.d.ts
index 3a405c9..c609f2f 100644
--- a/TypeScript/10ScopesAndTypes/types/callbacks/RagfairCallbacks.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/callbacks/RagfairCallbacks.d.ts
@@ -19,6 +19,9 @@ import { ConfigServer } from "../servers/ConfigServer";
 import { RagfairServer } from "../servers/RagfairServer";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+/**
+ * Handle ragfair related callback events
+ */
 export declare class RagfairCallbacks extends OnLoadOnUpdate {
     protected httpResponse: HttpResponseUtil;
     protected logger: ILogger;
diff --git a/TypeScript/10ScopesAndTypes/types/controllers/InraidController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/InraidController.d.ts
index 82bb64d..102a2fb 100644
--- a/TypeScript/10ScopesAndTypes/types/controllers/InraidController.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/controllers/InraidController.d.ts
@@ -35,6 +35,30 @@ export declare class InraidController {
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer);
     addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void;
     saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Handle updating the profile post-pmc raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Reduce body part hp to % of max
+     * @param pmcData profile to edit
+     * @param multipler multipler to apply to max health
+     */
+    protected reducePmcHealthToPercent(pmcData: IPmcData, multipler: number): void;
+    /**
+     * Handle updating the profile post-pscav raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePlayerScavProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Is the player dead after a raid - dead is anything other than "survived" / "runner"
+     * @param statusOnExit exit value from offraidData object
+     * @returns true if dead
+     */
+    protected isPlayerDead(statusOnExit: string): boolean;
     /**
      * Mark inventory items as FiR if player survived raid, otherwise remove FiR from them
      * @param offraidData Save Progress Request
diff --git a/TypeScript/10ScopesAndTypes/types/controllers/InventoryController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/InventoryController.d.ts
index f57f731..f564919 100644
--- a/TypeScript/10ScopesAndTypes/types/controllers/InventoryController.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/controllers/InventoryController.d.ts
@@ -92,7 +92,11 @@ export declare class InventoryController {
      */
     toggleItem(pmcData: IPmcData, body: IInventoryToggleRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Handles Tagging of items (primary Containers).
+     * Add a tag to an inventory item
+     * @param pmcData profile with item to add tag to
+     * @param body tag request data
+     * @param sessionID session id
+     * @returns client response object
      */
     tagItem(pmcData: IPmcData, body: IInventoryTagRequestData, sessionID: string): IItemEventRouterResponse;
     bindItem(pmcData: IPmcData, body: IInventoryBindRequestData, sessionID: string): IItemEventRouterResponse;
diff --git a/TypeScript/10ScopesAndTypes/types/controllers/LocationController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/LocationController.d.ts
index 90b6d7a..9db3205 100644
--- a/TypeScript/10ScopesAndTypes/types/controllers/LocationController.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/controllers/LocationController.d.ts
@@ -1,18 +1,33 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class LocationController {
     protected jsonUtil: JsonUtil;
+    protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/10ScopesAndTypes/types/controllers/MatchController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/MatchController.d.ts
index e8585d9..cb40023 100644
--- a/TypeScript/10ScopesAndTypes/types/controllers/MatchController.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/controllers/MatchController.d.ts
@@ -9,6 +9,7 @@ import { IGetProfileRequestData } from "../models/eft/match/IGetProfileRequestDa
 import { IJoinMatchRequestData } from "../models/eft/match/IJoinMatchRequestData";
 import { IJoinMatchResult } from "../models/eft/match/IJoinMatchResult";
 import { IStartOfflineRaidRequestData } from "../models/eft/match/IStartOffineRaidRequestData";
+import { IBotConfig } from "../models/spt/config/IBotConfig";
 import { IInRaidConfig } from "../models/spt/config/IInRaidConfig";
 import { IMatchConfig } from "../models/spt/config/IMatchConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
@@ -29,6 +30,7 @@ export declare class MatchController {
     protected applicationContext: ApplicationContext;
     protected matchConfig: IMatchConfig;
     protected inraidConfig: IInRaidConfig;
+    protected botConfig: IBotConfig;
     constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, applicationContext: ApplicationContext);
     getEnabled(): boolean;
     getProfile(info: IGetProfileRequestData): IPmcData[];
diff --git a/TypeScript/10ScopesAndTypes/types/controllers/QuestController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/QuestController.d.ts
index 2cbccfb..282f50e 100644
--- a/TypeScript/10ScopesAndTypes/types/controllers/QuestController.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/controllers/QuestController.d.ts
@@ -39,16 +39,31 @@ export declare class QuestController {
      * @returns array of IQuest
      */
     getClientQuests(sessionID: string): IQuest[];
+    /**
+     * Is the quest for the opposite side the player is on
+     * @param side player side (usec/bear)
+     * @param questId questId to check
+     */
+    protected questIsForOtherSide(side: string, questId: string): boolean;
+    /**
+     * Handle the client accepting a quest and starting it
+     * Send starting rewards if any to player and
+     * Send start notification if any to player
+     * @param pmcData Profile to update
+     * @param acceptedQuest Quest accepted
+     * @param sessionID Session id
+     * @returns client response
+     */
     acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Remove completed quest from profile
+     * Update completed quest in profile
      * Add newly unlocked quests to profile
      * Also recalculate thier level due to exp rewards
      * @param pmcData Player profile
-     * @param body completed quest request
-     * @param sessionID session id
-     * @returns ItemEvent response
+     * @param body Completed quest request
+     * @param sessionID Session id
+     * @returns ItemEvent client response
      */
     completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
@@ -67,10 +82,20 @@ export declare class QuestController {
     protected getQuestsFailedByCompletingQuest(completedQuestId: string): IQuest[];
     /**
      * Fail the quests provided
+     * Update quest in profile, otherwise add fresh quest object with failed status
      * @param sessionID session id
      * @param pmcData player profile
      * @param questsToFail quests to fail
      */
     protected failQuests(sessionID: string, pmcData: IPmcData, questsToFail: IQuest[]): void;
     handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment a backend counter stored value by an amount,
+     * Create counter if it does not exist
+     * @param pmcData Profile to find backend counter in
+     * @param conditionId backend counter id to update
+     * @param questId quest id counter is associated with
+     * @param counterValue value to increment the backend counter with
+     */
+    protected updateProfileBackendCounterValue(pmcData: IPmcData, conditionId: string, questId: string, counterValue: number): void;
 }
diff --git a/TypeScript/10ScopesAndTypes/types/controllers/RagfairController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/RagfairController.d.ts
index c4ffc15..06af740 100644
--- a/TypeScript/10ScopesAndTypes/types/controllers/RagfairController.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/controllers/RagfairController.d.ts
@@ -9,6 +9,7 @@ import { RagfairOfferHelper } from "../helpers/RagfairOfferHelper";
 import { RagfairSellHelper } from "../helpers/RagfairSellHelper";
 import { RagfairSortHelper } from "../helpers/RagfairSortHelper";
 import { RagfairTaxHelper } from "../helpers/RagfairTaxHelper";
+import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
@@ -33,6 +34,9 @@ import { RagfairPriceService } from "../services/RagfairPriceService";
 import { RagfairRequiredItemsService } from "../services/RagfairRequiredItemsService";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/**
+ * Handle RagfairCallback events
+ */
 export declare class RagfairController {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
@@ -52,14 +56,20 @@ export declare class RagfairController {
     protected handbookHelper: HandbookHelper;
     protected paymentHelper: PaymentHelper;
     protected inventoryHelper: InventoryHelper;
+    protected traderHelper: TraderHelper;
     protected ragfairHelper: RagfairHelper;
     protected ragfairOfferService: RagfairOfferService;
     protected ragfairRequiredItemsService: RagfairRequiredItemsService;
     protected ragfairOfferGenerator: RagfairOfferGenerator;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
     getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult;
+    /**
+     * Update a trader flea offer with buy restrictions stored in the traders assort
+     * @param offer flea offer to update
+     */
+    protected setTraderOfferPurchaseLimits(offer: IRagfairOffer): void;
     protected isLinkedSearch(info: ISearchRequestData): boolean;
     protected isRequiredSearch(info: ISearchRequestData): boolean;
     update(): void;
diff --git a/TypeScript/10ScopesAndTypes/types/controllers/RepeatableQuestController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/RepeatableQuestController.d.ts
index 98d05dd..4c31a3d 100644
--- a/TypeScript/10ScopesAndTypes/types/controllers/RepeatableQuestController.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/controllers/RepeatableQuestController.d.ts
@@ -7,6 +7,7 @@ import { Exit } from "../models/eft/common/ILocationBase";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { TraderInfo } from "../models/eft/common/tables/IBotBase";
 import { ICompletion, ICompletionAvailableFor, IElimination, IEliminationCondition, IExploration, IExplorationCondition, IPmcDataRepeatableQuest, IRepeatableQuest, IReward, IRewards } from "../models/eft/common/tables/IRepeatableQuests";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
 import { IRepeatableQuestChangeRequest } from "../models/eft/quests/IRepeatableQuestChangeRequest";
 import { ELocationName } from "../models/enums/ELocationName";
@@ -15,6 +16,7 @@ import { ILogger } from "../models/spt/utils/ILogger";
 import { ItemEventRouter } from "../routers/ItemEventRouter";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { PaymentService } from "../services/PaymentService";
 import { ProfileFixerService } from "../services/ProfileFixerService";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -64,9 +66,10 @@ export declare class RepeatableQuestController {
     protected itemEventRouter: ItemEventRouter;
     protected paymentService: PaymentService;
     protected objectId: ObjectId;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
-    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, configServer: ConfigServer);
+    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint
      * Returns an array of objects in the format of repeatable quests to the client.
@@ -217,4 +220,16 @@ export declare class RepeatableQuestController {
     debugLogRepeatableQuestIds(pmcData: IPmcData): void;
     probabilityObjectArray<K, V>(configArrayInput: ProbabilityObject<K, V>[]): ProbabilityObjectArray<K, V>;
     changeRepeatableQuest(pmcDataIn: IPmcData, body: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
+     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
+     */
+    protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig): [string, ITemplateItem][];
+    /**
+     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
+     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
+     * @param {*} tpl template id of item to check
+     * @returns boolean: true if item is valid reward
+     */
+    isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig): boolean;
 }
diff --git a/TypeScript/10ScopesAndTypes/types/controllers/TraderController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/TraderController.d.ts
index 0162064..b79f55e 100644
--- a/TypeScript/10ScopesAndTypes/types/controllers/TraderController.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/controllers/TraderController.d.ts
@@ -4,6 +4,7 @@ import { TraderHelper } from "../helpers/TraderHelper";
 import { IBarterScheme, ITraderAssort, ITraderBase } from "../models/eft/common/tables/ITrader";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { FenceService } from "../services/FenceService";
 import { TraderAssortService } from "../services/TraderAssortService";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
@@ -15,8 +16,9 @@ export declare class TraderController {
     protected traderHelper: TraderHelper;
     protected timeUtil: TimeUtil;
     protected traderAssortService: TraderAssortService;
+    protected fenceService: FenceService;
     protected jsonUtil: JsonUtil;
-    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, jsonUtil: JsonUtil);
+    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, fenceService: FenceService, jsonUtil: JsonUtil);
     /**
      * Runs when onLoad event is fired
      * Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
@@ -26,6 +28,7 @@ export declare class TraderController {
     /**
      * Runs when onUpdate is fired
      * If current time is > nextResupply(expire) time of trader, refresh traders assorts and
+     * Fence is handled slightly differently
      * @returns has run
      */
     update(): boolean;
diff --git a/TypeScript/10ScopesAndTypes/types/di/Container.d.ts b/TypeScript/10ScopesAndTypes/types/di/Container.d.ts
index 17791b0..98d1fa1 100644
--- a/TypeScript/10ScopesAndTypes/types/di/Container.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/di/Container.d.ts
@@ -1,4 +1,7 @@
 import { DependencyContainer } from "tsyringe";
+/**
+ * Handle the registration of classes to be used by the Dependency Injection code
+ */
 export declare class Container {
     static registerTypes(depContainer: DependencyContainer): void;
     static registerListTypes(depContainer: DependencyContainer): void;
diff --git a/TypeScript/10ScopesAndTypes/types/generators/BotGenerator.d.ts b/TypeScript/10ScopesAndTypes/types/generators/BotGenerator.d.ts
index a5fc0ad..7d58f95 100644
--- a/TypeScript/10ScopesAndTypes/types/generators/BotGenerator.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/generators/BotGenerator.d.ts
@@ -40,7 +40,7 @@ export declare class BotGenerator {
      * @param botTemplate base bot template to use  (e.g. assault/pmcbot)
      * @returns
      */
-    generatePlayerScav(role: string, difficulty: string, botTemplate: IBotType): IBotBase;
+    generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase;
     generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[];
     /**
      * Choose if a bot should become a PMC by checking if bot type is allowed to become a Pmc in botConfig.convertFromChances and doing a random int check
@@ -58,7 +58,7 @@ export declare class BotGenerator {
      * @returns IBotBase object
      */
     protected getCloneOfBotBase(): IBotBase;
-    protected generateBot(bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
+    protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
     /**
      * Log the number of PMCs generated to the debug console
      */
diff --git a/TypeScript/10ScopesAndTypes/types/generators/BotInventoryGenerator.d.ts b/TypeScript/10ScopesAndTypes/types/generators/BotInventoryGenerator.d.ts
index 35d1ee8..73f8ece 100644
--- a/TypeScript/10ScopesAndTypes/types/generators/BotInventoryGenerator.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/generators/BotInventoryGenerator.d.ts
@@ -18,7 +18,7 @@ export declare class BotInventoryGenerator {
     protected botGeneratorHelper: BotGeneratorHelper;
     protected weightedRandomHelper: WeightedRandomHelper;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper);
-    generateInventory(templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
+    generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
     protected generateEquipment(equipmentSlot: string, equipmentPool: Record<string, number>, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void;
     protected generateInventoryBase(): PmcInventory;
 }
diff --git a/TypeScript/10ScopesAndTypes/types/generators/BotLootGenerator.d.ts b/TypeScript/10ScopesAndTypes/types/generators/BotLootGenerator.d.ts
index c6a3f29..5a2d144 100644
--- a/TypeScript/10ScopesAndTypes/types/generators/BotLootGenerator.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/generators/BotLootGenerator.d.ts
@@ -24,7 +24,7 @@ export declare class BotLootGenerator {
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botLootCacheService: BotLootCacheService, configServer: ConfigServer);
-    generateLoot(templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
+    generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
     protected getRandomisedCount(min: number, max: number, nValue: number): number;
     /**
      * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached
@@ -47,7 +47,7 @@ export declare class BotLootGenerator {
      * @param botRole bots role, .e.g. pmcBot
      * @param isPmc are we generating for a pmc
      */
-    protected addLooseWeaponsToInventorySlot(botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
+    protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
     /**
      * Get a random item from the pool parameter using the biasedRandomNumber system
      * @param pool pool of items to pick an item from
diff --git a/TypeScript/10ScopesAndTypes/types/generators/BotWeaponGenerator.d.ts b/TypeScript/10ScopesAndTypes/types/generators/BotWeaponGenerator.d.ts
index 9215214..49fa7bf 100644
--- a/TypeScript/10ScopesAndTypes/types/generators/BotWeaponGenerator.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/generators/BotWeaponGenerator.d.ts
@@ -28,7 +28,18 @@ export declare class BotWeaponGenerator {
     protected botConfig: IBotConfig;
     constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer);
     /**
-     * Get a random weapon from a bots pool of weapons (weighted)
+     * Pick a random weapon based on weightings and generate a functional weapon
+     * @param equipmentSlot Primary/secondary/holster
+     * @param botTemplateInventory e.g. assault.json
+     * @param weaponParentId
+     * @param modChances
+     * @param botRole role of bot, e.g. assault/followerBully
+     * @param isPmc Is weapon generated for a pmc
+     * @returns GenerateWeaponResult object
+     */
+    generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    /**
+     * Get a random weighted weapon from a bots pool of weapons
      * @param equipmentSlot Primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
      * @returns weapon tpl
@@ -39,43 +50,24 @@ export declare class BotWeaponGenerator {
      * @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool())
      * @param equipmentSlot slot to fit into, primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
+     * @param weaponParentId ParentId of the weapon being generated
+     * @param modChances Dictionary of item types and % chance weapon will have that mod
+     * @param botRole e.g. assault/exusec
      * @param isPmc
      * @returns GenerateWeaponResult object
      */
-    generateWeaponByTpl(weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
     /**
-     * Generate an entirely random weapon
-     * @param equipmentSlot Primary/secondary/holster
-     * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
-     * @param isPmc
-     * @returns GenerateWeaponResult object
-     */
-    generateRandomWeapon(equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
-    /**
-     * Create array with weapon base as only element
-     * Add additional properties as required
-     * @param weaponTpl
-     * @param weaponParentId
-     * @param equipmentSlot
-     * @param weaponItemTemplate
+     * Create array with weapon base as only element and
+     * add additional properties based on weapon type
+     * @param weaponTpl Weapon tpl to create item with
+     * @param weaponParentId Weapons parent id
+     * @param equipmentSlot e.g. primary/secondary/holster
+     * @param weaponItemTemplate db template for weapon
      * @param botRole for durability values
-     * @returns
+     * @returns Base weapon item in array
      */
     constructWeaponBaseArray(weaponTpl: string, weaponParentId: string, equipmentSlot: string, weaponItemTemplate: ITemplateItem, botRole: string): Item[];
-    /**
-     * Add compatible magazines to an inventory based on a generated weapon
-     * @param weaponDetails
-     * @param magCounts
-     * @param inventory
-     * @param botRole the bot type we're getting generating extra mags for
-     */
-    addExtraMagazinesToInventory(weaponDetails: GenerateWeaponResult, magCounts: MinMax, inventory: PmcInventory, botRole: string): void;
     /**
      * Get the mods necessary to kit out a weapon to its preset level
      * @param weaponTpl weapon to find preset for
@@ -84,20 +76,32 @@ export declare class BotWeaponGenerator {
      * @returns array of weapon mods
      */
     protected getPresetWeaponMods(weaponTpl: string, equipmentSlot: string, weaponParentId: string, itemTemplate: ITemplateItem, botRole: string): Item[];
-    /** Checks if all required slots are occupied on a weapon and all it's mods */
+    /**
+     * Checks if all required slots are occupied on a weapon and all it's mods
+     * @param weaponItemArray Weapon + mods
+     * @returns true if valid
+     */
     protected isWeaponValid(weaponItemArray: Item[]): boolean;
     /**
      * Generates extra magazines or bullets (if magazine is internal) and adds them to TacticalVest and Pockets.
      * Additionally, adds extra bullets to SecuredContainer
-     * @param weaponMods
-     * @param weaponTemplate
-     * @param magCounts
-     * @param ammoTpl
-     * @param inventory
+     * @param weaponMods mods to attach to weapon
+     * @param weaponTemplate db template for weapon
+     * @param magCounts magazine count to add to inventory
+     * @param ammoTpl ammo templateId to add to magazines
+     * @param inventory inventory to add magazines to
      * @param botRole the bot type we're getting generating extra mags for
      * @returns
      */
-    protected generateExtraMagazines(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    addExtraMagazinesToInventory(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    /**
+     * Create a magazine using the parameters given
+     * @param magazineTpl Tpl of the magazine to create
+     * @param ammoTpl Ammo to add to magazine
+     * @param magTemplate template object of magazine
+     * @returns Item array
+     */
+    protected createMagazine(magazineTpl: string, ammoTpl: string, magTemplate: ITemplateItem): Item[];
     /**
      * Get a randomised number of bullets for a specific magazine
      * @param magCounts min and max count of magazines
@@ -138,10 +142,9 @@ export declare class BotWeaponGenerator {
      * Finds and return a compatible ammo tpl based on the bots ammo weightings (x.json/inventory/equipment/ammo)
      * @param ammo a list of ammo tpls the weapon can use
      * @param weaponTemplate the weapon we want to pick ammo for
-     * @param isPmc is the ammo being gathered for a pmc (runs pmc ammo filtering)
      * @returns an ammo tpl that works with the desired gun
      */
-    protected getCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem, isPmc: boolean): string;
+    protected getWeightedCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem): string;
     /**
      * Get a weapons compatible cartridge caliber
      * @param weaponTemplate Weapon to look up caliber of
diff --git a/TypeScript/10ScopesAndTypes/types/generators/LocationGenerator.d.ts b/TypeScript/10ScopesAndTypes/types/generators/LocationGenerator.d.ts
index bd368b5..cc61dcf 100644
--- a/TypeScript/10ScopesAndTypes/types/generators/LocationGenerator.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/generators/LocationGenerator.d.ts
@@ -3,10 +3,9 @@ import { GameEventHelper } from "../helpers/GameEventHelper";
 import { ItemHelper } from "../helpers/ItemHelper";
 import { PresetHelper } from "../helpers/PresetHelper";
 import { RagfairServerHelper } from "../helpers/RagfairServerHelper";
-import { ILooseLoot, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
+import { ILooseLoot, SpawnpointsForced, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IStaticAmmoDetails, IStaticContainerProps, IStaticForcedProps, IStaticLootDetails } from "../models/eft/common/tables/ILootBase";
-import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILocationConfig } from "../models/spt/config/ILocationConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
@@ -36,11 +35,19 @@ export declare class LocationGenerator {
     generateContainerLoot(containerIn: IStaticContainerProps, staticForced: IStaticForcedProps[], staticLootDist: Record<string, IStaticLootDetails>, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): IStaticContainerProps;
     protected getLooseLootMultiplerForLocation(location: string): number;
     protected getStaticLootMultiplerForLocation(location: string): number;
+    /**
+     * Create array of loose + forced loot using probability system
+     * @param dynamicLootDist
+     * @param staticAmmoDist
+     * @param locationName Location to generate loot for
+     * @returns Array of spawn points with loot in them
+     */
     generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): SpawnpointTemplate[];
+    /**
+     * Add forced spawn point loot into loot parameter array
+     * @param loot array to add forced loot to
+     * @param forcedSpawnPoints forced loot to add
+     */
+    protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[]): void;
     protected createItem(tpl: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, parentId?: string): IContainerItem;
-    protected getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
-    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
-    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
-    protected createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
-    protected createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
 }
diff --git a/TypeScript/10ScopesAndTypes/types/generators/LootGenerator.d.ts b/TypeScript/10ScopesAndTypes/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/10ScopesAndTypes/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/10ScopesAndTypes/types/generators/PMCLootGenerator.d.ts b/TypeScript/10ScopesAndTypes/types/generators/PMCLootGenerator.d.ts
index 64e6f7f..b9f2a83 100644
--- a/TypeScript/10ScopesAndTypes/types/generators/PMCLootGenerator.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/generators/PMCLootGenerator.d.ts
@@ -1,15 +1,21 @@
 import { ItemHelper } from "../helpers/ItemHelper";
-import { DatabaseServer } from "../servers/DatabaseServer";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+/**
+ * Handle the generation of dynamic PMC loot in pockets and backpacks
+ * and the removal of blacklisted items
+ */
 export declare class PMCLootGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected configServer: ConfigServer;
+    protected itemFilterService: ItemFilterService;
     protected pocketLootPool: string[];
     protected backpackLootPool: string[];
     protected botConfig: IBotConfig;
-    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer);
+    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer, itemFilterService: ItemFilterService);
     generatePMCPocketLootPool(): string[];
     generatePMCBackpackLootPool(): string[];
 }
diff --git a/TypeScript/10ScopesAndTypes/types/generators/ScavCaseRewardGenerator.d.ts b/TypeScript/10ScopesAndTypes/types/generators/ScavCaseRewardGenerator.d.ts
index c7d6ab7..89cb5c8 100644
--- a/TypeScript/10ScopesAndTypes/types/generators/ScavCaseRewardGenerator.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/generators/ScavCaseRewardGenerator.d.ts
@@ -8,9 +8,13 @@ import { RewardCountAndPriceDetails, ScavCaseRewardCountsAndPrices } from "../mo
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { RagfairPriceService } from "../services/RagfairPriceService";
 import { HashUtil } from "../utils/HashUtil";
 import { RandomUtil } from "../utils/RandomUtil";
+/**
+ * Handle the creation of randomised scav case rewards
+ */
 export declare class ScavCaseRewardGenerator {
     protected logger: ILogger;
     protected randomUtil: RandomUtil;
@@ -18,9 +22,10 @@ export declare class ScavCaseRewardGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected ragfairPriceService: RagfairPriceService;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected scavCaseConfig: IScavCaseConfig;
-    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, configServer: ConfigServer);
+    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Create an array of rewards that will be given to the player upon completing their scav case build
      * @param body client request
diff --git a/TypeScript/10ScopesAndTypes/types/generators/WeatherGenerator.d.ts b/TypeScript/10ScopesAndTypes/types/generators/WeatherGenerator.d.ts
index 44cecbb..8ddbe49 100644
--- a/TypeScript/10ScopesAndTypes/types/generators/WeatherGenerator.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/generators/WeatherGenerator.d.ts
@@ -1,7 +1,7 @@
 import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IWeatherData } from "../models/eft/weather/IWeatherData";
 import { IWeatherConfig } from "../models/spt/config/IWeatherConfig";
+import { ConfigServer } from "../servers/ConfigServer";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class WeatherGenerator {
@@ -21,11 +21,16 @@ export declare class WeatherGenerator {
     protected getAcceleratedTime(computedDate: Date): string;
     /**
      * Get current time formatted to fit BSGs requirement
-     * @param computedDate
+     * @param computedDate date to format into bsg style
      * @returns
      */
     protected getNormalTime(computedDate: Date): string;
-    generateWeather(data: IWeatherData): IWeatherData;
+    /**
+     * Return randomised Weather data
+     * @param weatherData weather input data
+     * @returns Randomised weather data
+     */
+    generateWeather(weatherData: IWeatherData): IWeatherData;
     protected getWeightedFog(): string;
     protected getWeightedRain(): number;
     protected getRandomFloat(node: string): number;
diff --git a/TypeScript/10ScopesAndTypes/types/helpers/AssortHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/AssortHelper.d.ts
index 15586b9..bfc157f 100644
--- a/TypeScript/10ScopesAndTypes/types/helpers/AssortHelper.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/helpers/AssortHelper.d.ts
@@ -17,7 +17,7 @@ export declare class AssortHelper {
      * @param assort assort items from a trader
      * @returns assort items minus locked quest assorts
      */
-    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort): ITraderAssort;
+    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort, flea?: boolean): ITraderAssort;
     /**
      * Remove assorts from a trader that have not been unlocked yet
      * @param pmcProfile player profile
@@ -32,5 +32,5 @@ export declare class AssortHelper {
      * @param itemID item id to remove from asort
      * @returns Modified assort
      */
-    removeItemFromAssort(assort: ITraderAssort, itemID: string): ITraderAssort;
+    removeItemFromAssort(assort: ITraderAssort, itemID: string, flea?: boolean): ITraderAssort;
 }
diff --git a/TypeScript/10ScopesAndTypes/types/helpers/BotGeneratorHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/BotGeneratorHelper.d.ts
index 3cd7256..eb0d215 100644
--- a/TypeScript/10ScopesAndTypes/types/helpers/BotGeneratorHelper.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/helpers/BotGeneratorHelper.d.ts
@@ -3,10 +3,12 @@ import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"
 import { Mods, ModsChances } from "../models/eft/common/tables/IBotType";
 import { Item, Repairable, Upd } from "../models/eft/common/tables/IItem";
 import { Grid, ITemplateItem, Slot } from "../models/eft/common/tables/ITemplateItem";
-import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
@@ -14,6 +16,7 @@ import { ContainerHelper } from "./ContainerHelper";
 import { InventoryHelper } from "./InventoryHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProbabilityHelper } from "./ProbabilityHelper";
+import { ProfileHelper } from "./ProfileHelper";
 export declare class BotGeneratorHelper {
     protected logger: ILogger;
     protected jsonUtil: JsonUtil;
@@ -25,10 +28,76 @@ export declare class BotGeneratorHelper {
     protected itemHelper: ItemHelper;
     protected inventoryHelper: InventoryHelper;
     protected containerHelper: ContainerHelper;
+    protected botEquipmentFilterService: BotEquipmentFilterService;
+    protected itemFilterService: ItemFilterService;
+    protected profileHelper: ProfileHelper;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, configServer: ConfigServer);
-    generateModsForItem(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, configServer: ConfigServer);
+    /**
+     * TODO - very similar to generateModsForWeapon
+     * Check mods are compatible and add to array
+     * @param equipment Equipment item to add mods to
+     * @param modPool Mod list to choose frm
+     * @param parentId parentid of item to add mod to
+     * @param parentTemplate template objet of item to add mods to
+     * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type
+     * @returns Item + compatible mods as an array
+     */
+    generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    /**
+     * TODO - very similar to generateModsForEquipment
+     * @param sessionId session id
+     * @param weapon Weapon to add mods to
+     * @param modPool pool of compatible mods to attach to gun
+     * @param weaponParentId parentId of weapon
+     * @param parentTemplate
+     * @param modSpawnChances
+     * @param ammoTpl ammo tpl to use when generating magazines/cartridges
+     * @param botRole role of bot weapon is generated for
+     * @returns Weapon with mods
+     */
+    generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[];
+    /**
+     * Generate a pool of mods for this bots mod type if bot has values inside `randomisedWeaponModSlots` array found in bot.json/equipment[botrole]
+     * @param allowedMods Mods to be added to mod pool
+     * @param botEquipBlacklist blacklist of items not allowed to be added to mod pool
+     * @param modSlot Slot to generate mods for
+     * @param itemModPool base mod pool to replace values of
+     */
+    protected generateDynamicModPool(allowedMods: string[], botEquipBlacklist: EquipmentFilterDetails, modSlot: string, itemModPool: Record<string, string[]>): void;
+    /**
+     * Check if the specific item type on the weapon has reached the set limit
+     * @param modTpl item to check is limited
+     * @param currentCount current number of this item on gun
+     * @param maxLimit mod limit allowed
+     * @param botRole role of bot we're checking weapon of
+     * @returns true if limit reached
+     */
+    protected weaponModLimitReached(modTpl: string, currentCount: {
+        count: number;
+    }, maxLimit: number, botRole: string): boolean;
+    /**
+     * log errors if mod is not valid for a slot
+     * @param modTpl
+     * @param found
+     * @param itemSlot
+     * @param modTemplate
+     * @param modSlot
+     * @param parentTemplate
+     * @returns true if valid
+     */
+    protected isModValidForSlot(modTpl: string, found: boolean, itemSlot: Slot, modTemplate: ITemplateItem, modSlot: string, parentTemplate: ITemplateItem): boolean;
+    /**
+     * Create a mod item with parameters as properties
+     * @param modId _id
+     * @param modTpl _tpl
+     * @param parentId parentId
+     * @param modSlot slotId
+     * @param modTemplate Used to add additional properites in the upd object
+     * @returns Item object
+     */
+    protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item;
     /**
      * Is this magazine cylinder related (revolvers and grenade launchers)
      * @param magazineParentName the name of the magazines parent
@@ -62,11 +131,11 @@ export declare class BotGeneratorHelper {
      * Those magazines (e.g. 60dc519adf4c47305f6d410d) have a "Cartridges" entry with a _max_count=0.
      * Ammo is not put into the magazine directly but assigned to the magazine's slots: The "camora_xxx" slots.
      * This function is a helper called by generateModsForItem for mods with parent type "CylinderMagazine"
-     *
-     * @param {object}      items               The items where the CylinderMagazine's camora are appended to
-     * @param {object}      modPool             modPool which should include available cartrigdes
-     * @param {string}      parentId            The CylinderMagazine's UID
-     * @param {object}      parentTemplate      The CylinderMagazine's template
+     * @param items The items where the CylinderMagazine's camora are appended to
+     * @param modPool modPool which should include available cartrigdes
+     * @param parentId The CylinderMagazine's UID
+     * @param parentTemplate The CylinderMagazine's template
+     * @returns
      */
     protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void;
     /**
@@ -75,6 +144,13 @@ export declare class BotGeneratorHelper {
      * @returns string array of shells fro luitple camora sources
      */
     protected mergeCamoraPoolsTogether(camorasWithShells: Record<string, string[]>): string[];
+    /**
+     * Adds properties to an item
+     * e.g. Repairable / HasHinge / Foldable / MaxDurability
+     * @param itemTemplate
+     * @param botRole Used by weapons to randomise the durability values
+     * @returns Item Upd object with extra properties
+     */
     generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): {
         upd?: Upd;
     };
@@ -93,12 +169,6 @@ export declare class BotGeneratorHelper {
      */
     protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable;
     protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string;
-    /**
-     * Sort by spawn chance, highest to lowest, higher is more common
-     * @param unsortedModArray String array to sort
-     * @returns Sorted string array
-     */
-    protected sortModArray(unsortedModArray: string[]): string[];
     /**
      * Can an item be added to an item without issue
      * @param items
@@ -117,8 +187,15 @@ export declare class BotGeneratorHelper {
      * @returns a `boolean` indicating item was added
      */
     addItemWithChildrenToEquipmentSlot(equipmentSlots: string[], parentId: string, parentTpl: string, itemWithChildren: Item[], inventory: PmcInventory): boolean;
+    /**
+     * is the provided item allowed inside a container
+     * @param slot location item wants to be placed in
+     * @param itemTpl item being placed
+     * @returns true if allowed
+     */
     protected itemAllowedInContainer(slot: Grid, itemTpl: string): boolean;
 }
+/** TODO - move into own class */
 export declare class ExhaustableArray<T> {
     private itemPool;
     private randomUtil;
diff --git a/TypeScript/10ScopesAndTypes/types/helpers/HideoutHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/HideoutHelper.d.ts
index 36e4009..7495a6a 100644
--- a/TypeScript/10ScopesAndTypes/types/helpers/HideoutHelper.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/helpers/HideoutHelper.d.ts
@@ -44,14 +44,72 @@ export declare class HideoutHelper {
     initProduction(recipeId: string, productionTime: number): Production;
     isProductionType(productive: Productive): productive is Production;
     applyPlayerUpgradesBonuses(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * TODO:
+     * After looking at the skills there doesnt seem to be a configuration per skill to boost
+     * the XP gain PER skill. I THINK you should be able to put the variable "SkillProgress" (just like health has it)
+     * and be able to tune the skill gain PER skill, but I havent tested it and Im not sure!
+     * @param pmcData
+     * @param bonus
+     */
     protected applySkillXPBoost(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * Process a players hideout, update areas that use resources + increment production timers
+     * @param sessionID Session id
+     */
     updatePlayerHideout(sessionID: string): void;
+    /**
+     * Update progress timer for water collector
+     * @param pmcData profile to update
+     * @param productionId id of water collection production to update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateWaterCollectorProductionTimer(pmcData: IPmcData, productionId: string, hideoutProperties: {
+        btcFarmCGs?: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Iterate over productions and update their progress timers
+     * @param pmcData Profile to check for productions and update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Update progress timer for scav case
+     * @param pmcData Profile to update
+     * @param productionId Id of scav case production to update
+     */
+    protected updateScavCaseProductionTimer(pmcData: IPmcData, productionId: string): void;
+    /**
+     * Iterate over hideout areas that use resources (fuel/filters etc) and update associated values
+     * @param sessionID Session id
+     * @param pmcData Profile to update areas of
+     * @param hideoutProperties hideout properties
+     */
+    protected updateAreasWithResources(sessionID: string, pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
     protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
     protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
-    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): HideoutArea;
-    protected updateWaterFilters(waterFilterArea: HideoutArea, pwProd: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
+    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): void;
+    /**
+     * Adjust water filter objects resourceValue or delete when they reach 0 resource
+     * @param waterFilterArea water filter area to update
+     * @param production production object
+     * @param isGeneratorOn is generatory enabled
+     * @param pmcData Player profile
+     * @returns Updated HideoutArea object
+     */
+    protected updateWaterFilters(waterFilterArea: HideoutArea, production: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
     protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
-    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): HideoutArea;
+    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): void;
     protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
     protected getBTCSlots(pmcData: IPmcData): number;
     protected getManagementSkillsSlots(): number;
diff --git a/TypeScript/10ScopesAndTypes/types/helpers/InRaidHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/InRaidHelper.d.ts
index b382e30..962df38 100644
--- a/TypeScript/10ScopesAndTypes/types/helpers/InRaidHelper.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/helpers/InRaidHelper.d.ts
@@ -18,18 +18,6 @@ export declare class InRaidHelper {
     protected paymentHelper: PaymentHelper;
     protected profileFixerService: ProfileFixerService;
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper, profileFixerService: ProfileFixerService);
-    /**
-     * Reset the SPT inraid property stored in a profile to 'none'
-     * @param sessionID Session id
-     */
-    protected removePlayer(sessionID: string): void;
-    /**
-     * Some maps have one-time-use keys (e.g. Labs
-     * Remove the relevant key from an inventory based on the post-raid request data passed in
-     * @param offraidData post-raid data
-     * @param sessionID Session id
-     */
-    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
     /**
      * Check an array of items and add an upd object to money items with a stack count of 1
      * Single stack money items have no upd object and thus no StackObjectsCount, causing issues
@@ -54,6 +42,18 @@ export declare class InRaidHelper {
      * @returns Reset profile object
      */
     updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData;
+    /**
+     * Some maps have one-time-use keys (e.g. Labs
+     * Remove the relevant key from an inventory based on the post-raid request data passed in
+     * @param offraidData post-raid data
+     * @param sessionID Session id
+     */
+    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Set the SPT inraid location Profile property to 'none'
+     * @param sessionID Session id
+     */
+    protected setPlayerInRaidLocationStatusToNone(sessionID: string): void;
     /**
      * Adds SpawnedInSession property to items found in a raid
      * Removes SpawnedInSession for non-scav players if item was taken into raid with SpawnedInSession = true
@@ -95,5 +95,10 @@ export declare class InRaidHelper {
      * @returns true if item is kept after death
      */
     isItemKeptAfterDeath(slotId: string): boolean;
+    /**
+     * Return the equipped items from a players inventory
+     * @param items Players inventory to search through
+     * @returns an array of equipped items
+     */
     getPlayerGear(items: Item[]): Item[];
 }
diff --git a/TypeScript/10ScopesAndTypes/types/helpers/ItemHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/ItemHelper.d.ts
index 1701c62..de10892 100644
--- a/TypeScript/10ScopesAndTypes/types/helpers/ItemHelper.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/helpers/ItemHelper.d.ts
@@ -1,35 +1,30 @@
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item, Repairable } from "../models/eft/common/tables/IItem";
+import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase";
 import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+import { MathUtil } from "../utils/MathUtil";
+import { ObjectId } from "../utils/ObjectId";
+import { RandomUtil } from "../utils/RandomUtil";
 declare class ItemHelper {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
     protected jsonUtil: JsonUtil;
+    protected randomUtil: RandomUtil;
+    protected objectId: ObjectId;
+    protected mathUtil: MathUtil;
     protected databaseServer: DatabaseServer;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer);
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer);
     /**
      * Checks if a id is a valid item. Valid meaning that it's an item that be stored in stash
      * @param       {string}    tpl       the template id / tpl
      * @returns                             boolean; true for items that may be in player posession and not quest items
      */
     isValidItem(tpl: string, invalidBaseTypes?: string[]): boolean;
-    /**
-     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
-     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
-     * @param {*} tpl template id of item to check
-     * @returns boolean: true if item is valid reward
-     */
-    isValidRewardItem(tpl: string): boolean;
-    /**
-     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
-     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
-     */
-    getRewardableItems(): [string, ITemplateItem][];
     /**
      * Check if the tpl / template Id provided is a descendent of the baseclass
      *
@@ -196,6 +191,22 @@ declare class ItemHelper {
      * @returns ItemSize object (width and height)
      */
     getItemSize(items: Item[], rootItemId: string): ItemHelper.ItemSize;
+    /**
+     * Get a random cartridge from an items Filter property
+     * @param item
+     * @returns
+     */
+    getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
+    createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
+    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
+    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
+    createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
+    /**
+     * Get the size of a stack, return 1 if no stack object count property found
+     * @param item Item to get stack size of
+     * @returns size of stack
+     */
+    getItemStackSize(item: Item): number;
 }
 declare namespace ItemHelper {
     interface ItemSize {
diff --git a/TypeScript/10ScopesAndTypes/types/helpers/ProfileHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/ProfileHelper.d.ts
index 9d4ff98..9c6560a 100644
--- a/TypeScript/10ScopesAndTypes/types/helpers/ProfileHelper.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/helpers/ProfileHelper.d.ts
@@ -24,6 +24,19 @@ export declare class ProfileHelper {
     constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, fenceService: FenceService);
     resetProfileQuestCondition(sessionID: string, conditionId: string): void;
     getCompleteProfile(sessionID: string): IPmcData[];
+    /**
+     * Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
+     * Server saves the post-raid changes prior to the xp screen getting the profile, this results in the xp screen using
+     * the now updated profile values as a base, meaning it shows x2 xp gained
+     * Instead, clone the post-raid profile (so we dont alter its values), apply the pre-raid xp values to the cloned objects and return
+     * Delete snapshot of pre-raid profile prior to returning profile data
+     * @param sessionId Session id
+     * @param output pmc and scav profiles array
+     * @param pmcProfile post-raid pmc profile
+     * @param scavProfile post-raid scav profile
+     * @returns updated profile array
+     */
+    protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
     isNicknameTaken(info: IValidateNicknameRequestData, sessionID: string): boolean;
     /**
      * Add experience to a PMC inside the players profile
diff --git a/TypeScript/10ScopesAndTypes/types/helpers/QuestHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/QuestHelper.d.ts
index 32e55ec..d66d150 100644
--- a/TypeScript/10ScopesAndTypes/types/helpers/QuestHelper.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/helpers/QuestHelper.d.ts
@@ -36,11 +36,20 @@ export declare class QuestHelper {
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
     constructor(logger: ILogger, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, itemHelper: ItemHelper, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, localeService: LocaleService, ragfairServerHelper: RagfairServerHelper, dialogueHelper: DialogueHelper, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, traderHelper: TraderHelper, configServer: ConfigServer);
-    questStatus(pmcData: IPmcData, questID: string): QuestStatus;
     /**
-     * returns true is the condition is satisfied
+    * Get status of a quest by quest id
+    * @param pmcData Profile to search
+    * @param questID Quest id to look up
+    * @returns QuestStauts enum
+    */
+    getQuestStatus(pmcData: IPmcData, questID: string): QuestStatus;
+    /**
+     * returns true is the level condition is satisfied
+     * @param playerLevel Players level
+     * @param condition Quest condition
+     * @returns true if player level is greater than or equal to quest
      */
-    evaluateLevel(pmcProfile: IPmcData, cond: AvailableForConditions): boolean;
+    doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean;
     getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[];
     /**
      * Increase skill points of a skill on player profile
diff --git a/TypeScript/10ScopesAndTypes/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/RagfairOfferHelper.d.ts
index 8d03bee..e9d72ca 100644
--- a/TypeScript/10ScopesAndTypes/types/helpers/RagfairOfferHelper.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/helpers/RagfairOfferHelper.d.ts
@@ -22,12 +22,14 @@ import { ProfileHelper } from "./ProfileHelper";
 import { RagfairHelper } from "./RagfairHelper";
 import { RagfairServerHelper } from "./RagfairServerHelper";
 import { RagfairSortHelper } from "./RagfairSortHelper";
+import { TraderHelper } from "./TraderHelper";
 export declare class RagfairOfferHelper {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
     protected hashUtil: HashUtil;
     protected itemEventRouter: ItemEventRouter;
     protected databaseServer: DatabaseServer;
+    protected traderHelper: TraderHelper;
     protected saveServer: SaveServer;
     protected dialogueHelper: DialogueHelper;
     protected itemHelper: ItemHelper;
@@ -43,10 +45,10 @@ export declare class RagfairOfferHelper {
     protected static goodSoldTemplate: string;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, traderHelper: TraderHelper, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
     getValidOffers(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
     getOffersForBuild(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
-    processOffers(sessionID: string): boolean;
+    processOffersOnProfile(sessionID: string): boolean;
     protected getProfileOffers(sessionID: string): IRagfairOffer[];
     protected deleteOfferByOfferId(sessionID: string, offerId: string): void;
     protected completeOffer(sessionID: string, offer: IRagfairOffer, boughtAmount: number): IItemEventRouterResponse;
diff --git a/TypeScript/10ScopesAndTypes/types/helpers/RagfairSellHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/RagfairSellHelper.d.ts
index 6ec004a..91b8a20 100644
--- a/TypeScript/10ScopesAndTypes/types/helpers/RagfairSellHelper.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/helpers/RagfairSellHelper.d.ts
@@ -11,6 +11,12 @@ export declare class RagfairSellHelper {
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     constructor(logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer);
-    calculateSellChance(baseChance: number, offerPrice: number, requirementsPriceInRub: number): number;
-    rollForSale(sellChance: number, count: number): SellResult[];
+    calculateSellChance(baseChancePercent: number, offerPriceRub: number, playerListedPriceRub: number): number;
+    /**
+     * Determine if the offer being listed will be sold
+     * @param sellChancePercent chance item will sell
+     * @param itemSellCount count of items to sell
+     * @returns Array of purchases of item(s) lsited
+     */
+    rollForSale(sellChancePercent: number, itemSellCount: number): SellResult[];
 }
diff --git a/TypeScript/10ScopesAndTypes/types/helpers/RagfairServerHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/RagfairServerHelper.d.ts
index e4939d1..a03cdda 100644
--- a/TypeScript/10ScopesAndTypes/types/helpers/RagfairServerHelper.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/helpers/RagfairServerHelper.d.ts
@@ -6,6 +6,7 @@ import { IRagfairConfig } from "../models/spt/config/IRagfairConfig";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { SaveServer } from "../servers/SaveServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { LocaleService } from "../services/LocaleService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -13,6 +14,9 @@ import { RandomUtil } from "../utils/RandomUtil";
 import { DialogueHelper } from "./DialogueHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProfileHelper } from "./ProfileHelper";
+/**
+ * Helper class for common ragfair server actions
+ */
 export declare class RagfairServerHelper {
     protected randomUtil: RandomUtil;
     protected hashUtil: HashUtil;
@@ -23,11 +27,12 @@ export declare class RagfairServerHelper {
     protected localeService: LocaleService;
     protected dialogueHelper: DialogueHelper;
     protected jsonUtil: JsonUtil;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
     protected static goodsReturnedTemplate: string;
-    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, configServer: ConfigServer);
+    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Is item valid / on blacklist / quest item
      * @param itemDetails
diff --git a/TypeScript/10ScopesAndTypes/types/helpers/TradeHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/TradeHelper.d.ts
index 975062b..7ab9768 100644
--- a/TypeScript/10ScopesAndTypes/types/helpers/TradeHelper.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/helpers/TradeHelper.d.ts
@@ -39,6 +39,12 @@ export declare class TradeHelper {
      * @returns
      */
     sellItem(pmcData: IPmcData, body: IProcessSellTradeRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment the assorts buy count by number of items purchased
+     * Show error on screen if player attepts to buy more than what the buy max allows
+     * @param assortBeingPurchased assort being bought
+     * @param itemsPurchasedCount number of items being bought
+     */
     protected incrementAssortBuyCount(assortBeingPurchased: Item, itemsPurchasedCount: number): void;
     protected checkPurchaseIsWithinTraderItemLimit(assortBeingPurchased: Item, assortId: string, count: number): void;
 }
diff --git a/TypeScript/10ScopesAndTypes/types/helpers/TraderAssortHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/TraderAssortHelper.d.ts
index 677dd66..025efd6 100644
--- a/TypeScript/10ScopesAndTypes/types/helpers/TraderAssortHelper.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/helpers/TraderAssortHelper.d.ts
@@ -1,6 +1,5 @@
 import { RagfairAssortGenerator } from "../generators/RagfairAssortGenerator";
 import { RagfairOfferGenerator } from "../generators/RagfairOfferGenerator";
-import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ITrader, ITraderAssort } from "../models/eft/common/tables/ITrader";
 import { ITraderConfig } from "../models/spt/config/ITraderConfig";
@@ -41,12 +40,7 @@ export declare class TraderAssortHelper {
      * @param traderId traders id
      * @returns a traders' assorts
      */
-    getAssort(sessionId: string, traderId: string): ITraderAssort;
-    /**
-     * if the fence assorts have expired, re-generate them
-     * @param pmcProfile Players profile
-     */
-    refreshFenceAssortIfExpired(pmcProfile: IPmcData): void;
+    getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort;
     /**
      * Reset a traders assorts and move nextResupply value to future
      * Flag trader as needing a flea offer reset to be picked up by flea update() function
diff --git a/TypeScript/10ScopesAndTypes/types/helpers/TraderHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/TraderHelper.d.ts
index 6bda5cd..0dc93e8 100644
--- a/TypeScript/10ScopesAndTypes/types/helpers/TraderHelper.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/helpers/TraderHelper.d.ts
@@ -65,7 +65,7 @@ export declare class TraderHelper {
      * @param item
      * @returns boolean
      */
-    protected isWeaponAndBelowTraderBuyDurability(traderID: string, item: Item): boolean;
+    protected isWeaponBelowTraderBuyDurability(traderID: string, item: Item): boolean;
     /**
      * Get the price of an item and all of its attached children
      * Take into account bonuses/adjsutments e.g. discounts
diff --git a/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/ITemplateItem.d.ts b/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/ITemplateItem.d.ts
index 23a1a14..6b2fa8f 100644
--- a/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/ITemplateItem.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/ITemplateItem.d.ts
@@ -34,6 +34,7 @@ export interface Props {
     LootExperience?: number;
     ExamineExperience?: number;
     HideEntrails?: boolean;
+    InsuranceDisabled?: boolean;
     RepairCost?: number;
     RepairSpeed?: number;
     ExtraSizeLeft?: number;
@@ -206,6 +207,7 @@ export interface Props {
     IsOneoff?: boolean;
     MustBoltBeOpennedForExternalReload?: boolean;
     MustBoltBeOpennedForInternalReload?: boolean;
+    NoFiremodeOnBoltcatch?: boolean;
     BoltAction?: boolean;
     HipAccuracyRestorationDelay?: number;
     HipAccuracyRestorationSpeed?: number;
diff --git a/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/ITrader.d.ts b/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/ITrader.d.ts
index a84f5af..37b2d61 100644
--- a/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/ITrader.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/ITrader.d.ts
@@ -67,6 +67,7 @@ export interface IBarterScheme {
     count: number;
     _tpl: string;
     onlyFunctional?: boolean;
+    sptQuestLocked?: boolean;
 }
 export interface ISuit {
     _id: string;
diff --git a/TypeScript/10ScopesAndTypes/types/models/eft/ragfair/IRagfairOffer.d.ts b/TypeScript/10ScopesAndTypes/types/models/eft/ragfair/IRagfairOffer.d.ts
index 63f655e..141b605 100644
--- a/TypeScript/10ScopesAndTypes/types/models/eft/ragfair/IRagfairOffer.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/models/eft/ragfair/IRagfairOffer.d.ts
@@ -15,6 +15,8 @@ export interface IRagfairOffer {
     name?: string;
     shortName?: string;
     loyaltyLevel: number;
+    buyRestrictionMax?: number;
+    buyRestrictionCurrent?: number;
     locked: boolean;
     unlimitedCount: boolean;
     summaryCost: number;
diff --git a/TypeScript/10ScopesAndTypes/types/models/enums/AmmoTypes.d.ts b/TypeScript/10ScopesAndTypes/types/models/enums/AmmoTypes.d.ts
index b52ddcf..254b410 100644
--- a/TypeScript/10ScopesAndTypes/types/models/enums/AmmoTypes.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/models/enums/AmmoTypes.d.ts
@@ -23,7 +23,7 @@ export declare enum Ammo762x54 {
     BT_GZH = "5e023d34e8a400319a28ed44",
     BS_GZH = "5e023d48186a883be655e551"
 }
-export declare enum Ammo338Lapua {
+export declare enum Ammo86x70 {
     TAC_X = "5fc382b6d6fa9c00c571bbc3",
     UCW = "5fc382c1016cce60e8341b20",
     AP = "5fc382a9d724d907e2077dab",
@@ -85,13 +85,13 @@ export declare enum Ammo9x21 {
     PE_GZH = "5a26ac06c4a282000c5a90a8",
     BT_GZH = "5a26ac0ec4a28200741e1e18"
 }
-export declare enum Ammo357Mag {
+export declare enum Ammo9x33R {
     FMJ = "62330b3ed4dc74626d570b95",
     HOLLOW_POINT = "62330bfadc5883093563729b",
     SOFT_POINT = "62330c40bdd19b369e1e53d1",
     JACKET_HP = "62330c18744e5e31df12f516"
 }
-export declare enum Ammo45ACP {
+export declare enum Ammo1143x23ACP {
     MATCH_FMJ = "5e81f423763d9f754677bf2e",
     HYDRA_SHOK = "5efb0fc6aeb21837e749c801",
     LASERMATCH_FMJ = "5efb0d4f4bc50b58e81710f3",
@@ -126,7 +126,7 @@ export declare enum Ammo556x45 {
     MK_318_MOD_0_SOST = "60194943740c5d77f6705eea",
     SSA_AP = "601949593ae8f707c4608daa"
 }
-export declare enum Ammo300Blackout {
+export declare enum Ammo762x35 {
     M62_TRACER = "619636be6db0f2477964e710",
     BCP_FMJ = "5fbe3ffdf8b6a877a729ea82",
     AP = "5fd20ff893a8961fc660a954",
diff --git a/TypeScript/10ScopesAndTypes/types/models/enums/BaseClasses.d.ts b/TypeScript/10ScopesAndTypes/types/models/enums/BaseClasses.d.ts
index e733bca..37c1398 100644
--- a/TypeScript/10ScopesAndTypes/types/models/enums/BaseClasses.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/models/enums/BaseClasses.d.ts
@@ -68,6 +68,7 @@ export declare enum BaseClasses {
     ASSAULT_SCOPE = "55818add4bdc2d5b648b456f",
     REFLEX_SIGHT = "55818ad54bdc2ddc698b4569",
     TACTICAL_COMBO = "55818b164bdc2ddc698b456c",
+    FLASHLIGHT = "55818b084bdc2d5b648b4571",
     MAGAZINE = "5448bc234bdc2d3c308b4569",
     LIGHT_LASER = "55818b0e4bdc2dde698b456e",
     FLASH_HIDER = "550aa4bf4bdc2dd6348b456b",
diff --git a/TypeScript/10ScopesAndTypes/types/models/enums/ConfigTypes.d.ts b/TypeScript/10ScopesAndTypes/types/models/enums/ConfigTypes.d.ts
index 61d6f99..468ece5 100644
--- a/TypeScript/10ScopesAndTypes/types/models/enums/ConfigTypes.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/models/enums/ConfigTypes.d.ts
@@ -8,6 +8,7 @@ export declare enum ConfigTypes {
     IN_RAID = "aki-inraid",
     INSURANCE = "aki-insurance",
     INVENTORY = "aki-inventory",
+    ITEM = "aki-item",
     LOCALE = "aki-locale",
     LOCATION = "aki-location",
     MATCH = "aki-match",
diff --git a/TypeScript/10ScopesAndTypes/types/models/enums/ELocationName.d.ts b/TypeScript/10ScopesAndTypes/types/models/enums/ELocationName.d.ts
index b56cc08..7ae7caa 100644
--- a/TypeScript/10ScopesAndTypes/types/models/enums/ELocationName.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/models/enums/ELocationName.d.ts
@@ -1,5 +1,6 @@
 export declare enum ELocationName {
     FACTORY_DAY = "factory4_day",
+    FACTORY_NIGHT = "factory4_night",
     BIGMAP = "bigmap",
     WOODS = "Woods",
     SHORELINE = "Shoreline",
diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/10ScopesAndTypes/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/config/IBotConfig.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/config/IBotConfig.d.ts
index e171087..f15fa73 100644
--- a/TypeScript/10ScopesAndTypes/types/models/spt/config/IBotConfig.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/models/spt/config/IBotConfig.d.ts
@@ -1,17 +1,31 @@
 import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
+import { IBotDurability } from "./IBotDurability";
+import { IPmcConfig } from "./IPmcConfig";
 export interface IBotConfig extends IBaseConfig {
     kind: "aki-bot";
+    /** How many variants of each bot should be generated on raid start */
     presetBatch: PresetBatch;
+    /** What bot types should be classified as bosses */
     bosses: string[];
-    durability: Durability;
+    /** Control weapon/armor durability min/max values for each bot type */
+    durability: IBotDurability;
+    /** Control the weighting of how expensive an average loot item is on a PMC or Scav */
     lootNValue: LootNvalue;
+    /** Control what bots are added to a bots revenge list key: bottype, value: bottypes to revenge on seeing their death */
     revenge: Record<string, string[]>;
-    pmc: PmcConfig;
+    /** PMC bot specific config settings */
+    pmc: IPmcConfig;
+    /** Control how many items are allowed to spawn on a bot
+     * key: bottype, value: <key: itemTpl: value: max item count> */
     itemSpawnLimits: Record<string, Record<string, number>>;
-    equipment: Record<string, Equipment>;
+    /** Blacklist/whitelist items on a bot */
+    equipment: Record<string, EquipmentFilters>;
+    /** Show a bots botType value after their name */
     showTypeInNickname: boolean;
+    /** Max number of bots that can be spawned in a raid at any one time */
     maxBotCap: number;
+    /** How many stacks of secret ammo should a bot have in its bot secure container */
     secureContainerAmmoStackCount: number;
 }
 export interface PresetBatch {
@@ -44,79 +58,22 @@ export interface PresetBatch {
     test: number;
     exUsec: number;
 }
-export interface Durability {
-    default: DefaultDurability;
-    pmc: PmcDurability;
-    boss: BotDurability;
-    follower: BotDurability;
-    assault: BotDurability;
-    cursedassault: BotDurability;
-    marksman: BotDurability;
-    pmcbot: BotDurability;
-    exusec: BotDurability;
-    sectantpriest: BotDurability;
-    sectantwarrior: BotDurability;
-}
-export interface DefaultDurability {
-    armor: DefaultArmor;
-    weapon: WeaponDurability;
-}
-export interface DefaultArmor {
-    maxDelta: number;
-    minDelta: number;
-}
-export interface WeaponDurability {
-    lowestMax: number;
-    highestMax: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface PmcDurability {
-    armor: PmcDurabilityArmor;
-    weapon: WeaponDurability;
-}
-export interface PmcDurabilityArmor {
-    lowestMaxPercent: number;
-    highestMaxPercent: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface BotDurability {
-    armor: ArmorDurability;
-    weapon: WeaponDurability;
-}
-export interface ArmorDurability {
-    maxDelta: number;
-    minDelta: number;
-}
 export interface LootNvalue {
     scav: number;
     pmc: number;
 }
-export interface PmcConfig {
-    dynamicLoot: PmcDynamicLoot;
-    difficulty: string;
-    looseWeaponInBackpackChancePercent: number;
-    looseWeaponInBackpackLootMinMax: MinMax;
-    isUsec: number;
-    chanceSameSideIsHostilePercent: number;
-    usecType: string;
-    bearType: string;
-    maxBackpackLootTotalRub: number;
-    maxPocketLootTotalRub: number;
-    maxVestLootTotalRub: number;
-    convertIntoPmcChance: Record<string, MinMax>;
-    enemyTypes: string[];
-}
-export interface PmcDynamicLoot {
-    whitelist: string[];
-    blacklist: string[];
-    moneyStackLimits: Record<string, number>;
-}
-export interface Equipment {
+export interface EquipmentFilters {
+    weaponModLimits: ModLimits;
+    randomisedWeaponModSlots?: string[];
     blacklist: EquipmentFilterDetails[];
     whitelist: EquipmentFilterDetails[];
 }
+export interface ModLimits {
+    /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */
+    scopeLimit?: number;
+    /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */
+    lightLaserLimit?: number;
+}
 export interface EquipmentFilterDetails {
     levelRange: MinMax;
     equipment: Record<string, string[]>;
diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/config/IBotDurability.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/config/IBotDurability.d.ts
new file mode 100644
index 0000000..38a47cc
--- /dev/null
+++ b/TypeScript/10ScopesAndTypes/types/models/spt/config/IBotDurability.d.ts
@@ -0,0 +1,47 @@
+export interface IBotDurability {
+    default: DefaultDurability;
+    pmc: PmcDurability;
+    boss: BotDurability;
+    follower: BotDurability;
+    assault: BotDurability;
+    cursedassault: BotDurability;
+    marksman: BotDurability;
+    pmcbot: BotDurability;
+    exusec: BotDurability;
+    gifter: BotDurability;
+    sectantpriest: BotDurability;
+    sectantwarrior: BotDurability;
+}
+/** Durability values to be used when a more specific bot type cant be found */
+export interface DefaultDurability {
+    armor: DefaultArmor;
+    weapon: WeaponDurability;
+}
+export interface DefaultArmor {
+    maxDelta: number;
+    minDelta: number;
+}
+export interface WeaponDurability {
+    lowestMax: number;
+    highestMax: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface PmcDurability {
+    armor: PmcDurabilityArmor;
+    weapon: WeaponDurability;
+}
+export interface PmcDurabilityArmor {
+    lowestMaxPercent: number;
+    highestMaxPercent: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface BotDurability {
+    armor: ArmorDurability;
+    weapon: WeaponDurability;
+}
+export interface ArmorDurability {
+    maxDelta: number;
+    minDelta: number;
+}
diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/config/IItemConfig.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/config/IItemConfig.d.ts
new file mode 100644
index 0000000..5ecccc2
--- /dev/null
+++ b/TypeScript/10ScopesAndTypes/types/models/spt/config/IItemConfig.d.ts
@@ -0,0 +1,5 @@
+import { IBaseConfig } from "./IBaseConfig";
+export interface IItemConfig extends IBaseConfig {
+    kind: "aki-item";
+    blacklist: string[];
+}
diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/config/IPmcConfig.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/config/IPmcConfig.d.ts
new file mode 100644
index 0000000..655b58d
--- /dev/null
+++ b/TypeScript/10ScopesAndTypes/types/models/spt/config/IPmcConfig.d.ts
@@ -0,0 +1,22 @@
+import { MinMax } from "../../common/MinMax";
+export interface IPmcConfig {
+    dynamicLoot: DynamicLoot;
+    useDifficultyOverride: boolean;
+    difficulty: string;
+    looseWeaponInBackpackChancePercent: number;
+    looseWeaponInBackpackLootMinMax: MinMax;
+    isUsec: number;
+    chanceSameSideIsHostilePercent: number;
+    usecType: string;
+    bearType: string;
+    maxBackpackLootTotalRub: number;
+    maxPocketLootTotalRub: number;
+    maxVestLootTotalRub: number;
+    convertIntoPmcChance: Record<string, MinMax>;
+    enemyTypes: string[];
+}
+export interface DynamicLoot {
+    whitelist: string[];
+    blacklist: string[];
+    moneyStackLimits: Record<string, number>;
+}
diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/config/IQuestConfig.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/config/IQuestConfig.d.ts
index be4a97b..45c9aae 100644
--- a/TypeScript/10ScopesAndTypes/types/models/spt/config/IQuestConfig.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/models/spt/config/IQuestConfig.d.ts
@@ -4,6 +4,8 @@ export interface IQuestConfig extends IBaseConfig {
     kind: "aki-quest";
     redeemTime: number;
     repeatableQuests: IRepeatableQuestConfig[];
+    bearOnlyQuests: string[];
+    usecOnlyQuests: string[];
 }
 export interface IRepeatableQuestConfig {
     name: string;
@@ -15,6 +17,10 @@ export interface IRepeatableQuestConfig {
     locations: Record<ELocationName, string[]>;
     traderWhitelist: ITraderWhitelist[];
     questConfig: IQuestConfig;
+    /** Item base types to block when generating rewards */
+    rewardBaseTypeBlacklist: string[];
+    /** Item tplIds to ignore when generating rewards */
+    rewardBlacklist: string[];
 }
 export interface IRewardScaling {
     levels: number[];
diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/config/IRagfairConfig.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/config/IRagfairConfig.d.ts
index 6369eda..3088717 100644
--- a/TypeScript/10ScopesAndTypes/types/models/spt/config/IRagfairConfig.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/models/spt/config/IRagfairConfig.d.ts
@@ -12,6 +12,7 @@ export interface Sell {
     chance: Chance;
     time: Time;
     reputation: Reputation;
+    simulatedSellHours: number;
 }
 export interface Chance {
     base: number;
diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/config/ITraderConfig.d.ts
index c8e8044..6b1c1e3 100644
--- a/TypeScript/10ScopesAndTypes/types/models/spt/config/ITraderConfig.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/models/spt/config/ITraderConfig.d.ts
@@ -12,8 +12,10 @@ export interface UpdateTime {
     seconds: number;
 }
 export interface FenceConfig {
+    partialRefreshTimeSeconds: number;
+    partialRefreshChangePercent: number;
     assortSize: number;
-    maxPresetsCount: number;
+    maxPresetsPercent: number;
     presetPriceMult: number;
     blacklist: string[];
 }
diff --git a/TypeScript/1LogToConsole/types/models/spt/location/AirDropLootItem.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/services/LootItem.d.ts
similarity index 54%
rename from TypeScript/1LogToConsole/types/models/spt/location/AirDropLootItem.d.ts
rename to TypeScript/10ScopesAndTypes/types/models/spt/services/LootItem.d.ts
index da791ff..2838472 100644
--- a/TypeScript/1LogToConsole/types/models/spt/location/AirDropLootItem.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/models/spt/services/LootItem.d.ts
@@ -1,5 +1,4 @@
-export declare class AirDropLootItem {
-    id: string;
+export declare class LootItem {
     tpl: string;
     isPreset: boolean;
     stackCount: number;
diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/services/LootRequest.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/10ScopesAndTypes/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/10ScopesAndTypes/types/services/BotEquipmentFilterService.d.ts b/TypeScript/10ScopesAndTypes/types/services/BotEquipmentFilterService.d.ts
index e49645b..632f961 100644
--- a/TypeScript/10ScopesAndTypes/types/services/BotEquipmentFilterService.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/services/BotEquipmentFilterService.d.ts
@@ -1,12 +1,12 @@
 import { IBotType } from "../models/eft/common/tables/IBotType";
-import { Equipment, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 export declare class BotEquipmentFilterService {
     protected logger: ILogger;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    protected botEquipmentFilterlists: Record<string, Equipment>;
+    protected botEquipmentFilterlists: Record<string, EquipmentFilters>;
     constructor(logger: ILogger, configServer: ConfigServer);
     /**
      * Filter a bots data to exclude equipment and cartridges defines in the botConfig
@@ -22,7 +22,7 @@ export declare class BotEquipmentFilterService {
      * @param playerLevel Level of the player
      * @returns EquipmentBlacklistDetails object
      */
-    protected getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
+    getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
     /**
      * Get the whitelist for a specific bot type that's within the players level
      * @param botRole Bot type
diff --git a/TypeScript/10ScopesAndTypes/types/services/FenceService.d.ts b/TypeScript/10ScopesAndTypes/types/services/FenceService.d.ts
index c9e325e..c940507 100644
--- a/TypeScript/10ScopesAndTypes/types/services/FenceService.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/services/FenceService.d.ts
@@ -12,6 +12,11 @@ import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+import { ItemFilterService } from "./ItemFilterService";
+/**
+ * Handle actions surrounding Fence
+ * e.g. generating or refreshing assorts / get next refresh time
+ */
 export declare class FenceService {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
@@ -22,18 +27,64 @@ export declare class FenceService {
     protected handbookHelper: HandbookHelper;
     protected itemHelper: ItemHelper;
     protected presetHelper: PresetHelper;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected fenceAssort: ITraderAssort;
     protected traderConfig: ITraderConfig;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, configServer: ConfigServer);
+    protected nextMiniRefreshTimestamp: number;
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, itemFilterService: ItemFilterService, configServer: ConfigServer);
     protected setFenceAssort(fenceAssort: ITraderAssort): void;
-    getFenceAssorts(): ITraderAssort;
+    /**
+     * Get assorts player can purchase
+     * Adjust prices based on fence level of player
+     * @param pmcProfile Player profile
+     * @returns ITraderAssort
+     */
+    getFenceAssorts(pmcProfile: IPmcData): ITraderAssort;
+    /**
+     * Get fence assorts with no price adjustments based on fence rep
+     * @returns ITraderAssort
+     */
+    getRawFenceAssorts(): ITraderAssort;
+    /**
+     * Does fence need to perform a partial refresh because its passed the refresh timer defined in trader.json
+     * @returns true if it needs a partial refresh
+     */
+    needsPartialRefresh(): boolean;
+    /**
+     * Replace a percentage of fence assorts with freshly generated items
+     */
+    performPartialRefresh(): void;
+    /**
+     * Choose an item (not mod) at random and remove from assorts
+     */
+    protected removeRandomItemFromAssorts(): void;
+    /**
+     * Get an integer rounded count of items to replace based on percentrage from traderConfig value
+     * @param totalItemCount total item count
+     * @returns rounded int of items to replace
+     */
+    protected getCountOfItemsToReplace(totalItemCount: number): number;
     /**
      * Get the count of items fence offers
      * @returns number
      */
     getOfferCount(): number;
-    generateFenceAssortCache(pmcData: IPmcData): void;
+    /**
+     * Create a trader assort for fence
+     */
+    generateFenceAssortCache(): void;
+    /**
+     * Create skeleton to hold assort items
+     * @returns ITraderAssort object
+     */
+    protected createBaseTraderAssortItem(): ITraderAssort;
+    /**
+     * Hydrate result parameter object with generated assorts
+     * @param assortCount Number of assorts to generate
+     * @param assorts object to add assorts to
+     */
+    protected createAssorts(assortCount: number, assorts: ITraderAssort): void;
     /**
      * Get the next update timestamp for fence
      * @returns future timestamp
@@ -44,11 +95,14 @@ export declare class FenceService {
      */
     protected getFenceRefreshTime(): number;
     /**
-     * Get the fence level the passed in profile has
+     * Get fence level the passed in profile has
      * @param pmcData Player profile
-     * @returns FenceLevel
+     * @returns FenceLevel object
      */
     getFenceInfo(pmcData: IPmcData): FenceLevel;
+    /**
+     * Remove an assort from fence by id
+     * @param assortIdToRemove assort id to remove from fence assorts
+     */
     removeFenceOffer(assortIdToRemove: string): void;
-    updateFenceOffers(pmcData: IPmcData): void;
 }
diff --git a/TypeScript/10ScopesAndTypes/types/services/InsuranceService.d.ts b/TypeScript/10ScopesAndTypes/types/services/InsuranceService.d.ts
index 171bf10..6be8a2f 100644
--- a/TypeScript/10ScopesAndTypes/types/services/InsuranceService.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/services/InsuranceService.d.ts
@@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
 import { SecureContainerHelper } from "../helpers/SecureContainerHelper";
 import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
+import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData";
 import { IInsuranceConfig } from "../models/spt/config/IInsuranceConfig";
@@ -44,8 +45,22 @@ export declare class InsuranceService {
      * @param mapId Id of the map player died/exited that caused the insurance to be issued on
      */
     sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void;
+    /**
+     * Store lost gear post-raid inside profile
+     * @param pmcData player profile to store gear in
+     * @param offraidData post-raid request object
+     * @param preRaidGear gear player wore prior to raid
+     * @param sessionID Session id
+     */
     storeLostGear(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
     storeInsuredItemsForReturn(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
-    protected addGearToSend(pmcData: IPmcData, insuredItem: any, actualItem: any, sessionID: string): any;
+    /**
+     * Add gear item to InsuredItems array in player profile
+     * @param pmcData profile to store item in
+     * @param insuredItem Item to store in profile
+     * @param actualItem item to store
+     * @param sessionID Session id
+     */
+    protected addGearToSend(pmcData: IPmcData, insuredItem: InsuredItem, actualItem: Item, sessionID: string): void;
     getPremium(pmcData: IPmcData, inventoryItem: Item, traderId: string): number;
 }
diff --git a/TypeScript/10ScopesAndTypes/types/services/ItemFilterService.d.ts b/TypeScript/10ScopesAndTypes/types/services/ItemFilterService.d.ts
new file mode 100644
index 0000000..c9c8ef3
--- /dev/null
+++ b/TypeScript/10ScopesAndTypes/types/services/ItemFilterService.d.ts
@@ -0,0 +1,24 @@
+import { IItemConfig } from "../models/spt/config/IItemConfig";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+/** Centralise the handling of blacklisting items, uses blacklist found in config/item.json */
+export declare class ItemFilterService {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected configServer: ConfigServer;
+    protected blacklist: string[];
+    protected itemConfig: IItemConfig;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer);
+    /**
+     * Check if the provided template id is blacklisted in config/item.json
+     * @param tpl template id
+     * @returns true if blacklisted
+     */
+    isItemBlacklisted(tpl: string): boolean;
+    /**
+     * Return every template id blacklisted in config/item.json
+     * @returns string array of blacklisted tempalte ids
+     */
+    getBlacklistedItems(): string[];
+}
diff --git a/TypeScript/10ScopesAndTypes/types/services/ProfileFixerService.d.ts b/TypeScript/10ScopesAndTypes/types/services/ProfileFixerService.d.ts
index ed1dec7..9cb5a38 100644
--- a/TypeScript/10ScopesAndTypes/types/services/ProfileFixerService.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/services/ProfileFixerService.d.ts
@@ -45,6 +45,11 @@ export declare class ProfileFixerService {
      * @param pmcProfile Profile to find and remove slots from
      */
     protected removeResourcesFromSlotsInHideoutWithoutLocationIndexValue(pmcProfile: IPmcData): void;
+    /**
+     * Hideout slots need to be in a specific order, locationIndex in ascending order
+     * @param pmcProfile profile to edit
+     */
+    protected reorderHideoutAreasWithResouceInputs(pmcProfile: IPmcData): void;
     /**
      * add in objects equal to the number of slots
      * @param areaType area to check
diff --git a/TypeScript/10ScopesAndTypes/types/utils/HashUtil.d.ts b/TypeScript/10ScopesAndTypes/types/utils/HashUtil.d.ts
index bacbf2a..a8500e1 100644
--- a/TypeScript/10ScopesAndTypes/types/utils/HashUtil.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/utils/HashUtil.d.ts
@@ -4,8 +4,18 @@ import { TimeUtil } from "./TimeUtil";
 export declare class HashUtil {
     protected timeUtil: TimeUtil;
     constructor(timeUtil: TimeUtil);
+    /**
+     * Create a 24 character id using the sha256 algorithm + current timestamp
+     * @returns 24 character hash
+     */
     generate(): string;
     generateMd5ForData(data: string): string;
     generateSha1ForData(data: string): string;
+    /**
+     * Create a hash for the data parameter
+     * @param algorithm algorithm to use to hash
+     * @param data data to be hashed
+     * @returns hash value
+     */
     generateHashForData(algorithm: string, data: crypto.BinaryLike): string;
 }
diff --git a/TypeScript/10ScopesAndTypes/types/utils/RandomUtil.d.ts b/TypeScript/10ScopesAndTypes/types/utils/RandomUtil.d.ts
index c24dd60..e35d21f 100644
--- a/TypeScript/10ScopesAndTypes/types/utils/RandomUtil.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/utils/RandomUtil.d.ts
@@ -150,4 +150,10 @@ export declare class RandomUtil {
      */
     drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[];
     getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number;
+    /**
+     * Fisher-Yates shuffle an array
+     * @param array Array to shuffle
+     * @returns Shuffled array
+     */
+    shuffle<T>(array: Array<T>): Array<T>;
 }
diff --git a/TypeScript/10ScopesAndTypes/types/utils/TimeUtil.d.ts b/TypeScript/10ScopesAndTypes/types/utils/TimeUtil.d.ts
index f437f8a..1367e26 100644
--- a/TypeScript/10ScopesAndTypes/types/utils/TimeUtil.d.ts
+++ b/TypeScript/10ScopesAndTypes/types/utils/TimeUtil.d.ts
@@ -1,3 +1,6 @@
+/**
+ * Utility class to handle time related problems
+ */
 export declare class TimeUtil {
     static readonly oneHourAsSeconds = 3600;
     formatTime(date: Date): string;
@@ -19,4 +22,10 @@ export declare class TimeUtil {
      * @returns current date in format: 00.00.0000 (dd.mm.yyyy)
      */
     getDateMailFormat(): string;
+    /**
+     * Convert hours into seconds
+     * @param hours hours to convert to seconds
+     * @returns number
+     */
+    getHoursAsSeconds(hours: number): number;
 }
diff --git a/TypeScript/11BundleLoadingSample/types/callbacks/LocationCallbacks.d.ts b/TypeScript/11BundleLoadingSample/types/callbacks/LocationCallbacks.d.ts
index cc69369..6e0b538 100644
--- a/TypeScript/11BundleLoadingSample/types/callbacks/LocationCallbacks.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/callbacks/LocationCallbacks.d.ts
@@ -11,4 +11,5 @@ export declare class LocationCallbacks {
     constructor(httpResponse: HttpResponseUtil, locationController: LocationController);
     getLocationData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<ILocationsGenerateAllResponse>;
     getLocation(url: string, info: IGetLocationRequestData, sessionID: string): IGetBodyResponseData<ILocationBase>;
+    getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): string;
 }
diff --git a/TypeScript/11BundleLoadingSample/types/callbacks/ProfileCallbacks.d.ts b/TypeScript/11BundleLoadingSample/types/callbacks/ProfileCallbacks.d.ts
index 6a86fc0..183bb0a 100644
--- a/TypeScript/11BundleLoadingSample/types/callbacks/ProfileCallbacks.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/callbacks/ProfileCallbacks.d.ts
@@ -1,5 +1,6 @@
 import { ProfileController } from "../controllers/ProfileController";
 import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData";
+import { IPmcData } from "../models/eft/common/IPmcData";
 import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData";
 import { INullResponseData } from "../models/eft/httpResponse/INullResponseData";
 import { IGetMiniProfileRequestData } from "../models/eft/launcher/IGetMiniProfileRequestData";
@@ -12,20 +13,51 @@ import { ISearchFriendResponse } from "../models/eft/profile/ISearchFriendRespon
 import { IValidateNicknameRequestData } from "../models/eft/profile/IValidateNicknameRequestData";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/** Handle profile related client events */
 export declare class ProfileCallbacks {
     protected httpResponse: HttpResponseUtil;
     protected timeUtil: TimeUtil;
     protected profileController: ProfileController;
     constructor(httpResponse: HttpResponseUtil, timeUtil: TimeUtil, profileController: ProfileController);
     createProfile(url: string, info: IProfileCreateRequestData, sessionID: string): IGetBodyResponseData<any>;
-    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
-    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
+    /**
+     * Get the complete player profile (scav + pmc character)
+     * @param url
+     * @param info Empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle the creation of a scav profile for player
+     * Occurs post-raid and when profile first created immediately after character details are confirmed by player
+     * @param url
+     * @param info empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle client/game/profile/voice/change event
+     * @param url
+     * @param info Change voice request object
+     * @param sessionID Session id
+     * @returns Client response
+     */
     changeVoice(url: string, info: IProfileChangeVoiceRequestData, sessionID: string): INullResponseData;
+    /**
+     * Handle client/game/profile/nickname/change event
+     * Client allows player to adjust their profile name
+     * @param url
+     * @param info Change nickname request object
+     * @param sessionID Session id
+     * @returns client response
+     */
     changeNickname(url: string, info: IProfileChangeNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     validateNickname(url: string, info: IValidateNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     getReservedNickname(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<string>;
     /**
-     * Called when creating a character, when you choose a character face/voice
+     * Called when creating a character when choosing a character face/voice
      * @param url
      * @param info response (empty)
      * @param sessionID
diff --git a/TypeScript/11BundleLoadingSample/types/callbacks/RagfairCallbacks.d.ts b/TypeScript/11BundleLoadingSample/types/callbacks/RagfairCallbacks.d.ts
index 3a405c9..c609f2f 100644
--- a/TypeScript/11BundleLoadingSample/types/callbacks/RagfairCallbacks.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/callbacks/RagfairCallbacks.d.ts
@@ -19,6 +19,9 @@ import { ConfigServer } from "../servers/ConfigServer";
 import { RagfairServer } from "../servers/RagfairServer";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+/**
+ * Handle ragfair related callback events
+ */
 export declare class RagfairCallbacks extends OnLoadOnUpdate {
     protected httpResponse: HttpResponseUtil;
     protected logger: ILogger;
diff --git a/TypeScript/11BundleLoadingSample/types/controllers/InraidController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/InraidController.d.ts
index 82bb64d..102a2fb 100644
--- a/TypeScript/11BundleLoadingSample/types/controllers/InraidController.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/controllers/InraidController.d.ts
@@ -35,6 +35,30 @@ export declare class InraidController {
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer);
     addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void;
     saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Handle updating the profile post-pmc raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Reduce body part hp to % of max
+     * @param pmcData profile to edit
+     * @param multipler multipler to apply to max health
+     */
+    protected reducePmcHealthToPercent(pmcData: IPmcData, multipler: number): void;
+    /**
+     * Handle updating the profile post-pscav raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePlayerScavProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Is the player dead after a raid - dead is anything other than "survived" / "runner"
+     * @param statusOnExit exit value from offraidData object
+     * @returns true if dead
+     */
+    protected isPlayerDead(statusOnExit: string): boolean;
     /**
      * Mark inventory items as FiR if player survived raid, otherwise remove FiR from them
      * @param offraidData Save Progress Request
diff --git a/TypeScript/11BundleLoadingSample/types/controllers/InventoryController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/InventoryController.d.ts
index f57f731..f564919 100644
--- a/TypeScript/11BundleLoadingSample/types/controllers/InventoryController.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/controllers/InventoryController.d.ts
@@ -92,7 +92,11 @@ export declare class InventoryController {
      */
     toggleItem(pmcData: IPmcData, body: IInventoryToggleRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Handles Tagging of items (primary Containers).
+     * Add a tag to an inventory item
+     * @param pmcData profile with item to add tag to
+     * @param body tag request data
+     * @param sessionID session id
+     * @returns client response object
      */
     tagItem(pmcData: IPmcData, body: IInventoryTagRequestData, sessionID: string): IItemEventRouterResponse;
     bindItem(pmcData: IPmcData, body: IInventoryBindRequestData, sessionID: string): IItemEventRouterResponse;
diff --git a/TypeScript/11BundleLoadingSample/types/controllers/LocationController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/LocationController.d.ts
index 90b6d7a..9db3205 100644
--- a/TypeScript/11BundleLoadingSample/types/controllers/LocationController.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/controllers/LocationController.d.ts
@@ -1,18 +1,33 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class LocationController {
     protected jsonUtil: JsonUtil;
+    protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/11BundleLoadingSample/types/controllers/MatchController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/MatchController.d.ts
index e8585d9..cb40023 100644
--- a/TypeScript/11BundleLoadingSample/types/controllers/MatchController.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/controllers/MatchController.d.ts
@@ -9,6 +9,7 @@ import { IGetProfileRequestData } from "../models/eft/match/IGetProfileRequestDa
 import { IJoinMatchRequestData } from "../models/eft/match/IJoinMatchRequestData";
 import { IJoinMatchResult } from "../models/eft/match/IJoinMatchResult";
 import { IStartOfflineRaidRequestData } from "../models/eft/match/IStartOffineRaidRequestData";
+import { IBotConfig } from "../models/spt/config/IBotConfig";
 import { IInRaidConfig } from "../models/spt/config/IInRaidConfig";
 import { IMatchConfig } from "../models/spt/config/IMatchConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
@@ -29,6 +30,7 @@ export declare class MatchController {
     protected applicationContext: ApplicationContext;
     protected matchConfig: IMatchConfig;
     protected inraidConfig: IInRaidConfig;
+    protected botConfig: IBotConfig;
     constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, applicationContext: ApplicationContext);
     getEnabled(): boolean;
     getProfile(info: IGetProfileRequestData): IPmcData[];
diff --git a/TypeScript/11BundleLoadingSample/types/controllers/QuestController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/QuestController.d.ts
index 2cbccfb..282f50e 100644
--- a/TypeScript/11BundleLoadingSample/types/controllers/QuestController.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/controllers/QuestController.d.ts
@@ -39,16 +39,31 @@ export declare class QuestController {
      * @returns array of IQuest
      */
     getClientQuests(sessionID: string): IQuest[];
+    /**
+     * Is the quest for the opposite side the player is on
+     * @param side player side (usec/bear)
+     * @param questId questId to check
+     */
+    protected questIsForOtherSide(side: string, questId: string): boolean;
+    /**
+     * Handle the client accepting a quest and starting it
+     * Send starting rewards if any to player and
+     * Send start notification if any to player
+     * @param pmcData Profile to update
+     * @param acceptedQuest Quest accepted
+     * @param sessionID Session id
+     * @returns client response
+     */
     acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Remove completed quest from profile
+     * Update completed quest in profile
      * Add newly unlocked quests to profile
      * Also recalculate thier level due to exp rewards
      * @param pmcData Player profile
-     * @param body completed quest request
-     * @param sessionID session id
-     * @returns ItemEvent response
+     * @param body Completed quest request
+     * @param sessionID Session id
+     * @returns ItemEvent client response
      */
     completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
@@ -67,10 +82,20 @@ export declare class QuestController {
     protected getQuestsFailedByCompletingQuest(completedQuestId: string): IQuest[];
     /**
      * Fail the quests provided
+     * Update quest in profile, otherwise add fresh quest object with failed status
      * @param sessionID session id
      * @param pmcData player profile
      * @param questsToFail quests to fail
      */
     protected failQuests(sessionID: string, pmcData: IPmcData, questsToFail: IQuest[]): void;
     handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment a backend counter stored value by an amount,
+     * Create counter if it does not exist
+     * @param pmcData Profile to find backend counter in
+     * @param conditionId backend counter id to update
+     * @param questId quest id counter is associated with
+     * @param counterValue value to increment the backend counter with
+     */
+    protected updateProfileBackendCounterValue(pmcData: IPmcData, conditionId: string, questId: string, counterValue: number): void;
 }
diff --git a/TypeScript/11BundleLoadingSample/types/controllers/RagfairController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/RagfairController.d.ts
index c4ffc15..06af740 100644
--- a/TypeScript/11BundleLoadingSample/types/controllers/RagfairController.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/controllers/RagfairController.d.ts
@@ -9,6 +9,7 @@ import { RagfairOfferHelper } from "../helpers/RagfairOfferHelper";
 import { RagfairSellHelper } from "../helpers/RagfairSellHelper";
 import { RagfairSortHelper } from "../helpers/RagfairSortHelper";
 import { RagfairTaxHelper } from "../helpers/RagfairTaxHelper";
+import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
@@ -33,6 +34,9 @@ import { RagfairPriceService } from "../services/RagfairPriceService";
 import { RagfairRequiredItemsService } from "../services/RagfairRequiredItemsService";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/**
+ * Handle RagfairCallback events
+ */
 export declare class RagfairController {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
@@ -52,14 +56,20 @@ export declare class RagfairController {
     protected handbookHelper: HandbookHelper;
     protected paymentHelper: PaymentHelper;
     protected inventoryHelper: InventoryHelper;
+    protected traderHelper: TraderHelper;
     protected ragfairHelper: RagfairHelper;
     protected ragfairOfferService: RagfairOfferService;
     protected ragfairRequiredItemsService: RagfairRequiredItemsService;
     protected ragfairOfferGenerator: RagfairOfferGenerator;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
     getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult;
+    /**
+     * Update a trader flea offer with buy restrictions stored in the traders assort
+     * @param offer flea offer to update
+     */
+    protected setTraderOfferPurchaseLimits(offer: IRagfairOffer): void;
     protected isLinkedSearch(info: ISearchRequestData): boolean;
     protected isRequiredSearch(info: ISearchRequestData): boolean;
     update(): void;
diff --git a/TypeScript/11BundleLoadingSample/types/controllers/RepeatableQuestController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/RepeatableQuestController.d.ts
index 98d05dd..4c31a3d 100644
--- a/TypeScript/11BundleLoadingSample/types/controllers/RepeatableQuestController.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/controllers/RepeatableQuestController.d.ts
@@ -7,6 +7,7 @@ import { Exit } from "../models/eft/common/ILocationBase";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { TraderInfo } from "../models/eft/common/tables/IBotBase";
 import { ICompletion, ICompletionAvailableFor, IElimination, IEliminationCondition, IExploration, IExplorationCondition, IPmcDataRepeatableQuest, IRepeatableQuest, IReward, IRewards } from "../models/eft/common/tables/IRepeatableQuests";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
 import { IRepeatableQuestChangeRequest } from "../models/eft/quests/IRepeatableQuestChangeRequest";
 import { ELocationName } from "../models/enums/ELocationName";
@@ -15,6 +16,7 @@ import { ILogger } from "../models/spt/utils/ILogger";
 import { ItemEventRouter } from "../routers/ItemEventRouter";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { PaymentService } from "../services/PaymentService";
 import { ProfileFixerService } from "../services/ProfileFixerService";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -64,9 +66,10 @@ export declare class RepeatableQuestController {
     protected itemEventRouter: ItemEventRouter;
     protected paymentService: PaymentService;
     protected objectId: ObjectId;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
-    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, configServer: ConfigServer);
+    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint
      * Returns an array of objects in the format of repeatable quests to the client.
@@ -217,4 +220,16 @@ export declare class RepeatableQuestController {
     debugLogRepeatableQuestIds(pmcData: IPmcData): void;
     probabilityObjectArray<K, V>(configArrayInput: ProbabilityObject<K, V>[]): ProbabilityObjectArray<K, V>;
     changeRepeatableQuest(pmcDataIn: IPmcData, body: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
+     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
+     */
+    protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig): [string, ITemplateItem][];
+    /**
+     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
+     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
+     * @param {*} tpl template id of item to check
+     * @returns boolean: true if item is valid reward
+     */
+    isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig): boolean;
 }
diff --git a/TypeScript/11BundleLoadingSample/types/controllers/TraderController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/TraderController.d.ts
index 0162064..b79f55e 100644
--- a/TypeScript/11BundleLoadingSample/types/controllers/TraderController.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/controllers/TraderController.d.ts
@@ -4,6 +4,7 @@ import { TraderHelper } from "../helpers/TraderHelper";
 import { IBarterScheme, ITraderAssort, ITraderBase } from "../models/eft/common/tables/ITrader";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { FenceService } from "../services/FenceService";
 import { TraderAssortService } from "../services/TraderAssortService";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
@@ -15,8 +16,9 @@ export declare class TraderController {
     protected traderHelper: TraderHelper;
     protected timeUtil: TimeUtil;
     protected traderAssortService: TraderAssortService;
+    protected fenceService: FenceService;
     protected jsonUtil: JsonUtil;
-    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, jsonUtil: JsonUtil);
+    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, fenceService: FenceService, jsonUtil: JsonUtil);
     /**
      * Runs when onLoad event is fired
      * Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
@@ -26,6 +28,7 @@ export declare class TraderController {
     /**
      * Runs when onUpdate is fired
      * If current time is > nextResupply(expire) time of trader, refresh traders assorts and
+     * Fence is handled slightly differently
      * @returns has run
      */
     update(): boolean;
diff --git a/TypeScript/11BundleLoadingSample/types/di/Container.d.ts b/TypeScript/11BundleLoadingSample/types/di/Container.d.ts
index 17791b0..98d1fa1 100644
--- a/TypeScript/11BundleLoadingSample/types/di/Container.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/di/Container.d.ts
@@ -1,4 +1,7 @@
 import { DependencyContainer } from "tsyringe";
+/**
+ * Handle the registration of classes to be used by the Dependency Injection code
+ */
 export declare class Container {
     static registerTypes(depContainer: DependencyContainer): void;
     static registerListTypes(depContainer: DependencyContainer): void;
diff --git a/TypeScript/11BundleLoadingSample/types/generators/BotGenerator.d.ts b/TypeScript/11BundleLoadingSample/types/generators/BotGenerator.d.ts
index a5fc0ad..7d58f95 100644
--- a/TypeScript/11BundleLoadingSample/types/generators/BotGenerator.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/generators/BotGenerator.d.ts
@@ -40,7 +40,7 @@ export declare class BotGenerator {
      * @param botTemplate base bot template to use  (e.g. assault/pmcbot)
      * @returns
      */
-    generatePlayerScav(role: string, difficulty: string, botTemplate: IBotType): IBotBase;
+    generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase;
     generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[];
     /**
      * Choose if a bot should become a PMC by checking if bot type is allowed to become a Pmc in botConfig.convertFromChances and doing a random int check
@@ -58,7 +58,7 @@ export declare class BotGenerator {
      * @returns IBotBase object
      */
     protected getCloneOfBotBase(): IBotBase;
-    protected generateBot(bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
+    protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
     /**
      * Log the number of PMCs generated to the debug console
      */
diff --git a/TypeScript/11BundleLoadingSample/types/generators/BotInventoryGenerator.d.ts b/TypeScript/11BundleLoadingSample/types/generators/BotInventoryGenerator.d.ts
index 35d1ee8..73f8ece 100644
--- a/TypeScript/11BundleLoadingSample/types/generators/BotInventoryGenerator.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/generators/BotInventoryGenerator.d.ts
@@ -18,7 +18,7 @@ export declare class BotInventoryGenerator {
     protected botGeneratorHelper: BotGeneratorHelper;
     protected weightedRandomHelper: WeightedRandomHelper;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper);
-    generateInventory(templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
+    generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
     protected generateEquipment(equipmentSlot: string, equipmentPool: Record<string, number>, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void;
     protected generateInventoryBase(): PmcInventory;
 }
diff --git a/TypeScript/11BundleLoadingSample/types/generators/BotLootGenerator.d.ts b/TypeScript/11BundleLoadingSample/types/generators/BotLootGenerator.d.ts
index c6a3f29..5a2d144 100644
--- a/TypeScript/11BundleLoadingSample/types/generators/BotLootGenerator.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/generators/BotLootGenerator.d.ts
@@ -24,7 +24,7 @@ export declare class BotLootGenerator {
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botLootCacheService: BotLootCacheService, configServer: ConfigServer);
-    generateLoot(templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
+    generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
     protected getRandomisedCount(min: number, max: number, nValue: number): number;
     /**
      * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached
@@ -47,7 +47,7 @@ export declare class BotLootGenerator {
      * @param botRole bots role, .e.g. pmcBot
      * @param isPmc are we generating for a pmc
      */
-    protected addLooseWeaponsToInventorySlot(botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
+    protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
     /**
      * Get a random item from the pool parameter using the biasedRandomNumber system
      * @param pool pool of items to pick an item from
diff --git a/TypeScript/11BundleLoadingSample/types/generators/BotWeaponGenerator.d.ts b/TypeScript/11BundleLoadingSample/types/generators/BotWeaponGenerator.d.ts
index 9215214..49fa7bf 100644
--- a/TypeScript/11BundleLoadingSample/types/generators/BotWeaponGenerator.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/generators/BotWeaponGenerator.d.ts
@@ -28,7 +28,18 @@ export declare class BotWeaponGenerator {
     protected botConfig: IBotConfig;
     constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer);
     /**
-     * Get a random weapon from a bots pool of weapons (weighted)
+     * Pick a random weapon based on weightings and generate a functional weapon
+     * @param equipmentSlot Primary/secondary/holster
+     * @param botTemplateInventory e.g. assault.json
+     * @param weaponParentId
+     * @param modChances
+     * @param botRole role of bot, e.g. assault/followerBully
+     * @param isPmc Is weapon generated for a pmc
+     * @returns GenerateWeaponResult object
+     */
+    generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    /**
+     * Get a random weighted weapon from a bots pool of weapons
      * @param equipmentSlot Primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
      * @returns weapon tpl
@@ -39,43 +50,24 @@ export declare class BotWeaponGenerator {
      * @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool())
      * @param equipmentSlot slot to fit into, primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
+     * @param weaponParentId ParentId of the weapon being generated
+     * @param modChances Dictionary of item types and % chance weapon will have that mod
+     * @param botRole e.g. assault/exusec
      * @param isPmc
      * @returns GenerateWeaponResult object
      */
-    generateWeaponByTpl(weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
     /**
-     * Generate an entirely random weapon
-     * @param equipmentSlot Primary/secondary/holster
-     * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
-     * @param isPmc
-     * @returns GenerateWeaponResult object
-     */
-    generateRandomWeapon(equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
-    /**
-     * Create array with weapon base as only element
-     * Add additional properties as required
-     * @param weaponTpl
-     * @param weaponParentId
-     * @param equipmentSlot
-     * @param weaponItemTemplate
+     * Create array with weapon base as only element and
+     * add additional properties based on weapon type
+     * @param weaponTpl Weapon tpl to create item with
+     * @param weaponParentId Weapons parent id
+     * @param equipmentSlot e.g. primary/secondary/holster
+     * @param weaponItemTemplate db template for weapon
      * @param botRole for durability values
-     * @returns
+     * @returns Base weapon item in array
      */
     constructWeaponBaseArray(weaponTpl: string, weaponParentId: string, equipmentSlot: string, weaponItemTemplate: ITemplateItem, botRole: string): Item[];
-    /**
-     * Add compatible magazines to an inventory based on a generated weapon
-     * @param weaponDetails
-     * @param magCounts
-     * @param inventory
-     * @param botRole the bot type we're getting generating extra mags for
-     */
-    addExtraMagazinesToInventory(weaponDetails: GenerateWeaponResult, magCounts: MinMax, inventory: PmcInventory, botRole: string): void;
     /**
      * Get the mods necessary to kit out a weapon to its preset level
      * @param weaponTpl weapon to find preset for
@@ -84,20 +76,32 @@ export declare class BotWeaponGenerator {
      * @returns array of weapon mods
      */
     protected getPresetWeaponMods(weaponTpl: string, equipmentSlot: string, weaponParentId: string, itemTemplate: ITemplateItem, botRole: string): Item[];
-    /** Checks if all required slots are occupied on a weapon and all it's mods */
+    /**
+     * Checks if all required slots are occupied on a weapon and all it's mods
+     * @param weaponItemArray Weapon + mods
+     * @returns true if valid
+     */
     protected isWeaponValid(weaponItemArray: Item[]): boolean;
     /**
      * Generates extra magazines or bullets (if magazine is internal) and adds them to TacticalVest and Pockets.
      * Additionally, adds extra bullets to SecuredContainer
-     * @param weaponMods
-     * @param weaponTemplate
-     * @param magCounts
-     * @param ammoTpl
-     * @param inventory
+     * @param weaponMods mods to attach to weapon
+     * @param weaponTemplate db template for weapon
+     * @param magCounts magazine count to add to inventory
+     * @param ammoTpl ammo templateId to add to magazines
+     * @param inventory inventory to add magazines to
      * @param botRole the bot type we're getting generating extra mags for
      * @returns
      */
-    protected generateExtraMagazines(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    addExtraMagazinesToInventory(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    /**
+     * Create a magazine using the parameters given
+     * @param magazineTpl Tpl of the magazine to create
+     * @param ammoTpl Ammo to add to magazine
+     * @param magTemplate template object of magazine
+     * @returns Item array
+     */
+    protected createMagazine(magazineTpl: string, ammoTpl: string, magTemplate: ITemplateItem): Item[];
     /**
      * Get a randomised number of bullets for a specific magazine
      * @param magCounts min and max count of magazines
@@ -138,10 +142,9 @@ export declare class BotWeaponGenerator {
      * Finds and return a compatible ammo tpl based on the bots ammo weightings (x.json/inventory/equipment/ammo)
      * @param ammo a list of ammo tpls the weapon can use
      * @param weaponTemplate the weapon we want to pick ammo for
-     * @param isPmc is the ammo being gathered for a pmc (runs pmc ammo filtering)
      * @returns an ammo tpl that works with the desired gun
      */
-    protected getCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem, isPmc: boolean): string;
+    protected getWeightedCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem): string;
     /**
      * Get a weapons compatible cartridge caliber
      * @param weaponTemplate Weapon to look up caliber of
diff --git a/TypeScript/11BundleLoadingSample/types/generators/LocationGenerator.d.ts b/TypeScript/11BundleLoadingSample/types/generators/LocationGenerator.d.ts
index bd368b5..cc61dcf 100644
--- a/TypeScript/11BundleLoadingSample/types/generators/LocationGenerator.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/generators/LocationGenerator.d.ts
@@ -3,10 +3,9 @@ import { GameEventHelper } from "../helpers/GameEventHelper";
 import { ItemHelper } from "../helpers/ItemHelper";
 import { PresetHelper } from "../helpers/PresetHelper";
 import { RagfairServerHelper } from "../helpers/RagfairServerHelper";
-import { ILooseLoot, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
+import { ILooseLoot, SpawnpointsForced, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IStaticAmmoDetails, IStaticContainerProps, IStaticForcedProps, IStaticLootDetails } from "../models/eft/common/tables/ILootBase";
-import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILocationConfig } from "../models/spt/config/ILocationConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
@@ -36,11 +35,19 @@ export declare class LocationGenerator {
     generateContainerLoot(containerIn: IStaticContainerProps, staticForced: IStaticForcedProps[], staticLootDist: Record<string, IStaticLootDetails>, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): IStaticContainerProps;
     protected getLooseLootMultiplerForLocation(location: string): number;
     protected getStaticLootMultiplerForLocation(location: string): number;
+    /**
+     * Create array of loose + forced loot using probability system
+     * @param dynamicLootDist
+     * @param staticAmmoDist
+     * @param locationName Location to generate loot for
+     * @returns Array of spawn points with loot in them
+     */
     generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): SpawnpointTemplate[];
+    /**
+     * Add forced spawn point loot into loot parameter array
+     * @param loot array to add forced loot to
+     * @param forcedSpawnPoints forced loot to add
+     */
+    protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[]): void;
     protected createItem(tpl: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, parentId?: string): IContainerItem;
-    protected getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
-    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
-    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
-    protected createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
-    protected createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
 }
diff --git a/TypeScript/11BundleLoadingSample/types/generators/LootGenerator.d.ts b/TypeScript/11BundleLoadingSample/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/11BundleLoadingSample/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/11BundleLoadingSample/types/generators/PMCLootGenerator.d.ts b/TypeScript/11BundleLoadingSample/types/generators/PMCLootGenerator.d.ts
index 64e6f7f..b9f2a83 100644
--- a/TypeScript/11BundleLoadingSample/types/generators/PMCLootGenerator.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/generators/PMCLootGenerator.d.ts
@@ -1,15 +1,21 @@
 import { ItemHelper } from "../helpers/ItemHelper";
-import { DatabaseServer } from "../servers/DatabaseServer";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+/**
+ * Handle the generation of dynamic PMC loot in pockets and backpacks
+ * and the removal of blacklisted items
+ */
 export declare class PMCLootGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected configServer: ConfigServer;
+    protected itemFilterService: ItemFilterService;
     protected pocketLootPool: string[];
     protected backpackLootPool: string[];
     protected botConfig: IBotConfig;
-    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer);
+    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer, itemFilterService: ItemFilterService);
     generatePMCPocketLootPool(): string[];
     generatePMCBackpackLootPool(): string[];
 }
diff --git a/TypeScript/11BundleLoadingSample/types/generators/ScavCaseRewardGenerator.d.ts b/TypeScript/11BundleLoadingSample/types/generators/ScavCaseRewardGenerator.d.ts
index c7d6ab7..89cb5c8 100644
--- a/TypeScript/11BundleLoadingSample/types/generators/ScavCaseRewardGenerator.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/generators/ScavCaseRewardGenerator.d.ts
@@ -8,9 +8,13 @@ import { RewardCountAndPriceDetails, ScavCaseRewardCountsAndPrices } from "../mo
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { RagfairPriceService } from "../services/RagfairPriceService";
 import { HashUtil } from "../utils/HashUtil";
 import { RandomUtil } from "../utils/RandomUtil";
+/**
+ * Handle the creation of randomised scav case rewards
+ */
 export declare class ScavCaseRewardGenerator {
     protected logger: ILogger;
     protected randomUtil: RandomUtil;
@@ -18,9 +22,10 @@ export declare class ScavCaseRewardGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected ragfairPriceService: RagfairPriceService;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected scavCaseConfig: IScavCaseConfig;
-    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, configServer: ConfigServer);
+    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Create an array of rewards that will be given to the player upon completing their scav case build
      * @param body client request
diff --git a/TypeScript/11BundleLoadingSample/types/generators/WeatherGenerator.d.ts b/TypeScript/11BundleLoadingSample/types/generators/WeatherGenerator.d.ts
index 44cecbb..8ddbe49 100644
--- a/TypeScript/11BundleLoadingSample/types/generators/WeatherGenerator.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/generators/WeatherGenerator.d.ts
@@ -1,7 +1,7 @@
 import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IWeatherData } from "../models/eft/weather/IWeatherData";
 import { IWeatherConfig } from "../models/spt/config/IWeatherConfig";
+import { ConfigServer } from "../servers/ConfigServer";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class WeatherGenerator {
@@ -21,11 +21,16 @@ export declare class WeatherGenerator {
     protected getAcceleratedTime(computedDate: Date): string;
     /**
      * Get current time formatted to fit BSGs requirement
-     * @param computedDate
+     * @param computedDate date to format into bsg style
      * @returns
      */
     protected getNormalTime(computedDate: Date): string;
-    generateWeather(data: IWeatherData): IWeatherData;
+    /**
+     * Return randomised Weather data
+     * @param weatherData weather input data
+     * @returns Randomised weather data
+     */
+    generateWeather(weatherData: IWeatherData): IWeatherData;
     protected getWeightedFog(): string;
     protected getWeightedRain(): number;
     protected getRandomFloat(node: string): number;
diff --git a/TypeScript/11BundleLoadingSample/types/helpers/AssortHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/AssortHelper.d.ts
index 15586b9..bfc157f 100644
--- a/TypeScript/11BundleLoadingSample/types/helpers/AssortHelper.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/helpers/AssortHelper.d.ts
@@ -17,7 +17,7 @@ export declare class AssortHelper {
      * @param assort assort items from a trader
      * @returns assort items minus locked quest assorts
      */
-    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort): ITraderAssort;
+    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort, flea?: boolean): ITraderAssort;
     /**
      * Remove assorts from a trader that have not been unlocked yet
      * @param pmcProfile player profile
@@ -32,5 +32,5 @@ export declare class AssortHelper {
      * @param itemID item id to remove from asort
      * @returns Modified assort
      */
-    removeItemFromAssort(assort: ITraderAssort, itemID: string): ITraderAssort;
+    removeItemFromAssort(assort: ITraderAssort, itemID: string, flea?: boolean): ITraderAssort;
 }
diff --git a/TypeScript/11BundleLoadingSample/types/helpers/BotGeneratorHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/BotGeneratorHelper.d.ts
index 3cd7256..eb0d215 100644
--- a/TypeScript/11BundleLoadingSample/types/helpers/BotGeneratorHelper.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/helpers/BotGeneratorHelper.d.ts
@@ -3,10 +3,12 @@ import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"
 import { Mods, ModsChances } from "../models/eft/common/tables/IBotType";
 import { Item, Repairable, Upd } from "../models/eft/common/tables/IItem";
 import { Grid, ITemplateItem, Slot } from "../models/eft/common/tables/ITemplateItem";
-import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
@@ -14,6 +16,7 @@ import { ContainerHelper } from "./ContainerHelper";
 import { InventoryHelper } from "./InventoryHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProbabilityHelper } from "./ProbabilityHelper";
+import { ProfileHelper } from "./ProfileHelper";
 export declare class BotGeneratorHelper {
     protected logger: ILogger;
     protected jsonUtil: JsonUtil;
@@ -25,10 +28,76 @@ export declare class BotGeneratorHelper {
     protected itemHelper: ItemHelper;
     protected inventoryHelper: InventoryHelper;
     protected containerHelper: ContainerHelper;
+    protected botEquipmentFilterService: BotEquipmentFilterService;
+    protected itemFilterService: ItemFilterService;
+    protected profileHelper: ProfileHelper;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, configServer: ConfigServer);
-    generateModsForItem(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, configServer: ConfigServer);
+    /**
+     * TODO - very similar to generateModsForWeapon
+     * Check mods are compatible and add to array
+     * @param equipment Equipment item to add mods to
+     * @param modPool Mod list to choose frm
+     * @param parentId parentid of item to add mod to
+     * @param parentTemplate template objet of item to add mods to
+     * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type
+     * @returns Item + compatible mods as an array
+     */
+    generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    /**
+     * TODO - very similar to generateModsForEquipment
+     * @param sessionId session id
+     * @param weapon Weapon to add mods to
+     * @param modPool pool of compatible mods to attach to gun
+     * @param weaponParentId parentId of weapon
+     * @param parentTemplate
+     * @param modSpawnChances
+     * @param ammoTpl ammo tpl to use when generating magazines/cartridges
+     * @param botRole role of bot weapon is generated for
+     * @returns Weapon with mods
+     */
+    generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[];
+    /**
+     * Generate a pool of mods for this bots mod type if bot has values inside `randomisedWeaponModSlots` array found in bot.json/equipment[botrole]
+     * @param allowedMods Mods to be added to mod pool
+     * @param botEquipBlacklist blacklist of items not allowed to be added to mod pool
+     * @param modSlot Slot to generate mods for
+     * @param itemModPool base mod pool to replace values of
+     */
+    protected generateDynamicModPool(allowedMods: string[], botEquipBlacklist: EquipmentFilterDetails, modSlot: string, itemModPool: Record<string, string[]>): void;
+    /**
+     * Check if the specific item type on the weapon has reached the set limit
+     * @param modTpl item to check is limited
+     * @param currentCount current number of this item on gun
+     * @param maxLimit mod limit allowed
+     * @param botRole role of bot we're checking weapon of
+     * @returns true if limit reached
+     */
+    protected weaponModLimitReached(modTpl: string, currentCount: {
+        count: number;
+    }, maxLimit: number, botRole: string): boolean;
+    /**
+     * log errors if mod is not valid for a slot
+     * @param modTpl
+     * @param found
+     * @param itemSlot
+     * @param modTemplate
+     * @param modSlot
+     * @param parentTemplate
+     * @returns true if valid
+     */
+    protected isModValidForSlot(modTpl: string, found: boolean, itemSlot: Slot, modTemplate: ITemplateItem, modSlot: string, parentTemplate: ITemplateItem): boolean;
+    /**
+     * Create a mod item with parameters as properties
+     * @param modId _id
+     * @param modTpl _tpl
+     * @param parentId parentId
+     * @param modSlot slotId
+     * @param modTemplate Used to add additional properites in the upd object
+     * @returns Item object
+     */
+    protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item;
     /**
      * Is this magazine cylinder related (revolvers and grenade launchers)
      * @param magazineParentName the name of the magazines parent
@@ -62,11 +131,11 @@ export declare class BotGeneratorHelper {
      * Those magazines (e.g. 60dc519adf4c47305f6d410d) have a "Cartridges" entry with a _max_count=0.
      * Ammo is not put into the magazine directly but assigned to the magazine's slots: The "camora_xxx" slots.
      * This function is a helper called by generateModsForItem for mods with parent type "CylinderMagazine"
-     *
-     * @param {object}      items               The items where the CylinderMagazine's camora are appended to
-     * @param {object}      modPool             modPool which should include available cartrigdes
-     * @param {string}      parentId            The CylinderMagazine's UID
-     * @param {object}      parentTemplate      The CylinderMagazine's template
+     * @param items The items where the CylinderMagazine's camora are appended to
+     * @param modPool modPool which should include available cartrigdes
+     * @param parentId The CylinderMagazine's UID
+     * @param parentTemplate The CylinderMagazine's template
+     * @returns
      */
     protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void;
     /**
@@ -75,6 +144,13 @@ export declare class BotGeneratorHelper {
      * @returns string array of shells fro luitple camora sources
      */
     protected mergeCamoraPoolsTogether(camorasWithShells: Record<string, string[]>): string[];
+    /**
+     * Adds properties to an item
+     * e.g. Repairable / HasHinge / Foldable / MaxDurability
+     * @param itemTemplate
+     * @param botRole Used by weapons to randomise the durability values
+     * @returns Item Upd object with extra properties
+     */
     generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): {
         upd?: Upd;
     };
@@ -93,12 +169,6 @@ export declare class BotGeneratorHelper {
      */
     protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable;
     protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string;
-    /**
-     * Sort by spawn chance, highest to lowest, higher is more common
-     * @param unsortedModArray String array to sort
-     * @returns Sorted string array
-     */
-    protected sortModArray(unsortedModArray: string[]): string[];
     /**
      * Can an item be added to an item without issue
      * @param items
@@ -117,8 +187,15 @@ export declare class BotGeneratorHelper {
      * @returns a `boolean` indicating item was added
      */
     addItemWithChildrenToEquipmentSlot(equipmentSlots: string[], parentId: string, parentTpl: string, itemWithChildren: Item[], inventory: PmcInventory): boolean;
+    /**
+     * is the provided item allowed inside a container
+     * @param slot location item wants to be placed in
+     * @param itemTpl item being placed
+     * @returns true if allowed
+     */
     protected itemAllowedInContainer(slot: Grid, itemTpl: string): boolean;
 }
+/** TODO - move into own class */
 export declare class ExhaustableArray<T> {
     private itemPool;
     private randomUtil;
diff --git a/TypeScript/11BundleLoadingSample/types/helpers/HideoutHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/HideoutHelper.d.ts
index 36e4009..7495a6a 100644
--- a/TypeScript/11BundleLoadingSample/types/helpers/HideoutHelper.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/helpers/HideoutHelper.d.ts
@@ -44,14 +44,72 @@ export declare class HideoutHelper {
     initProduction(recipeId: string, productionTime: number): Production;
     isProductionType(productive: Productive): productive is Production;
     applyPlayerUpgradesBonuses(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * TODO:
+     * After looking at the skills there doesnt seem to be a configuration per skill to boost
+     * the XP gain PER skill. I THINK you should be able to put the variable "SkillProgress" (just like health has it)
+     * and be able to tune the skill gain PER skill, but I havent tested it and Im not sure!
+     * @param pmcData
+     * @param bonus
+     */
     protected applySkillXPBoost(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * Process a players hideout, update areas that use resources + increment production timers
+     * @param sessionID Session id
+     */
     updatePlayerHideout(sessionID: string): void;
+    /**
+     * Update progress timer for water collector
+     * @param pmcData profile to update
+     * @param productionId id of water collection production to update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateWaterCollectorProductionTimer(pmcData: IPmcData, productionId: string, hideoutProperties: {
+        btcFarmCGs?: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Iterate over productions and update their progress timers
+     * @param pmcData Profile to check for productions and update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Update progress timer for scav case
+     * @param pmcData Profile to update
+     * @param productionId Id of scav case production to update
+     */
+    protected updateScavCaseProductionTimer(pmcData: IPmcData, productionId: string): void;
+    /**
+     * Iterate over hideout areas that use resources (fuel/filters etc) and update associated values
+     * @param sessionID Session id
+     * @param pmcData Profile to update areas of
+     * @param hideoutProperties hideout properties
+     */
+    protected updateAreasWithResources(sessionID: string, pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
     protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
     protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
-    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): HideoutArea;
-    protected updateWaterFilters(waterFilterArea: HideoutArea, pwProd: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
+    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): void;
+    /**
+     * Adjust water filter objects resourceValue or delete when they reach 0 resource
+     * @param waterFilterArea water filter area to update
+     * @param production production object
+     * @param isGeneratorOn is generatory enabled
+     * @param pmcData Player profile
+     * @returns Updated HideoutArea object
+     */
+    protected updateWaterFilters(waterFilterArea: HideoutArea, production: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
     protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
-    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): HideoutArea;
+    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): void;
     protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
     protected getBTCSlots(pmcData: IPmcData): number;
     protected getManagementSkillsSlots(): number;
diff --git a/TypeScript/11BundleLoadingSample/types/helpers/InRaidHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/InRaidHelper.d.ts
index b382e30..962df38 100644
--- a/TypeScript/11BundleLoadingSample/types/helpers/InRaidHelper.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/helpers/InRaidHelper.d.ts
@@ -18,18 +18,6 @@ export declare class InRaidHelper {
     protected paymentHelper: PaymentHelper;
     protected profileFixerService: ProfileFixerService;
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper, profileFixerService: ProfileFixerService);
-    /**
-     * Reset the SPT inraid property stored in a profile to 'none'
-     * @param sessionID Session id
-     */
-    protected removePlayer(sessionID: string): void;
-    /**
-     * Some maps have one-time-use keys (e.g. Labs
-     * Remove the relevant key from an inventory based on the post-raid request data passed in
-     * @param offraidData post-raid data
-     * @param sessionID Session id
-     */
-    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
     /**
      * Check an array of items and add an upd object to money items with a stack count of 1
      * Single stack money items have no upd object and thus no StackObjectsCount, causing issues
@@ -54,6 +42,18 @@ export declare class InRaidHelper {
      * @returns Reset profile object
      */
     updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData;
+    /**
+     * Some maps have one-time-use keys (e.g. Labs
+     * Remove the relevant key from an inventory based on the post-raid request data passed in
+     * @param offraidData post-raid data
+     * @param sessionID Session id
+     */
+    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Set the SPT inraid location Profile property to 'none'
+     * @param sessionID Session id
+     */
+    protected setPlayerInRaidLocationStatusToNone(sessionID: string): void;
     /**
      * Adds SpawnedInSession property to items found in a raid
      * Removes SpawnedInSession for non-scav players if item was taken into raid with SpawnedInSession = true
@@ -95,5 +95,10 @@ export declare class InRaidHelper {
      * @returns true if item is kept after death
      */
     isItemKeptAfterDeath(slotId: string): boolean;
+    /**
+     * Return the equipped items from a players inventory
+     * @param items Players inventory to search through
+     * @returns an array of equipped items
+     */
     getPlayerGear(items: Item[]): Item[];
 }
diff --git a/TypeScript/11BundleLoadingSample/types/helpers/ItemHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/ItemHelper.d.ts
index 1701c62..de10892 100644
--- a/TypeScript/11BundleLoadingSample/types/helpers/ItemHelper.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/helpers/ItemHelper.d.ts
@@ -1,35 +1,30 @@
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item, Repairable } from "../models/eft/common/tables/IItem";
+import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase";
 import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+import { MathUtil } from "../utils/MathUtil";
+import { ObjectId } from "../utils/ObjectId";
+import { RandomUtil } from "../utils/RandomUtil";
 declare class ItemHelper {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
     protected jsonUtil: JsonUtil;
+    protected randomUtil: RandomUtil;
+    protected objectId: ObjectId;
+    protected mathUtil: MathUtil;
     protected databaseServer: DatabaseServer;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer);
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer);
     /**
      * Checks if a id is a valid item. Valid meaning that it's an item that be stored in stash
      * @param       {string}    tpl       the template id / tpl
      * @returns                             boolean; true for items that may be in player posession and not quest items
      */
     isValidItem(tpl: string, invalidBaseTypes?: string[]): boolean;
-    /**
-     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
-     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
-     * @param {*} tpl template id of item to check
-     * @returns boolean: true if item is valid reward
-     */
-    isValidRewardItem(tpl: string): boolean;
-    /**
-     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
-     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
-     */
-    getRewardableItems(): [string, ITemplateItem][];
     /**
      * Check if the tpl / template Id provided is a descendent of the baseclass
      *
@@ -196,6 +191,22 @@ declare class ItemHelper {
      * @returns ItemSize object (width and height)
      */
     getItemSize(items: Item[], rootItemId: string): ItemHelper.ItemSize;
+    /**
+     * Get a random cartridge from an items Filter property
+     * @param item
+     * @returns
+     */
+    getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
+    createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
+    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
+    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
+    createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
+    /**
+     * Get the size of a stack, return 1 if no stack object count property found
+     * @param item Item to get stack size of
+     * @returns size of stack
+     */
+    getItemStackSize(item: Item): number;
 }
 declare namespace ItemHelper {
     interface ItemSize {
diff --git a/TypeScript/11BundleLoadingSample/types/helpers/ProfileHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/ProfileHelper.d.ts
index 9d4ff98..9c6560a 100644
--- a/TypeScript/11BundleLoadingSample/types/helpers/ProfileHelper.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/helpers/ProfileHelper.d.ts
@@ -24,6 +24,19 @@ export declare class ProfileHelper {
     constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, fenceService: FenceService);
     resetProfileQuestCondition(sessionID: string, conditionId: string): void;
     getCompleteProfile(sessionID: string): IPmcData[];
+    /**
+     * Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
+     * Server saves the post-raid changes prior to the xp screen getting the profile, this results in the xp screen using
+     * the now updated profile values as a base, meaning it shows x2 xp gained
+     * Instead, clone the post-raid profile (so we dont alter its values), apply the pre-raid xp values to the cloned objects and return
+     * Delete snapshot of pre-raid profile prior to returning profile data
+     * @param sessionId Session id
+     * @param output pmc and scav profiles array
+     * @param pmcProfile post-raid pmc profile
+     * @param scavProfile post-raid scav profile
+     * @returns updated profile array
+     */
+    protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
     isNicknameTaken(info: IValidateNicknameRequestData, sessionID: string): boolean;
     /**
      * Add experience to a PMC inside the players profile
diff --git a/TypeScript/11BundleLoadingSample/types/helpers/QuestHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/QuestHelper.d.ts
index 32e55ec..d66d150 100644
--- a/TypeScript/11BundleLoadingSample/types/helpers/QuestHelper.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/helpers/QuestHelper.d.ts
@@ -36,11 +36,20 @@ export declare class QuestHelper {
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
     constructor(logger: ILogger, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, itemHelper: ItemHelper, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, localeService: LocaleService, ragfairServerHelper: RagfairServerHelper, dialogueHelper: DialogueHelper, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, traderHelper: TraderHelper, configServer: ConfigServer);
-    questStatus(pmcData: IPmcData, questID: string): QuestStatus;
     /**
-     * returns true is the condition is satisfied
+    * Get status of a quest by quest id
+    * @param pmcData Profile to search
+    * @param questID Quest id to look up
+    * @returns QuestStauts enum
+    */
+    getQuestStatus(pmcData: IPmcData, questID: string): QuestStatus;
+    /**
+     * returns true is the level condition is satisfied
+     * @param playerLevel Players level
+     * @param condition Quest condition
+     * @returns true if player level is greater than or equal to quest
      */
-    evaluateLevel(pmcProfile: IPmcData, cond: AvailableForConditions): boolean;
+    doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean;
     getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[];
     /**
      * Increase skill points of a skill on player profile
diff --git a/TypeScript/11BundleLoadingSample/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/RagfairOfferHelper.d.ts
index 8d03bee..e9d72ca 100644
--- a/TypeScript/11BundleLoadingSample/types/helpers/RagfairOfferHelper.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/helpers/RagfairOfferHelper.d.ts
@@ -22,12 +22,14 @@ import { ProfileHelper } from "./ProfileHelper";
 import { RagfairHelper } from "./RagfairHelper";
 import { RagfairServerHelper } from "./RagfairServerHelper";
 import { RagfairSortHelper } from "./RagfairSortHelper";
+import { TraderHelper } from "./TraderHelper";
 export declare class RagfairOfferHelper {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
     protected hashUtil: HashUtil;
     protected itemEventRouter: ItemEventRouter;
     protected databaseServer: DatabaseServer;
+    protected traderHelper: TraderHelper;
     protected saveServer: SaveServer;
     protected dialogueHelper: DialogueHelper;
     protected itemHelper: ItemHelper;
@@ -43,10 +45,10 @@ export declare class RagfairOfferHelper {
     protected static goodSoldTemplate: string;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, traderHelper: TraderHelper, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
     getValidOffers(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
     getOffersForBuild(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
-    processOffers(sessionID: string): boolean;
+    processOffersOnProfile(sessionID: string): boolean;
     protected getProfileOffers(sessionID: string): IRagfairOffer[];
     protected deleteOfferByOfferId(sessionID: string, offerId: string): void;
     protected completeOffer(sessionID: string, offer: IRagfairOffer, boughtAmount: number): IItemEventRouterResponse;
diff --git a/TypeScript/11BundleLoadingSample/types/helpers/RagfairSellHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/RagfairSellHelper.d.ts
index 6ec004a..91b8a20 100644
--- a/TypeScript/11BundleLoadingSample/types/helpers/RagfairSellHelper.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/helpers/RagfairSellHelper.d.ts
@@ -11,6 +11,12 @@ export declare class RagfairSellHelper {
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     constructor(logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer);
-    calculateSellChance(baseChance: number, offerPrice: number, requirementsPriceInRub: number): number;
-    rollForSale(sellChance: number, count: number): SellResult[];
+    calculateSellChance(baseChancePercent: number, offerPriceRub: number, playerListedPriceRub: number): number;
+    /**
+     * Determine if the offer being listed will be sold
+     * @param sellChancePercent chance item will sell
+     * @param itemSellCount count of items to sell
+     * @returns Array of purchases of item(s) lsited
+     */
+    rollForSale(sellChancePercent: number, itemSellCount: number): SellResult[];
 }
diff --git a/TypeScript/11BundleLoadingSample/types/helpers/RagfairServerHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/RagfairServerHelper.d.ts
index e4939d1..a03cdda 100644
--- a/TypeScript/11BundleLoadingSample/types/helpers/RagfairServerHelper.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/helpers/RagfairServerHelper.d.ts
@@ -6,6 +6,7 @@ import { IRagfairConfig } from "../models/spt/config/IRagfairConfig";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { SaveServer } from "../servers/SaveServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { LocaleService } from "../services/LocaleService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -13,6 +14,9 @@ import { RandomUtil } from "../utils/RandomUtil";
 import { DialogueHelper } from "./DialogueHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProfileHelper } from "./ProfileHelper";
+/**
+ * Helper class for common ragfair server actions
+ */
 export declare class RagfairServerHelper {
     protected randomUtil: RandomUtil;
     protected hashUtil: HashUtil;
@@ -23,11 +27,12 @@ export declare class RagfairServerHelper {
     protected localeService: LocaleService;
     protected dialogueHelper: DialogueHelper;
     protected jsonUtil: JsonUtil;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
     protected static goodsReturnedTemplate: string;
-    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, configServer: ConfigServer);
+    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Is item valid / on blacklist / quest item
      * @param itemDetails
diff --git a/TypeScript/11BundleLoadingSample/types/helpers/TradeHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/TradeHelper.d.ts
index 975062b..7ab9768 100644
--- a/TypeScript/11BundleLoadingSample/types/helpers/TradeHelper.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/helpers/TradeHelper.d.ts
@@ -39,6 +39,12 @@ export declare class TradeHelper {
      * @returns
      */
     sellItem(pmcData: IPmcData, body: IProcessSellTradeRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment the assorts buy count by number of items purchased
+     * Show error on screen if player attepts to buy more than what the buy max allows
+     * @param assortBeingPurchased assort being bought
+     * @param itemsPurchasedCount number of items being bought
+     */
     protected incrementAssortBuyCount(assortBeingPurchased: Item, itemsPurchasedCount: number): void;
     protected checkPurchaseIsWithinTraderItemLimit(assortBeingPurchased: Item, assortId: string, count: number): void;
 }
diff --git a/TypeScript/11BundleLoadingSample/types/helpers/TraderAssortHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/TraderAssortHelper.d.ts
index 677dd66..025efd6 100644
--- a/TypeScript/11BundleLoadingSample/types/helpers/TraderAssortHelper.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/helpers/TraderAssortHelper.d.ts
@@ -1,6 +1,5 @@
 import { RagfairAssortGenerator } from "../generators/RagfairAssortGenerator";
 import { RagfairOfferGenerator } from "../generators/RagfairOfferGenerator";
-import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ITrader, ITraderAssort } from "../models/eft/common/tables/ITrader";
 import { ITraderConfig } from "../models/spt/config/ITraderConfig";
@@ -41,12 +40,7 @@ export declare class TraderAssortHelper {
      * @param traderId traders id
      * @returns a traders' assorts
      */
-    getAssort(sessionId: string, traderId: string): ITraderAssort;
-    /**
-     * if the fence assorts have expired, re-generate them
-     * @param pmcProfile Players profile
-     */
-    refreshFenceAssortIfExpired(pmcProfile: IPmcData): void;
+    getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort;
     /**
      * Reset a traders assorts and move nextResupply value to future
      * Flag trader as needing a flea offer reset to be picked up by flea update() function
diff --git a/TypeScript/11BundleLoadingSample/types/helpers/TraderHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/TraderHelper.d.ts
index 6bda5cd..0dc93e8 100644
--- a/TypeScript/11BundleLoadingSample/types/helpers/TraderHelper.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/helpers/TraderHelper.d.ts
@@ -65,7 +65,7 @@ export declare class TraderHelper {
      * @param item
      * @returns boolean
      */
-    protected isWeaponAndBelowTraderBuyDurability(traderID: string, item: Item): boolean;
+    protected isWeaponBelowTraderBuyDurability(traderID: string, item: Item): boolean;
     /**
      * Get the price of an item and all of its attached children
      * Take into account bonuses/adjsutments e.g. discounts
diff --git a/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/ITemplateItem.d.ts b/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/ITemplateItem.d.ts
index 23a1a14..6b2fa8f 100644
--- a/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/ITemplateItem.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/ITemplateItem.d.ts
@@ -34,6 +34,7 @@ export interface Props {
     LootExperience?: number;
     ExamineExperience?: number;
     HideEntrails?: boolean;
+    InsuranceDisabled?: boolean;
     RepairCost?: number;
     RepairSpeed?: number;
     ExtraSizeLeft?: number;
@@ -206,6 +207,7 @@ export interface Props {
     IsOneoff?: boolean;
     MustBoltBeOpennedForExternalReload?: boolean;
     MustBoltBeOpennedForInternalReload?: boolean;
+    NoFiremodeOnBoltcatch?: boolean;
     BoltAction?: boolean;
     HipAccuracyRestorationDelay?: number;
     HipAccuracyRestorationSpeed?: number;
diff --git a/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/ITrader.d.ts b/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/ITrader.d.ts
index a84f5af..37b2d61 100644
--- a/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/ITrader.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/ITrader.d.ts
@@ -67,6 +67,7 @@ export interface IBarterScheme {
     count: number;
     _tpl: string;
     onlyFunctional?: boolean;
+    sptQuestLocked?: boolean;
 }
 export interface ISuit {
     _id: string;
diff --git a/TypeScript/11BundleLoadingSample/types/models/eft/ragfair/IRagfairOffer.d.ts b/TypeScript/11BundleLoadingSample/types/models/eft/ragfair/IRagfairOffer.d.ts
index 63f655e..141b605 100644
--- a/TypeScript/11BundleLoadingSample/types/models/eft/ragfair/IRagfairOffer.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/models/eft/ragfair/IRagfairOffer.d.ts
@@ -15,6 +15,8 @@ export interface IRagfairOffer {
     name?: string;
     shortName?: string;
     loyaltyLevel: number;
+    buyRestrictionMax?: number;
+    buyRestrictionCurrent?: number;
     locked: boolean;
     unlimitedCount: boolean;
     summaryCost: number;
diff --git a/TypeScript/11BundleLoadingSample/types/models/enums/AmmoTypes.d.ts b/TypeScript/11BundleLoadingSample/types/models/enums/AmmoTypes.d.ts
index b52ddcf..254b410 100644
--- a/TypeScript/11BundleLoadingSample/types/models/enums/AmmoTypes.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/models/enums/AmmoTypes.d.ts
@@ -23,7 +23,7 @@ export declare enum Ammo762x54 {
     BT_GZH = "5e023d34e8a400319a28ed44",
     BS_GZH = "5e023d48186a883be655e551"
 }
-export declare enum Ammo338Lapua {
+export declare enum Ammo86x70 {
     TAC_X = "5fc382b6d6fa9c00c571bbc3",
     UCW = "5fc382c1016cce60e8341b20",
     AP = "5fc382a9d724d907e2077dab",
@@ -85,13 +85,13 @@ export declare enum Ammo9x21 {
     PE_GZH = "5a26ac06c4a282000c5a90a8",
     BT_GZH = "5a26ac0ec4a28200741e1e18"
 }
-export declare enum Ammo357Mag {
+export declare enum Ammo9x33R {
     FMJ = "62330b3ed4dc74626d570b95",
     HOLLOW_POINT = "62330bfadc5883093563729b",
     SOFT_POINT = "62330c40bdd19b369e1e53d1",
     JACKET_HP = "62330c18744e5e31df12f516"
 }
-export declare enum Ammo45ACP {
+export declare enum Ammo1143x23ACP {
     MATCH_FMJ = "5e81f423763d9f754677bf2e",
     HYDRA_SHOK = "5efb0fc6aeb21837e749c801",
     LASERMATCH_FMJ = "5efb0d4f4bc50b58e81710f3",
@@ -126,7 +126,7 @@ export declare enum Ammo556x45 {
     MK_318_MOD_0_SOST = "60194943740c5d77f6705eea",
     SSA_AP = "601949593ae8f707c4608daa"
 }
-export declare enum Ammo300Blackout {
+export declare enum Ammo762x35 {
     M62_TRACER = "619636be6db0f2477964e710",
     BCP_FMJ = "5fbe3ffdf8b6a877a729ea82",
     AP = "5fd20ff893a8961fc660a954",
diff --git a/TypeScript/11BundleLoadingSample/types/models/enums/BaseClasses.d.ts b/TypeScript/11BundleLoadingSample/types/models/enums/BaseClasses.d.ts
index e733bca..37c1398 100644
--- a/TypeScript/11BundleLoadingSample/types/models/enums/BaseClasses.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/models/enums/BaseClasses.d.ts
@@ -68,6 +68,7 @@ export declare enum BaseClasses {
     ASSAULT_SCOPE = "55818add4bdc2d5b648b456f",
     REFLEX_SIGHT = "55818ad54bdc2ddc698b4569",
     TACTICAL_COMBO = "55818b164bdc2ddc698b456c",
+    FLASHLIGHT = "55818b084bdc2d5b648b4571",
     MAGAZINE = "5448bc234bdc2d3c308b4569",
     LIGHT_LASER = "55818b0e4bdc2dde698b456e",
     FLASH_HIDER = "550aa4bf4bdc2dd6348b456b",
diff --git a/TypeScript/11BundleLoadingSample/types/models/enums/ConfigTypes.d.ts b/TypeScript/11BundleLoadingSample/types/models/enums/ConfigTypes.d.ts
index 61d6f99..468ece5 100644
--- a/TypeScript/11BundleLoadingSample/types/models/enums/ConfigTypes.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/models/enums/ConfigTypes.d.ts
@@ -8,6 +8,7 @@ export declare enum ConfigTypes {
     IN_RAID = "aki-inraid",
     INSURANCE = "aki-insurance",
     INVENTORY = "aki-inventory",
+    ITEM = "aki-item",
     LOCALE = "aki-locale",
     LOCATION = "aki-location",
     MATCH = "aki-match",
diff --git a/TypeScript/11BundleLoadingSample/types/models/enums/ELocationName.d.ts b/TypeScript/11BundleLoadingSample/types/models/enums/ELocationName.d.ts
index b56cc08..7ae7caa 100644
--- a/TypeScript/11BundleLoadingSample/types/models/enums/ELocationName.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/models/enums/ELocationName.d.ts
@@ -1,5 +1,6 @@
 export declare enum ELocationName {
     FACTORY_DAY = "factory4_day",
+    FACTORY_NIGHT = "factory4_night",
     BIGMAP = "bigmap",
     WOODS = "Woods",
     SHORELINE = "Shoreline",
diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/11BundleLoadingSample/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/config/IBotConfig.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/config/IBotConfig.d.ts
index e171087..f15fa73 100644
--- a/TypeScript/11BundleLoadingSample/types/models/spt/config/IBotConfig.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/models/spt/config/IBotConfig.d.ts
@@ -1,17 +1,31 @@
 import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
+import { IBotDurability } from "./IBotDurability";
+import { IPmcConfig } from "./IPmcConfig";
 export interface IBotConfig extends IBaseConfig {
     kind: "aki-bot";
+    /** How many variants of each bot should be generated on raid start */
     presetBatch: PresetBatch;
+    /** What bot types should be classified as bosses */
     bosses: string[];
-    durability: Durability;
+    /** Control weapon/armor durability min/max values for each bot type */
+    durability: IBotDurability;
+    /** Control the weighting of how expensive an average loot item is on a PMC or Scav */
     lootNValue: LootNvalue;
+    /** Control what bots are added to a bots revenge list key: bottype, value: bottypes to revenge on seeing their death */
     revenge: Record<string, string[]>;
-    pmc: PmcConfig;
+    /** PMC bot specific config settings */
+    pmc: IPmcConfig;
+    /** Control how many items are allowed to spawn on a bot
+     * key: bottype, value: <key: itemTpl: value: max item count> */
     itemSpawnLimits: Record<string, Record<string, number>>;
-    equipment: Record<string, Equipment>;
+    /** Blacklist/whitelist items on a bot */
+    equipment: Record<string, EquipmentFilters>;
+    /** Show a bots botType value after their name */
     showTypeInNickname: boolean;
+    /** Max number of bots that can be spawned in a raid at any one time */
     maxBotCap: number;
+    /** How many stacks of secret ammo should a bot have in its bot secure container */
     secureContainerAmmoStackCount: number;
 }
 export interface PresetBatch {
@@ -44,79 +58,22 @@ export interface PresetBatch {
     test: number;
     exUsec: number;
 }
-export interface Durability {
-    default: DefaultDurability;
-    pmc: PmcDurability;
-    boss: BotDurability;
-    follower: BotDurability;
-    assault: BotDurability;
-    cursedassault: BotDurability;
-    marksman: BotDurability;
-    pmcbot: BotDurability;
-    exusec: BotDurability;
-    sectantpriest: BotDurability;
-    sectantwarrior: BotDurability;
-}
-export interface DefaultDurability {
-    armor: DefaultArmor;
-    weapon: WeaponDurability;
-}
-export interface DefaultArmor {
-    maxDelta: number;
-    minDelta: number;
-}
-export interface WeaponDurability {
-    lowestMax: number;
-    highestMax: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface PmcDurability {
-    armor: PmcDurabilityArmor;
-    weapon: WeaponDurability;
-}
-export interface PmcDurabilityArmor {
-    lowestMaxPercent: number;
-    highestMaxPercent: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface BotDurability {
-    armor: ArmorDurability;
-    weapon: WeaponDurability;
-}
-export interface ArmorDurability {
-    maxDelta: number;
-    minDelta: number;
-}
 export interface LootNvalue {
     scav: number;
     pmc: number;
 }
-export interface PmcConfig {
-    dynamicLoot: PmcDynamicLoot;
-    difficulty: string;
-    looseWeaponInBackpackChancePercent: number;
-    looseWeaponInBackpackLootMinMax: MinMax;
-    isUsec: number;
-    chanceSameSideIsHostilePercent: number;
-    usecType: string;
-    bearType: string;
-    maxBackpackLootTotalRub: number;
-    maxPocketLootTotalRub: number;
-    maxVestLootTotalRub: number;
-    convertIntoPmcChance: Record<string, MinMax>;
-    enemyTypes: string[];
-}
-export interface PmcDynamicLoot {
-    whitelist: string[];
-    blacklist: string[];
-    moneyStackLimits: Record<string, number>;
-}
-export interface Equipment {
+export interface EquipmentFilters {
+    weaponModLimits: ModLimits;
+    randomisedWeaponModSlots?: string[];
     blacklist: EquipmentFilterDetails[];
     whitelist: EquipmentFilterDetails[];
 }
+export interface ModLimits {
+    /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */
+    scopeLimit?: number;
+    /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */
+    lightLaserLimit?: number;
+}
 export interface EquipmentFilterDetails {
     levelRange: MinMax;
     equipment: Record<string, string[]>;
diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/config/IBotDurability.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/config/IBotDurability.d.ts
new file mode 100644
index 0000000..38a47cc
--- /dev/null
+++ b/TypeScript/11BundleLoadingSample/types/models/spt/config/IBotDurability.d.ts
@@ -0,0 +1,47 @@
+export interface IBotDurability {
+    default: DefaultDurability;
+    pmc: PmcDurability;
+    boss: BotDurability;
+    follower: BotDurability;
+    assault: BotDurability;
+    cursedassault: BotDurability;
+    marksman: BotDurability;
+    pmcbot: BotDurability;
+    exusec: BotDurability;
+    gifter: BotDurability;
+    sectantpriest: BotDurability;
+    sectantwarrior: BotDurability;
+}
+/** Durability values to be used when a more specific bot type cant be found */
+export interface DefaultDurability {
+    armor: DefaultArmor;
+    weapon: WeaponDurability;
+}
+export interface DefaultArmor {
+    maxDelta: number;
+    minDelta: number;
+}
+export interface WeaponDurability {
+    lowestMax: number;
+    highestMax: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface PmcDurability {
+    armor: PmcDurabilityArmor;
+    weapon: WeaponDurability;
+}
+export interface PmcDurabilityArmor {
+    lowestMaxPercent: number;
+    highestMaxPercent: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface BotDurability {
+    armor: ArmorDurability;
+    weapon: WeaponDurability;
+}
+export interface ArmorDurability {
+    maxDelta: number;
+    minDelta: number;
+}
diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/config/IItemConfig.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/config/IItemConfig.d.ts
new file mode 100644
index 0000000..5ecccc2
--- /dev/null
+++ b/TypeScript/11BundleLoadingSample/types/models/spt/config/IItemConfig.d.ts
@@ -0,0 +1,5 @@
+import { IBaseConfig } from "./IBaseConfig";
+export interface IItemConfig extends IBaseConfig {
+    kind: "aki-item";
+    blacklist: string[];
+}
diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/config/IPmcConfig.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/config/IPmcConfig.d.ts
new file mode 100644
index 0000000..655b58d
--- /dev/null
+++ b/TypeScript/11BundleLoadingSample/types/models/spt/config/IPmcConfig.d.ts
@@ -0,0 +1,22 @@
+import { MinMax } from "../../common/MinMax";
+export interface IPmcConfig {
+    dynamicLoot: DynamicLoot;
+    useDifficultyOverride: boolean;
+    difficulty: string;
+    looseWeaponInBackpackChancePercent: number;
+    looseWeaponInBackpackLootMinMax: MinMax;
+    isUsec: number;
+    chanceSameSideIsHostilePercent: number;
+    usecType: string;
+    bearType: string;
+    maxBackpackLootTotalRub: number;
+    maxPocketLootTotalRub: number;
+    maxVestLootTotalRub: number;
+    convertIntoPmcChance: Record<string, MinMax>;
+    enemyTypes: string[];
+}
+export interface DynamicLoot {
+    whitelist: string[];
+    blacklist: string[];
+    moneyStackLimits: Record<string, number>;
+}
diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/config/IQuestConfig.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/config/IQuestConfig.d.ts
index be4a97b..45c9aae 100644
--- a/TypeScript/11BundleLoadingSample/types/models/spt/config/IQuestConfig.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/models/spt/config/IQuestConfig.d.ts
@@ -4,6 +4,8 @@ export interface IQuestConfig extends IBaseConfig {
     kind: "aki-quest";
     redeemTime: number;
     repeatableQuests: IRepeatableQuestConfig[];
+    bearOnlyQuests: string[];
+    usecOnlyQuests: string[];
 }
 export interface IRepeatableQuestConfig {
     name: string;
@@ -15,6 +17,10 @@ export interface IRepeatableQuestConfig {
     locations: Record<ELocationName, string[]>;
     traderWhitelist: ITraderWhitelist[];
     questConfig: IQuestConfig;
+    /** Item base types to block when generating rewards */
+    rewardBaseTypeBlacklist: string[];
+    /** Item tplIds to ignore when generating rewards */
+    rewardBlacklist: string[];
 }
 export interface IRewardScaling {
     levels: number[];
diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/config/IRagfairConfig.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/config/IRagfairConfig.d.ts
index 6369eda..3088717 100644
--- a/TypeScript/11BundleLoadingSample/types/models/spt/config/IRagfairConfig.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/models/spt/config/IRagfairConfig.d.ts
@@ -12,6 +12,7 @@ export interface Sell {
     chance: Chance;
     time: Time;
     reputation: Reputation;
+    simulatedSellHours: number;
 }
 export interface Chance {
     base: number;
diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/config/ITraderConfig.d.ts
index c8e8044..6b1c1e3 100644
--- a/TypeScript/11BundleLoadingSample/types/models/spt/config/ITraderConfig.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/models/spt/config/ITraderConfig.d.ts
@@ -12,8 +12,10 @@ export interface UpdateTime {
     seconds: number;
 }
 export interface FenceConfig {
+    partialRefreshTimeSeconds: number;
+    partialRefreshChangePercent: number;
     assortSize: number;
-    maxPresetsCount: number;
+    maxPresetsPercent: number;
     presetPriceMult: number;
     blacklist: string[];
 }
diff --git a/TypeScript/2EditDatabase/types/models/spt/location/AirDropLootItem.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/services/LootItem.d.ts
similarity index 54%
rename from TypeScript/2EditDatabase/types/models/spt/location/AirDropLootItem.d.ts
rename to TypeScript/11BundleLoadingSample/types/models/spt/services/LootItem.d.ts
index da791ff..2838472 100644
--- a/TypeScript/2EditDatabase/types/models/spt/location/AirDropLootItem.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/models/spt/services/LootItem.d.ts
@@ -1,5 +1,4 @@
-export declare class AirDropLootItem {
-    id: string;
+export declare class LootItem {
     tpl: string;
     isPreset: boolean;
     stackCount: number;
diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/services/LootRequest.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/11BundleLoadingSample/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/11BundleLoadingSample/types/services/BotEquipmentFilterService.d.ts b/TypeScript/11BundleLoadingSample/types/services/BotEquipmentFilterService.d.ts
index e49645b..632f961 100644
--- a/TypeScript/11BundleLoadingSample/types/services/BotEquipmentFilterService.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/services/BotEquipmentFilterService.d.ts
@@ -1,12 +1,12 @@
 import { IBotType } from "../models/eft/common/tables/IBotType";
-import { Equipment, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 export declare class BotEquipmentFilterService {
     protected logger: ILogger;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    protected botEquipmentFilterlists: Record<string, Equipment>;
+    protected botEquipmentFilterlists: Record<string, EquipmentFilters>;
     constructor(logger: ILogger, configServer: ConfigServer);
     /**
      * Filter a bots data to exclude equipment and cartridges defines in the botConfig
@@ -22,7 +22,7 @@ export declare class BotEquipmentFilterService {
      * @param playerLevel Level of the player
      * @returns EquipmentBlacklistDetails object
      */
-    protected getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
+    getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
     /**
      * Get the whitelist for a specific bot type that's within the players level
      * @param botRole Bot type
diff --git a/TypeScript/11BundleLoadingSample/types/services/FenceService.d.ts b/TypeScript/11BundleLoadingSample/types/services/FenceService.d.ts
index c9e325e..c940507 100644
--- a/TypeScript/11BundleLoadingSample/types/services/FenceService.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/services/FenceService.d.ts
@@ -12,6 +12,11 @@ import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+import { ItemFilterService } from "./ItemFilterService";
+/**
+ * Handle actions surrounding Fence
+ * e.g. generating or refreshing assorts / get next refresh time
+ */
 export declare class FenceService {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
@@ -22,18 +27,64 @@ export declare class FenceService {
     protected handbookHelper: HandbookHelper;
     protected itemHelper: ItemHelper;
     protected presetHelper: PresetHelper;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected fenceAssort: ITraderAssort;
     protected traderConfig: ITraderConfig;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, configServer: ConfigServer);
+    protected nextMiniRefreshTimestamp: number;
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, itemFilterService: ItemFilterService, configServer: ConfigServer);
     protected setFenceAssort(fenceAssort: ITraderAssort): void;
-    getFenceAssorts(): ITraderAssort;
+    /**
+     * Get assorts player can purchase
+     * Adjust prices based on fence level of player
+     * @param pmcProfile Player profile
+     * @returns ITraderAssort
+     */
+    getFenceAssorts(pmcProfile: IPmcData): ITraderAssort;
+    /**
+     * Get fence assorts with no price adjustments based on fence rep
+     * @returns ITraderAssort
+     */
+    getRawFenceAssorts(): ITraderAssort;
+    /**
+     * Does fence need to perform a partial refresh because its passed the refresh timer defined in trader.json
+     * @returns true if it needs a partial refresh
+     */
+    needsPartialRefresh(): boolean;
+    /**
+     * Replace a percentage of fence assorts with freshly generated items
+     */
+    performPartialRefresh(): void;
+    /**
+     * Choose an item (not mod) at random and remove from assorts
+     */
+    protected removeRandomItemFromAssorts(): void;
+    /**
+     * Get an integer rounded count of items to replace based on percentrage from traderConfig value
+     * @param totalItemCount total item count
+     * @returns rounded int of items to replace
+     */
+    protected getCountOfItemsToReplace(totalItemCount: number): number;
     /**
      * Get the count of items fence offers
      * @returns number
      */
     getOfferCount(): number;
-    generateFenceAssortCache(pmcData: IPmcData): void;
+    /**
+     * Create a trader assort for fence
+     */
+    generateFenceAssortCache(): void;
+    /**
+     * Create skeleton to hold assort items
+     * @returns ITraderAssort object
+     */
+    protected createBaseTraderAssortItem(): ITraderAssort;
+    /**
+     * Hydrate result parameter object with generated assorts
+     * @param assortCount Number of assorts to generate
+     * @param assorts object to add assorts to
+     */
+    protected createAssorts(assortCount: number, assorts: ITraderAssort): void;
     /**
      * Get the next update timestamp for fence
      * @returns future timestamp
@@ -44,11 +95,14 @@ export declare class FenceService {
      */
     protected getFenceRefreshTime(): number;
     /**
-     * Get the fence level the passed in profile has
+     * Get fence level the passed in profile has
      * @param pmcData Player profile
-     * @returns FenceLevel
+     * @returns FenceLevel object
      */
     getFenceInfo(pmcData: IPmcData): FenceLevel;
+    /**
+     * Remove an assort from fence by id
+     * @param assortIdToRemove assort id to remove from fence assorts
+     */
     removeFenceOffer(assortIdToRemove: string): void;
-    updateFenceOffers(pmcData: IPmcData): void;
 }
diff --git a/TypeScript/11BundleLoadingSample/types/services/InsuranceService.d.ts b/TypeScript/11BundleLoadingSample/types/services/InsuranceService.d.ts
index 171bf10..6be8a2f 100644
--- a/TypeScript/11BundleLoadingSample/types/services/InsuranceService.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/services/InsuranceService.d.ts
@@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
 import { SecureContainerHelper } from "../helpers/SecureContainerHelper";
 import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
+import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData";
 import { IInsuranceConfig } from "../models/spt/config/IInsuranceConfig";
@@ -44,8 +45,22 @@ export declare class InsuranceService {
      * @param mapId Id of the map player died/exited that caused the insurance to be issued on
      */
     sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void;
+    /**
+     * Store lost gear post-raid inside profile
+     * @param pmcData player profile to store gear in
+     * @param offraidData post-raid request object
+     * @param preRaidGear gear player wore prior to raid
+     * @param sessionID Session id
+     */
     storeLostGear(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
     storeInsuredItemsForReturn(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
-    protected addGearToSend(pmcData: IPmcData, insuredItem: any, actualItem: any, sessionID: string): any;
+    /**
+     * Add gear item to InsuredItems array in player profile
+     * @param pmcData profile to store item in
+     * @param insuredItem Item to store in profile
+     * @param actualItem item to store
+     * @param sessionID Session id
+     */
+    protected addGearToSend(pmcData: IPmcData, insuredItem: InsuredItem, actualItem: Item, sessionID: string): void;
     getPremium(pmcData: IPmcData, inventoryItem: Item, traderId: string): number;
 }
diff --git a/TypeScript/11BundleLoadingSample/types/services/ItemFilterService.d.ts b/TypeScript/11BundleLoadingSample/types/services/ItemFilterService.d.ts
new file mode 100644
index 0000000..c9c8ef3
--- /dev/null
+++ b/TypeScript/11BundleLoadingSample/types/services/ItemFilterService.d.ts
@@ -0,0 +1,24 @@
+import { IItemConfig } from "../models/spt/config/IItemConfig";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+/** Centralise the handling of blacklisting items, uses blacklist found in config/item.json */
+export declare class ItemFilterService {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected configServer: ConfigServer;
+    protected blacklist: string[];
+    protected itemConfig: IItemConfig;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer);
+    /**
+     * Check if the provided template id is blacklisted in config/item.json
+     * @param tpl template id
+     * @returns true if blacklisted
+     */
+    isItemBlacklisted(tpl: string): boolean;
+    /**
+     * Return every template id blacklisted in config/item.json
+     * @returns string array of blacklisted tempalte ids
+     */
+    getBlacklistedItems(): string[];
+}
diff --git a/TypeScript/11BundleLoadingSample/types/services/ProfileFixerService.d.ts b/TypeScript/11BundleLoadingSample/types/services/ProfileFixerService.d.ts
index ed1dec7..9cb5a38 100644
--- a/TypeScript/11BundleLoadingSample/types/services/ProfileFixerService.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/services/ProfileFixerService.d.ts
@@ -45,6 +45,11 @@ export declare class ProfileFixerService {
      * @param pmcProfile Profile to find and remove slots from
      */
     protected removeResourcesFromSlotsInHideoutWithoutLocationIndexValue(pmcProfile: IPmcData): void;
+    /**
+     * Hideout slots need to be in a specific order, locationIndex in ascending order
+     * @param pmcProfile profile to edit
+     */
+    protected reorderHideoutAreasWithResouceInputs(pmcProfile: IPmcData): void;
     /**
      * add in objects equal to the number of slots
      * @param areaType area to check
diff --git a/TypeScript/11BundleLoadingSample/types/utils/HashUtil.d.ts b/TypeScript/11BundleLoadingSample/types/utils/HashUtil.d.ts
index bacbf2a..a8500e1 100644
--- a/TypeScript/11BundleLoadingSample/types/utils/HashUtil.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/utils/HashUtil.d.ts
@@ -4,8 +4,18 @@ import { TimeUtil } from "./TimeUtil";
 export declare class HashUtil {
     protected timeUtil: TimeUtil;
     constructor(timeUtil: TimeUtil);
+    /**
+     * Create a 24 character id using the sha256 algorithm + current timestamp
+     * @returns 24 character hash
+     */
     generate(): string;
     generateMd5ForData(data: string): string;
     generateSha1ForData(data: string): string;
+    /**
+     * Create a hash for the data parameter
+     * @param algorithm algorithm to use to hash
+     * @param data data to be hashed
+     * @returns hash value
+     */
     generateHashForData(algorithm: string, data: crypto.BinaryLike): string;
 }
diff --git a/TypeScript/11BundleLoadingSample/types/utils/RandomUtil.d.ts b/TypeScript/11BundleLoadingSample/types/utils/RandomUtil.d.ts
index c24dd60..e35d21f 100644
--- a/TypeScript/11BundleLoadingSample/types/utils/RandomUtil.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/utils/RandomUtil.d.ts
@@ -150,4 +150,10 @@ export declare class RandomUtil {
      */
     drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[];
     getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number;
+    /**
+     * Fisher-Yates shuffle an array
+     * @param array Array to shuffle
+     * @returns Shuffled array
+     */
+    shuffle<T>(array: Array<T>): Array<T>;
 }
diff --git a/TypeScript/11BundleLoadingSample/types/utils/TimeUtil.d.ts b/TypeScript/11BundleLoadingSample/types/utils/TimeUtil.d.ts
index f437f8a..1367e26 100644
--- a/TypeScript/11BundleLoadingSample/types/utils/TimeUtil.d.ts
+++ b/TypeScript/11BundleLoadingSample/types/utils/TimeUtil.d.ts
@@ -1,3 +1,6 @@
+/**
+ * Utility class to handle time related problems
+ */
 export declare class TimeUtil {
     static readonly oneHourAsSeconds = 3600;
     formatTime(date: Date): string;
@@ -19,4 +22,10 @@ export declare class TimeUtil {
      * @returns current date in format: 00.00.0000 (dd.mm.yyyy)
      */
     getDateMailFormat(): string;
+    /**
+     * Convert hours into seconds
+     * @param hours hours to convert to seconds
+     * @returns number
+     */
+    getHoursAsSeconds(hours: number): number;
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/callbacks/LocationCallbacks.d.ts b/TypeScript/12ClassExtensionOverride/types/callbacks/LocationCallbacks.d.ts
index cc69369..6e0b538 100644
--- a/TypeScript/12ClassExtensionOverride/types/callbacks/LocationCallbacks.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/callbacks/LocationCallbacks.d.ts
@@ -11,4 +11,5 @@ export declare class LocationCallbacks {
     constructor(httpResponse: HttpResponseUtil, locationController: LocationController);
     getLocationData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<ILocationsGenerateAllResponse>;
     getLocation(url: string, info: IGetLocationRequestData, sessionID: string): IGetBodyResponseData<ILocationBase>;
+    getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): string;
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/callbacks/ProfileCallbacks.d.ts b/TypeScript/12ClassExtensionOverride/types/callbacks/ProfileCallbacks.d.ts
index 6a86fc0..183bb0a 100644
--- a/TypeScript/12ClassExtensionOverride/types/callbacks/ProfileCallbacks.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/callbacks/ProfileCallbacks.d.ts
@@ -1,5 +1,6 @@
 import { ProfileController } from "../controllers/ProfileController";
 import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData";
+import { IPmcData } from "../models/eft/common/IPmcData";
 import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData";
 import { INullResponseData } from "../models/eft/httpResponse/INullResponseData";
 import { IGetMiniProfileRequestData } from "../models/eft/launcher/IGetMiniProfileRequestData";
@@ -12,20 +13,51 @@ import { ISearchFriendResponse } from "../models/eft/profile/ISearchFriendRespon
 import { IValidateNicknameRequestData } from "../models/eft/profile/IValidateNicknameRequestData";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/** Handle profile related client events */
 export declare class ProfileCallbacks {
     protected httpResponse: HttpResponseUtil;
     protected timeUtil: TimeUtil;
     protected profileController: ProfileController;
     constructor(httpResponse: HttpResponseUtil, timeUtil: TimeUtil, profileController: ProfileController);
     createProfile(url: string, info: IProfileCreateRequestData, sessionID: string): IGetBodyResponseData<any>;
-    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
-    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
+    /**
+     * Get the complete player profile (scav + pmc character)
+     * @param url
+     * @param info Empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle the creation of a scav profile for player
+     * Occurs post-raid and when profile first created immediately after character details are confirmed by player
+     * @param url
+     * @param info empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle client/game/profile/voice/change event
+     * @param url
+     * @param info Change voice request object
+     * @param sessionID Session id
+     * @returns Client response
+     */
     changeVoice(url: string, info: IProfileChangeVoiceRequestData, sessionID: string): INullResponseData;
+    /**
+     * Handle client/game/profile/nickname/change event
+     * Client allows player to adjust their profile name
+     * @param url
+     * @param info Change nickname request object
+     * @param sessionID Session id
+     * @returns client response
+     */
     changeNickname(url: string, info: IProfileChangeNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     validateNickname(url: string, info: IValidateNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     getReservedNickname(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<string>;
     /**
-     * Called when creating a character, when you choose a character face/voice
+     * Called when creating a character when choosing a character face/voice
      * @param url
      * @param info response (empty)
      * @param sessionID
diff --git a/TypeScript/12ClassExtensionOverride/types/callbacks/RagfairCallbacks.d.ts b/TypeScript/12ClassExtensionOverride/types/callbacks/RagfairCallbacks.d.ts
index 3a405c9..c609f2f 100644
--- a/TypeScript/12ClassExtensionOverride/types/callbacks/RagfairCallbacks.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/callbacks/RagfairCallbacks.d.ts
@@ -19,6 +19,9 @@ import { ConfigServer } from "../servers/ConfigServer";
 import { RagfairServer } from "../servers/RagfairServer";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+/**
+ * Handle ragfair related callback events
+ */
 export declare class RagfairCallbacks extends OnLoadOnUpdate {
     protected httpResponse: HttpResponseUtil;
     protected logger: ILogger;
diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/InraidController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/InraidController.d.ts
index 82bb64d..102a2fb 100644
--- a/TypeScript/12ClassExtensionOverride/types/controllers/InraidController.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/controllers/InraidController.d.ts
@@ -35,6 +35,30 @@ export declare class InraidController {
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer);
     addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void;
     saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Handle updating the profile post-pmc raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Reduce body part hp to % of max
+     * @param pmcData profile to edit
+     * @param multipler multipler to apply to max health
+     */
+    protected reducePmcHealthToPercent(pmcData: IPmcData, multipler: number): void;
+    /**
+     * Handle updating the profile post-pscav raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePlayerScavProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Is the player dead after a raid - dead is anything other than "survived" / "runner"
+     * @param statusOnExit exit value from offraidData object
+     * @returns true if dead
+     */
+    protected isPlayerDead(statusOnExit: string): boolean;
     /**
      * Mark inventory items as FiR if player survived raid, otherwise remove FiR from them
      * @param offraidData Save Progress Request
diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/InventoryController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/InventoryController.d.ts
index f57f731..f564919 100644
--- a/TypeScript/12ClassExtensionOverride/types/controllers/InventoryController.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/controllers/InventoryController.d.ts
@@ -92,7 +92,11 @@ export declare class InventoryController {
      */
     toggleItem(pmcData: IPmcData, body: IInventoryToggleRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Handles Tagging of items (primary Containers).
+     * Add a tag to an inventory item
+     * @param pmcData profile with item to add tag to
+     * @param body tag request data
+     * @param sessionID session id
+     * @returns client response object
      */
     tagItem(pmcData: IPmcData, body: IInventoryTagRequestData, sessionID: string): IItemEventRouterResponse;
     bindItem(pmcData: IPmcData, body: IInventoryBindRequestData, sessionID: string): IItemEventRouterResponse;
diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/LocationController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/LocationController.d.ts
index 90b6d7a..9db3205 100644
--- a/TypeScript/12ClassExtensionOverride/types/controllers/LocationController.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/controllers/LocationController.d.ts
@@ -1,18 +1,33 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class LocationController {
     protected jsonUtil: JsonUtil;
+    protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/MatchController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/MatchController.d.ts
index e8585d9..cb40023 100644
--- a/TypeScript/12ClassExtensionOverride/types/controllers/MatchController.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/controllers/MatchController.d.ts
@@ -9,6 +9,7 @@ import { IGetProfileRequestData } from "../models/eft/match/IGetProfileRequestDa
 import { IJoinMatchRequestData } from "../models/eft/match/IJoinMatchRequestData";
 import { IJoinMatchResult } from "../models/eft/match/IJoinMatchResult";
 import { IStartOfflineRaidRequestData } from "../models/eft/match/IStartOffineRaidRequestData";
+import { IBotConfig } from "../models/spt/config/IBotConfig";
 import { IInRaidConfig } from "../models/spt/config/IInRaidConfig";
 import { IMatchConfig } from "../models/spt/config/IMatchConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
@@ -29,6 +30,7 @@ export declare class MatchController {
     protected applicationContext: ApplicationContext;
     protected matchConfig: IMatchConfig;
     protected inraidConfig: IInRaidConfig;
+    protected botConfig: IBotConfig;
     constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, applicationContext: ApplicationContext);
     getEnabled(): boolean;
     getProfile(info: IGetProfileRequestData): IPmcData[];
diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/QuestController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/QuestController.d.ts
index 2cbccfb..282f50e 100644
--- a/TypeScript/12ClassExtensionOverride/types/controllers/QuestController.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/controllers/QuestController.d.ts
@@ -39,16 +39,31 @@ export declare class QuestController {
      * @returns array of IQuest
      */
     getClientQuests(sessionID: string): IQuest[];
+    /**
+     * Is the quest for the opposite side the player is on
+     * @param side player side (usec/bear)
+     * @param questId questId to check
+     */
+    protected questIsForOtherSide(side: string, questId: string): boolean;
+    /**
+     * Handle the client accepting a quest and starting it
+     * Send starting rewards if any to player and
+     * Send start notification if any to player
+     * @param pmcData Profile to update
+     * @param acceptedQuest Quest accepted
+     * @param sessionID Session id
+     * @returns client response
+     */
     acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Remove completed quest from profile
+     * Update completed quest in profile
      * Add newly unlocked quests to profile
      * Also recalculate thier level due to exp rewards
      * @param pmcData Player profile
-     * @param body completed quest request
-     * @param sessionID session id
-     * @returns ItemEvent response
+     * @param body Completed quest request
+     * @param sessionID Session id
+     * @returns ItemEvent client response
      */
     completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
@@ -67,10 +82,20 @@ export declare class QuestController {
     protected getQuestsFailedByCompletingQuest(completedQuestId: string): IQuest[];
     /**
      * Fail the quests provided
+     * Update quest in profile, otherwise add fresh quest object with failed status
      * @param sessionID session id
      * @param pmcData player profile
      * @param questsToFail quests to fail
      */
     protected failQuests(sessionID: string, pmcData: IPmcData, questsToFail: IQuest[]): void;
     handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment a backend counter stored value by an amount,
+     * Create counter if it does not exist
+     * @param pmcData Profile to find backend counter in
+     * @param conditionId backend counter id to update
+     * @param questId quest id counter is associated with
+     * @param counterValue value to increment the backend counter with
+     */
+    protected updateProfileBackendCounterValue(pmcData: IPmcData, conditionId: string, questId: string, counterValue: number): void;
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/RagfairController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/RagfairController.d.ts
index c4ffc15..06af740 100644
--- a/TypeScript/12ClassExtensionOverride/types/controllers/RagfairController.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/controllers/RagfairController.d.ts
@@ -9,6 +9,7 @@ import { RagfairOfferHelper } from "../helpers/RagfairOfferHelper";
 import { RagfairSellHelper } from "../helpers/RagfairSellHelper";
 import { RagfairSortHelper } from "../helpers/RagfairSortHelper";
 import { RagfairTaxHelper } from "../helpers/RagfairTaxHelper";
+import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
@@ -33,6 +34,9 @@ import { RagfairPriceService } from "../services/RagfairPriceService";
 import { RagfairRequiredItemsService } from "../services/RagfairRequiredItemsService";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/**
+ * Handle RagfairCallback events
+ */
 export declare class RagfairController {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
@@ -52,14 +56,20 @@ export declare class RagfairController {
     protected handbookHelper: HandbookHelper;
     protected paymentHelper: PaymentHelper;
     protected inventoryHelper: InventoryHelper;
+    protected traderHelper: TraderHelper;
     protected ragfairHelper: RagfairHelper;
     protected ragfairOfferService: RagfairOfferService;
     protected ragfairRequiredItemsService: RagfairRequiredItemsService;
     protected ragfairOfferGenerator: RagfairOfferGenerator;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
     getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult;
+    /**
+     * Update a trader flea offer with buy restrictions stored in the traders assort
+     * @param offer flea offer to update
+     */
+    protected setTraderOfferPurchaseLimits(offer: IRagfairOffer): void;
     protected isLinkedSearch(info: ISearchRequestData): boolean;
     protected isRequiredSearch(info: ISearchRequestData): boolean;
     update(): void;
diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/RepeatableQuestController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/RepeatableQuestController.d.ts
index 98d05dd..4c31a3d 100644
--- a/TypeScript/12ClassExtensionOverride/types/controllers/RepeatableQuestController.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/controllers/RepeatableQuestController.d.ts
@@ -7,6 +7,7 @@ import { Exit } from "../models/eft/common/ILocationBase";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { TraderInfo } from "../models/eft/common/tables/IBotBase";
 import { ICompletion, ICompletionAvailableFor, IElimination, IEliminationCondition, IExploration, IExplorationCondition, IPmcDataRepeatableQuest, IRepeatableQuest, IReward, IRewards } from "../models/eft/common/tables/IRepeatableQuests";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
 import { IRepeatableQuestChangeRequest } from "../models/eft/quests/IRepeatableQuestChangeRequest";
 import { ELocationName } from "../models/enums/ELocationName";
@@ -15,6 +16,7 @@ import { ILogger } from "../models/spt/utils/ILogger";
 import { ItemEventRouter } from "../routers/ItemEventRouter";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { PaymentService } from "../services/PaymentService";
 import { ProfileFixerService } from "../services/ProfileFixerService";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -64,9 +66,10 @@ export declare class RepeatableQuestController {
     protected itemEventRouter: ItemEventRouter;
     protected paymentService: PaymentService;
     protected objectId: ObjectId;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
-    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, configServer: ConfigServer);
+    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint
      * Returns an array of objects in the format of repeatable quests to the client.
@@ -217,4 +220,16 @@ export declare class RepeatableQuestController {
     debugLogRepeatableQuestIds(pmcData: IPmcData): void;
     probabilityObjectArray<K, V>(configArrayInput: ProbabilityObject<K, V>[]): ProbabilityObjectArray<K, V>;
     changeRepeatableQuest(pmcDataIn: IPmcData, body: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
+     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
+     */
+    protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig): [string, ITemplateItem][];
+    /**
+     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
+     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
+     * @param {*} tpl template id of item to check
+     * @returns boolean: true if item is valid reward
+     */
+    isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig): boolean;
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/TraderController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/TraderController.d.ts
index 0162064..b79f55e 100644
--- a/TypeScript/12ClassExtensionOverride/types/controllers/TraderController.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/controllers/TraderController.d.ts
@@ -4,6 +4,7 @@ import { TraderHelper } from "../helpers/TraderHelper";
 import { IBarterScheme, ITraderAssort, ITraderBase } from "../models/eft/common/tables/ITrader";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { FenceService } from "../services/FenceService";
 import { TraderAssortService } from "../services/TraderAssortService";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
@@ -15,8 +16,9 @@ export declare class TraderController {
     protected traderHelper: TraderHelper;
     protected timeUtil: TimeUtil;
     protected traderAssortService: TraderAssortService;
+    protected fenceService: FenceService;
     protected jsonUtil: JsonUtil;
-    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, jsonUtil: JsonUtil);
+    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, fenceService: FenceService, jsonUtil: JsonUtil);
     /**
      * Runs when onLoad event is fired
      * Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
@@ -26,6 +28,7 @@ export declare class TraderController {
     /**
      * Runs when onUpdate is fired
      * If current time is > nextResupply(expire) time of trader, refresh traders assorts and
+     * Fence is handled slightly differently
      * @returns has run
      */
     update(): boolean;
diff --git a/TypeScript/12ClassExtensionOverride/types/di/Container.d.ts b/TypeScript/12ClassExtensionOverride/types/di/Container.d.ts
index 17791b0..98d1fa1 100644
--- a/TypeScript/12ClassExtensionOverride/types/di/Container.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/di/Container.d.ts
@@ -1,4 +1,7 @@
 import { DependencyContainer } from "tsyringe";
+/**
+ * Handle the registration of classes to be used by the Dependency Injection code
+ */
 export declare class Container {
     static registerTypes(depContainer: DependencyContainer): void;
     static registerListTypes(depContainer: DependencyContainer): void;
diff --git a/TypeScript/12ClassExtensionOverride/types/generators/BotGenerator.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/BotGenerator.d.ts
index a5fc0ad..7d58f95 100644
--- a/TypeScript/12ClassExtensionOverride/types/generators/BotGenerator.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/generators/BotGenerator.d.ts
@@ -40,7 +40,7 @@ export declare class BotGenerator {
      * @param botTemplate base bot template to use  (e.g. assault/pmcbot)
      * @returns
      */
-    generatePlayerScav(role: string, difficulty: string, botTemplate: IBotType): IBotBase;
+    generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase;
     generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[];
     /**
      * Choose if a bot should become a PMC by checking if bot type is allowed to become a Pmc in botConfig.convertFromChances and doing a random int check
@@ -58,7 +58,7 @@ export declare class BotGenerator {
      * @returns IBotBase object
      */
     protected getCloneOfBotBase(): IBotBase;
-    protected generateBot(bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
+    protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
     /**
      * Log the number of PMCs generated to the debug console
      */
diff --git a/TypeScript/12ClassExtensionOverride/types/generators/BotInventoryGenerator.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/BotInventoryGenerator.d.ts
index 35d1ee8..73f8ece 100644
--- a/TypeScript/12ClassExtensionOverride/types/generators/BotInventoryGenerator.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/generators/BotInventoryGenerator.d.ts
@@ -18,7 +18,7 @@ export declare class BotInventoryGenerator {
     protected botGeneratorHelper: BotGeneratorHelper;
     protected weightedRandomHelper: WeightedRandomHelper;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper);
-    generateInventory(templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
+    generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
     protected generateEquipment(equipmentSlot: string, equipmentPool: Record<string, number>, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void;
     protected generateInventoryBase(): PmcInventory;
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/generators/BotLootGenerator.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/BotLootGenerator.d.ts
index c6a3f29..5a2d144 100644
--- a/TypeScript/12ClassExtensionOverride/types/generators/BotLootGenerator.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/generators/BotLootGenerator.d.ts
@@ -24,7 +24,7 @@ export declare class BotLootGenerator {
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botLootCacheService: BotLootCacheService, configServer: ConfigServer);
-    generateLoot(templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
+    generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
     protected getRandomisedCount(min: number, max: number, nValue: number): number;
     /**
      * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached
@@ -47,7 +47,7 @@ export declare class BotLootGenerator {
      * @param botRole bots role, .e.g. pmcBot
      * @param isPmc are we generating for a pmc
      */
-    protected addLooseWeaponsToInventorySlot(botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
+    protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
     /**
      * Get a random item from the pool parameter using the biasedRandomNumber system
      * @param pool pool of items to pick an item from
diff --git a/TypeScript/12ClassExtensionOverride/types/generators/BotWeaponGenerator.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/BotWeaponGenerator.d.ts
index 9215214..49fa7bf 100644
--- a/TypeScript/12ClassExtensionOverride/types/generators/BotWeaponGenerator.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/generators/BotWeaponGenerator.d.ts
@@ -28,7 +28,18 @@ export declare class BotWeaponGenerator {
     protected botConfig: IBotConfig;
     constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer);
     /**
-     * Get a random weapon from a bots pool of weapons (weighted)
+     * Pick a random weapon based on weightings and generate a functional weapon
+     * @param equipmentSlot Primary/secondary/holster
+     * @param botTemplateInventory e.g. assault.json
+     * @param weaponParentId
+     * @param modChances
+     * @param botRole role of bot, e.g. assault/followerBully
+     * @param isPmc Is weapon generated for a pmc
+     * @returns GenerateWeaponResult object
+     */
+    generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    /**
+     * Get a random weighted weapon from a bots pool of weapons
      * @param equipmentSlot Primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
      * @returns weapon tpl
@@ -39,43 +50,24 @@ export declare class BotWeaponGenerator {
      * @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool())
      * @param equipmentSlot slot to fit into, primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
+     * @param weaponParentId ParentId of the weapon being generated
+     * @param modChances Dictionary of item types and % chance weapon will have that mod
+     * @param botRole e.g. assault/exusec
      * @param isPmc
      * @returns GenerateWeaponResult object
      */
-    generateWeaponByTpl(weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
     /**
-     * Generate an entirely random weapon
-     * @param equipmentSlot Primary/secondary/holster
-     * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
-     * @param isPmc
-     * @returns GenerateWeaponResult object
-     */
-    generateRandomWeapon(equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
-    /**
-     * Create array with weapon base as only element
-     * Add additional properties as required
-     * @param weaponTpl
-     * @param weaponParentId
-     * @param equipmentSlot
-     * @param weaponItemTemplate
+     * Create array with weapon base as only element and
+     * add additional properties based on weapon type
+     * @param weaponTpl Weapon tpl to create item with
+     * @param weaponParentId Weapons parent id
+     * @param equipmentSlot e.g. primary/secondary/holster
+     * @param weaponItemTemplate db template for weapon
      * @param botRole for durability values
-     * @returns
+     * @returns Base weapon item in array
      */
     constructWeaponBaseArray(weaponTpl: string, weaponParentId: string, equipmentSlot: string, weaponItemTemplate: ITemplateItem, botRole: string): Item[];
-    /**
-     * Add compatible magazines to an inventory based on a generated weapon
-     * @param weaponDetails
-     * @param magCounts
-     * @param inventory
-     * @param botRole the bot type we're getting generating extra mags for
-     */
-    addExtraMagazinesToInventory(weaponDetails: GenerateWeaponResult, magCounts: MinMax, inventory: PmcInventory, botRole: string): void;
     /**
      * Get the mods necessary to kit out a weapon to its preset level
      * @param weaponTpl weapon to find preset for
@@ -84,20 +76,32 @@ export declare class BotWeaponGenerator {
      * @returns array of weapon mods
      */
     protected getPresetWeaponMods(weaponTpl: string, equipmentSlot: string, weaponParentId: string, itemTemplate: ITemplateItem, botRole: string): Item[];
-    /** Checks if all required slots are occupied on a weapon and all it's mods */
+    /**
+     * Checks if all required slots are occupied on a weapon and all it's mods
+     * @param weaponItemArray Weapon + mods
+     * @returns true if valid
+     */
     protected isWeaponValid(weaponItemArray: Item[]): boolean;
     /**
      * Generates extra magazines or bullets (if magazine is internal) and adds them to TacticalVest and Pockets.
      * Additionally, adds extra bullets to SecuredContainer
-     * @param weaponMods
-     * @param weaponTemplate
-     * @param magCounts
-     * @param ammoTpl
-     * @param inventory
+     * @param weaponMods mods to attach to weapon
+     * @param weaponTemplate db template for weapon
+     * @param magCounts magazine count to add to inventory
+     * @param ammoTpl ammo templateId to add to magazines
+     * @param inventory inventory to add magazines to
      * @param botRole the bot type we're getting generating extra mags for
      * @returns
      */
-    protected generateExtraMagazines(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    addExtraMagazinesToInventory(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    /**
+     * Create a magazine using the parameters given
+     * @param magazineTpl Tpl of the magazine to create
+     * @param ammoTpl Ammo to add to magazine
+     * @param magTemplate template object of magazine
+     * @returns Item array
+     */
+    protected createMagazine(magazineTpl: string, ammoTpl: string, magTemplate: ITemplateItem): Item[];
     /**
      * Get a randomised number of bullets for a specific magazine
      * @param magCounts min and max count of magazines
@@ -138,10 +142,9 @@ export declare class BotWeaponGenerator {
      * Finds and return a compatible ammo tpl based on the bots ammo weightings (x.json/inventory/equipment/ammo)
      * @param ammo a list of ammo tpls the weapon can use
      * @param weaponTemplate the weapon we want to pick ammo for
-     * @param isPmc is the ammo being gathered for a pmc (runs pmc ammo filtering)
      * @returns an ammo tpl that works with the desired gun
      */
-    protected getCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem, isPmc: boolean): string;
+    protected getWeightedCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem): string;
     /**
      * Get a weapons compatible cartridge caliber
      * @param weaponTemplate Weapon to look up caliber of
diff --git a/TypeScript/12ClassExtensionOverride/types/generators/LocationGenerator.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/LocationGenerator.d.ts
index bd368b5..cc61dcf 100644
--- a/TypeScript/12ClassExtensionOverride/types/generators/LocationGenerator.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/generators/LocationGenerator.d.ts
@@ -3,10 +3,9 @@ import { GameEventHelper } from "../helpers/GameEventHelper";
 import { ItemHelper } from "../helpers/ItemHelper";
 import { PresetHelper } from "../helpers/PresetHelper";
 import { RagfairServerHelper } from "../helpers/RagfairServerHelper";
-import { ILooseLoot, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
+import { ILooseLoot, SpawnpointsForced, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IStaticAmmoDetails, IStaticContainerProps, IStaticForcedProps, IStaticLootDetails } from "../models/eft/common/tables/ILootBase";
-import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILocationConfig } from "../models/spt/config/ILocationConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
@@ -36,11 +35,19 @@ export declare class LocationGenerator {
     generateContainerLoot(containerIn: IStaticContainerProps, staticForced: IStaticForcedProps[], staticLootDist: Record<string, IStaticLootDetails>, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): IStaticContainerProps;
     protected getLooseLootMultiplerForLocation(location: string): number;
     protected getStaticLootMultiplerForLocation(location: string): number;
+    /**
+     * Create array of loose + forced loot using probability system
+     * @param dynamicLootDist
+     * @param staticAmmoDist
+     * @param locationName Location to generate loot for
+     * @returns Array of spawn points with loot in them
+     */
     generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): SpawnpointTemplate[];
+    /**
+     * Add forced spawn point loot into loot parameter array
+     * @param loot array to add forced loot to
+     * @param forcedSpawnPoints forced loot to add
+     */
+    protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[]): void;
     protected createItem(tpl: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, parentId?: string): IContainerItem;
-    protected getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
-    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
-    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
-    protected createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
-    protected createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/generators/LootGenerator.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/12ClassExtensionOverride/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/12ClassExtensionOverride/types/generators/PMCLootGenerator.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/PMCLootGenerator.d.ts
index 64e6f7f..b9f2a83 100644
--- a/TypeScript/12ClassExtensionOverride/types/generators/PMCLootGenerator.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/generators/PMCLootGenerator.d.ts
@@ -1,15 +1,21 @@
 import { ItemHelper } from "../helpers/ItemHelper";
-import { DatabaseServer } from "../servers/DatabaseServer";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+/**
+ * Handle the generation of dynamic PMC loot in pockets and backpacks
+ * and the removal of blacklisted items
+ */
 export declare class PMCLootGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected configServer: ConfigServer;
+    protected itemFilterService: ItemFilterService;
     protected pocketLootPool: string[];
     protected backpackLootPool: string[];
     protected botConfig: IBotConfig;
-    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer);
+    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer, itemFilterService: ItemFilterService);
     generatePMCPocketLootPool(): string[];
     generatePMCBackpackLootPool(): string[];
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/generators/ScavCaseRewardGenerator.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/ScavCaseRewardGenerator.d.ts
index c7d6ab7..89cb5c8 100644
--- a/TypeScript/12ClassExtensionOverride/types/generators/ScavCaseRewardGenerator.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/generators/ScavCaseRewardGenerator.d.ts
@@ -8,9 +8,13 @@ import { RewardCountAndPriceDetails, ScavCaseRewardCountsAndPrices } from "../mo
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { RagfairPriceService } from "../services/RagfairPriceService";
 import { HashUtil } from "../utils/HashUtil";
 import { RandomUtil } from "../utils/RandomUtil";
+/**
+ * Handle the creation of randomised scav case rewards
+ */
 export declare class ScavCaseRewardGenerator {
     protected logger: ILogger;
     protected randomUtil: RandomUtil;
@@ -18,9 +22,10 @@ export declare class ScavCaseRewardGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected ragfairPriceService: RagfairPriceService;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected scavCaseConfig: IScavCaseConfig;
-    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, configServer: ConfigServer);
+    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Create an array of rewards that will be given to the player upon completing their scav case build
      * @param body client request
diff --git a/TypeScript/12ClassExtensionOverride/types/generators/WeatherGenerator.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/WeatherGenerator.d.ts
index 44cecbb..8ddbe49 100644
--- a/TypeScript/12ClassExtensionOverride/types/generators/WeatherGenerator.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/generators/WeatherGenerator.d.ts
@@ -1,7 +1,7 @@
 import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IWeatherData } from "../models/eft/weather/IWeatherData";
 import { IWeatherConfig } from "../models/spt/config/IWeatherConfig";
+import { ConfigServer } from "../servers/ConfigServer";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class WeatherGenerator {
@@ -21,11 +21,16 @@ export declare class WeatherGenerator {
     protected getAcceleratedTime(computedDate: Date): string;
     /**
      * Get current time formatted to fit BSGs requirement
-     * @param computedDate
+     * @param computedDate date to format into bsg style
      * @returns
      */
     protected getNormalTime(computedDate: Date): string;
-    generateWeather(data: IWeatherData): IWeatherData;
+    /**
+     * Return randomised Weather data
+     * @param weatherData weather input data
+     * @returns Randomised weather data
+     */
+    generateWeather(weatherData: IWeatherData): IWeatherData;
     protected getWeightedFog(): string;
     protected getWeightedRain(): number;
     protected getRandomFloat(node: string): number;
diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/AssortHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/AssortHelper.d.ts
index 15586b9..bfc157f 100644
--- a/TypeScript/12ClassExtensionOverride/types/helpers/AssortHelper.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/helpers/AssortHelper.d.ts
@@ -17,7 +17,7 @@ export declare class AssortHelper {
      * @param assort assort items from a trader
      * @returns assort items minus locked quest assorts
      */
-    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort): ITraderAssort;
+    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort, flea?: boolean): ITraderAssort;
     /**
      * Remove assorts from a trader that have not been unlocked yet
      * @param pmcProfile player profile
@@ -32,5 +32,5 @@ export declare class AssortHelper {
      * @param itemID item id to remove from asort
      * @returns Modified assort
      */
-    removeItemFromAssort(assort: ITraderAssort, itemID: string): ITraderAssort;
+    removeItemFromAssort(assort: ITraderAssort, itemID: string, flea?: boolean): ITraderAssort;
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/BotGeneratorHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/BotGeneratorHelper.d.ts
index 3cd7256..eb0d215 100644
--- a/TypeScript/12ClassExtensionOverride/types/helpers/BotGeneratorHelper.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/helpers/BotGeneratorHelper.d.ts
@@ -3,10 +3,12 @@ import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"
 import { Mods, ModsChances } from "../models/eft/common/tables/IBotType";
 import { Item, Repairable, Upd } from "../models/eft/common/tables/IItem";
 import { Grid, ITemplateItem, Slot } from "../models/eft/common/tables/ITemplateItem";
-import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
@@ -14,6 +16,7 @@ import { ContainerHelper } from "./ContainerHelper";
 import { InventoryHelper } from "./InventoryHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProbabilityHelper } from "./ProbabilityHelper";
+import { ProfileHelper } from "./ProfileHelper";
 export declare class BotGeneratorHelper {
     protected logger: ILogger;
     protected jsonUtil: JsonUtil;
@@ -25,10 +28,76 @@ export declare class BotGeneratorHelper {
     protected itemHelper: ItemHelper;
     protected inventoryHelper: InventoryHelper;
     protected containerHelper: ContainerHelper;
+    protected botEquipmentFilterService: BotEquipmentFilterService;
+    protected itemFilterService: ItemFilterService;
+    protected profileHelper: ProfileHelper;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, configServer: ConfigServer);
-    generateModsForItem(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, configServer: ConfigServer);
+    /**
+     * TODO - very similar to generateModsForWeapon
+     * Check mods are compatible and add to array
+     * @param equipment Equipment item to add mods to
+     * @param modPool Mod list to choose frm
+     * @param parentId parentid of item to add mod to
+     * @param parentTemplate template objet of item to add mods to
+     * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type
+     * @returns Item + compatible mods as an array
+     */
+    generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    /**
+     * TODO - very similar to generateModsForEquipment
+     * @param sessionId session id
+     * @param weapon Weapon to add mods to
+     * @param modPool pool of compatible mods to attach to gun
+     * @param weaponParentId parentId of weapon
+     * @param parentTemplate
+     * @param modSpawnChances
+     * @param ammoTpl ammo tpl to use when generating magazines/cartridges
+     * @param botRole role of bot weapon is generated for
+     * @returns Weapon with mods
+     */
+    generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[];
+    /**
+     * Generate a pool of mods for this bots mod type if bot has values inside `randomisedWeaponModSlots` array found in bot.json/equipment[botrole]
+     * @param allowedMods Mods to be added to mod pool
+     * @param botEquipBlacklist blacklist of items not allowed to be added to mod pool
+     * @param modSlot Slot to generate mods for
+     * @param itemModPool base mod pool to replace values of
+     */
+    protected generateDynamicModPool(allowedMods: string[], botEquipBlacklist: EquipmentFilterDetails, modSlot: string, itemModPool: Record<string, string[]>): void;
+    /**
+     * Check if the specific item type on the weapon has reached the set limit
+     * @param modTpl item to check is limited
+     * @param currentCount current number of this item on gun
+     * @param maxLimit mod limit allowed
+     * @param botRole role of bot we're checking weapon of
+     * @returns true if limit reached
+     */
+    protected weaponModLimitReached(modTpl: string, currentCount: {
+        count: number;
+    }, maxLimit: number, botRole: string): boolean;
+    /**
+     * log errors if mod is not valid for a slot
+     * @param modTpl
+     * @param found
+     * @param itemSlot
+     * @param modTemplate
+     * @param modSlot
+     * @param parentTemplate
+     * @returns true if valid
+     */
+    protected isModValidForSlot(modTpl: string, found: boolean, itemSlot: Slot, modTemplate: ITemplateItem, modSlot: string, parentTemplate: ITemplateItem): boolean;
+    /**
+     * Create a mod item with parameters as properties
+     * @param modId _id
+     * @param modTpl _tpl
+     * @param parentId parentId
+     * @param modSlot slotId
+     * @param modTemplate Used to add additional properites in the upd object
+     * @returns Item object
+     */
+    protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item;
     /**
      * Is this magazine cylinder related (revolvers and grenade launchers)
      * @param magazineParentName the name of the magazines parent
@@ -62,11 +131,11 @@ export declare class BotGeneratorHelper {
      * Those magazines (e.g. 60dc519adf4c47305f6d410d) have a "Cartridges" entry with a _max_count=0.
      * Ammo is not put into the magazine directly but assigned to the magazine's slots: The "camora_xxx" slots.
      * This function is a helper called by generateModsForItem for mods with parent type "CylinderMagazine"
-     *
-     * @param {object}      items               The items where the CylinderMagazine's camora are appended to
-     * @param {object}      modPool             modPool which should include available cartrigdes
-     * @param {string}      parentId            The CylinderMagazine's UID
-     * @param {object}      parentTemplate      The CylinderMagazine's template
+     * @param items The items where the CylinderMagazine's camora are appended to
+     * @param modPool modPool which should include available cartrigdes
+     * @param parentId The CylinderMagazine's UID
+     * @param parentTemplate The CylinderMagazine's template
+     * @returns
      */
     protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void;
     /**
@@ -75,6 +144,13 @@ export declare class BotGeneratorHelper {
      * @returns string array of shells fro luitple camora sources
      */
     protected mergeCamoraPoolsTogether(camorasWithShells: Record<string, string[]>): string[];
+    /**
+     * Adds properties to an item
+     * e.g. Repairable / HasHinge / Foldable / MaxDurability
+     * @param itemTemplate
+     * @param botRole Used by weapons to randomise the durability values
+     * @returns Item Upd object with extra properties
+     */
     generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): {
         upd?: Upd;
     };
@@ -93,12 +169,6 @@ export declare class BotGeneratorHelper {
      */
     protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable;
     protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string;
-    /**
-     * Sort by spawn chance, highest to lowest, higher is more common
-     * @param unsortedModArray String array to sort
-     * @returns Sorted string array
-     */
-    protected sortModArray(unsortedModArray: string[]): string[];
     /**
      * Can an item be added to an item without issue
      * @param items
@@ -117,8 +187,15 @@ export declare class BotGeneratorHelper {
      * @returns a `boolean` indicating item was added
      */
     addItemWithChildrenToEquipmentSlot(equipmentSlots: string[], parentId: string, parentTpl: string, itemWithChildren: Item[], inventory: PmcInventory): boolean;
+    /**
+     * is the provided item allowed inside a container
+     * @param slot location item wants to be placed in
+     * @param itemTpl item being placed
+     * @returns true if allowed
+     */
     protected itemAllowedInContainer(slot: Grid, itemTpl: string): boolean;
 }
+/** TODO - move into own class */
 export declare class ExhaustableArray<T> {
     private itemPool;
     private randomUtil;
diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/HideoutHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/HideoutHelper.d.ts
index 36e4009..7495a6a 100644
--- a/TypeScript/12ClassExtensionOverride/types/helpers/HideoutHelper.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/helpers/HideoutHelper.d.ts
@@ -44,14 +44,72 @@ export declare class HideoutHelper {
     initProduction(recipeId: string, productionTime: number): Production;
     isProductionType(productive: Productive): productive is Production;
     applyPlayerUpgradesBonuses(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * TODO:
+     * After looking at the skills there doesnt seem to be a configuration per skill to boost
+     * the XP gain PER skill. I THINK you should be able to put the variable "SkillProgress" (just like health has it)
+     * and be able to tune the skill gain PER skill, but I havent tested it and Im not sure!
+     * @param pmcData
+     * @param bonus
+     */
     protected applySkillXPBoost(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * Process a players hideout, update areas that use resources + increment production timers
+     * @param sessionID Session id
+     */
     updatePlayerHideout(sessionID: string): void;
+    /**
+     * Update progress timer for water collector
+     * @param pmcData profile to update
+     * @param productionId id of water collection production to update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateWaterCollectorProductionTimer(pmcData: IPmcData, productionId: string, hideoutProperties: {
+        btcFarmCGs?: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Iterate over productions and update their progress timers
+     * @param pmcData Profile to check for productions and update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Update progress timer for scav case
+     * @param pmcData Profile to update
+     * @param productionId Id of scav case production to update
+     */
+    protected updateScavCaseProductionTimer(pmcData: IPmcData, productionId: string): void;
+    /**
+     * Iterate over hideout areas that use resources (fuel/filters etc) and update associated values
+     * @param sessionID Session id
+     * @param pmcData Profile to update areas of
+     * @param hideoutProperties hideout properties
+     */
+    protected updateAreasWithResources(sessionID: string, pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
     protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
     protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
-    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): HideoutArea;
-    protected updateWaterFilters(waterFilterArea: HideoutArea, pwProd: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
+    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): void;
+    /**
+     * Adjust water filter objects resourceValue or delete when they reach 0 resource
+     * @param waterFilterArea water filter area to update
+     * @param production production object
+     * @param isGeneratorOn is generatory enabled
+     * @param pmcData Player profile
+     * @returns Updated HideoutArea object
+     */
+    protected updateWaterFilters(waterFilterArea: HideoutArea, production: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
     protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
-    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): HideoutArea;
+    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): void;
     protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
     protected getBTCSlots(pmcData: IPmcData): number;
     protected getManagementSkillsSlots(): number;
diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/InRaidHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/InRaidHelper.d.ts
index b382e30..962df38 100644
--- a/TypeScript/12ClassExtensionOverride/types/helpers/InRaidHelper.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/helpers/InRaidHelper.d.ts
@@ -18,18 +18,6 @@ export declare class InRaidHelper {
     protected paymentHelper: PaymentHelper;
     protected profileFixerService: ProfileFixerService;
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper, profileFixerService: ProfileFixerService);
-    /**
-     * Reset the SPT inraid property stored in a profile to 'none'
-     * @param sessionID Session id
-     */
-    protected removePlayer(sessionID: string): void;
-    /**
-     * Some maps have one-time-use keys (e.g. Labs
-     * Remove the relevant key from an inventory based on the post-raid request data passed in
-     * @param offraidData post-raid data
-     * @param sessionID Session id
-     */
-    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
     /**
      * Check an array of items and add an upd object to money items with a stack count of 1
      * Single stack money items have no upd object and thus no StackObjectsCount, causing issues
@@ -54,6 +42,18 @@ export declare class InRaidHelper {
      * @returns Reset profile object
      */
     updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData;
+    /**
+     * Some maps have one-time-use keys (e.g. Labs
+     * Remove the relevant key from an inventory based on the post-raid request data passed in
+     * @param offraidData post-raid data
+     * @param sessionID Session id
+     */
+    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Set the SPT inraid location Profile property to 'none'
+     * @param sessionID Session id
+     */
+    protected setPlayerInRaidLocationStatusToNone(sessionID: string): void;
     /**
      * Adds SpawnedInSession property to items found in a raid
      * Removes SpawnedInSession for non-scav players if item was taken into raid with SpawnedInSession = true
@@ -95,5 +95,10 @@ export declare class InRaidHelper {
      * @returns true if item is kept after death
      */
     isItemKeptAfterDeath(slotId: string): boolean;
+    /**
+     * Return the equipped items from a players inventory
+     * @param items Players inventory to search through
+     * @returns an array of equipped items
+     */
     getPlayerGear(items: Item[]): Item[];
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/ItemHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/ItemHelper.d.ts
index 1701c62..de10892 100644
--- a/TypeScript/12ClassExtensionOverride/types/helpers/ItemHelper.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/helpers/ItemHelper.d.ts
@@ -1,35 +1,30 @@
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item, Repairable } from "../models/eft/common/tables/IItem";
+import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase";
 import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+import { MathUtil } from "../utils/MathUtil";
+import { ObjectId } from "../utils/ObjectId";
+import { RandomUtil } from "../utils/RandomUtil";
 declare class ItemHelper {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
     protected jsonUtil: JsonUtil;
+    protected randomUtil: RandomUtil;
+    protected objectId: ObjectId;
+    protected mathUtil: MathUtil;
     protected databaseServer: DatabaseServer;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer);
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer);
     /**
      * Checks if a id is a valid item. Valid meaning that it's an item that be stored in stash
      * @param       {string}    tpl       the template id / tpl
      * @returns                             boolean; true for items that may be in player posession and not quest items
      */
     isValidItem(tpl: string, invalidBaseTypes?: string[]): boolean;
-    /**
-     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
-     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
-     * @param {*} tpl template id of item to check
-     * @returns boolean: true if item is valid reward
-     */
-    isValidRewardItem(tpl: string): boolean;
-    /**
-     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
-     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
-     */
-    getRewardableItems(): [string, ITemplateItem][];
     /**
      * Check if the tpl / template Id provided is a descendent of the baseclass
      *
@@ -196,6 +191,22 @@ declare class ItemHelper {
      * @returns ItemSize object (width and height)
      */
     getItemSize(items: Item[], rootItemId: string): ItemHelper.ItemSize;
+    /**
+     * Get a random cartridge from an items Filter property
+     * @param item
+     * @returns
+     */
+    getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
+    createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
+    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
+    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
+    createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
+    /**
+     * Get the size of a stack, return 1 if no stack object count property found
+     * @param item Item to get stack size of
+     * @returns size of stack
+     */
+    getItemStackSize(item: Item): number;
 }
 declare namespace ItemHelper {
     interface ItemSize {
diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/ProfileHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/ProfileHelper.d.ts
index 9d4ff98..9c6560a 100644
--- a/TypeScript/12ClassExtensionOverride/types/helpers/ProfileHelper.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/helpers/ProfileHelper.d.ts
@@ -24,6 +24,19 @@ export declare class ProfileHelper {
     constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, fenceService: FenceService);
     resetProfileQuestCondition(sessionID: string, conditionId: string): void;
     getCompleteProfile(sessionID: string): IPmcData[];
+    /**
+     * Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
+     * Server saves the post-raid changes prior to the xp screen getting the profile, this results in the xp screen using
+     * the now updated profile values as a base, meaning it shows x2 xp gained
+     * Instead, clone the post-raid profile (so we dont alter its values), apply the pre-raid xp values to the cloned objects and return
+     * Delete snapshot of pre-raid profile prior to returning profile data
+     * @param sessionId Session id
+     * @param output pmc and scav profiles array
+     * @param pmcProfile post-raid pmc profile
+     * @param scavProfile post-raid scav profile
+     * @returns updated profile array
+     */
+    protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
     isNicknameTaken(info: IValidateNicknameRequestData, sessionID: string): boolean;
     /**
      * Add experience to a PMC inside the players profile
diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/QuestHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/QuestHelper.d.ts
index 32e55ec..d66d150 100644
--- a/TypeScript/12ClassExtensionOverride/types/helpers/QuestHelper.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/helpers/QuestHelper.d.ts
@@ -36,11 +36,20 @@ export declare class QuestHelper {
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
     constructor(logger: ILogger, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, itemHelper: ItemHelper, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, localeService: LocaleService, ragfairServerHelper: RagfairServerHelper, dialogueHelper: DialogueHelper, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, traderHelper: TraderHelper, configServer: ConfigServer);
-    questStatus(pmcData: IPmcData, questID: string): QuestStatus;
     /**
-     * returns true is the condition is satisfied
+    * Get status of a quest by quest id
+    * @param pmcData Profile to search
+    * @param questID Quest id to look up
+    * @returns QuestStauts enum
+    */
+    getQuestStatus(pmcData: IPmcData, questID: string): QuestStatus;
+    /**
+     * returns true is the level condition is satisfied
+     * @param playerLevel Players level
+     * @param condition Quest condition
+     * @returns true if player level is greater than or equal to quest
      */
-    evaluateLevel(pmcProfile: IPmcData, cond: AvailableForConditions): boolean;
+    doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean;
     getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[];
     /**
      * Increase skill points of a skill on player profile
diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/RagfairOfferHelper.d.ts
index 8d03bee..e9d72ca 100644
--- a/TypeScript/12ClassExtensionOverride/types/helpers/RagfairOfferHelper.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/helpers/RagfairOfferHelper.d.ts
@@ -22,12 +22,14 @@ import { ProfileHelper } from "./ProfileHelper";
 import { RagfairHelper } from "./RagfairHelper";
 import { RagfairServerHelper } from "./RagfairServerHelper";
 import { RagfairSortHelper } from "./RagfairSortHelper";
+import { TraderHelper } from "./TraderHelper";
 export declare class RagfairOfferHelper {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
     protected hashUtil: HashUtil;
     protected itemEventRouter: ItemEventRouter;
     protected databaseServer: DatabaseServer;
+    protected traderHelper: TraderHelper;
     protected saveServer: SaveServer;
     protected dialogueHelper: DialogueHelper;
     protected itemHelper: ItemHelper;
@@ -43,10 +45,10 @@ export declare class RagfairOfferHelper {
     protected static goodSoldTemplate: string;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, traderHelper: TraderHelper, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
     getValidOffers(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
     getOffersForBuild(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
-    processOffers(sessionID: string): boolean;
+    processOffersOnProfile(sessionID: string): boolean;
     protected getProfileOffers(sessionID: string): IRagfairOffer[];
     protected deleteOfferByOfferId(sessionID: string, offerId: string): void;
     protected completeOffer(sessionID: string, offer: IRagfairOffer, boughtAmount: number): IItemEventRouterResponse;
diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/RagfairSellHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/RagfairSellHelper.d.ts
index 6ec004a..91b8a20 100644
--- a/TypeScript/12ClassExtensionOverride/types/helpers/RagfairSellHelper.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/helpers/RagfairSellHelper.d.ts
@@ -11,6 +11,12 @@ export declare class RagfairSellHelper {
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     constructor(logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer);
-    calculateSellChance(baseChance: number, offerPrice: number, requirementsPriceInRub: number): number;
-    rollForSale(sellChance: number, count: number): SellResult[];
+    calculateSellChance(baseChancePercent: number, offerPriceRub: number, playerListedPriceRub: number): number;
+    /**
+     * Determine if the offer being listed will be sold
+     * @param sellChancePercent chance item will sell
+     * @param itemSellCount count of items to sell
+     * @returns Array of purchases of item(s) lsited
+     */
+    rollForSale(sellChancePercent: number, itemSellCount: number): SellResult[];
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/RagfairServerHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/RagfairServerHelper.d.ts
index e4939d1..a03cdda 100644
--- a/TypeScript/12ClassExtensionOverride/types/helpers/RagfairServerHelper.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/helpers/RagfairServerHelper.d.ts
@@ -6,6 +6,7 @@ import { IRagfairConfig } from "../models/spt/config/IRagfairConfig";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { SaveServer } from "../servers/SaveServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { LocaleService } from "../services/LocaleService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -13,6 +14,9 @@ import { RandomUtil } from "../utils/RandomUtil";
 import { DialogueHelper } from "./DialogueHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProfileHelper } from "./ProfileHelper";
+/**
+ * Helper class for common ragfair server actions
+ */
 export declare class RagfairServerHelper {
     protected randomUtil: RandomUtil;
     protected hashUtil: HashUtil;
@@ -23,11 +27,12 @@ export declare class RagfairServerHelper {
     protected localeService: LocaleService;
     protected dialogueHelper: DialogueHelper;
     protected jsonUtil: JsonUtil;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
     protected static goodsReturnedTemplate: string;
-    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, configServer: ConfigServer);
+    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Is item valid / on blacklist / quest item
      * @param itemDetails
diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/TradeHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/TradeHelper.d.ts
index 975062b..7ab9768 100644
--- a/TypeScript/12ClassExtensionOverride/types/helpers/TradeHelper.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/helpers/TradeHelper.d.ts
@@ -39,6 +39,12 @@ export declare class TradeHelper {
      * @returns
      */
     sellItem(pmcData: IPmcData, body: IProcessSellTradeRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment the assorts buy count by number of items purchased
+     * Show error on screen if player attepts to buy more than what the buy max allows
+     * @param assortBeingPurchased assort being bought
+     * @param itemsPurchasedCount number of items being bought
+     */
     protected incrementAssortBuyCount(assortBeingPurchased: Item, itemsPurchasedCount: number): void;
     protected checkPurchaseIsWithinTraderItemLimit(assortBeingPurchased: Item, assortId: string, count: number): void;
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/TraderAssortHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/TraderAssortHelper.d.ts
index 677dd66..025efd6 100644
--- a/TypeScript/12ClassExtensionOverride/types/helpers/TraderAssortHelper.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/helpers/TraderAssortHelper.d.ts
@@ -1,6 +1,5 @@
 import { RagfairAssortGenerator } from "../generators/RagfairAssortGenerator";
 import { RagfairOfferGenerator } from "../generators/RagfairOfferGenerator";
-import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ITrader, ITraderAssort } from "../models/eft/common/tables/ITrader";
 import { ITraderConfig } from "../models/spt/config/ITraderConfig";
@@ -41,12 +40,7 @@ export declare class TraderAssortHelper {
      * @param traderId traders id
      * @returns a traders' assorts
      */
-    getAssort(sessionId: string, traderId: string): ITraderAssort;
-    /**
-     * if the fence assorts have expired, re-generate them
-     * @param pmcProfile Players profile
-     */
-    refreshFenceAssortIfExpired(pmcProfile: IPmcData): void;
+    getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort;
     /**
      * Reset a traders assorts and move nextResupply value to future
      * Flag trader as needing a flea offer reset to be picked up by flea update() function
diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/TraderHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/TraderHelper.d.ts
index 6bda5cd..0dc93e8 100644
--- a/TypeScript/12ClassExtensionOverride/types/helpers/TraderHelper.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/helpers/TraderHelper.d.ts
@@ -65,7 +65,7 @@ export declare class TraderHelper {
      * @param item
      * @returns boolean
      */
-    protected isWeaponAndBelowTraderBuyDurability(traderID: string, item: Item): boolean;
+    protected isWeaponBelowTraderBuyDurability(traderID: string, item: Item): boolean;
     /**
      * Get the price of an item and all of its attached children
      * Take into account bonuses/adjsutments e.g. discounts
diff --git a/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/ITemplateItem.d.ts b/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/ITemplateItem.d.ts
index 23a1a14..6b2fa8f 100644
--- a/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/ITemplateItem.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/ITemplateItem.d.ts
@@ -34,6 +34,7 @@ export interface Props {
     LootExperience?: number;
     ExamineExperience?: number;
     HideEntrails?: boolean;
+    InsuranceDisabled?: boolean;
     RepairCost?: number;
     RepairSpeed?: number;
     ExtraSizeLeft?: number;
@@ -206,6 +207,7 @@ export interface Props {
     IsOneoff?: boolean;
     MustBoltBeOpennedForExternalReload?: boolean;
     MustBoltBeOpennedForInternalReload?: boolean;
+    NoFiremodeOnBoltcatch?: boolean;
     BoltAction?: boolean;
     HipAccuracyRestorationDelay?: number;
     HipAccuracyRestorationSpeed?: number;
diff --git a/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/ITrader.d.ts b/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/ITrader.d.ts
index a84f5af..37b2d61 100644
--- a/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/ITrader.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/ITrader.d.ts
@@ -67,6 +67,7 @@ export interface IBarterScheme {
     count: number;
     _tpl: string;
     onlyFunctional?: boolean;
+    sptQuestLocked?: boolean;
 }
 export interface ISuit {
     _id: string;
diff --git a/TypeScript/12ClassExtensionOverride/types/models/eft/ragfair/IRagfairOffer.d.ts b/TypeScript/12ClassExtensionOverride/types/models/eft/ragfair/IRagfairOffer.d.ts
index 63f655e..141b605 100644
--- a/TypeScript/12ClassExtensionOverride/types/models/eft/ragfair/IRagfairOffer.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/models/eft/ragfair/IRagfairOffer.d.ts
@@ -15,6 +15,8 @@ export interface IRagfairOffer {
     name?: string;
     shortName?: string;
     loyaltyLevel: number;
+    buyRestrictionMax?: number;
+    buyRestrictionCurrent?: number;
     locked: boolean;
     unlimitedCount: boolean;
     summaryCost: number;
diff --git a/TypeScript/12ClassExtensionOverride/types/models/enums/AmmoTypes.d.ts b/TypeScript/12ClassExtensionOverride/types/models/enums/AmmoTypes.d.ts
index b52ddcf..254b410 100644
--- a/TypeScript/12ClassExtensionOverride/types/models/enums/AmmoTypes.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/models/enums/AmmoTypes.d.ts
@@ -23,7 +23,7 @@ export declare enum Ammo762x54 {
     BT_GZH = "5e023d34e8a400319a28ed44",
     BS_GZH = "5e023d48186a883be655e551"
 }
-export declare enum Ammo338Lapua {
+export declare enum Ammo86x70 {
     TAC_X = "5fc382b6d6fa9c00c571bbc3",
     UCW = "5fc382c1016cce60e8341b20",
     AP = "5fc382a9d724d907e2077dab",
@@ -85,13 +85,13 @@ export declare enum Ammo9x21 {
     PE_GZH = "5a26ac06c4a282000c5a90a8",
     BT_GZH = "5a26ac0ec4a28200741e1e18"
 }
-export declare enum Ammo357Mag {
+export declare enum Ammo9x33R {
     FMJ = "62330b3ed4dc74626d570b95",
     HOLLOW_POINT = "62330bfadc5883093563729b",
     SOFT_POINT = "62330c40bdd19b369e1e53d1",
     JACKET_HP = "62330c18744e5e31df12f516"
 }
-export declare enum Ammo45ACP {
+export declare enum Ammo1143x23ACP {
     MATCH_FMJ = "5e81f423763d9f754677bf2e",
     HYDRA_SHOK = "5efb0fc6aeb21837e749c801",
     LASERMATCH_FMJ = "5efb0d4f4bc50b58e81710f3",
@@ -126,7 +126,7 @@ export declare enum Ammo556x45 {
     MK_318_MOD_0_SOST = "60194943740c5d77f6705eea",
     SSA_AP = "601949593ae8f707c4608daa"
 }
-export declare enum Ammo300Blackout {
+export declare enum Ammo762x35 {
     M62_TRACER = "619636be6db0f2477964e710",
     BCP_FMJ = "5fbe3ffdf8b6a877a729ea82",
     AP = "5fd20ff893a8961fc660a954",
diff --git a/TypeScript/12ClassExtensionOverride/types/models/enums/BaseClasses.d.ts b/TypeScript/12ClassExtensionOverride/types/models/enums/BaseClasses.d.ts
index e733bca..37c1398 100644
--- a/TypeScript/12ClassExtensionOverride/types/models/enums/BaseClasses.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/models/enums/BaseClasses.d.ts
@@ -68,6 +68,7 @@ export declare enum BaseClasses {
     ASSAULT_SCOPE = "55818add4bdc2d5b648b456f",
     REFLEX_SIGHT = "55818ad54bdc2ddc698b4569",
     TACTICAL_COMBO = "55818b164bdc2ddc698b456c",
+    FLASHLIGHT = "55818b084bdc2d5b648b4571",
     MAGAZINE = "5448bc234bdc2d3c308b4569",
     LIGHT_LASER = "55818b0e4bdc2dde698b456e",
     FLASH_HIDER = "550aa4bf4bdc2dd6348b456b",
diff --git a/TypeScript/12ClassExtensionOverride/types/models/enums/ConfigTypes.d.ts b/TypeScript/12ClassExtensionOverride/types/models/enums/ConfigTypes.d.ts
index 61d6f99..468ece5 100644
--- a/TypeScript/12ClassExtensionOverride/types/models/enums/ConfigTypes.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/models/enums/ConfigTypes.d.ts
@@ -8,6 +8,7 @@ export declare enum ConfigTypes {
     IN_RAID = "aki-inraid",
     INSURANCE = "aki-insurance",
     INVENTORY = "aki-inventory",
+    ITEM = "aki-item",
     LOCALE = "aki-locale",
     LOCATION = "aki-location",
     MATCH = "aki-match",
diff --git a/TypeScript/12ClassExtensionOverride/types/models/enums/ELocationName.d.ts b/TypeScript/12ClassExtensionOverride/types/models/enums/ELocationName.d.ts
index b56cc08..7ae7caa 100644
--- a/TypeScript/12ClassExtensionOverride/types/models/enums/ELocationName.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/models/enums/ELocationName.d.ts
@@ -1,5 +1,6 @@
 export declare enum ELocationName {
     FACTORY_DAY = "factory4_day",
+    FACTORY_NIGHT = "factory4_night",
     BIGMAP = "bigmap",
     WOODS = "Woods",
     SHORELINE = "Shoreline",
diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IBotConfig.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IBotConfig.d.ts
index e171087..f15fa73 100644
--- a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IBotConfig.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IBotConfig.d.ts
@@ -1,17 +1,31 @@
 import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
+import { IBotDurability } from "./IBotDurability";
+import { IPmcConfig } from "./IPmcConfig";
 export interface IBotConfig extends IBaseConfig {
     kind: "aki-bot";
+    /** How many variants of each bot should be generated on raid start */
     presetBatch: PresetBatch;
+    /** What bot types should be classified as bosses */
     bosses: string[];
-    durability: Durability;
+    /** Control weapon/armor durability min/max values for each bot type */
+    durability: IBotDurability;
+    /** Control the weighting of how expensive an average loot item is on a PMC or Scav */
     lootNValue: LootNvalue;
+    /** Control what bots are added to a bots revenge list key: bottype, value: bottypes to revenge on seeing their death */
     revenge: Record<string, string[]>;
-    pmc: PmcConfig;
+    /** PMC bot specific config settings */
+    pmc: IPmcConfig;
+    /** Control how many items are allowed to spawn on a bot
+     * key: bottype, value: <key: itemTpl: value: max item count> */
     itemSpawnLimits: Record<string, Record<string, number>>;
-    equipment: Record<string, Equipment>;
+    /** Blacklist/whitelist items on a bot */
+    equipment: Record<string, EquipmentFilters>;
+    /** Show a bots botType value after their name */
     showTypeInNickname: boolean;
+    /** Max number of bots that can be spawned in a raid at any one time */
     maxBotCap: number;
+    /** How many stacks of secret ammo should a bot have in its bot secure container */
     secureContainerAmmoStackCount: number;
 }
 export interface PresetBatch {
@@ -44,79 +58,22 @@ export interface PresetBatch {
     test: number;
     exUsec: number;
 }
-export interface Durability {
-    default: DefaultDurability;
-    pmc: PmcDurability;
-    boss: BotDurability;
-    follower: BotDurability;
-    assault: BotDurability;
-    cursedassault: BotDurability;
-    marksman: BotDurability;
-    pmcbot: BotDurability;
-    exusec: BotDurability;
-    sectantpriest: BotDurability;
-    sectantwarrior: BotDurability;
-}
-export interface DefaultDurability {
-    armor: DefaultArmor;
-    weapon: WeaponDurability;
-}
-export interface DefaultArmor {
-    maxDelta: number;
-    minDelta: number;
-}
-export interface WeaponDurability {
-    lowestMax: number;
-    highestMax: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface PmcDurability {
-    armor: PmcDurabilityArmor;
-    weapon: WeaponDurability;
-}
-export interface PmcDurabilityArmor {
-    lowestMaxPercent: number;
-    highestMaxPercent: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface BotDurability {
-    armor: ArmorDurability;
-    weapon: WeaponDurability;
-}
-export interface ArmorDurability {
-    maxDelta: number;
-    minDelta: number;
-}
 export interface LootNvalue {
     scav: number;
     pmc: number;
 }
-export interface PmcConfig {
-    dynamicLoot: PmcDynamicLoot;
-    difficulty: string;
-    looseWeaponInBackpackChancePercent: number;
-    looseWeaponInBackpackLootMinMax: MinMax;
-    isUsec: number;
-    chanceSameSideIsHostilePercent: number;
-    usecType: string;
-    bearType: string;
-    maxBackpackLootTotalRub: number;
-    maxPocketLootTotalRub: number;
-    maxVestLootTotalRub: number;
-    convertIntoPmcChance: Record<string, MinMax>;
-    enemyTypes: string[];
-}
-export interface PmcDynamicLoot {
-    whitelist: string[];
-    blacklist: string[];
-    moneyStackLimits: Record<string, number>;
-}
-export interface Equipment {
+export interface EquipmentFilters {
+    weaponModLimits: ModLimits;
+    randomisedWeaponModSlots?: string[];
     blacklist: EquipmentFilterDetails[];
     whitelist: EquipmentFilterDetails[];
 }
+export interface ModLimits {
+    /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */
+    scopeLimit?: number;
+    /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */
+    lightLaserLimit?: number;
+}
 export interface EquipmentFilterDetails {
     levelRange: MinMax;
     equipment: Record<string, string[]>;
diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IBotDurability.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IBotDurability.d.ts
new file mode 100644
index 0000000..38a47cc
--- /dev/null
+++ b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IBotDurability.d.ts
@@ -0,0 +1,47 @@
+export interface IBotDurability {
+    default: DefaultDurability;
+    pmc: PmcDurability;
+    boss: BotDurability;
+    follower: BotDurability;
+    assault: BotDurability;
+    cursedassault: BotDurability;
+    marksman: BotDurability;
+    pmcbot: BotDurability;
+    exusec: BotDurability;
+    gifter: BotDurability;
+    sectantpriest: BotDurability;
+    sectantwarrior: BotDurability;
+}
+/** Durability values to be used when a more specific bot type cant be found */
+export interface DefaultDurability {
+    armor: DefaultArmor;
+    weapon: WeaponDurability;
+}
+export interface DefaultArmor {
+    maxDelta: number;
+    minDelta: number;
+}
+export interface WeaponDurability {
+    lowestMax: number;
+    highestMax: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface PmcDurability {
+    armor: PmcDurabilityArmor;
+    weapon: WeaponDurability;
+}
+export interface PmcDurabilityArmor {
+    lowestMaxPercent: number;
+    highestMaxPercent: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface BotDurability {
+    armor: ArmorDurability;
+    weapon: WeaponDurability;
+}
+export interface ArmorDurability {
+    maxDelta: number;
+    minDelta: number;
+}
diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IItemConfig.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IItemConfig.d.ts
new file mode 100644
index 0000000..5ecccc2
--- /dev/null
+++ b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IItemConfig.d.ts
@@ -0,0 +1,5 @@
+import { IBaseConfig } from "./IBaseConfig";
+export interface IItemConfig extends IBaseConfig {
+    kind: "aki-item";
+    blacklist: string[];
+}
diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IPmcConfig.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IPmcConfig.d.ts
new file mode 100644
index 0000000..655b58d
--- /dev/null
+++ b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IPmcConfig.d.ts
@@ -0,0 +1,22 @@
+import { MinMax } from "../../common/MinMax";
+export interface IPmcConfig {
+    dynamicLoot: DynamicLoot;
+    useDifficultyOverride: boolean;
+    difficulty: string;
+    looseWeaponInBackpackChancePercent: number;
+    looseWeaponInBackpackLootMinMax: MinMax;
+    isUsec: number;
+    chanceSameSideIsHostilePercent: number;
+    usecType: string;
+    bearType: string;
+    maxBackpackLootTotalRub: number;
+    maxPocketLootTotalRub: number;
+    maxVestLootTotalRub: number;
+    convertIntoPmcChance: Record<string, MinMax>;
+    enemyTypes: string[];
+}
+export interface DynamicLoot {
+    whitelist: string[];
+    blacklist: string[];
+    moneyStackLimits: Record<string, number>;
+}
diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IQuestConfig.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IQuestConfig.d.ts
index be4a97b..45c9aae 100644
--- a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IQuestConfig.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IQuestConfig.d.ts
@@ -4,6 +4,8 @@ export interface IQuestConfig extends IBaseConfig {
     kind: "aki-quest";
     redeemTime: number;
     repeatableQuests: IRepeatableQuestConfig[];
+    bearOnlyQuests: string[];
+    usecOnlyQuests: string[];
 }
 export interface IRepeatableQuestConfig {
     name: string;
@@ -15,6 +17,10 @@ export interface IRepeatableQuestConfig {
     locations: Record<ELocationName, string[]>;
     traderWhitelist: ITraderWhitelist[];
     questConfig: IQuestConfig;
+    /** Item base types to block when generating rewards */
+    rewardBaseTypeBlacklist: string[];
+    /** Item tplIds to ignore when generating rewards */
+    rewardBlacklist: string[];
 }
 export interface IRewardScaling {
     levels: number[];
diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IRagfairConfig.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IRagfairConfig.d.ts
index 6369eda..3088717 100644
--- a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IRagfairConfig.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IRagfairConfig.d.ts
@@ -12,6 +12,7 @@ export interface Sell {
     chance: Chance;
     time: Time;
     reputation: Reputation;
+    simulatedSellHours: number;
 }
 export interface Chance {
     base: number;
diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/config/ITraderConfig.d.ts
index c8e8044..6b1c1e3 100644
--- a/TypeScript/12ClassExtensionOverride/types/models/spt/config/ITraderConfig.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/models/spt/config/ITraderConfig.d.ts
@@ -12,8 +12,10 @@ export interface UpdateTime {
     seconds: number;
 }
 export interface FenceConfig {
+    partialRefreshTimeSeconds: number;
+    partialRefreshChangePercent: number;
     assortSize: number;
-    maxPresetsCount: number;
+    maxPresetsPercent: number;
     presetPriceMult: number;
     blacklist: string[];
 }
diff --git a/TypeScript/3GetSptConfigFile/types/models/spt/location/AirDropLootItem.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/services/LootItem.d.ts
similarity index 54%
rename from TypeScript/3GetSptConfigFile/types/models/spt/location/AirDropLootItem.d.ts
rename to TypeScript/12ClassExtensionOverride/types/models/spt/services/LootItem.d.ts
index da791ff..2838472 100644
--- a/TypeScript/3GetSptConfigFile/types/models/spt/location/AirDropLootItem.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/models/spt/services/LootItem.d.ts
@@ -1,5 +1,4 @@
-export declare class AirDropLootItem {
-    id: string;
+export declare class LootItem {
     tpl: string;
     isPreset: boolean;
     stackCount: number;
diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/services/LootRequest.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/12ClassExtensionOverride/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/12ClassExtensionOverride/types/services/BotEquipmentFilterService.d.ts b/TypeScript/12ClassExtensionOverride/types/services/BotEquipmentFilterService.d.ts
index e49645b..632f961 100644
--- a/TypeScript/12ClassExtensionOverride/types/services/BotEquipmentFilterService.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/services/BotEquipmentFilterService.d.ts
@@ -1,12 +1,12 @@
 import { IBotType } from "../models/eft/common/tables/IBotType";
-import { Equipment, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 export declare class BotEquipmentFilterService {
     protected logger: ILogger;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    protected botEquipmentFilterlists: Record<string, Equipment>;
+    protected botEquipmentFilterlists: Record<string, EquipmentFilters>;
     constructor(logger: ILogger, configServer: ConfigServer);
     /**
      * Filter a bots data to exclude equipment and cartridges defines in the botConfig
@@ -22,7 +22,7 @@ export declare class BotEquipmentFilterService {
      * @param playerLevel Level of the player
      * @returns EquipmentBlacklistDetails object
      */
-    protected getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
+    getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
     /**
      * Get the whitelist for a specific bot type that's within the players level
      * @param botRole Bot type
diff --git a/TypeScript/12ClassExtensionOverride/types/services/FenceService.d.ts b/TypeScript/12ClassExtensionOverride/types/services/FenceService.d.ts
index c9e325e..c940507 100644
--- a/TypeScript/12ClassExtensionOverride/types/services/FenceService.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/services/FenceService.d.ts
@@ -12,6 +12,11 @@ import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+import { ItemFilterService } from "./ItemFilterService";
+/**
+ * Handle actions surrounding Fence
+ * e.g. generating or refreshing assorts / get next refresh time
+ */
 export declare class FenceService {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
@@ -22,18 +27,64 @@ export declare class FenceService {
     protected handbookHelper: HandbookHelper;
     protected itemHelper: ItemHelper;
     protected presetHelper: PresetHelper;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected fenceAssort: ITraderAssort;
     protected traderConfig: ITraderConfig;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, configServer: ConfigServer);
+    protected nextMiniRefreshTimestamp: number;
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, itemFilterService: ItemFilterService, configServer: ConfigServer);
     protected setFenceAssort(fenceAssort: ITraderAssort): void;
-    getFenceAssorts(): ITraderAssort;
+    /**
+     * Get assorts player can purchase
+     * Adjust prices based on fence level of player
+     * @param pmcProfile Player profile
+     * @returns ITraderAssort
+     */
+    getFenceAssorts(pmcProfile: IPmcData): ITraderAssort;
+    /**
+     * Get fence assorts with no price adjustments based on fence rep
+     * @returns ITraderAssort
+     */
+    getRawFenceAssorts(): ITraderAssort;
+    /**
+     * Does fence need to perform a partial refresh because its passed the refresh timer defined in trader.json
+     * @returns true if it needs a partial refresh
+     */
+    needsPartialRefresh(): boolean;
+    /**
+     * Replace a percentage of fence assorts with freshly generated items
+     */
+    performPartialRefresh(): void;
+    /**
+     * Choose an item (not mod) at random and remove from assorts
+     */
+    protected removeRandomItemFromAssorts(): void;
+    /**
+     * Get an integer rounded count of items to replace based on percentrage from traderConfig value
+     * @param totalItemCount total item count
+     * @returns rounded int of items to replace
+     */
+    protected getCountOfItemsToReplace(totalItemCount: number): number;
     /**
      * Get the count of items fence offers
      * @returns number
      */
     getOfferCount(): number;
-    generateFenceAssortCache(pmcData: IPmcData): void;
+    /**
+     * Create a trader assort for fence
+     */
+    generateFenceAssortCache(): void;
+    /**
+     * Create skeleton to hold assort items
+     * @returns ITraderAssort object
+     */
+    protected createBaseTraderAssortItem(): ITraderAssort;
+    /**
+     * Hydrate result parameter object with generated assorts
+     * @param assortCount Number of assorts to generate
+     * @param assorts object to add assorts to
+     */
+    protected createAssorts(assortCount: number, assorts: ITraderAssort): void;
     /**
      * Get the next update timestamp for fence
      * @returns future timestamp
@@ -44,11 +95,14 @@ export declare class FenceService {
      */
     protected getFenceRefreshTime(): number;
     /**
-     * Get the fence level the passed in profile has
+     * Get fence level the passed in profile has
      * @param pmcData Player profile
-     * @returns FenceLevel
+     * @returns FenceLevel object
      */
     getFenceInfo(pmcData: IPmcData): FenceLevel;
+    /**
+     * Remove an assort from fence by id
+     * @param assortIdToRemove assort id to remove from fence assorts
+     */
     removeFenceOffer(assortIdToRemove: string): void;
-    updateFenceOffers(pmcData: IPmcData): void;
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/services/InsuranceService.d.ts b/TypeScript/12ClassExtensionOverride/types/services/InsuranceService.d.ts
index 171bf10..6be8a2f 100644
--- a/TypeScript/12ClassExtensionOverride/types/services/InsuranceService.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/services/InsuranceService.d.ts
@@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
 import { SecureContainerHelper } from "../helpers/SecureContainerHelper";
 import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
+import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData";
 import { IInsuranceConfig } from "../models/spt/config/IInsuranceConfig";
@@ -44,8 +45,22 @@ export declare class InsuranceService {
      * @param mapId Id of the map player died/exited that caused the insurance to be issued on
      */
     sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void;
+    /**
+     * Store lost gear post-raid inside profile
+     * @param pmcData player profile to store gear in
+     * @param offraidData post-raid request object
+     * @param preRaidGear gear player wore prior to raid
+     * @param sessionID Session id
+     */
     storeLostGear(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
     storeInsuredItemsForReturn(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
-    protected addGearToSend(pmcData: IPmcData, insuredItem: any, actualItem: any, sessionID: string): any;
+    /**
+     * Add gear item to InsuredItems array in player profile
+     * @param pmcData profile to store item in
+     * @param insuredItem Item to store in profile
+     * @param actualItem item to store
+     * @param sessionID Session id
+     */
+    protected addGearToSend(pmcData: IPmcData, insuredItem: InsuredItem, actualItem: Item, sessionID: string): void;
     getPremium(pmcData: IPmcData, inventoryItem: Item, traderId: string): number;
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/services/ItemFilterService.d.ts b/TypeScript/12ClassExtensionOverride/types/services/ItemFilterService.d.ts
new file mode 100644
index 0000000..c9c8ef3
--- /dev/null
+++ b/TypeScript/12ClassExtensionOverride/types/services/ItemFilterService.d.ts
@@ -0,0 +1,24 @@
+import { IItemConfig } from "../models/spt/config/IItemConfig";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+/** Centralise the handling of blacklisting items, uses blacklist found in config/item.json */
+export declare class ItemFilterService {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected configServer: ConfigServer;
+    protected blacklist: string[];
+    protected itemConfig: IItemConfig;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer);
+    /**
+     * Check if the provided template id is blacklisted in config/item.json
+     * @param tpl template id
+     * @returns true if blacklisted
+     */
+    isItemBlacklisted(tpl: string): boolean;
+    /**
+     * Return every template id blacklisted in config/item.json
+     * @returns string array of blacklisted tempalte ids
+     */
+    getBlacklistedItems(): string[];
+}
diff --git a/TypeScript/12ClassExtensionOverride/types/services/ProfileFixerService.d.ts b/TypeScript/12ClassExtensionOverride/types/services/ProfileFixerService.d.ts
index ed1dec7..9cb5a38 100644
--- a/TypeScript/12ClassExtensionOverride/types/services/ProfileFixerService.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/services/ProfileFixerService.d.ts
@@ -45,6 +45,11 @@ export declare class ProfileFixerService {
      * @param pmcProfile Profile to find and remove slots from
      */
     protected removeResourcesFromSlotsInHideoutWithoutLocationIndexValue(pmcProfile: IPmcData): void;
+    /**
+     * Hideout slots need to be in a specific order, locationIndex in ascending order
+     * @param pmcProfile profile to edit
+     */
+    protected reorderHideoutAreasWithResouceInputs(pmcProfile: IPmcData): void;
     /**
      * add in objects equal to the number of slots
      * @param areaType area to check
diff --git a/TypeScript/12ClassExtensionOverride/types/utils/HashUtil.d.ts b/TypeScript/12ClassExtensionOverride/types/utils/HashUtil.d.ts
index bacbf2a..a8500e1 100644
--- a/TypeScript/12ClassExtensionOverride/types/utils/HashUtil.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/utils/HashUtil.d.ts
@@ -4,8 +4,18 @@ import { TimeUtil } from "./TimeUtil";
 export declare class HashUtil {
     protected timeUtil: TimeUtil;
     constructor(timeUtil: TimeUtil);
+    /**
+     * Create a 24 character id using the sha256 algorithm + current timestamp
+     * @returns 24 character hash
+     */
     generate(): string;
     generateMd5ForData(data: string): string;
     generateSha1ForData(data: string): string;
+    /**
+     * Create a hash for the data parameter
+     * @param algorithm algorithm to use to hash
+     * @param data data to be hashed
+     * @returns hash value
+     */
     generateHashForData(algorithm: string, data: crypto.BinaryLike): string;
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/utils/RandomUtil.d.ts b/TypeScript/12ClassExtensionOverride/types/utils/RandomUtil.d.ts
index c24dd60..e35d21f 100644
--- a/TypeScript/12ClassExtensionOverride/types/utils/RandomUtil.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/utils/RandomUtil.d.ts
@@ -150,4 +150,10 @@ export declare class RandomUtil {
      */
     drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[];
     getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number;
+    /**
+     * Fisher-Yates shuffle an array
+     * @param array Array to shuffle
+     * @returns Shuffled array
+     */
+    shuffle<T>(array: Array<T>): Array<T>;
 }
diff --git a/TypeScript/12ClassExtensionOverride/types/utils/TimeUtil.d.ts b/TypeScript/12ClassExtensionOverride/types/utils/TimeUtil.d.ts
index f437f8a..1367e26 100644
--- a/TypeScript/12ClassExtensionOverride/types/utils/TimeUtil.d.ts
+++ b/TypeScript/12ClassExtensionOverride/types/utils/TimeUtil.d.ts
@@ -1,3 +1,6 @@
+/**
+ * Utility class to handle time related problems
+ */
 export declare class TimeUtil {
     static readonly oneHourAsSeconds = 3600;
     formatTime(date: Date): string;
@@ -19,4 +22,10 @@ export declare class TimeUtil {
      * @returns current date in format: 00.00.0000 (dd.mm.yyyy)
      */
     getDateMailFormat(): string;
+    /**
+     * Convert hours into seconds
+     * @param hours hours to convert to seconds
+     * @returns number
+     */
+    getHoursAsSeconds(hours: number): number;
 }
diff --git a/TypeScript/13AddTrader/types/callbacks/LocationCallbacks.d.ts b/TypeScript/13AddTrader/types/callbacks/LocationCallbacks.d.ts
index cc69369..6e0b538 100644
--- a/TypeScript/13AddTrader/types/callbacks/LocationCallbacks.d.ts
+++ b/TypeScript/13AddTrader/types/callbacks/LocationCallbacks.d.ts
@@ -11,4 +11,5 @@ export declare class LocationCallbacks {
     constructor(httpResponse: HttpResponseUtil, locationController: LocationController);
     getLocationData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<ILocationsGenerateAllResponse>;
     getLocation(url: string, info: IGetLocationRequestData, sessionID: string): IGetBodyResponseData<ILocationBase>;
+    getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): string;
 }
diff --git a/TypeScript/13AddTrader/types/callbacks/ProfileCallbacks.d.ts b/TypeScript/13AddTrader/types/callbacks/ProfileCallbacks.d.ts
index 6a86fc0..183bb0a 100644
--- a/TypeScript/13AddTrader/types/callbacks/ProfileCallbacks.d.ts
+++ b/TypeScript/13AddTrader/types/callbacks/ProfileCallbacks.d.ts
@@ -1,5 +1,6 @@
 import { ProfileController } from "../controllers/ProfileController";
 import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData";
+import { IPmcData } from "../models/eft/common/IPmcData";
 import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData";
 import { INullResponseData } from "../models/eft/httpResponse/INullResponseData";
 import { IGetMiniProfileRequestData } from "../models/eft/launcher/IGetMiniProfileRequestData";
@@ -12,20 +13,51 @@ import { ISearchFriendResponse } from "../models/eft/profile/ISearchFriendRespon
 import { IValidateNicknameRequestData } from "../models/eft/profile/IValidateNicknameRequestData";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/** Handle profile related client events */
 export declare class ProfileCallbacks {
     protected httpResponse: HttpResponseUtil;
     protected timeUtil: TimeUtil;
     protected profileController: ProfileController;
     constructor(httpResponse: HttpResponseUtil, timeUtil: TimeUtil, profileController: ProfileController);
     createProfile(url: string, info: IProfileCreateRequestData, sessionID: string): IGetBodyResponseData<any>;
-    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
-    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
+    /**
+     * Get the complete player profile (scav + pmc character)
+     * @param url
+     * @param info Empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle the creation of a scav profile for player
+     * Occurs post-raid and when profile first created immediately after character details are confirmed by player
+     * @param url
+     * @param info empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle client/game/profile/voice/change event
+     * @param url
+     * @param info Change voice request object
+     * @param sessionID Session id
+     * @returns Client response
+     */
     changeVoice(url: string, info: IProfileChangeVoiceRequestData, sessionID: string): INullResponseData;
+    /**
+     * Handle client/game/profile/nickname/change event
+     * Client allows player to adjust their profile name
+     * @param url
+     * @param info Change nickname request object
+     * @param sessionID Session id
+     * @returns client response
+     */
     changeNickname(url: string, info: IProfileChangeNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     validateNickname(url: string, info: IValidateNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     getReservedNickname(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<string>;
     /**
-     * Called when creating a character, when you choose a character face/voice
+     * Called when creating a character when choosing a character face/voice
      * @param url
      * @param info response (empty)
      * @param sessionID
diff --git a/TypeScript/13AddTrader/types/callbacks/RagfairCallbacks.d.ts b/TypeScript/13AddTrader/types/callbacks/RagfairCallbacks.d.ts
index 3a405c9..c609f2f 100644
--- a/TypeScript/13AddTrader/types/callbacks/RagfairCallbacks.d.ts
+++ b/TypeScript/13AddTrader/types/callbacks/RagfairCallbacks.d.ts
@@ -19,6 +19,9 @@ import { ConfigServer } from "../servers/ConfigServer";
 import { RagfairServer } from "../servers/RagfairServer";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+/**
+ * Handle ragfair related callback events
+ */
 export declare class RagfairCallbacks extends OnLoadOnUpdate {
     protected httpResponse: HttpResponseUtil;
     protected logger: ILogger;
diff --git a/TypeScript/13AddTrader/types/controllers/InraidController.d.ts b/TypeScript/13AddTrader/types/controllers/InraidController.d.ts
index 82bb64d..102a2fb 100644
--- a/TypeScript/13AddTrader/types/controllers/InraidController.d.ts
+++ b/TypeScript/13AddTrader/types/controllers/InraidController.d.ts
@@ -35,6 +35,30 @@ export declare class InraidController {
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer);
     addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void;
     saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Handle updating the profile post-pmc raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Reduce body part hp to % of max
+     * @param pmcData profile to edit
+     * @param multipler multipler to apply to max health
+     */
+    protected reducePmcHealthToPercent(pmcData: IPmcData, multipler: number): void;
+    /**
+     * Handle updating the profile post-pscav raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePlayerScavProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Is the player dead after a raid - dead is anything other than "survived" / "runner"
+     * @param statusOnExit exit value from offraidData object
+     * @returns true if dead
+     */
+    protected isPlayerDead(statusOnExit: string): boolean;
     /**
      * Mark inventory items as FiR if player survived raid, otherwise remove FiR from them
      * @param offraidData Save Progress Request
diff --git a/TypeScript/13AddTrader/types/controllers/InventoryController.d.ts b/TypeScript/13AddTrader/types/controllers/InventoryController.d.ts
index f57f731..f564919 100644
--- a/TypeScript/13AddTrader/types/controllers/InventoryController.d.ts
+++ b/TypeScript/13AddTrader/types/controllers/InventoryController.d.ts
@@ -92,7 +92,11 @@ export declare class InventoryController {
      */
     toggleItem(pmcData: IPmcData, body: IInventoryToggleRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Handles Tagging of items (primary Containers).
+     * Add a tag to an inventory item
+     * @param pmcData profile with item to add tag to
+     * @param body tag request data
+     * @param sessionID session id
+     * @returns client response object
      */
     tagItem(pmcData: IPmcData, body: IInventoryTagRequestData, sessionID: string): IItemEventRouterResponse;
     bindItem(pmcData: IPmcData, body: IInventoryBindRequestData, sessionID: string): IItemEventRouterResponse;
diff --git a/TypeScript/13AddTrader/types/controllers/LocationController.d.ts b/TypeScript/13AddTrader/types/controllers/LocationController.d.ts
index 90b6d7a..9db3205 100644
--- a/TypeScript/13AddTrader/types/controllers/LocationController.d.ts
+++ b/TypeScript/13AddTrader/types/controllers/LocationController.d.ts
@@ -1,18 +1,33 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class LocationController {
     protected jsonUtil: JsonUtil;
+    protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/13AddTrader/types/controllers/MatchController.d.ts b/TypeScript/13AddTrader/types/controllers/MatchController.d.ts
index e8585d9..cb40023 100644
--- a/TypeScript/13AddTrader/types/controllers/MatchController.d.ts
+++ b/TypeScript/13AddTrader/types/controllers/MatchController.d.ts
@@ -9,6 +9,7 @@ import { IGetProfileRequestData } from "../models/eft/match/IGetProfileRequestDa
 import { IJoinMatchRequestData } from "../models/eft/match/IJoinMatchRequestData";
 import { IJoinMatchResult } from "../models/eft/match/IJoinMatchResult";
 import { IStartOfflineRaidRequestData } from "../models/eft/match/IStartOffineRaidRequestData";
+import { IBotConfig } from "../models/spt/config/IBotConfig";
 import { IInRaidConfig } from "../models/spt/config/IInRaidConfig";
 import { IMatchConfig } from "../models/spt/config/IMatchConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
@@ -29,6 +30,7 @@ export declare class MatchController {
     protected applicationContext: ApplicationContext;
     protected matchConfig: IMatchConfig;
     protected inraidConfig: IInRaidConfig;
+    protected botConfig: IBotConfig;
     constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, applicationContext: ApplicationContext);
     getEnabled(): boolean;
     getProfile(info: IGetProfileRequestData): IPmcData[];
diff --git a/TypeScript/13AddTrader/types/controllers/QuestController.d.ts b/TypeScript/13AddTrader/types/controllers/QuestController.d.ts
index 2cbccfb..282f50e 100644
--- a/TypeScript/13AddTrader/types/controllers/QuestController.d.ts
+++ b/TypeScript/13AddTrader/types/controllers/QuestController.d.ts
@@ -39,16 +39,31 @@ export declare class QuestController {
      * @returns array of IQuest
      */
     getClientQuests(sessionID: string): IQuest[];
+    /**
+     * Is the quest for the opposite side the player is on
+     * @param side player side (usec/bear)
+     * @param questId questId to check
+     */
+    protected questIsForOtherSide(side: string, questId: string): boolean;
+    /**
+     * Handle the client accepting a quest and starting it
+     * Send starting rewards if any to player and
+     * Send start notification if any to player
+     * @param pmcData Profile to update
+     * @param acceptedQuest Quest accepted
+     * @param sessionID Session id
+     * @returns client response
+     */
     acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Remove completed quest from profile
+     * Update completed quest in profile
      * Add newly unlocked quests to profile
      * Also recalculate thier level due to exp rewards
      * @param pmcData Player profile
-     * @param body completed quest request
-     * @param sessionID session id
-     * @returns ItemEvent response
+     * @param body Completed quest request
+     * @param sessionID Session id
+     * @returns ItemEvent client response
      */
     completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
@@ -67,10 +82,20 @@ export declare class QuestController {
     protected getQuestsFailedByCompletingQuest(completedQuestId: string): IQuest[];
     /**
      * Fail the quests provided
+     * Update quest in profile, otherwise add fresh quest object with failed status
      * @param sessionID session id
      * @param pmcData player profile
      * @param questsToFail quests to fail
      */
     protected failQuests(sessionID: string, pmcData: IPmcData, questsToFail: IQuest[]): void;
     handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment a backend counter stored value by an amount,
+     * Create counter if it does not exist
+     * @param pmcData Profile to find backend counter in
+     * @param conditionId backend counter id to update
+     * @param questId quest id counter is associated with
+     * @param counterValue value to increment the backend counter with
+     */
+    protected updateProfileBackendCounterValue(pmcData: IPmcData, conditionId: string, questId: string, counterValue: number): void;
 }
diff --git a/TypeScript/13AddTrader/types/controllers/RagfairController.d.ts b/TypeScript/13AddTrader/types/controllers/RagfairController.d.ts
index c4ffc15..06af740 100644
--- a/TypeScript/13AddTrader/types/controllers/RagfairController.d.ts
+++ b/TypeScript/13AddTrader/types/controllers/RagfairController.d.ts
@@ -9,6 +9,7 @@ import { RagfairOfferHelper } from "../helpers/RagfairOfferHelper";
 import { RagfairSellHelper } from "../helpers/RagfairSellHelper";
 import { RagfairSortHelper } from "../helpers/RagfairSortHelper";
 import { RagfairTaxHelper } from "../helpers/RagfairTaxHelper";
+import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
@@ -33,6 +34,9 @@ import { RagfairPriceService } from "../services/RagfairPriceService";
 import { RagfairRequiredItemsService } from "../services/RagfairRequiredItemsService";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/**
+ * Handle RagfairCallback events
+ */
 export declare class RagfairController {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
@@ -52,14 +56,20 @@ export declare class RagfairController {
     protected handbookHelper: HandbookHelper;
     protected paymentHelper: PaymentHelper;
     protected inventoryHelper: InventoryHelper;
+    protected traderHelper: TraderHelper;
     protected ragfairHelper: RagfairHelper;
     protected ragfairOfferService: RagfairOfferService;
     protected ragfairRequiredItemsService: RagfairRequiredItemsService;
     protected ragfairOfferGenerator: RagfairOfferGenerator;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
     getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult;
+    /**
+     * Update a trader flea offer with buy restrictions stored in the traders assort
+     * @param offer flea offer to update
+     */
+    protected setTraderOfferPurchaseLimits(offer: IRagfairOffer): void;
     protected isLinkedSearch(info: ISearchRequestData): boolean;
     protected isRequiredSearch(info: ISearchRequestData): boolean;
     update(): void;
diff --git a/TypeScript/13AddTrader/types/controllers/RepeatableQuestController.d.ts b/TypeScript/13AddTrader/types/controllers/RepeatableQuestController.d.ts
index 98d05dd..4c31a3d 100644
--- a/TypeScript/13AddTrader/types/controllers/RepeatableQuestController.d.ts
+++ b/TypeScript/13AddTrader/types/controllers/RepeatableQuestController.d.ts
@@ -7,6 +7,7 @@ import { Exit } from "../models/eft/common/ILocationBase";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { TraderInfo } from "../models/eft/common/tables/IBotBase";
 import { ICompletion, ICompletionAvailableFor, IElimination, IEliminationCondition, IExploration, IExplorationCondition, IPmcDataRepeatableQuest, IRepeatableQuest, IReward, IRewards } from "../models/eft/common/tables/IRepeatableQuests";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
 import { IRepeatableQuestChangeRequest } from "../models/eft/quests/IRepeatableQuestChangeRequest";
 import { ELocationName } from "../models/enums/ELocationName";
@@ -15,6 +16,7 @@ import { ILogger } from "../models/spt/utils/ILogger";
 import { ItemEventRouter } from "../routers/ItemEventRouter";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { PaymentService } from "../services/PaymentService";
 import { ProfileFixerService } from "../services/ProfileFixerService";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -64,9 +66,10 @@ export declare class RepeatableQuestController {
     protected itemEventRouter: ItemEventRouter;
     protected paymentService: PaymentService;
     protected objectId: ObjectId;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
-    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, configServer: ConfigServer);
+    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint
      * Returns an array of objects in the format of repeatable quests to the client.
@@ -217,4 +220,16 @@ export declare class RepeatableQuestController {
     debugLogRepeatableQuestIds(pmcData: IPmcData): void;
     probabilityObjectArray<K, V>(configArrayInput: ProbabilityObject<K, V>[]): ProbabilityObjectArray<K, V>;
     changeRepeatableQuest(pmcDataIn: IPmcData, body: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
+     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
+     */
+    protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig): [string, ITemplateItem][];
+    /**
+     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
+     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
+     * @param {*} tpl template id of item to check
+     * @returns boolean: true if item is valid reward
+     */
+    isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig): boolean;
 }
diff --git a/TypeScript/13AddTrader/types/controllers/TraderController.d.ts b/TypeScript/13AddTrader/types/controllers/TraderController.d.ts
index 0162064..b79f55e 100644
--- a/TypeScript/13AddTrader/types/controllers/TraderController.d.ts
+++ b/TypeScript/13AddTrader/types/controllers/TraderController.d.ts
@@ -4,6 +4,7 @@ import { TraderHelper } from "../helpers/TraderHelper";
 import { IBarterScheme, ITraderAssort, ITraderBase } from "../models/eft/common/tables/ITrader";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { FenceService } from "../services/FenceService";
 import { TraderAssortService } from "../services/TraderAssortService";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
@@ -15,8 +16,9 @@ export declare class TraderController {
     protected traderHelper: TraderHelper;
     protected timeUtil: TimeUtil;
     protected traderAssortService: TraderAssortService;
+    protected fenceService: FenceService;
     protected jsonUtil: JsonUtil;
-    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, jsonUtil: JsonUtil);
+    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, fenceService: FenceService, jsonUtil: JsonUtil);
     /**
      * Runs when onLoad event is fired
      * Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
@@ -26,6 +28,7 @@ export declare class TraderController {
     /**
      * Runs when onUpdate is fired
      * If current time is > nextResupply(expire) time of trader, refresh traders assorts and
+     * Fence is handled slightly differently
      * @returns has run
      */
     update(): boolean;
diff --git a/TypeScript/13AddTrader/types/di/Container.d.ts b/TypeScript/13AddTrader/types/di/Container.d.ts
index 17791b0..98d1fa1 100644
--- a/TypeScript/13AddTrader/types/di/Container.d.ts
+++ b/TypeScript/13AddTrader/types/di/Container.d.ts
@@ -1,4 +1,7 @@
 import { DependencyContainer } from "tsyringe";
+/**
+ * Handle the registration of classes to be used by the Dependency Injection code
+ */
 export declare class Container {
     static registerTypes(depContainer: DependencyContainer): void;
     static registerListTypes(depContainer: DependencyContainer): void;
diff --git a/TypeScript/13AddTrader/types/generators/BotGenerator.d.ts b/TypeScript/13AddTrader/types/generators/BotGenerator.d.ts
index a5fc0ad..7d58f95 100644
--- a/TypeScript/13AddTrader/types/generators/BotGenerator.d.ts
+++ b/TypeScript/13AddTrader/types/generators/BotGenerator.d.ts
@@ -40,7 +40,7 @@ export declare class BotGenerator {
      * @param botTemplate base bot template to use  (e.g. assault/pmcbot)
      * @returns
      */
-    generatePlayerScav(role: string, difficulty: string, botTemplate: IBotType): IBotBase;
+    generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase;
     generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[];
     /**
      * Choose if a bot should become a PMC by checking if bot type is allowed to become a Pmc in botConfig.convertFromChances and doing a random int check
@@ -58,7 +58,7 @@ export declare class BotGenerator {
      * @returns IBotBase object
      */
     protected getCloneOfBotBase(): IBotBase;
-    protected generateBot(bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
+    protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
     /**
      * Log the number of PMCs generated to the debug console
      */
diff --git a/TypeScript/13AddTrader/types/generators/BotInventoryGenerator.d.ts b/TypeScript/13AddTrader/types/generators/BotInventoryGenerator.d.ts
index 35d1ee8..73f8ece 100644
--- a/TypeScript/13AddTrader/types/generators/BotInventoryGenerator.d.ts
+++ b/TypeScript/13AddTrader/types/generators/BotInventoryGenerator.d.ts
@@ -18,7 +18,7 @@ export declare class BotInventoryGenerator {
     protected botGeneratorHelper: BotGeneratorHelper;
     protected weightedRandomHelper: WeightedRandomHelper;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper);
-    generateInventory(templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
+    generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
     protected generateEquipment(equipmentSlot: string, equipmentPool: Record<string, number>, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void;
     protected generateInventoryBase(): PmcInventory;
 }
diff --git a/TypeScript/13AddTrader/types/generators/BotLootGenerator.d.ts b/TypeScript/13AddTrader/types/generators/BotLootGenerator.d.ts
index c6a3f29..5a2d144 100644
--- a/TypeScript/13AddTrader/types/generators/BotLootGenerator.d.ts
+++ b/TypeScript/13AddTrader/types/generators/BotLootGenerator.d.ts
@@ -24,7 +24,7 @@ export declare class BotLootGenerator {
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botLootCacheService: BotLootCacheService, configServer: ConfigServer);
-    generateLoot(templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
+    generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
     protected getRandomisedCount(min: number, max: number, nValue: number): number;
     /**
      * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached
@@ -47,7 +47,7 @@ export declare class BotLootGenerator {
      * @param botRole bots role, .e.g. pmcBot
      * @param isPmc are we generating for a pmc
      */
-    protected addLooseWeaponsToInventorySlot(botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
+    protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
     /**
      * Get a random item from the pool parameter using the biasedRandomNumber system
      * @param pool pool of items to pick an item from
diff --git a/TypeScript/13AddTrader/types/generators/BotWeaponGenerator.d.ts b/TypeScript/13AddTrader/types/generators/BotWeaponGenerator.d.ts
index 9215214..49fa7bf 100644
--- a/TypeScript/13AddTrader/types/generators/BotWeaponGenerator.d.ts
+++ b/TypeScript/13AddTrader/types/generators/BotWeaponGenerator.d.ts
@@ -28,7 +28,18 @@ export declare class BotWeaponGenerator {
     protected botConfig: IBotConfig;
     constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer);
     /**
-     * Get a random weapon from a bots pool of weapons (weighted)
+     * Pick a random weapon based on weightings and generate a functional weapon
+     * @param equipmentSlot Primary/secondary/holster
+     * @param botTemplateInventory e.g. assault.json
+     * @param weaponParentId
+     * @param modChances
+     * @param botRole role of bot, e.g. assault/followerBully
+     * @param isPmc Is weapon generated for a pmc
+     * @returns GenerateWeaponResult object
+     */
+    generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    /**
+     * Get a random weighted weapon from a bots pool of weapons
      * @param equipmentSlot Primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
      * @returns weapon tpl
@@ -39,43 +50,24 @@ export declare class BotWeaponGenerator {
      * @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool())
      * @param equipmentSlot slot to fit into, primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
+     * @param weaponParentId ParentId of the weapon being generated
+     * @param modChances Dictionary of item types and % chance weapon will have that mod
+     * @param botRole e.g. assault/exusec
      * @param isPmc
      * @returns GenerateWeaponResult object
      */
-    generateWeaponByTpl(weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
     /**
-     * Generate an entirely random weapon
-     * @param equipmentSlot Primary/secondary/holster
-     * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
-     * @param isPmc
-     * @returns GenerateWeaponResult object
-     */
-    generateRandomWeapon(equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
-    /**
-     * Create array with weapon base as only element
-     * Add additional properties as required
-     * @param weaponTpl
-     * @param weaponParentId
-     * @param equipmentSlot
-     * @param weaponItemTemplate
+     * Create array with weapon base as only element and
+     * add additional properties based on weapon type
+     * @param weaponTpl Weapon tpl to create item with
+     * @param weaponParentId Weapons parent id
+     * @param equipmentSlot e.g. primary/secondary/holster
+     * @param weaponItemTemplate db template for weapon
      * @param botRole for durability values
-     * @returns
+     * @returns Base weapon item in array
      */
     constructWeaponBaseArray(weaponTpl: string, weaponParentId: string, equipmentSlot: string, weaponItemTemplate: ITemplateItem, botRole: string): Item[];
-    /**
-     * Add compatible magazines to an inventory based on a generated weapon
-     * @param weaponDetails
-     * @param magCounts
-     * @param inventory
-     * @param botRole the bot type we're getting generating extra mags for
-     */
-    addExtraMagazinesToInventory(weaponDetails: GenerateWeaponResult, magCounts: MinMax, inventory: PmcInventory, botRole: string): void;
     /**
      * Get the mods necessary to kit out a weapon to its preset level
      * @param weaponTpl weapon to find preset for
@@ -84,20 +76,32 @@ export declare class BotWeaponGenerator {
      * @returns array of weapon mods
      */
     protected getPresetWeaponMods(weaponTpl: string, equipmentSlot: string, weaponParentId: string, itemTemplate: ITemplateItem, botRole: string): Item[];
-    /** Checks if all required slots are occupied on a weapon and all it's mods */
+    /**
+     * Checks if all required slots are occupied on a weapon and all it's mods
+     * @param weaponItemArray Weapon + mods
+     * @returns true if valid
+     */
     protected isWeaponValid(weaponItemArray: Item[]): boolean;
     /**
      * Generates extra magazines or bullets (if magazine is internal) and adds them to TacticalVest and Pockets.
      * Additionally, adds extra bullets to SecuredContainer
-     * @param weaponMods
-     * @param weaponTemplate
-     * @param magCounts
-     * @param ammoTpl
-     * @param inventory
+     * @param weaponMods mods to attach to weapon
+     * @param weaponTemplate db template for weapon
+     * @param magCounts magazine count to add to inventory
+     * @param ammoTpl ammo templateId to add to magazines
+     * @param inventory inventory to add magazines to
      * @param botRole the bot type we're getting generating extra mags for
      * @returns
      */
-    protected generateExtraMagazines(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    addExtraMagazinesToInventory(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    /**
+     * Create a magazine using the parameters given
+     * @param magazineTpl Tpl of the magazine to create
+     * @param ammoTpl Ammo to add to magazine
+     * @param magTemplate template object of magazine
+     * @returns Item array
+     */
+    protected createMagazine(magazineTpl: string, ammoTpl: string, magTemplate: ITemplateItem): Item[];
     /**
      * Get a randomised number of bullets for a specific magazine
      * @param magCounts min and max count of magazines
@@ -138,10 +142,9 @@ export declare class BotWeaponGenerator {
      * Finds and return a compatible ammo tpl based on the bots ammo weightings (x.json/inventory/equipment/ammo)
      * @param ammo a list of ammo tpls the weapon can use
      * @param weaponTemplate the weapon we want to pick ammo for
-     * @param isPmc is the ammo being gathered for a pmc (runs pmc ammo filtering)
      * @returns an ammo tpl that works with the desired gun
      */
-    protected getCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem, isPmc: boolean): string;
+    protected getWeightedCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem): string;
     /**
      * Get a weapons compatible cartridge caliber
      * @param weaponTemplate Weapon to look up caliber of
diff --git a/TypeScript/13AddTrader/types/generators/LocationGenerator.d.ts b/TypeScript/13AddTrader/types/generators/LocationGenerator.d.ts
index bd368b5..cc61dcf 100644
--- a/TypeScript/13AddTrader/types/generators/LocationGenerator.d.ts
+++ b/TypeScript/13AddTrader/types/generators/LocationGenerator.d.ts
@@ -3,10 +3,9 @@ import { GameEventHelper } from "../helpers/GameEventHelper";
 import { ItemHelper } from "../helpers/ItemHelper";
 import { PresetHelper } from "../helpers/PresetHelper";
 import { RagfairServerHelper } from "../helpers/RagfairServerHelper";
-import { ILooseLoot, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
+import { ILooseLoot, SpawnpointsForced, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IStaticAmmoDetails, IStaticContainerProps, IStaticForcedProps, IStaticLootDetails } from "../models/eft/common/tables/ILootBase";
-import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILocationConfig } from "../models/spt/config/ILocationConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
@@ -36,11 +35,19 @@ export declare class LocationGenerator {
     generateContainerLoot(containerIn: IStaticContainerProps, staticForced: IStaticForcedProps[], staticLootDist: Record<string, IStaticLootDetails>, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): IStaticContainerProps;
     protected getLooseLootMultiplerForLocation(location: string): number;
     protected getStaticLootMultiplerForLocation(location: string): number;
+    /**
+     * Create array of loose + forced loot using probability system
+     * @param dynamicLootDist
+     * @param staticAmmoDist
+     * @param locationName Location to generate loot for
+     * @returns Array of spawn points with loot in them
+     */
     generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): SpawnpointTemplate[];
+    /**
+     * Add forced spawn point loot into loot parameter array
+     * @param loot array to add forced loot to
+     * @param forcedSpawnPoints forced loot to add
+     */
+    protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[]): void;
     protected createItem(tpl: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, parentId?: string): IContainerItem;
-    protected getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
-    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
-    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
-    protected createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
-    protected createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
 }
diff --git a/TypeScript/13AddTrader/types/generators/LootGenerator.d.ts b/TypeScript/13AddTrader/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/13AddTrader/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/13AddTrader/types/generators/PMCLootGenerator.d.ts b/TypeScript/13AddTrader/types/generators/PMCLootGenerator.d.ts
index 64e6f7f..b9f2a83 100644
--- a/TypeScript/13AddTrader/types/generators/PMCLootGenerator.d.ts
+++ b/TypeScript/13AddTrader/types/generators/PMCLootGenerator.d.ts
@@ -1,15 +1,21 @@
 import { ItemHelper } from "../helpers/ItemHelper";
-import { DatabaseServer } from "../servers/DatabaseServer";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+/**
+ * Handle the generation of dynamic PMC loot in pockets and backpacks
+ * and the removal of blacklisted items
+ */
 export declare class PMCLootGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected configServer: ConfigServer;
+    protected itemFilterService: ItemFilterService;
     protected pocketLootPool: string[];
     protected backpackLootPool: string[];
     protected botConfig: IBotConfig;
-    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer);
+    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer, itemFilterService: ItemFilterService);
     generatePMCPocketLootPool(): string[];
     generatePMCBackpackLootPool(): string[];
 }
diff --git a/TypeScript/13AddTrader/types/generators/ScavCaseRewardGenerator.d.ts b/TypeScript/13AddTrader/types/generators/ScavCaseRewardGenerator.d.ts
index c7d6ab7..89cb5c8 100644
--- a/TypeScript/13AddTrader/types/generators/ScavCaseRewardGenerator.d.ts
+++ b/TypeScript/13AddTrader/types/generators/ScavCaseRewardGenerator.d.ts
@@ -8,9 +8,13 @@ import { RewardCountAndPriceDetails, ScavCaseRewardCountsAndPrices } from "../mo
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { RagfairPriceService } from "../services/RagfairPriceService";
 import { HashUtil } from "../utils/HashUtil";
 import { RandomUtil } from "../utils/RandomUtil";
+/**
+ * Handle the creation of randomised scav case rewards
+ */
 export declare class ScavCaseRewardGenerator {
     protected logger: ILogger;
     protected randomUtil: RandomUtil;
@@ -18,9 +22,10 @@ export declare class ScavCaseRewardGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected ragfairPriceService: RagfairPriceService;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected scavCaseConfig: IScavCaseConfig;
-    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, configServer: ConfigServer);
+    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Create an array of rewards that will be given to the player upon completing their scav case build
      * @param body client request
diff --git a/TypeScript/13AddTrader/types/generators/WeatherGenerator.d.ts b/TypeScript/13AddTrader/types/generators/WeatherGenerator.d.ts
index 44cecbb..8ddbe49 100644
--- a/TypeScript/13AddTrader/types/generators/WeatherGenerator.d.ts
+++ b/TypeScript/13AddTrader/types/generators/WeatherGenerator.d.ts
@@ -1,7 +1,7 @@
 import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IWeatherData } from "../models/eft/weather/IWeatherData";
 import { IWeatherConfig } from "../models/spt/config/IWeatherConfig";
+import { ConfigServer } from "../servers/ConfigServer";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class WeatherGenerator {
@@ -21,11 +21,16 @@ export declare class WeatherGenerator {
     protected getAcceleratedTime(computedDate: Date): string;
     /**
      * Get current time formatted to fit BSGs requirement
-     * @param computedDate
+     * @param computedDate date to format into bsg style
      * @returns
      */
     protected getNormalTime(computedDate: Date): string;
-    generateWeather(data: IWeatherData): IWeatherData;
+    /**
+     * Return randomised Weather data
+     * @param weatherData weather input data
+     * @returns Randomised weather data
+     */
+    generateWeather(weatherData: IWeatherData): IWeatherData;
     protected getWeightedFog(): string;
     protected getWeightedRain(): number;
     protected getRandomFloat(node: string): number;
diff --git a/TypeScript/13AddTrader/types/helpers/AssortHelper.d.ts b/TypeScript/13AddTrader/types/helpers/AssortHelper.d.ts
index 15586b9..bfc157f 100644
--- a/TypeScript/13AddTrader/types/helpers/AssortHelper.d.ts
+++ b/TypeScript/13AddTrader/types/helpers/AssortHelper.d.ts
@@ -17,7 +17,7 @@ export declare class AssortHelper {
      * @param assort assort items from a trader
      * @returns assort items minus locked quest assorts
      */
-    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort): ITraderAssort;
+    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort, flea?: boolean): ITraderAssort;
     /**
      * Remove assorts from a trader that have not been unlocked yet
      * @param pmcProfile player profile
@@ -32,5 +32,5 @@ export declare class AssortHelper {
      * @param itemID item id to remove from asort
      * @returns Modified assort
      */
-    removeItemFromAssort(assort: ITraderAssort, itemID: string): ITraderAssort;
+    removeItemFromAssort(assort: ITraderAssort, itemID: string, flea?: boolean): ITraderAssort;
 }
diff --git a/TypeScript/13AddTrader/types/helpers/BotGeneratorHelper.d.ts b/TypeScript/13AddTrader/types/helpers/BotGeneratorHelper.d.ts
index 3cd7256..eb0d215 100644
--- a/TypeScript/13AddTrader/types/helpers/BotGeneratorHelper.d.ts
+++ b/TypeScript/13AddTrader/types/helpers/BotGeneratorHelper.d.ts
@@ -3,10 +3,12 @@ import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"
 import { Mods, ModsChances } from "../models/eft/common/tables/IBotType";
 import { Item, Repairable, Upd } from "../models/eft/common/tables/IItem";
 import { Grid, ITemplateItem, Slot } from "../models/eft/common/tables/ITemplateItem";
-import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
@@ -14,6 +16,7 @@ import { ContainerHelper } from "./ContainerHelper";
 import { InventoryHelper } from "./InventoryHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProbabilityHelper } from "./ProbabilityHelper";
+import { ProfileHelper } from "./ProfileHelper";
 export declare class BotGeneratorHelper {
     protected logger: ILogger;
     protected jsonUtil: JsonUtil;
@@ -25,10 +28,76 @@ export declare class BotGeneratorHelper {
     protected itemHelper: ItemHelper;
     protected inventoryHelper: InventoryHelper;
     protected containerHelper: ContainerHelper;
+    protected botEquipmentFilterService: BotEquipmentFilterService;
+    protected itemFilterService: ItemFilterService;
+    protected profileHelper: ProfileHelper;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, configServer: ConfigServer);
-    generateModsForItem(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, configServer: ConfigServer);
+    /**
+     * TODO - very similar to generateModsForWeapon
+     * Check mods are compatible and add to array
+     * @param equipment Equipment item to add mods to
+     * @param modPool Mod list to choose frm
+     * @param parentId parentid of item to add mod to
+     * @param parentTemplate template objet of item to add mods to
+     * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type
+     * @returns Item + compatible mods as an array
+     */
+    generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    /**
+     * TODO - very similar to generateModsForEquipment
+     * @param sessionId session id
+     * @param weapon Weapon to add mods to
+     * @param modPool pool of compatible mods to attach to gun
+     * @param weaponParentId parentId of weapon
+     * @param parentTemplate
+     * @param modSpawnChances
+     * @param ammoTpl ammo tpl to use when generating magazines/cartridges
+     * @param botRole role of bot weapon is generated for
+     * @returns Weapon with mods
+     */
+    generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[];
+    /**
+     * Generate a pool of mods for this bots mod type if bot has values inside `randomisedWeaponModSlots` array found in bot.json/equipment[botrole]
+     * @param allowedMods Mods to be added to mod pool
+     * @param botEquipBlacklist blacklist of items not allowed to be added to mod pool
+     * @param modSlot Slot to generate mods for
+     * @param itemModPool base mod pool to replace values of
+     */
+    protected generateDynamicModPool(allowedMods: string[], botEquipBlacklist: EquipmentFilterDetails, modSlot: string, itemModPool: Record<string, string[]>): void;
+    /**
+     * Check if the specific item type on the weapon has reached the set limit
+     * @param modTpl item to check is limited
+     * @param currentCount current number of this item on gun
+     * @param maxLimit mod limit allowed
+     * @param botRole role of bot we're checking weapon of
+     * @returns true if limit reached
+     */
+    protected weaponModLimitReached(modTpl: string, currentCount: {
+        count: number;
+    }, maxLimit: number, botRole: string): boolean;
+    /**
+     * log errors if mod is not valid for a slot
+     * @param modTpl
+     * @param found
+     * @param itemSlot
+     * @param modTemplate
+     * @param modSlot
+     * @param parentTemplate
+     * @returns true if valid
+     */
+    protected isModValidForSlot(modTpl: string, found: boolean, itemSlot: Slot, modTemplate: ITemplateItem, modSlot: string, parentTemplate: ITemplateItem): boolean;
+    /**
+     * Create a mod item with parameters as properties
+     * @param modId _id
+     * @param modTpl _tpl
+     * @param parentId parentId
+     * @param modSlot slotId
+     * @param modTemplate Used to add additional properites in the upd object
+     * @returns Item object
+     */
+    protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item;
     /**
      * Is this magazine cylinder related (revolvers and grenade launchers)
      * @param magazineParentName the name of the magazines parent
@@ -62,11 +131,11 @@ export declare class BotGeneratorHelper {
      * Those magazines (e.g. 60dc519adf4c47305f6d410d) have a "Cartridges" entry with a _max_count=0.
      * Ammo is not put into the magazine directly but assigned to the magazine's slots: The "camora_xxx" slots.
      * This function is a helper called by generateModsForItem for mods with parent type "CylinderMagazine"
-     *
-     * @param {object}      items               The items where the CylinderMagazine's camora are appended to
-     * @param {object}      modPool             modPool which should include available cartrigdes
-     * @param {string}      parentId            The CylinderMagazine's UID
-     * @param {object}      parentTemplate      The CylinderMagazine's template
+     * @param items The items where the CylinderMagazine's camora are appended to
+     * @param modPool modPool which should include available cartrigdes
+     * @param parentId The CylinderMagazine's UID
+     * @param parentTemplate The CylinderMagazine's template
+     * @returns
      */
     protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void;
     /**
@@ -75,6 +144,13 @@ export declare class BotGeneratorHelper {
      * @returns string array of shells fro luitple camora sources
      */
     protected mergeCamoraPoolsTogether(camorasWithShells: Record<string, string[]>): string[];
+    /**
+     * Adds properties to an item
+     * e.g. Repairable / HasHinge / Foldable / MaxDurability
+     * @param itemTemplate
+     * @param botRole Used by weapons to randomise the durability values
+     * @returns Item Upd object with extra properties
+     */
     generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): {
         upd?: Upd;
     };
@@ -93,12 +169,6 @@ export declare class BotGeneratorHelper {
      */
     protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable;
     protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string;
-    /**
-     * Sort by spawn chance, highest to lowest, higher is more common
-     * @param unsortedModArray String array to sort
-     * @returns Sorted string array
-     */
-    protected sortModArray(unsortedModArray: string[]): string[];
     /**
      * Can an item be added to an item without issue
      * @param items
@@ -117,8 +187,15 @@ export declare class BotGeneratorHelper {
      * @returns a `boolean` indicating item was added
      */
     addItemWithChildrenToEquipmentSlot(equipmentSlots: string[], parentId: string, parentTpl: string, itemWithChildren: Item[], inventory: PmcInventory): boolean;
+    /**
+     * is the provided item allowed inside a container
+     * @param slot location item wants to be placed in
+     * @param itemTpl item being placed
+     * @returns true if allowed
+     */
     protected itemAllowedInContainer(slot: Grid, itemTpl: string): boolean;
 }
+/** TODO - move into own class */
 export declare class ExhaustableArray<T> {
     private itemPool;
     private randomUtil;
diff --git a/TypeScript/13AddTrader/types/helpers/HideoutHelper.d.ts b/TypeScript/13AddTrader/types/helpers/HideoutHelper.d.ts
index 36e4009..7495a6a 100644
--- a/TypeScript/13AddTrader/types/helpers/HideoutHelper.d.ts
+++ b/TypeScript/13AddTrader/types/helpers/HideoutHelper.d.ts
@@ -44,14 +44,72 @@ export declare class HideoutHelper {
     initProduction(recipeId: string, productionTime: number): Production;
     isProductionType(productive: Productive): productive is Production;
     applyPlayerUpgradesBonuses(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * TODO:
+     * After looking at the skills there doesnt seem to be a configuration per skill to boost
+     * the XP gain PER skill. I THINK you should be able to put the variable "SkillProgress" (just like health has it)
+     * and be able to tune the skill gain PER skill, but I havent tested it and Im not sure!
+     * @param pmcData
+     * @param bonus
+     */
     protected applySkillXPBoost(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * Process a players hideout, update areas that use resources + increment production timers
+     * @param sessionID Session id
+     */
     updatePlayerHideout(sessionID: string): void;
+    /**
+     * Update progress timer for water collector
+     * @param pmcData profile to update
+     * @param productionId id of water collection production to update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateWaterCollectorProductionTimer(pmcData: IPmcData, productionId: string, hideoutProperties: {
+        btcFarmCGs?: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Iterate over productions and update their progress timers
+     * @param pmcData Profile to check for productions and update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Update progress timer for scav case
+     * @param pmcData Profile to update
+     * @param productionId Id of scav case production to update
+     */
+    protected updateScavCaseProductionTimer(pmcData: IPmcData, productionId: string): void;
+    /**
+     * Iterate over hideout areas that use resources (fuel/filters etc) and update associated values
+     * @param sessionID Session id
+     * @param pmcData Profile to update areas of
+     * @param hideoutProperties hideout properties
+     */
+    protected updateAreasWithResources(sessionID: string, pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
     protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
     protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
-    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): HideoutArea;
-    protected updateWaterFilters(waterFilterArea: HideoutArea, pwProd: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
+    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): void;
+    /**
+     * Adjust water filter objects resourceValue or delete when they reach 0 resource
+     * @param waterFilterArea water filter area to update
+     * @param production production object
+     * @param isGeneratorOn is generatory enabled
+     * @param pmcData Player profile
+     * @returns Updated HideoutArea object
+     */
+    protected updateWaterFilters(waterFilterArea: HideoutArea, production: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
     protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
-    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): HideoutArea;
+    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): void;
     protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
     protected getBTCSlots(pmcData: IPmcData): number;
     protected getManagementSkillsSlots(): number;
diff --git a/TypeScript/13AddTrader/types/helpers/InRaidHelper.d.ts b/TypeScript/13AddTrader/types/helpers/InRaidHelper.d.ts
index b382e30..962df38 100644
--- a/TypeScript/13AddTrader/types/helpers/InRaidHelper.d.ts
+++ b/TypeScript/13AddTrader/types/helpers/InRaidHelper.d.ts
@@ -18,18 +18,6 @@ export declare class InRaidHelper {
     protected paymentHelper: PaymentHelper;
     protected profileFixerService: ProfileFixerService;
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper, profileFixerService: ProfileFixerService);
-    /**
-     * Reset the SPT inraid property stored in a profile to 'none'
-     * @param sessionID Session id
-     */
-    protected removePlayer(sessionID: string): void;
-    /**
-     * Some maps have one-time-use keys (e.g. Labs
-     * Remove the relevant key from an inventory based on the post-raid request data passed in
-     * @param offraidData post-raid data
-     * @param sessionID Session id
-     */
-    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
     /**
      * Check an array of items and add an upd object to money items with a stack count of 1
      * Single stack money items have no upd object and thus no StackObjectsCount, causing issues
@@ -54,6 +42,18 @@ export declare class InRaidHelper {
      * @returns Reset profile object
      */
     updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData;
+    /**
+     * Some maps have one-time-use keys (e.g. Labs
+     * Remove the relevant key from an inventory based on the post-raid request data passed in
+     * @param offraidData post-raid data
+     * @param sessionID Session id
+     */
+    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Set the SPT inraid location Profile property to 'none'
+     * @param sessionID Session id
+     */
+    protected setPlayerInRaidLocationStatusToNone(sessionID: string): void;
     /**
      * Adds SpawnedInSession property to items found in a raid
      * Removes SpawnedInSession for non-scav players if item was taken into raid with SpawnedInSession = true
@@ -95,5 +95,10 @@ export declare class InRaidHelper {
      * @returns true if item is kept after death
      */
     isItemKeptAfterDeath(slotId: string): boolean;
+    /**
+     * Return the equipped items from a players inventory
+     * @param items Players inventory to search through
+     * @returns an array of equipped items
+     */
     getPlayerGear(items: Item[]): Item[];
 }
diff --git a/TypeScript/13AddTrader/types/helpers/ItemHelper.d.ts b/TypeScript/13AddTrader/types/helpers/ItemHelper.d.ts
index 1701c62..de10892 100644
--- a/TypeScript/13AddTrader/types/helpers/ItemHelper.d.ts
+++ b/TypeScript/13AddTrader/types/helpers/ItemHelper.d.ts
@@ -1,35 +1,30 @@
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item, Repairable } from "../models/eft/common/tables/IItem";
+import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase";
 import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+import { MathUtil } from "../utils/MathUtil";
+import { ObjectId } from "../utils/ObjectId";
+import { RandomUtil } from "../utils/RandomUtil";
 declare class ItemHelper {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
     protected jsonUtil: JsonUtil;
+    protected randomUtil: RandomUtil;
+    protected objectId: ObjectId;
+    protected mathUtil: MathUtil;
     protected databaseServer: DatabaseServer;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer);
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer);
     /**
      * Checks if a id is a valid item. Valid meaning that it's an item that be stored in stash
      * @param       {string}    tpl       the template id / tpl
      * @returns                             boolean; true for items that may be in player posession and not quest items
      */
     isValidItem(tpl: string, invalidBaseTypes?: string[]): boolean;
-    /**
-     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
-     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
-     * @param {*} tpl template id of item to check
-     * @returns boolean: true if item is valid reward
-     */
-    isValidRewardItem(tpl: string): boolean;
-    /**
-     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
-     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
-     */
-    getRewardableItems(): [string, ITemplateItem][];
     /**
      * Check if the tpl / template Id provided is a descendent of the baseclass
      *
@@ -196,6 +191,22 @@ declare class ItemHelper {
      * @returns ItemSize object (width and height)
      */
     getItemSize(items: Item[], rootItemId: string): ItemHelper.ItemSize;
+    /**
+     * Get a random cartridge from an items Filter property
+     * @param item
+     * @returns
+     */
+    getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
+    createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
+    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
+    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
+    createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
+    /**
+     * Get the size of a stack, return 1 if no stack object count property found
+     * @param item Item to get stack size of
+     * @returns size of stack
+     */
+    getItemStackSize(item: Item): number;
 }
 declare namespace ItemHelper {
     interface ItemSize {
diff --git a/TypeScript/13AddTrader/types/helpers/ProfileHelper.d.ts b/TypeScript/13AddTrader/types/helpers/ProfileHelper.d.ts
index 9d4ff98..9c6560a 100644
--- a/TypeScript/13AddTrader/types/helpers/ProfileHelper.d.ts
+++ b/TypeScript/13AddTrader/types/helpers/ProfileHelper.d.ts
@@ -24,6 +24,19 @@ export declare class ProfileHelper {
     constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, fenceService: FenceService);
     resetProfileQuestCondition(sessionID: string, conditionId: string): void;
     getCompleteProfile(sessionID: string): IPmcData[];
+    /**
+     * Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
+     * Server saves the post-raid changes prior to the xp screen getting the profile, this results in the xp screen using
+     * the now updated profile values as a base, meaning it shows x2 xp gained
+     * Instead, clone the post-raid profile (so we dont alter its values), apply the pre-raid xp values to the cloned objects and return
+     * Delete snapshot of pre-raid profile prior to returning profile data
+     * @param sessionId Session id
+     * @param output pmc and scav profiles array
+     * @param pmcProfile post-raid pmc profile
+     * @param scavProfile post-raid scav profile
+     * @returns updated profile array
+     */
+    protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
     isNicknameTaken(info: IValidateNicknameRequestData, sessionID: string): boolean;
     /**
      * Add experience to a PMC inside the players profile
diff --git a/TypeScript/13AddTrader/types/helpers/QuestHelper.d.ts b/TypeScript/13AddTrader/types/helpers/QuestHelper.d.ts
index 32e55ec..d66d150 100644
--- a/TypeScript/13AddTrader/types/helpers/QuestHelper.d.ts
+++ b/TypeScript/13AddTrader/types/helpers/QuestHelper.d.ts
@@ -36,11 +36,20 @@ export declare class QuestHelper {
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
     constructor(logger: ILogger, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, itemHelper: ItemHelper, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, localeService: LocaleService, ragfairServerHelper: RagfairServerHelper, dialogueHelper: DialogueHelper, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, traderHelper: TraderHelper, configServer: ConfigServer);
-    questStatus(pmcData: IPmcData, questID: string): QuestStatus;
     /**
-     * returns true is the condition is satisfied
+    * Get status of a quest by quest id
+    * @param pmcData Profile to search
+    * @param questID Quest id to look up
+    * @returns QuestStauts enum
+    */
+    getQuestStatus(pmcData: IPmcData, questID: string): QuestStatus;
+    /**
+     * returns true is the level condition is satisfied
+     * @param playerLevel Players level
+     * @param condition Quest condition
+     * @returns true if player level is greater than or equal to quest
      */
-    evaluateLevel(pmcProfile: IPmcData, cond: AvailableForConditions): boolean;
+    doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean;
     getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[];
     /**
      * Increase skill points of a skill on player profile
diff --git a/TypeScript/13AddTrader/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/13AddTrader/types/helpers/RagfairOfferHelper.d.ts
index 8d03bee..e9d72ca 100644
--- a/TypeScript/13AddTrader/types/helpers/RagfairOfferHelper.d.ts
+++ b/TypeScript/13AddTrader/types/helpers/RagfairOfferHelper.d.ts
@@ -22,12 +22,14 @@ import { ProfileHelper } from "./ProfileHelper";
 import { RagfairHelper } from "./RagfairHelper";
 import { RagfairServerHelper } from "./RagfairServerHelper";
 import { RagfairSortHelper } from "./RagfairSortHelper";
+import { TraderHelper } from "./TraderHelper";
 export declare class RagfairOfferHelper {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
     protected hashUtil: HashUtil;
     protected itemEventRouter: ItemEventRouter;
     protected databaseServer: DatabaseServer;
+    protected traderHelper: TraderHelper;
     protected saveServer: SaveServer;
     protected dialogueHelper: DialogueHelper;
     protected itemHelper: ItemHelper;
@@ -43,10 +45,10 @@ export declare class RagfairOfferHelper {
     protected static goodSoldTemplate: string;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, traderHelper: TraderHelper, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
     getValidOffers(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
     getOffersForBuild(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
-    processOffers(sessionID: string): boolean;
+    processOffersOnProfile(sessionID: string): boolean;
     protected getProfileOffers(sessionID: string): IRagfairOffer[];
     protected deleteOfferByOfferId(sessionID: string, offerId: string): void;
     protected completeOffer(sessionID: string, offer: IRagfairOffer, boughtAmount: number): IItemEventRouterResponse;
diff --git a/TypeScript/13AddTrader/types/helpers/RagfairSellHelper.d.ts b/TypeScript/13AddTrader/types/helpers/RagfairSellHelper.d.ts
index 6ec004a..91b8a20 100644
--- a/TypeScript/13AddTrader/types/helpers/RagfairSellHelper.d.ts
+++ b/TypeScript/13AddTrader/types/helpers/RagfairSellHelper.d.ts
@@ -11,6 +11,12 @@ export declare class RagfairSellHelper {
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     constructor(logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer);
-    calculateSellChance(baseChance: number, offerPrice: number, requirementsPriceInRub: number): number;
-    rollForSale(sellChance: number, count: number): SellResult[];
+    calculateSellChance(baseChancePercent: number, offerPriceRub: number, playerListedPriceRub: number): number;
+    /**
+     * Determine if the offer being listed will be sold
+     * @param sellChancePercent chance item will sell
+     * @param itemSellCount count of items to sell
+     * @returns Array of purchases of item(s) lsited
+     */
+    rollForSale(sellChancePercent: number, itemSellCount: number): SellResult[];
 }
diff --git a/TypeScript/13AddTrader/types/helpers/RagfairServerHelper.d.ts b/TypeScript/13AddTrader/types/helpers/RagfairServerHelper.d.ts
index e4939d1..a03cdda 100644
--- a/TypeScript/13AddTrader/types/helpers/RagfairServerHelper.d.ts
+++ b/TypeScript/13AddTrader/types/helpers/RagfairServerHelper.d.ts
@@ -6,6 +6,7 @@ import { IRagfairConfig } from "../models/spt/config/IRagfairConfig";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { SaveServer } from "../servers/SaveServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { LocaleService } from "../services/LocaleService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -13,6 +14,9 @@ import { RandomUtil } from "../utils/RandomUtil";
 import { DialogueHelper } from "./DialogueHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProfileHelper } from "./ProfileHelper";
+/**
+ * Helper class for common ragfair server actions
+ */
 export declare class RagfairServerHelper {
     protected randomUtil: RandomUtil;
     protected hashUtil: HashUtil;
@@ -23,11 +27,12 @@ export declare class RagfairServerHelper {
     protected localeService: LocaleService;
     protected dialogueHelper: DialogueHelper;
     protected jsonUtil: JsonUtil;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
     protected static goodsReturnedTemplate: string;
-    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, configServer: ConfigServer);
+    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Is item valid / on blacklist / quest item
      * @param itemDetails
diff --git a/TypeScript/13AddTrader/types/helpers/TradeHelper.d.ts b/TypeScript/13AddTrader/types/helpers/TradeHelper.d.ts
index 975062b..7ab9768 100644
--- a/TypeScript/13AddTrader/types/helpers/TradeHelper.d.ts
+++ b/TypeScript/13AddTrader/types/helpers/TradeHelper.d.ts
@@ -39,6 +39,12 @@ export declare class TradeHelper {
      * @returns
      */
     sellItem(pmcData: IPmcData, body: IProcessSellTradeRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment the assorts buy count by number of items purchased
+     * Show error on screen if player attepts to buy more than what the buy max allows
+     * @param assortBeingPurchased assort being bought
+     * @param itemsPurchasedCount number of items being bought
+     */
     protected incrementAssortBuyCount(assortBeingPurchased: Item, itemsPurchasedCount: number): void;
     protected checkPurchaseIsWithinTraderItemLimit(assortBeingPurchased: Item, assortId: string, count: number): void;
 }
diff --git a/TypeScript/13AddTrader/types/helpers/TraderAssortHelper.d.ts b/TypeScript/13AddTrader/types/helpers/TraderAssortHelper.d.ts
index 677dd66..025efd6 100644
--- a/TypeScript/13AddTrader/types/helpers/TraderAssortHelper.d.ts
+++ b/TypeScript/13AddTrader/types/helpers/TraderAssortHelper.d.ts
@@ -1,6 +1,5 @@
 import { RagfairAssortGenerator } from "../generators/RagfairAssortGenerator";
 import { RagfairOfferGenerator } from "../generators/RagfairOfferGenerator";
-import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ITrader, ITraderAssort } from "../models/eft/common/tables/ITrader";
 import { ITraderConfig } from "../models/spt/config/ITraderConfig";
@@ -41,12 +40,7 @@ export declare class TraderAssortHelper {
      * @param traderId traders id
      * @returns a traders' assorts
      */
-    getAssort(sessionId: string, traderId: string): ITraderAssort;
-    /**
-     * if the fence assorts have expired, re-generate them
-     * @param pmcProfile Players profile
-     */
-    refreshFenceAssortIfExpired(pmcProfile: IPmcData): void;
+    getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort;
     /**
      * Reset a traders assorts and move nextResupply value to future
      * Flag trader as needing a flea offer reset to be picked up by flea update() function
diff --git a/TypeScript/13AddTrader/types/helpers/TraderHelper.d.ts b/TypeScript/13AddTrader/types/helpers/TraderHelper.d.ts
index 6bda5cd..0dc93e8 100644
--- a/TypeScript/13AddTrader/types/helpers/TraderHelper.d.ts
+++ b/TypeScript/13AddTrader/types/helpers/TraderHelper.d.ts
@@ -65,7 +65,7 @@ export declare class TraderHelper {
      * @param item
      * @returns boolean
      */
-    protected isWeaponAndBelowTraderBuyDurability(traderID: string, item: Item): boolean;
+    protected isWeaponBelowTraderBuyDurability(traderID: string, item: Item): boolean;
     /**
      * Get the price of an item and all of its attached children
      * Take into account bonuses/adjsutments e.g. discounts
diff --git a/TypeScript/13AddTrader/types/models/eft/common/tables/ITemplateItem.d.ts b/TypeScript/13AddTrader/types/models/eft/common/tables/ITemplateItem.d.ts
index 23a1a14..6b2fa8f 100644
--- a/TypeScript/13AddTrader/types/models/eft/common/tables/ITemplateItem.d.ts
+++ b/TypeScript/13AddTrader/types/models/eft/common/tables/ITemplateItem.d.ts
@@ -34,6 +34,7 @@ export interface Props {
     LootExperience?: number;
     ExamineExperience?: number;
     HideEntrails?: boolean;
+    InsuranceDisabled?: boolean;
     RepairCost?: number;
     RepairSpeed?: number;
     ExtraSizeLeft?: number;
@@ -206,6 +207,7 @@ export interface Props {
     IsOneoff?: boolean;
     MustBoltBeOpennedForExternalReload?: boolean;
     MustBoltBeOpennedForInternalReload?: boolean;
+    NoFiremodeOnBoltcatch?: boolean;
     BoltAction?: boolean;
     HipAccuracyRestorationDelay?: number;
     HipAccuracyRestorationSpeed?: number;
diff --git a/TypeScript/13AddTrader/types/models/eft/common/tables/ITrader.d.ts b/TypeScript/13AddTrader/types/models/eft/common/tables/ITrader.d.ts
index a84f5af..37b2d61 100644
--- a/TypeScript/13AddTrader/types/models/eft/common/tables/ITrader.d.ts
+++ b/TypeScript/13AddTrader/types/models/eft/common/tables/ITrader.d.ts
@@ -67,6 +67,7 @@ export interface IBarterScheme {
     count: number;
     _tpl: string;
     onlyFunctional?: boolean;
+    sptQuestLocked?: boolean;
 }
 export interface ISuit {
     _id: string;
diff --git a/TypeScript/13AddTrader/types/models/eft/ragfair/IRagfairOffer.d.ts b/TypeScript/13AddTrader/types/models/eft/ragfair/IRagfairOffer.d.ts
index 63f655e..141b605 100644
--- a/TypeScript/13AddTrader/types/models/eft/ragfair/IRagfairOffer.d.ts
+++ b/TypeScript/13AddTrader/types/models/eft/ragfair/IRagfairOffer.d.ts
@@ -15,6 +15,8 @@ export interface IRagfairOffer {
     name?: string;
     shortName?: string;
     loyaltyLevel: number;
+    buyRestrictionMax?: number;
+    buyRestrictionCurrent?: number;
     locked: boolean;
     unlimitedCount: boolean;
     summaryCost: number;
diff --git a/TypeScript/13AddTrader/types/models/enums/AmmoTypes.d.ts b/TypeScript/13AddTrader/types/models/enums/AmmoTypes.d.ts
index b52ddcf..254b410 100644
--- a/TypeScript/13AddTrader/types/models/enums/AmmoTypes.d.ts
+++ b/TypeScript/13AddTrader/types/models/enums/AmmoTypes.d.ts
@@ -23,7 +23,7 @@ export declare enum Ammo762x54 {
     BT_GZH = "5e023d34e8a400319a28ed44",
     BS_GZH = "5e023d48186a883be655e551"
 }
-export declare enum Ammo338Lapua {
+export declare enum Ammo86x70 {
     TAC_X = "5fc382b6d6fa9c00c571bbc3",
     UCW = "5fc382c1016cce60e8341b20",
     AP = "5fc382a9d724d907e2077dab",
@@ -85,13 +85,13 @@ export declare enum Ammo9x21 {
     PE_GZH = "5a26ac06c4a282000c5a90a8",
     BT_GZH = "5a26ac0ec4a28200741e1e18"
 }
-export declare enum Ammo357Mag {
+export declare enum Ammo9x33R {
     FMJ = "62330b3ed4dc74626d570b95",
     HOLLOW_POINT = "62330bfadc5883093563729b",
     SOFT_POINT = "62330c40bdd19b369e1e53d1",
     JACKET_HP = "62330c18744e5e31df12f516"
 }
-export declare enum Ammo45ACP {
+export declare enum Ammo1143x23ACP {
     MATCH_FMJ = "5e81f423763d9f754677bf2e",
     HYDRA_SHOK = "5efb0fc6aeb21837e749c801",
     LASERMATCH_FMJ = "5efb0d4f4bc50b58e81710f3",
@@ -126,7 +126,7 @@ export declare enum Ammo556x45 {
     MK_318_MOD_0_SOST = "60194943740c5d77f6705eea",
     SSA_AP = "601949593ae8f707c4608daa"
 }
-export declare enum Ammo300Blackout {
+export declare enum Ammo762x35 {
     M62_TRACER = "619636be6db0f2477964e710",
     BCP_FMJ = "5fbe3ffdf8b6a877a729ea82",
     AP = "5fd20ff893a8961fc660a954",
diff --git a/TypeScript/13AddTrader/types/models/enums/BaseClasses.d.ts b/TypeScript/13AddTrader/types/models/enums/BaseClasses.d.ts
index e733bca..37c1398 100644
--- a/TypeScript/13AddTrader/types/models/enums/BaseClasses.d.ts
+++ b/TypeScript/13AddTrader/types/models/enums/BaseClasses.d.ts
@@ -68,6 +68,7 @@ export declare enum BaseClasses {
     ASSAULT_SCOPE = "55818add4bdc2d5b648b456f",
     REFLEX_SIGHT = "55818ad54bdc2ddc698b4569",
     TACTICAL_COMBO = "55818b164bdc2ddc698b456c",
+    FLASHLIGHT = "55818b084bdc2d5b648b4571",
     MAGAZINE = "5448bc234bdc2d3c308b4569",
     LIGHT_LASER = "55818b0e4bdc2dde698b456e",
     FLASH_HIDER = "550aa4bf4bdc2dd6348b456b",
diff --git a/TypeScript/13AddTrader/types/models/enums/ConfigTypes.d.ts b/TypeScript/13AddTrader/types/models/enums/ConfigTypes.d.ts
index 61d6f99..468ece5 100644
--- a/TypeScript/13AddTrader/types/models/enums/ConfigTypes.d.ts
+++ b/TypeScript/13AddTrader/types/models/enums/ConfigTypes.d.ts
@@ -8,6 +8,7 @@ export declare enum ConfigTypes {
     IN_RAID = "aki-inraid",
     INSURANCE = "aki-insurance",
     INVENTORY = "aki-inventory",
+    ITEM = "aki-item",
     LOCALE = "aki-locale",
     LOCATION = "aki-location",
     MATCH = "aki-match",
diff --git a/TypeScript/13AddTrader/types/models/enums/ELocationName.d.ts b/TypeScript/13AddTrader/types/models/enums/ELocationName.d.ts
index b56cc08..7ae7caa 100644
--- a/TypeScript/13AddTrader/types/models/enums/ELocationName.d.ts
+++ b/TypeScript/13AddTrader/types/models/enums/ELocationName.d.ts
@@ -1,5 +1,6 @@
 export declare enum ELocationName {
     FACTORY_DAY = "factory4_day",
+    FACTORY_NIGHT = "factory4_night",
     BIGMAP = "bigmap",
     WOODS = "Woods",
     SHORELINE = "Shoreline",
diff --git a/TypeScript/13AddTrader/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/13AddTrader/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/13AddTrader/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/13AddTrader/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/13AddTrader/types/models/spt/config/IBotConfig.d.ts b/TypeScript/13AddTrader/types/models/spt/config/IBotConfig.d.ts
index e171087..f15fa73 100644
--- a/TypeScript/13AddTrader/types/models/spt/config/IBotConfig.d.ts
+++ b/TypeScript/13AddTrader/types/models/spt/config/IBotConfig.d.ts
@@ -1,17 +1,31 @@
 import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
+import { IBotDurability } from "./IBotDurability";
+import { IPmcConfig } from "./IPmcConfig";
 export interface IBotConfig extends IBaseConfig {
     kind: "aki-bot";
+    /** How many variants of each bot should be generated on raid start */
     presetBatch: PresetBatch;
+    /** What bot types should be classified as bosses */
     bosses: string[];
-    durability: Durability;
+    /** Control weapon/armor durability min/max values for each bot type */
+    durability: IBotDurability;
+    /** Control the weighting of how expensive an average loot item is on a PMC or Scav */
     lootNValue: LootNvalue;
+    /** Control what bots are added to a bots revenge list key: bottype, value: bottypes to revenge on seeing their death */
     revenge: Record<string, string[]>;
-    pmc: PmcConfig;
+    /** PMC bot specific config settings */
+    pmc: IPmcConfig;
+    /** Control how many items are allowed to spawn on a bot
+     * key: bottype, value: <key: itemTpl: value: max item count> */
     itemSpawnLimits: Record<string, Record<string, number>>;
-    equipment: Record<string, Equipment>;
+    /** Blacklist/whitelist items on a bot */
+    equipment: Record<string, EquipmentFilters>;
+    /** Show a bots botType value after their name */
     showTypeInNickname: boolean;
+    /** Max number of bots that can be spawned in a raid at any one time */
     maxBotCap: number;
+    /** How many stacks of secret ammo should a bot have in its bot secure container */
     secureContainerAmmoStackCount: number;
 }
 export interface PresetBatch {
@@ -44,79 +58,22 @@ export interface PresetBatch {
     test: number;
     exUsec: number;
 }
-export interface Durability {
-    default: DefaultDurability;
-    pmc: PmcDurability;
-    boss: BotDurability;
-    follower: BotDurability;
-    assault: BotDurability;
-    cursedassault: BotDurability;
-    marksman: BotDurability;
-    pmcbot: BotDurability;
-    exusec: BotDurability;
-    sectantpriest: BotDurability;
-    sectantwarrior: BotDurability;
-}
-export interface DefaultDurability {
-    armor: DefaultArmor;
-    weapon: WeaponDurability;
-}
-export interface DefaultArmor {
-    maxDelta: number;
-    minDelta: number;
-}
-export interface WeaponDurability {
-    lowestMax: number;
-    highestMax: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface PmcDurability {
-    armor: PmcDurabilityArmor;
-    weapon: WeaponDurability;
-}
-export interface PmcDurabilityArmor {
-    lowestMaxPercent: number;
-    highestMaxPercent: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface BotDurability {
-    armor: ArmorDurability;
-    weapon: WeaponDurability;
-}
-export interface ArmorDurability {
-    maxDelta: number;
-    minDelta: number;
-}
 export interface LootNvalue {
     scav: number;
     pmc: number;
 }
-export interface PmcConfig {
-    dynamicLoot: PmcDynamicLoot;
-    difficulty: string;
-    looseWeaponInBackpackChancePercent: number;
-    looseWeaponInBackpackLootMinMax: MinMax;
-    isUsec: number;
-    chanceSameSideIsHostilePercent: number;
-    usecType: string;
-    bearType: string;
-    maxBackpackLootTotalRub: number;
-    maxPocketLootTotalRub: number;
-    maxVestLootTotalRub: number;
-    convertIntoPmcChance: Record<string, MinMax>;
-    enemyTypes: string[];
-}
-export interface PmcDynamicLoot {
-    whitelist: string[];
-    blacklist: string[];
-    moneyStackLimits: Record<string, number>;
-}
-export interface Equipment {
+export interface EquipmentFilters {
+    weaponModLimits: ModLimits;
+    randomisedWeaponModSlots?: string[];
     blacklist: EquipmentFilterDetails[];
     whitelist: EquipmentFilterDetails[];
 }
+export interface ModLimits {
+    /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */
+    scopeLimit?: number;
+    /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */
+    lightLaserLimit?: number;
+}
 export interface EquipmentFilterDetails {
     levelRange: MinMax;
     equipment: Record<string, string[]>;
diff --git a/TypeScript/13AddTrader/types/models/spt/config/IBotDurability.d.ts b/TypeScript/13AddTrader/types/models/spt/config/IBotDurability.d.ts
new file mode 100644
index 0000000..38a47cc
--- /dev/null
+++ b/TypeScript/13AddTrader/types/models/spt/config/IBotDurability.d.ts
@@ -0,0 +1,47 @@
+export interface IBotDurability {
+    default: DefaultDurability;
+    pmc: PmcDurability;
+    boss: BotDurability;
+    follower: BotDurability;
+    assault: BotDurability;
+    cursedassault: BotDurability;
+    marksman: BotDurability;
+    pmcbot: BotDurability;
+    exusec: BotDurability;
+    gifter: BotDurability;
+    sectantpriest: BotDurability;
+    sectantwarrior: BotDurability;
+}
+/** Durability values to be used when a more specific bot type cant be found */
+export interface DefaultDurability {
+    armor: DefaultArmor;
+    weapon: WeaponDurability;
+}
+export interface DefaultArmor {
+    maxDelta: number;
+    minDelta: number;
+}
+export interface WeaponDurability {
+    lowestMax: number;
+    highestMax: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface PmcDurability {
+    armor: PmcDurabilityArmor;
+    weapon: WeaponDurability;
+}
+export interface PmcDurabilityArmor {
+    lowestMaxPercent: number;
+    highestMaxPercent: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface BotDurability {
+    armor: ArmorDurability;
+    weapon: WeaponDurability;
+}
+export interface ArmorDurability {
+    maxDelta: number;
+    minDelta: number;
+}
diff --git a/TypeScript/13AddTrader/types/models/spt/config/IItemConfig.d.ts b/TypeScript/13AddTrader/types/models/spt/config/IItemConfig.d.ts
new file mode 100644
index 0000000..5ecccc2
--- /dev/null
+++ b/TypeScript/13AddTrader/types/models/spt/config/IItemConfig.d.ts
@@ -0,0 +1,5 @@
+import { IBaseConfig } from "./IBaseConfig";
+export interface IItemConfig extends IBaseConfig {
+    kind: "aki-item";
+    blacklist: string[];
+}
diff --git a/TypeScript/13AddTrader/types/models/spt/config/IPmcConfig.d.ts b/TypeScript/13AddTrader/types/models/spt/config/IPmcConfig.d.ts
new file mode 100644
index 0000000..655b58d
--- /dev/null
+++ b/TypeScript/13AddTrader/types/models/spt/config/IPmcConfig.d.ts
@@ -0,0 +1,22 @@
+import { MinMax } from "../../common/MinMax";
+export interface IPmcConfig {
+    dynamicLoot: DynamicLoot;
+    useDifficultyOverride: boolean;
+    difficulty: string;
+    looseWeaponInBackpackChancePercent: number;
+    looseWeaponInBackpackLootMinMax: MinMax;
+    isUsec: number;
+    chanceSameSideIsHostilePercent: number;
+    usecType: string;
+    bearType: string;
+    maxBackpackLootTotalRub: number;
+    maxPocketLootTotalRub: number;
+    maxVestLootTotalRub: number;
+    convertIntoPmcChance: Record<string, MinMax>;
+    enemyTypes: string[];
+}
+export interface DynamicLoot {
+    whitelist: string[];
+    blacklist: string[];
+    moneyStackLimits: Record<string, number>;
+}
diff --git a/TypeScript/13AddTrader/types/models/spt/config/IQuestConfig.d.ts b/TypeScript/13AddTrader/types/models/spt/config/IQuestConfig.d.ts
index be4a97b..45c9aae 100644
--- a/TypeScript/13AddTrader/types/models/spt/config/IQuestConfig.d.ts
+++ b/TypeScript/13AddTrader/types/models/spt/config/IQuestConfig.d.ts
@@ -4,6 +4,8 @@ export interface IQuestConfig extends IBaseConfig {
     kind: "aki-quest";
     redeemTime: number;
     repeatableQuests: IRepeatableQuestConfig[];
+    bearOnlyQuests: string[];
+    usecOnlyQuests: string[];
 }
 export interface IRepeatableQuestConfig {
     name: string;
@@ -15,6 +17,10 @@ export interface IRepeatableQuestConfig {
     locations: Record<ELocationName, string[]>;
     traderWhitelist: ITraderWhitelist[];
     questConfig: IQuestConfig;
+    /** Item base types to block when generating rewards */
+    rewardBaseTypeBlacklist: string[];
+    /** Item tplIds to ignore when generating rewards */
+    rewardBlacklist: string[];
 }
 export interface IRewardScaling {
     levels: number[];
diff --git a/TypeScript/13AddTrader/types/models/spt/config/IRagfairConfig.d.ts b/TypeScript/13AddTrader/types/models/spt/config/IRagfairConfig.d.ts
index 6369eda..3088717 100644
--- a/TypeScript/13AddTrader/types/models/spt/config/IRagfairConfig.d.ts
+++ b/TypeScript/13AddTrader/types/models/spt/config/IRagfairConfig.d.ts
@@ -12,6 +12,7 @@ export interface Sell {
     chance: Chance;
     time: Time;
     reputation: Reputation;
+    simulatedSellHours: number;
 }
 export interface Chance {
     base: number;
diff --git a/TypeScript/13AddTrader/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/13AddTrader/types/models/spt/config/ITraderConfig.d.ts
index c8e8044..6b1c1e3 100644
--- a/TypeScript/13AddTrader/types/models/spt/config/ITraderConfig.d.ts
+++ b/TypeScript/13AddTrader/types/models/spt/config/ITraderConfig.d.ts
@@ -12,8 +12,10 @@ export interface UpdateTime {
     seconds: number;
 }
 export interface FenceConfig {
+    partialRefreshTimeSeconds: number;
+    partialRefreshChangePercent: number;
     assortSize: number;
-    maxPresetsCount: number;
+    maxPresetsPercent: number;
     presetPriceMult: number;
     blacklist: string[];
 }
diff --git a/TypeScript/13AddTrader/types/models/spt/services/LootItem.d.ts b/TypeScript/13AddTrader/types/models/spt/services/LootItem.d.ts
new file mode 100644
index 0000000..2838472
--- /dev/null
+++ b/TypeScript/13AddTrader/types/models/spt/services/LootItem.d.ts
@@ -0,0 +1,5 @@
+export declare class LootItem {
+    tpl: string;
+    isPreset: boolean;
+    stackCount: number;
+}
diff --git a/TypeScript/13AddTrader/types/models/spt/services/LootRequest.d.ts b/TypeScript/13AddTrader/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/13AddTrader/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/13AddTrader/types/services/BotEquipmentFilterService.d.ts b/TypeScript/13AddTrader/types/services/BotEquipmentFilterService.d.ts
index e49645b..632f961 100644
--- a/TypeScript/13AddTrader/types/services/BotEquipmentFilterService.d.ts
+++ b/TypeScript/13AddTrader/types/services/BotEquipmentFilterService.d.ts
@@ -1,12 +1,12 @@
 import { IBotType } from "../models/eft/common/tables/IBotType";
-import { Equipment, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 export declare class BotEquipmentFilterService {
     protected logger: ILogger;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    protected botEquipmentFilterlists: Record<string, Equipment>;
+    protected botEquipmentFilterlists: Record<string, EquipmentFilters>;
     constructor(logger: ILogger, configServer: ConfigServer);
     /**
      * Filter a bots data to exclude equipment and cartridges defines in the botConfig
@@ -22,7 +22,7 @@ export declare class BotEquipmentFilterService {
      * @param playerLevel Level of the player
      * @returns EquipmentBlacklistDetails object
      */
-    protected getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
+    getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
     /**
      * Get the whitelist for a specific bot type that's within the players level
      * @param botRole Bot type
diff --git a/TypeScript/13AddTrader/types/services/FenceService.d.ts b/TypeScript/13AddTrader/types/services/FenceService.d.ts
index c9e325e..c940507 100644
--- a/TypeScript/13AddTrader/types/services/FenceService.d.ts
+++ b/TypeScript/13AddTrader/types/services/FenceService.d.ts
@@ -12,6 +12,11 @@ import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+import { ItemFilterService } from "./ItemFilterService";
+/**
+ * Handle actions surrounding Fence
+ * e.g. generating or refreshing assorts / get next refresh time
+ */
 export declare class FenceService {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
@@ -22,18 +27,64 @@ export declare class FenceService {
     protected handbookHelper: HandbookHelper;
     protected itemHelper: ItemHelper;
     protected presetHelper: PresetHelper;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected fenceAssort: ITraderAssort;
     protected traderConfig: ITraderConfig;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, configServer: ConfigServer);
+    protected nextMiniRefreshTimestamp: number;
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, itemFilterService: ItemFilterService, configServer: ConfigServer);
     protected setFenceAssort(fenceAssort: ITraderAssort): void;
-    getFenceAssorts(): ITraderAssort;
+    /**
+     * Get assorts player can purchase
+     * Adjust prices based on fence level of player
+     * @param pmcProfile Player profile
+     * @returns ITraderAssort
+     */
+    getFenceAssorts(pmcProfile: IPmcData): ITraderAssort;
+    /**
+     * Get fence assorts with no price adjustments based on fence rep
+     * @returns ITraderAssort
+     */
+    getRawFenceAssorts(): ITraderAssort;
+    /**
+     * Does fence need to perform a partial refresh because its passed the refresh timer defined in trader.json
+     * @returns true if it needs a partial refresh
+     */
+    needsPartialRefresh(): boolean;
+    /**
+     * Replace a percentage of fence assorts with freshly generated items
+     */
+    performPartialRefresh(): void;
+    /**
+     * Choose an item (not mod) at random and remove from assorts
+     */
+    protected removeRandomItemFromAssorts(): void;
+    /**
+     * Get an integer rounded count of items to replace based on percentrage from traderConfig value
+     * @param totalItemCount total item count
+     * @returns rounded int of items to replace
+     */
+    protected getCountOfItemsToReplace(totalItemCount: number): number;
     /**
      * Get the count of items fence offers
      * @returns number
      */
     getOfferCount(): number;
-    generateFenceAssortCache(pmcData: IPmcData): void;
+    /**
+     * Create a trader assort for fence
+     */
+    generateFenceAssortCache(): void;
+    /**
+     * Create skeleton to hold assort items
+     * @returns ITraderAssort object
+     */
+    protected createBaseTraderAssortItem(): ITraderAssort;
+    /**
+     * Hydrate result parameter object with generated assorts
+     * @param assortCount Number of assorts to generate
+     * @param assorts object to add assorts to
+     */
+    protected createAssorts(assortCount: number, assorts: ITraderAssort): void;
     /**
      * Get the next update timestamp for fence
      * @returns future timestamp
@@ -44,11 +95,14 @@ export declare class FenceService {
      */
     protected getFenceRefreshTime(): number;
     /**
-     * Get the fence level the passed in profile has
+     * Get fence level the passed in profile has
      * @param pmcData Player profile
-     * @returns FenceLevel
+     * @returns FenceLevel object
      */
     getFenceInfo(pmcData: IPmcData): FenceLevel;
+    /**
+     * Remove an assort from fence by id
+     * @param assortIdToRemove assort id to remove from fence assorts
+     */
     removeFenceOffer(assortIdToRemove: string): void;
-    updateFenceOffers(pmcData: IPmcData): void;
 }
diff --git a/TypeScript/13AddTrader/types/services/InsuranceService.d.ts b/TypeScript/13AddTrader/types/services/InsuranceService.d.ts
index 171bf10..6be8a2f 100644
--- a/TypeScript/13AddTrader/types/services/InsuranceService.d.ts
+++ b/TypeScript/13AddTrader/types/services/InsuranceService.d.ts
@@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
 import { SecureContainerHelper } from "../helpers/SecureContainerHelper";
 import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
+import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData";
 import { IInsuranceConfig } from "../models/spt/config/IInsuranceConfig";
@@ -44,8 +45,22 @@ export declare class InsuranceService {
      * @param mapId Id of the map player died/exited that caused the insurance to be issued on
      */
     sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void;
+    /**
+     * Store lost gear post-raid inside profile
+     * @param pmcData player profile to store gear in
+     * @param offraidData post-raid request object
+     * @param preRaidGear gear player wore prior to raid
+     * @param sessionID Session id
+     */
     storeLostGear(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
     storeInsuredItemsForReturn(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
-    protected addGearToSend(pmcData: IPmcData, insuredItem: any, actualItem: any, sessionID: string): any;
+    /**
+     * Add gear item to InsuredItems array in player profile
+     * @param pmcData profile to store item in
+     * @param insuredItem Item to store in profile
+     * @param actualItem item to store
+     * @param sessionID Session id
+     */
+    protected addGearToSend(pmcData: IPmcData, insuredItem: InsuredItem, actualItem: Item, sessionID: string): void;
     getPremium(pmcData: IPmcData, inventoryItem: Item, traderId: string): number;
 }
diff --git a/TypeScript/13AddTrader/types/services/ItemFilterService.d.ts b/TypeScript/13AddTrader/types/services/ItemFilterService.d.ts
new file mode 100644
index 0000000..c9c8ef3
--- /dev/null
+++ b/TypeScript/13AddTrader/types/services/ItemFilterService.d.ts
@@ -0,0 +1,24 @@
+import { IItemConfig } from "../models/spt/config/IItemConfig";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+/** Centralise the handling of blacklisting items, uses blacklist found in config/item.json */
+export declare class ItemFilterService {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected configServer: ConfigServer;
+    protected blacklist: string[];
+    protected itemConfig: IItemConfig;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer);
+    /**
+     * Check if the provided template id is blacklisted in config/item.json
+     * @param tpl template id
+     * @returns true if blacklisted
+     */
+    isItemBlacklisted(tpl: string): boolean;
+    /**
+     * Return every template id blacklisted in config/item.json
+     * @returns string array of blacklisted tempalte ids
+     */
+    getBlacklistedItems(): string[];
+}
diff --git a/TypeScript/13AddTrader/types/services/ProfileFixerService.d.ts b/TypeScript/13AddTrader/types/services/ProfileFixerService.d.ts
index ed1dec7..9cb5a38 100644
--- a/TypeScript/13AddTrader/types/services/ProfileFixerService.d.ts
+++ b/TypeScript/13AddTrader/types/services/ProfileFixerService.d.ts
@@ -45,6 +45,11 @@ export declare class ProfileFixerService {
      * @param pmcProfile Profile to find and remove slots from
      */
     protected removeResourcesFromSlotsInHideoutWithoutLocationIndexValue(pmcProfile: IPmcData): void;
+    /**
+     * Hideout slots need to be in a specific order, locationIndex in ascending order
+     * @param pmcProfile profile to edit
+     */
+    protected reorderHideoutAreasWithResouceInputs(pmcProfile: IPmcData): void;
     /**
      * add in objects equal to the number of slots
      * @param areaType area to check
diff --git a/TypeScript/13AddTrader/types/utils/HashUtil.d.ts b/TypeScript/13AddTrader/types/utils/HashUtil.d.ts
index bacbf2a..a8500e1 100644
--- a/TypeScript/13AddTrader/types/utils/HashUtil.d.ts
+++ b/TypeScript/13AddTrader/types/utils/HashUtil.d.ts
@@ -4,8 +4,18 @@ import { TimeUtil } from "./TimeUtil";
 export declare class HashUtil {
     protected timeUtil: TimeUtil;
     constructor(timeUtil: TimeUtil);
+    /**
+     * Create a 24 character id using the sha256 algorithm + current timestamp
+     * @returns 24 character hash
+     */
     generate(): string;
     generateMd5ForData(data: string): string;
     generateSha1ForData(data: string): string;
+    /**
+     * Create a hash for the data parameter
+     * @param algorithm algorithm to use to hash
+     * @param data data to be hashed
+     * @returns hash value
+     */
     generateHashForData(algorithm: string, data: crypto.BinaryLike): string;
 }
diff --git a/TypeScript/13AddTrader/types/utils/RandomUtil.d.ts b/TypeScript/13AddTrader/types/utils/RandomUtil.d.ts
index c24dd60..e35d21f 100644
--- a/TypeScript/13AddTrader/types/utils/RandomUtil.d.ts
+++ b/TypeScript/13AddTrader/types/utils/RandomUtil.d.ts
@@ -150,4 +150,10 @@ export declare class RandomUtil {
      */
     drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[];
     getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number;
+    /**
+     * Fisher-Yates shuffle an array
+     * @param array Array to shuffle
+     * @returns Shuffled array
+     */
+    shuffle<T>(array: Array<T>): Array<T>;
 }
diff --git a/TypeScript/13AddTrader/types/utils/TimeUtil.d.ts b/TypeScript/13AddTrader/types/utils/TimeUtil.d.ts
index f437f8a..1367e26 100644
--- a/TypeScript/13AddTrader/types/utils/TimeUtil.d.ts
+++ b/TypeScript/13AddTrader/types/utils/TimeUtil.d.ts
@@ -1,3 +1,6 @@
+/**
+ * Utility class to handle time related problems
+ */
 export declare class TimeUtil {
     static readonly oneHourAsSeconds = 3600;
     formatTime(date: Date): string;
@@ -19,4 +22,10 @@ export declare class TimeUtil {
      * @returns current date in format: 00.00.0000 (dd.mm.yyyy)
      */
     getDateMailFormat(): string;
+    /**
+     * Convert hours into seconds
+     * @param hours hours to convert to seconds
+     * @returns number
+     */
+    getHoursAsSeconds(hours: number): number;
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/callbacks/LocationCallbacks.d.ts b/TypeScript/14AfterDBLoadHook/types/callbacks/LocationCallbacks.d.ts
index cc69369..6e0b538 100644
--- a/TypeScript/14AfterDBLoadHook/types/callbacks/LocationCallbacks.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/callbacks/LocationCallbacks.d.ts
@@ -11,4 +11,5 @@ export declare class LocationCallbacks {
     constructor(httpResponse: HttpResponseUtil, locationController: LocationController);
     getLocationData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<ILocationsGenerateAllResponse>;
     getLocation(url: string, info: IGetLocationRequestData, sessionID: string): IGetBodyResponseData<ILocationBase>;
+    getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): string;
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/callbacks/ProfileCallbacks.d.ts b/TypeScript/14AfterDBLoadHook/types/callbacks/ProfileCallbacks.d.ts
index 6a86fc0..183bb0a 100644
--- a/TypeScript/14AfterDBLoadHook/types/callbacks/ProfileCallbacks.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/callbacks/ProfileCallbacks.d.ts
@@ -1,5 +1,6 @@
 import { ProfileController } from "../controllers/ProfileController";
 import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData";
+import { IPmcData } from "../models/eft/common/IPmcData";
 import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData";
 import { INullResponseData } from "../models/eft/httpResponse/INullResponseData";
 import { IGetMiniProfileRequestData } from "../models/eft/launcher/IGetMiniProfileRequestData";
@@ -12,20 +13,51 @@ import { ISearchFriendResponse } from "../models/eft/profile/ISearchFriendRespon
 import { IValidateNicknameRequestData } from "../models/eft/profile/IValidateNicknameRequestData";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/** Handle profile related client events */
 export declare class ProfileCallbacks {
     protected httpResponse: HttpResponseUtil;
     protected timeUtil: TimeUtil;
     protected profileController: ProfileController;
     constructor(httpResponse: HttpResponseUtil, timeUtil: TimeUtil, profileController: ProfileController);
     createProfile(url: string, info: IProfileCreateRequestData, sessionID: string): IGetBodyResponseData<any>;
-    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
-    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
+    /**
+     * Get the complete player profile (scav + pmc character)
+     * @param url
+     * @param info Empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle the creation of a scav profile for player
+     * Occurs post-raid and when profile first created immediately after character details are confirmed by player
+     * @param url
+     * @param info empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle client/game/profile/voice/change event
+     * @param url
+     * @param info Change voice request object
+     * @param sessionID Session id
+     * @returns Client response
+     */
     changeVoice(url: string, info: IProfileChangeVoiceRequestData, sessionID: string): INullResponseData;
+    /**
+     * Handle client/game/profile/nickname/change event
+     * Client allows player to adjust their profile name
+     * @param url
+     * @param info Change nickname request object
+     * @param sessionID Session id
+     * @returns client response
+     */
     changeNickname(url: string, info: IProfileChangeNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     validateNickname(url: string, info: IValidateNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     getReservedNickname(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<string>;
     /**
-     * Called when creating a character, when you choose a character face/voice
+     * Called when creating a character when choosing a character face/voice
      * @param url
      * @param info response (empty)
      * @param sessionID
diff --git a/TypeScript/14AfterDBLoadHook/types/callbacks/RagfairCallbacks.d.ts b/TypeScript/14AfterDBLoadHook/types/callbacks/RagfairCallbacks.d.ts
index 3a405c9..c609f2f 100644
--- a/TypeScript/14AfterDBLoadHook/types/callbacks/RagfairCallbacks.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/callbacks/RagfairCallbacks.d.ts
@@ -19,6 +19,9 @@ import { ConfigServer } from "../servers/ConfigServer";
 import { RagfairServer } from "../servers/RagfairServer";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+/**
+ * Handle ragfair related callback events
+ */
 export declare class RagfairCallbacks extends OnLoadOnUpdate {
     protected httpResponse: HttpResponseUtil;
     protected logger: ILogger;
diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/InraidController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/InraidController.d.ts
index 82bb64d..102a2fb 100644
--- a/TypeScript/14AfterDBLoadHook/types/controllers/InraidController.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/controllers/InraidController.d.ts
@@ -35,6 +35,30 @@ export declare class InraidController {
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer);
     addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void;
     saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Handle updating the profile post-pmc raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Reduce body part hp to % of max
+     * @param pmcData profile to edit
+     * @param multipler multipler to apply to max health
+     */
+    protected reducePmcHealthToPercent(pmcData: IPmcData, multipler: number): void;
+    /**
+     * Handle updating the profile post-pscav raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePlayerScavProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Is the player dead after a raid - dead is anything other than "survived" / "runner"
+     * @param statusOnExit exit value from offraidData object
+     * @returns true if dead
+     */
+    protected isPlayerDead(statusOnExit: string): boolean;
     /**
      * Mark inventory items as FiR if player survived raid, otherwise remove FiR from them
      * @param offraidData Save Progress Request
diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/InventoryController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/InventoryController.d.ts
index f57f731..f564919 100644
--- a/TypeScript/14AfterDBLoadHook/types/controllers/InventoryController.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/controllers/InventoryController.d.ts
@@ -92,7 +92,11 @@ export declare class InventoryController {
      */
     toggleItem(pmcData: IPmcData, body: IInventoryToggleRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Handles Tagging of items (primary Containers).
+     * Add a tag to an inventory item
+     * @param pmcData profile with item to add tag to
+     * @param body tag request data
+     * @param sessionID session id
+     * @returns client response object
      */
     tagItem(pmcData: IPmcData, body: IInventoryTagRequestData, sessionID: string): IItemEventRouterResponse;
     bindItem(pmcData: IPmcData, body: IInventoryBindRequestData, sessionID: string): IItemEventRouterResponse;
diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/LocationController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/LocationController.d.ts
index 90b6d7a..9db3205 100644
--- a/TypeScript/14AfterDBLoadHook/types/controllers/LocationController.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/controllers/LocationController.d.ts
@@ -1,18 +1,33 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class LocationController {
     protected jsonUtil: JsonUtil;
+    protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/MatchController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/MatchController.d.ts
index e8585d9..cb40023 100644
--- a/TypeScript/14AfterDBLoadHook/types/controllers/MatchController.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/controllers/MatchController.d.ts
@@ -9,6 +9,7 @@ import { IGetProfileRequestData } from "../models/eft/match/IGetProfileRequestDa
 import { IJoinMatchRequestData } from "../models/eft/match/IJoinMatchRequestData";
 import { IJoinMatchResult } from "../models/eft/match/IJoinMatchResult";
 import { IStartOfflineRaidRequestData } from "../models/eft/match/IStartOffineRaidRequestData";
+import { IBotConfig } from "../models/spt/config/IBotConfig";
 import { IInRaidConfig } from "../models/spt/config/IInRaidConfig";
 import { IMatchConfig } from "../models/spt/config/IMatchConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
@@ -29,6 +30,7 @@ export declare class MatchController {
     protected applicationContext: ApplicationContext;
     protected matchConfig: IMatchConfig;
     protected inraidConfig: IInRaidConfig;
+    protected botConfig: IBotConfig;
     constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, applicationContext: ApplicationContext);
     getEnabled(): boolean;
     getProfile(info: IGetProfileRequestData): IPmcData[];
diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/QuestController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/QuestController.d.ts
index 2cbccfb..282f50e 100644
--- a/TypeScript/14AfterDBLoadHook/types/controllers/QuestController.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/controllers/QuestController.d.ts
@@ -39,16 +39,31 @@ export declare class QuestController {
      * @returns array of IQuest
      */
     getClientQuests(sessionID: string): IQuest[];
+    /**
+     * Is the quest for the opposite side the player is on
+     * @param side player side (usec/bear)
+     * @param questId questId to check
+     */
+    protected questIsForOtherSide(side: string, questId: string): boolean;
+    /**
+     * Handle the client accepting a quest and starting it
+     * Send starting rewards if any to player and
+     * Send start notification if any to player
+     * @param pmcData Profile to update
+     * @param acceptedQuest Quest accepted
+     * @param sessionID Session id
+     * @returns client response
+     */
     acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Remove completed quest from profile
+     * Update completed quest in profile
      * Add newly unlocked quests to profile
      * Also recalculate thier level due to exp rewards
      * @param pmcData Player profile
-     * @param body completed quest request
-     * @param sessionID session id
-     * @returns ItemEvent response
+     * @param body Completed quest request
+     * @param sessionID Session id
+     * @returns ItemEvent client response
      */
     completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
@@ -67,10 +82,20 @@ export declare class QuestController {
     protected getQuestsFailedByCompletingQuest(completedQuestId: string): IQuest[];
     /**
      * Fail the quests provided
+     * Update quest in profile, otherwise add fresh quest object with failed status
      * @param sessionID session id
      * @param pmcData player profile
      * @param questsToFail quests to fail
      */
     protected failQuests(sessionID: string, pmcData: IPmcData, questsToFail: IQuest[]): void;
     handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment a backend counter stored value by an amount,
+     * Create counter if it does not exist
+     * @param pmcData Profile to find backend counter in
+     * @param conditionId backend counter id to update
+     * @param questId quest id counter is associated with
+     * @param counterValue value to increment the backend counter with
+     */
+    protected updateProfileBackendCounterValue(pmcData: IPmcData, conditionId: string, questId: string, counterValue: number): void;
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/RagfairController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/RagfairController.d.ts
index c4ffc15..06af740 100644
--- a/TypeScript/14AfterDBLoadHook/types/controllers/RagfairController.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/controllers/RagfairController.d.ts
@@ -9,6 +9,7 @@ import { RagfairOfferHelper } from "../helpers/RagfairOfferHelper";
 import { RagfairSellHelper } from "../helpers/RagfairSellHelper";
 import { RagfairSortHelper } from "../helpers/RagfairSortHelper";
 import { RagfairTaxHelper } from "../helpers/RagfairTaxHelper";
+import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
@@ -33,6 +34,9 @@ import { RagfairPriceService } from "../services/RagfairPriceService";
 import { RagfairRequiredItemsService } from "../services/RagfairRequiredItemsService";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/**
+ * Handle RagfairCallback events
+ */
 export declare class RagfairController {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
@@ -52,14 +56,20 @@ export declare class RagfairController {
     protected handbookHelper: HandbookHelper;
     protected paymentHelper: PaymentHelper;
     protected inventoryHelper: InventoryHelper;
+    protected traderHelper: TraderHelper;
     protected ragfairHelper: RagfairHelper;
     protected ragfairOfferService: RagfairOfferService;
     protected ragfairRequiredItemsService: RagfairRequiredItemsService;
     protected ragfairOfferGenerator: RagfairOfferGenerator;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
     getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult;
+    /**
+     * Update a trader flea offer with buy restrictions stored in the traders assort
+     * @param offer flea offer to update
+     */
+    protected setTraderOfferPurchaseLimits(offer: IRagfairOffer): void;
     protected isLinkedSearch(info: ISearchRequestData): boolean;
     protected isRequiredSearch(info: ISearchRequestData): boolean;
     update(): void;
diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/RepeatableQuestController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/RepeatableQuestController.d.ts
index 98d05dd..4c31a3d 100644
--- a/TypeScript/14AfterDBLoadHook/types/controllers/RepeatableQuestController.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/controllers/RepeatableQuestController.d.ts
@@ -7,6 +7,7 @@ import { Exit } from "../models/eft/common/ILocationBase";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { TraderInfo } from "../models/eft/common/tables/IBotBase";
 import { ICompletion, ICompletionAvailableFor, IElimination, IEliminationCondition, IExploration, IExplorationCondition, IPmcDataRepeatableQuest, IRepeatableQuest, IReward, IRewards } from "../models/eft/common/tables/IRepeatableQuests";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
 import { IRepeatableQuestChangeRequest } from "../models/eft/quests/IRepeatableQuestChangeRequest";
 import { ELocationName } from "../models/enums/ELocationName";
@@ -15,6 +16,7 @@ import { ILogger } from "../models/spt/utils/ILogger";
 import { ItemEventRouter } from "../routers/ItemEventRouter";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { PaymentService } from "../services/PaymentService";
 import { ProfileFixerService } from "../services/ProfileFixerService";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -64,9 +66,10 @@ export declare class RepeatableQuestController {
     protected itemEventRouter: ItemEventRouter;
     protected paymentService: PaymentService;
     protected objectId: ObjectId;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
-    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, configServer: ConfigServer);
+    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint
      * Returns an array of objects in the format of repeatable quests to the client.
@@ -217,4 +220,16 @@ export declare class RepeatableQuestController {
     debugLogRepeatableQuestIds(pmcData: IPmcData): void;
     probabilityObjectArray<K, V>(configArrayInput: ProbabilityObject<K, V>[]): ProbabilityObjectArray<K, V>;
     changeRepeatableQuest(pmcDataIn: IPmcData, body: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
+     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
+     */
+    protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig): [string, ITemplateItem][];
+    /**
+     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
+     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
+     * @param {*} tpl template id of item to check
+     * @returns boolean: true if item is valid reward
+     */
+    isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig): boolean;
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/TraderController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/TraderController.d.ts
index 0162064..b79f55e 100644
--- a/TypeScript/14AfterDBLoadHook/types/controllers/TraderController.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/controllers/TraderController.d.ts
@@ -4,6 +4,7 @@ import { TraderHelper } from "../helpers/TraderHelper";
 import { IBarterScheme, ITraderAssort, ITraderBase } from "../models/eft/common/tables/ITrader";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { FenceService } from "../services/FenceService";
 import { TraderAssortService } from "../services/TraderAssortService";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
@@ -15,8 +16,9 @@ export declare class TraderController {
     protected traderHelper: TraderHelper;
     protected timeUtil: TimeUtil;
     protected traderAssortService: TraderAssortService;
+    protected fenceService: FenceService;
     protected jsonUtil: JsonUtil;
-    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, jsonUtil: JsonUtil);
+    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, fenceService: FenceService, jsonUtil: JsonUtil);
     /**
      * Runs when onLoad event is fired
      * Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
@@ -26,6 +28,7 @@ export declare class TraderController {
     /**
      * Runs when onUpdate is fired
      * If current time is > nextResupply(expire) time of trader, refresh traders assorts and
+     * Fence is handled slightly differently
      * @returns has run
      */
     update(): boolean;
diff --git a/TypeScript/14AfterDBLoadHook/types/di/Container.d.ts b/TypeScript/14AfterDBLoadHook/types/di/Container.d.ts
index 17791b0..98d1fa1 100644
--- a/TypeScript/14AfterDBLoadHook/types/di/Container.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/di/Container.d.ts
@@ -1,4 +1,7 @@
 import { DependencyContainer } from "tsyringe";
+/**
+ * Handle the registration of classes to be used by the Dependency Injection code
+ */
 export declare class Container {
     static registerTypes(depContainer: DependencyContainer): void;
     static registerListTypes(depContainer: DependencyContainer): void;
diff --git a/TypeScript/14AfterDBLoadHook/types/generators/BotGenerator.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/BotGenerator.d.ts
index a5fc0ad..7d58f95 100644
--- a/TypeScript/14AfterDBLoadHook/types/generators/BotGenerator.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/generators/BotGenerator.d.ts
@@ -40,7 +40,7 @@ export declare class BotGenerator {
      * @param botTemplate base bot template to use  (e.g. assault/pmcbot)
      * @returns
      */
-    generatePlayerScav(role: string, difficulty: string, botTemplate: IBotType): IBotBase;
+    generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase;
     generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[];
     /**
      * Choose if a bot should become a PMC by checking if bot type is allowed to become a Pmc in botConfig.convertFromChances and doing a random int check
@@ -58,7 +58,7 @@ export declare class BotGenerator {
      * @returns IBotBase object
      */
     protected getCloneOfBotBase(): IBotBase;
-    protected generateBot(bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
+    protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
     /**
      * Log the number of PMCs generated to the debug console
      */
diff --git a/TypeScript/14AfterDBLoadHook/types/generators/BotInventoryGenerator.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/BotInventoryGenerator.d.ts
index 35d1ee8..73f8ece 100644
--- a/TypeScript/14AfterDBLoadHook/types/generators/BotInventoryGenerator.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/generators/BotInventoryGenerator.d.ts
@@ -18,7 +18,7 @@ export declare class BotInventoryGenerator {
     protected botGeneratorHelper: BotGeneratorHelper;
     protected weightedRandomHelper: WeightedRandomHelper;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper);
-    generateInventory(templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
+    generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
     protected generateEquipment(equipmentSlot: string, equipmentPool: Record<string, number>, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void;
     protected generateInventoryBase(): PmcInventory;
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/generators/BotLootGenerator.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/BotLootGenerator.d.ts
index c6a3f29..5a2d144 100644
--- a/TypeScript/14AfterDBLoadHook/types/generators/BotLootGenerator.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/generators/BotLootGenerator.d.ts
@@ -24,7 +24,7 @@ export declare class BotLootGenerator {
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botLootCacheService: BotLootCacheService, configServer: ConfigServer);
-    generateLoot(templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
+    generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
     protected getRandomisedCount(min: number, max: number, nValue: number): number;
     /**
      * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached
@@ -47,7 +47,7 @@ export declare class BotLootGenerator {
      * @param botRole bots role, .e.g. pmcBot
      * @param isPmc are we generating for a pmc
      */
-    protected addLooseWeaponsToInventorySlot(botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
+    protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
     /**
      * Get a random item from the pool parameter using the biasedRandomNumber system
      * @param pool pool of items to pick an item from
diff --git a/TypeScript/14AfterDBLoadHook/types/generators/BotWeaponGenerator.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/BotWeaponGenerator.d.ts
index 9215214..49fa7bf 100644
--- a/TypeScript/14AfterDBLoadHook/types/generators/BotWeaponGenerator.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/generators/BotWeaponGenerator.d.ts
@@ -28,7 +28,18 @@ export declare class BotWeaponGenerator {
     protected botConfig: IBotConfig;
     constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer);
     /**
-     * Get a random weapon from a bots pool of weapons (weighted)
+     * Pick a random weapon based on weightings and generate a functional weapon
+     * @param equipmentSlot Primary/secondary/holster
+     * @param botTemplateInventory e.g. assault.json
+     * @param weaponParentId
+     * @param modChances
+     * @param botRole role of bot, e.g. assault/followerBully
+     * @param isPmc Is weapon generated for a pmc
+     * @returns GenerateWeaponResult object
+     */
+    generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    /**
+     * Get a random weighted weapon from a bots pool of weapons
      * @param equipmentSlot Primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
      * @returns weapon tpl
@@ -39,43 +50,24 @@ export declare class BotWeaponGenerator {
      * @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool())
      * @param equipmentSlot slot to fit into, primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
+     * @param weaponParentId ParentId of the weapon being generated
+     * @param modChances Dictionary of item types and % chance weapon will have that mod
+     * @param botRole e.g. assault/exusec
      * @param isPmc
      * @returns GenerateWeaponResult object
      */
-    generateWeaponByTpl(weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
     /**
-     * Generate an entirely random weapon
-     * @param equipmentSlot Primary/secondary/holster
-     * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
-     * @param isPmc
-     * @returns GenerateWeaponResult object
-     */
-    generateRandomWeapon(equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
-    /**
-     * Create array with weapon base as only element
-     * Add additional properties as required
-     * @param weaponTpl
-     * @param weaponParentId
-     * @param equipmentSlot
-     * @param weaponItemTemplate
+     * Create array with weapon base as only element and
+     * add additional properties based on weapon type
+     * @param weaponTpl Weapon tpl to create item with
+     * @param weaponParentId Weapons parent id
+     * @param equipmentSlot e.g. primary/secondary/holster
+     * @param weaponItemTemplate db template for weapon
      * @param botRole for durability values
-     * @returns
+     * @returns Base weapon item in array
      */
     constructWeaponBaseArray(weaponTpl: string, weaponParentId: string, equipmentSlot: string, weaponItemTemplate: ITemplateItem, botRole: string): Item[];
-    /**
-     * Add compatible magazines to an inventory based on a generated weapon
-     * @param weaponDetails
-     * @param magCounts
-     * @param inventory
-     * @param botRole the bot type we're getting generating extra mags for
-     */
-    addExtraMagazinesToInventory(weaponDetails: GenerateWeaponResult, magCounts: MinMax, inventory: PmcInventory, botRole: string): void;
     /**
      * Get the mods necessary to kit out a weapon to its preset level
      * @param weaponTpl weapon to find preset for
@@ -84,20 +76,32 @@ export declare class BotWeaponGenerator {
      * @returns array of weapon mods
      */
     protected getPresetWeaponMods(weaponTpl: string, equipmentSlot: string, weaponParentId: string, itemTemplate: ITemplateItem, botRole: string): Item[];
-    /** Checks if all required slots are occupied on a weapon and all it's mods */
+    /**
+     * Checks if all required slots are occupied on a weapon and all it's mods
+     * @param weaponItemArray Weapon + mods
+     * @returns true if valid
+     */
     protected isWeaponValid(weaponItemArray: Item[]): boolean;
     /**
      * Generates extra magazines or bullets (if magazine is internal) and adds them to TacticalVest and Pockets.
      * Additionally, adds extra bullets to SecuredContainer
-     * @param weaponMods
-     * @param weaponTemplate
-     * @param magCounts
-     * @param ammoTpl
-     * @param inventory
+     * @param weaponMods mods to attach to weapon
+     * @param weaponTemplate db template for weapon
+     * @param magCounts magazine count to add to inventory
+     * @param ammoTpl ammo templateId to add to magazines
+     * @param inventory inventory to add magazines to
      * @param botRole the bot type we're getting generating extra mags for
      * @returns
      */
-    protected generateExtraMagazines(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    addExtraMagazinesToInventory(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    /**
+     * Create a magazine using the parameters given
+     * @param magazineTpl Tpl of the magazine to create
+     * @param ammoTpl Ammo to add to magazine
+     * @param magTemplate template object of magazine
+     * @returns Item array
+     */
+    protected createMagazine(magazineTpl: string, ammoTpl: string, magTemplate: ITemplateItem): Item[];
     /**
      * Get a randomised number of bullets for a specific magazine
      * @param magCounts min and max count of magazines
@@ -138,10 +142,9 @@ export declare class BotWeaponGenerator {
      * Finds and return a compatible ammo tpl based on the bots ammo weightings (x.json/inventory/equipment/ammo)
      * @param ammo a list of ammo tpls the weapon can use
      * @param weaponTemplate the weapon we want to pick ammo for
-     * @param isPmc is the ammo being gathered for a pmc (runs pmc ammo filtering)
      * @returns an ammo tpl that works with the desired gun
      */
-    protected getCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem, isPmc: boolean): string;
+    protected getWeightedCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem): string;
     /**
      * Get a weapons compatible cartridge caliber
      * @param weaponTemplate Weapon to look up caliber of
diff --git a/TypeScript/14AfterDBLoadHook/types/generators/LocationGenerator.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/LocationGenerator.d.ts
index bd368b5..cc61dcf 100644
--- a/TypeScript/14AfterDBLoadHook/types/generators/LocationGenerator.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/generators/LocationGenerator.d.ts
@@ -3,10 +3,9 @@ import { GameEventHelper } from "../helpers/GameEventHelper";
 import { ItemHelper } from "../helpers/ItemHelper";
 import { PresetHelper } from "../helpers/PresetHelper";
 import { RagfairServerHelper } from "../helpers/RagfairServerHelper";
-import { ILooseLoot, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
+import { ILooseLoot, SpawnpointsForced, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IStaticAmmoDetails, IStaticContainerProps, IStaticForcedProps, IStaticLootDetails } from "../models/eft/common/tables/ILootBase";
-import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILocationConfig } from "../models/spt/config/ILocationConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
@@ -36,11 +35,19 @@ export declare class LocationGenerator {
     generateContainerLoot(containerIn: IStaticContainerProps, staticForced: IStaticForcedProps[], staticLootDist: Record<string, IStaticLootDetails>, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): IStaticContainerProps;
     protected getLooseLootMultiplerForLocation(location: string): number;
     protected getStaticLootMultiplerForLocation(location: string): number;
+    /**
+     * Create array of loose + forced loot using probability system
+     * @param dynamicLootDist
+     * @param staticAmmoDist
+     * @param locationName Location to generate loot for
+     * @returns Array of spawn points with loot in them
+     */
     generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): SpawnpointTemplate[];
+    /**
+     * Add forced spawn point loot into loot parameter array
+     * @param loot array to add forced loot to
+     * @param forcedSpawnPoints forced loot to add
+     */
+    protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[]): void;
     protected createItem(tpl: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, parentId?: string): IContainerItem;
-    protected getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
-    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
-    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
-    protected createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
-    protected createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/generators/LootGenerator.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/14AfterDBLoadHook/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/14AfterDBLoadHook/types/generators/PMCLootGenerator.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/PMCLootGenerator.d.ts
index 64e6f7f..b9f2a83 100644
--- a/TypeScript/14AfterDBLoadHook/types/generators/PMCLootGenerator.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/generators/PMCLootGenerator.d.ts
@@ -1,15 +1,21 @@
 import { ItemHelper } from "../helpers/ItemHelper";
-import { DatabaseServer } from "../servers/DatabaseServer";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+/**
+ * Handle the generation of dynamic PMC loot in pockets and backpacks
+ * and the removal of blacklisted items
+ */
 export declare class PMCLootGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected configServer: ConfigServer;
+    protected itemFilterService: ItemFilterService;
     protected pocketLootPool: string[];
     protected backpackLootPool: string[];
     protected botConfig: IBotConfig;
-    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer);
+    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer, itemFilterService: ItemFilterService);
     generatePMCPocketLootPool(): string[];
     generatePMCBackpackLootPool(): string[];
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/generators/ScavCaseRewardGenerator.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/ScavCaseRewardGenerator.d.ts
index c7d6ab7..89cb5c8 100644
--- a/TypeScript/14AfterDBLoadHook/types/generators/ScavCaseRewardGenerator.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/generators/ScavCaseRewardGenerator.d.ts
@@ -8,9 +8,13 @@ import { RewardCountAndPriceDetails, ScavCaseRewardCountsAndPrices } from "../mo
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { RagfairPriceService } from "../services/RagfairPriceService";
 import { HashUtil } from "../utils/HashUtil";
 import { RandomUtil } from "../utils/RandomUtil";
+/**
+ * Handle the creation of randomised scav case rewards
+ */
 export declare class ScavCaseRewardGenerator {
     protected logger: ILogger;
     protected randomUtil: RandomUtil;
@@ -18,9 +22,10 @@ export declare class ScavCaseRewardGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected ragfairPriceService: RagfairPriceService;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected scavCaseConfig: IScavCaseConfig;
-    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, configServer: ConfigServer);
+    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Create an array of rewards that will be given to the player upon completing their scav case build
      * @param body client request
diff --git a/TypeScript/14AfterDBLoadHook/types/generators/WeatherGenerator.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/WeatherGenerator.d.ts
index 44cecbb..8ddbe49 100644
--- a/TypeScript/14AfterDBLoadHook/types/generators/WeatherGenerator.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/generators/WeatherGenerator.d.ts
@@ -1,7 +1,7 @@
 import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IWeatherData } from "../models/eft/weather/IWeatherData";
 import { IWeatherConfig } from "../models/spt/config/IWeatherConfig";
+import { ConfigServer } from "../servers/ConfigServer";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class WeatherGenerator {
@@ -21,11 +21,16 @@ export declare class WeatherGenerator {
     protected getAcceleratedTime(computedDate: Date): string;
     /**
      * Get current time formatted to fit BSGs requirement
-     * @param computedDate
+     * @param computedDate date to format into bsg style
      * @returns
      */
     protected getNormalTime(computedDate: Date): string;
-    generateWeather(data: IWeatherData): IWeatherData;
+    /**
+     * Return randomised Weather data
+     * @param weatherData weather input data
+     * @returns Randomised weather data
+     */
+    generateWeather(weatherData: IWeatherData): IWeatherData;
     protected getWeightedFog(): string;
     protected getWeightedRain(): number;
     protected getRandomFloat(node: string): number;
diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/AssortHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/AssortHelper.d.ts
index 15586b9..bfc157f 100644
--- a/TypeScript/14AfterDBLoadHook/types/helpers/AssortHelper.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/helpers/AssortHelper.d.ts
@@ -17,7 +17,7 @@ export declare class AssortHelper {
      * @param assort assort items from a trader
      * @returns assort items minus locked quest assorts
      */
-    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort): ITraderAssort;
+    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort, flea?: boolean): ITraderAssort;
     /**
      * Remove assorts from a trader that have not been unlocked yet
      * @param pmcProfile player profile
@@ -32,5 +32,5 @@ export declare class AssortHelper {
      * @param itemID item id to remove from asort
      * @returns Modified assort
      */
-    removeItemFromAssort(assort: ITraderAssort, itemID: string): ITraderAssort;
+    removeItemFromAssort(assort: ITraderAssort, itemID: string, flea?: boolean): ITraderAssort;
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/BotGeneratorHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/BotGeneratorHelper.d.ts
index 3cd7256..eb0d215 100644
--- a/TypeScript/14AfterDBLoadHook/types/helpers/BotGeneratorHelper.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/helpers/BotGeneratorHelper.d.ts
@@ -3,10 +3,12 @@ import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"
 import { Mods, ModsChances } from "../models/eft/common/tables/IBotType";
 import { Item, Repairable, Upd } from "../models/eft/common/tables/IItem";
 import { Grid, ITemplateItem, Slot } from "../models/eft/common/tables/ITemplateItem";
-import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
@@ -14,6 +16,7 @@ import { ContainerHelper } from "./ContainerHelper";
 import { InventoryHelper } from "./InventoryHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProbabilityHelper } from "./ProbabilityHelper";
+import { ProfileHelper } from "./ProfileHelper";
 export declare class BotGeneratorHelper {
     protected logger: ILogger;
     protected jsonUtil: JsonUtil;
@@ -25,10 +28,76 @@ export declare class BotGeneratorHelper {
     protected itemHelper: ItemHelper;
     protected inventoryHelper: InventoryHelper;
     protected containerHelper: ContainerHelper;
+    protected botEquipmentFilterService: BotEquipmentFilterService;
+    protected itemFilterService: ItemFilterService;
+    protected profileHelper: ProfileHelper;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, configServer: ConfigServer);
-    generateModsForItem(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, configServer: ConfigServer);
+    /**
+     * TODO - very similar to generateModsForWeapon
+     * Check mods are compatible and add to array
+     * @param equipment Equipment item to add mods to
+     * @param modPool Mod list to choose frm
+     * @param parentId parentid of item to add mod to
+     * @param parentTemplate template objet of item to add mods to
+     * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type
+     * @returns Item + compatible mods as an array
+     */
+    generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    /**
+     * TODO - very similar to generateModsForEquipment
+     * @param sessionId session id
+     * @param weapon Weapon to add mods to
+     * @param modPool pool of compatible mods to attach to gun
+     * @param weaponParentId parentId of weapon
+     * @param parentTemplate
+     * @param modSpawnChances
+     * @param ammoTpl ammo tpl to use when generating magazines/cartridges
+     * @param botRole role of bot weapon is generated for
+     * @returns Weapon with mods
+     */
+    generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[];
+    /**
+     * Generate a pool of mods for this bots mod type if bot has values inside `randomisedWeaponModSlots` array found in bot.json/equipment[botrole]
+     * @param allowedMods Mods to be added to mod pool
+     * @param botEquipBlacklist blacklist of items not allowed to be added to mod pool
+     * @param modSlot Slot to generate mods for
+     * @param itemModPool base mod pool to replace values of
+     */
+    protected generateDynamicModPool(allowedMods: string[], botEquipBlacklist: EquipmentFilterDetails, modSlot: string, itemModPool: Record<string, string[]>): void;
+    /**
+     * Check if the specific item type on the weapon has reached the set limit
+     * @param modTpl item to check is limited
+     * @param currentCount current number of this item on gun
+     * @param maxLimit mod limit allowed
+     * @param botRole role of bot we're checking weapon of
+     * @returns true if limit reached
+     */
+    protected weaponModLimitReached(modTpl: string, currentCount: {
+        count: number;
+    }, maxLimit: number, botRole: string): boolean;
+    /**
+     * log errors if mod is not valid for a slot
+     * @param modTpl
+     * @param found
+     * @param itemSlot
+     * @param modTemplate
+     * @param modSlot
+     * @param parentTemplate
+     * @returns true if valid
+     */
+    protected isModValidForSlot(modTpl: string, found: boolean, itemSlot: Slot, modTemplate: ITemplateItem, modSlot: string, parentTemplate: ITemplateItem): boolean;
+    /**
+     * Create a mod item with parameters as properties
+     * @param modId _id
+     * @param modTpl _tpl
+     * @param parentId parentId
+     * @param modSlot slotId
+     * @param modTemplate Used to add additional properites in the upd object
+     * @returns Item object
+     */
+    protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item;
     /**
      * Is this magazine cylinder related (revolvers and grenade launchers)
      * @param magazineParentName the name of the magazines parent
@@ -62,11 +131,11 @@ export declare class BotGeneratorHelper {
      * Those magazines (e.g. 60dc519adf4c47305f6d410d) have a "Cartridges" entry with a _max_count=0.
      * Ammo is not put into the magazine directly but assigned to the magazine's slots: The "camora_xxx" slots.
      * This function is a helper called by generateModsForItem for mods with parent type "CylinderMagazine"
-     *
-     * @param {object}      items               The items where the CylinderMagazine's camora are appended to
-     * @param {object}      modPool             modPool which should include available cartrigdes
-     * @param {string}      parentId            The CylinderMagazine's UID
-     * @param {object}      parentTemplate      The CylinderMagazine's template
+     * @param items The items where the CylinderMagazine's camora are appended to
+     * @param modPool modPool which should include available cartrigdes
+     * @param parentId The CylinderMagazine's UID
+     * @param parentTemplate The CylinderMagazine's template
+     * @returns
      */
     protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void;
     /**
@@ -75,6 +144,13 @@ export declare class BotGeneratorHelper {
      * @returns string array of shells fro luitple camora sources
      */
     protected mergeCamoraPoolsTogether(camorasWithShells: Record<string, string[]>): string[];
+    /**
+     * Adds properties to an item
+     * e.g. Repairable / HasHinge / Foldable / MaxDurability
+     * @param itemTemplate
+     * @param botRole Used by weapons to randomise the durability values
+     * @returns Item Upd object with extra properties
+     */
     generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): {
         upd?: Upd;
     };
@@ -93,12 +169,6 @@ export declare class BotGeneratorHelper {
      */
     protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable;
     protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string;
-    /**
-     * Sort by spawn chance, highest to lowest, higher is more common
-     * @param unsortedModArray String array to sort
-     * @returns Sorted string array
-     */
-    protected sortModArray(unsortedModArray: string[]): string[];
     /**
      * Can an item be added to an item without issue
      * @param items
@@ -117,8 +187,15 @@ export declare class BotGeneratorHelper {
      * @returns a `boolean` indicating item was added
      */
     addItemWithChildrenToEquipmentSlot(equipmentSlots: string[], parentId: string, parentTpl: string, itemWithChildren: Item[], inventory: PmcInventory): boolean;
+    /**
+     * is the provided item allowed inside a container
+     * @param slot location item wants to be placed in
+     * @param itemTpl item being placed
+     * @returns true if allowed
+     */
     protected itemAllowedInContainer(slot: Grid, itemTpl: string): boolean;
 }
+/** TODO - move into own class */
 export declare class ExhaustableArray<T> {
     private itemPool;
     private randomUtil;
diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/HideoutHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/HideoutHelper.d.ts
index 36e4009..7495a6a 100644
--- a/TypeScript/14AfterDBLoadHook/types/helpers/HideoutHelper.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/helpers/HideoutHelper.d.ts
@@ -44,14 +44,72 @@ export declare class HideoutHelper {
     initProduction(recipeId: string, productionTime: number): Production;
     isProductionType(productive: Productive): productive is Production;
     applyPlayerUpgradesBonuses(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * TODO:
+     * After looking at the skills there doesnt seem to be a configuration per skill to boost
+     * the XP gain PER skill. I THINK you should be able to put the variable "SkillProgress" (just like health has it)
+     * and be able to tune the skill gain PER skill, but I havent tested it and Im not sure!
+     * @param pmcData
+     * @param bonus
+     */
     protected applySkillXPBoost(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * Process a players hideout, update areas that use resources + increment production timers
+     * @param sessionID Session id
+     */
     updatePlayerHideout(sessionID: string): void;
+    /**
+     * Update progress timer for water collector
+     * @param pmcData profile to update
+     * @param productionId id of water collection production to update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateWaterCollectorProductionTimer(pmcData: IPmcData, productionId: string, hideoutProperties: {
+        btcFarmCGs?: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Iterate over productions and update their progress timers
+     * @param pmcData Profile to check for productions and update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Update progress timer for scav case
+     * @param pmcData Profile to update
+     * @param productionId Id of scav case production to update
+     */
+    protected updateScavCaseProductionTimer(pmcData: IPmcData, productionId: string): void;
+    /**
+     * Iterate over hideout areas that use resources (fuel/filters etc) and update associated values
+     * @param sessionID Session id
+     * @param pmcData Profile to update areas of
+     * @param hideoutProperties hideout properties
+     */
+    protected updateAreasWithResources(sessionID: string, pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
     protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
     protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
-    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): HideoutArea;
-    protected updateWaterFilters(waterFilterArea: HideoutArea, pwProd: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
+    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): void;
+    /**
+     * Adjust water filter objects resourceValue or delete when they reach 0 resource
+     * @param waterFilterArea water filter area to update
+     * @param production production object
+     * @param isGeneratorOn is generatory enabled
+     * @param pmcData Player profile
+     * @returns Updated HideoutArea object
+     */
+    protected updateWaterFilters(waterFilterArea: HideoutArea, production: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
     protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
-    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): HideoutArea;
+    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): void;
     protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
     protected getBTCSlots(pmcData: IPmcData): number;
     protected getManagementSkillsSlots(): number;
diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/InRaidHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/InRaidHelper.d.ts
index b382e30..962df38 100644
--- a/TypeScript/14AfterDBLoadHook/types/helpers/InRaidHelper.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/helpers/InRaidHelper.d.ts
@@ -18,18 +18,6 @@ export declare class InRaidHelper {
     protected paymentHelper: PaymentHelper;
     protected profileFixerService: ProfileFixerService;
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper, profileFixerService: ProfileFixerService);
-    /**
-     * Reset the SPT inraid property stored in a profile to 'none'
-     * @param sessionID Session id
-     */
-    protected removePlayer(sessionID: string): void;
-    /**
-     * Some maps have one-time-use keys (e.g. Labs
-     * Remove the relevant key from an inventory based on the post-raid request data passed in
-     * @param offraidData post-raid data
-     * @param sessionID Session id
-     */
-    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
     /**
      * Check an array of items and add an upd object to money items with a stack count of 1
      * Single stack money items have no upd object and thus no StackObjectsCount, causing issues
@@ -54,6 +42,18 @@ export declare class InRaidHelper {
      * @returns Reset profile object
      */
     updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData;
+    /**
+     * Some maps have one-time-use keys (e.g. Labs
+     * Remove the relevant key from an inventory based on the post-raid request data passed in
+     * @param offraidData post-raid data
+     * @param sessionID Session id
+     */
+    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Set the SPT inraid location Profile property to 'none'
+     * @param sessionID Session id
+     */
+    protected setPlayerInRaidLocationStatusToNone(sessionID: string): void;
     /**
      * Adds SpawnedInSession property to items found in a raid
      * Removes SpawnedInSession for non-scav players if item was taken into raid with SpawnedInSession = true
@@ -95,5 +95,10 @@ export declare class InRaidHelper {
      * @returns true if item is kept after death
      */
     isItemKeptAfterDeath(slotId: string): boolean;
+    /**
+     * Return the equipped items from a players inventory
+     * @param items Players inventory to search through
+     * @returns an array of equipped items
+     */
     getPlayerGear(items: Item[]): Item[];
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/ItemHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/ItemHelper.d.ts
index 1701c62..de10892 100644
--- a/TypeScript/14AfterDBLoadHook/types/helpers/ItemHelper.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/helpers/ItemHelper.d.ts
@@ -1,35 +1,30 @@
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item, Repairable } from "../models/eft/common/tables/IItem";
+import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase";
 import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+import { MathUtil } from "../utils/MathUtil";
+import { ObjectId } from "../utils/ObjectId";
+import { RandomUtil } from "../utils/RandomUtil";
 declare class ItemHelper {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
     protected jsonUtil: JsonUtil;
+    protected randomUtil: RandomUtil;
+    protected objectId: ObjectId;
+    protected mathUtil: MathUtil;
     protected databaseServer: DatabaseServer;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer);
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer);
     /**
      * Checks if a id is a valid item. Valid meaning that it's an item that be stored in stash
      * @param       {string}    tpl       the template id / tpl
      * @returns                             boolean; true for items that may be in player posession and not quest items
      */
     isValidItem(tpl: string, invalidBaseTypes?: string[]): boolean;
-    /**
-     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
-     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
-     * @param {*} tpl template id of item to check
-     * @returns boolean: true if item is valid reward
-     */
-    isValidRewardItem(tpl: string): boolean;
-    /**
-     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
-     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
-     */
-    getRewardableItems(): [string, ITemplateItem][];
     /**
      * Check if the tpl / template Id provided is a descendent of the baseclass
      *
@@ -196,6 +191,22 @@ declare class ItemHelper {
      * @returns ItemSize object (width and height)
      */
     getItemSize(items: Item[], rootItemId: string): ItemHelper.ItemSize;
+    /**
+     * Get a random cartridge from an items Filter property
+     * @param item
+     * @returns
+     */
+    getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
+    createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
+    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
+    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
+    createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
+    /**
+     * Get the size of a stack, return 1 if no stack object count property found
+     * @param item Item to get stack size of
+     * @returns size of stack
+     */
+    getItemStackSize(item: Item): number;
 }
 declare namespace ItemHelper {
     interface ItemSize {
diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/ProfileHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/ProfileHelper.d.ts
index 9d4ff98..9c6560a 100644
--- a/TypeScript/14AfterDBLoadHook/types/helpers/ProfileHelper.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/helpers/ProfileHelper.d.ts
@@ -24,6 +24,19 @@ export declare class ProfileHelper {
     constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, fenceService: FenceService);
     resetProfileQuestCondition(sessionID: string, conditionId: string): void;
     getCompleteProfile(sessionID: string): IPmcData[];
+    /**
+     * Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
+     * Server saves the post-raid changes prior to the xp screen getting the profile, this results in the xp screen using
+     * the now updated profile values as a base, meaning it shows x2 xp gained
+     * Instead, clone the post-raid profile (so we dont alter its values), apply the pre-raid xp values to the cloned objects and return
+     * Delete snapshot of pre-raid profile prior to returning profile data
+     * @param sessionId Session id
+     * @param output pmc and scav profiles array
+     * @param pmcProfile post-raid pmc profile
+     * @param scavProfile post-raid scav profile
+     * @returns updated profile array
+     */
+    protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
     isNicknameTaken(info: IValidateNicknameRequestData, sessionID: string): boolean;
     /**
      * Add experience to a PMC inside the players profile
diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/QuestHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/QuestHelper.d.ts
index 32e55ec..d66d150 100644
--- a/TypeScript/14AfterDBLoadHook/types/helpers/QuestHelper.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/helpers/QuestHelper.d.ts
@@ -36,11 +36,20 @@ export declare class QuestHelper {
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
     constructor(logger: ILogger, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, itemHelper: ItemHelper, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, localeService: LocaleService, ragfairServerHelper: RagfairServerHelper, dialogueHelper: DialogueHelper, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, traderHelper: TraderHelper, configServer: ConfigServer);
-    questStatus(pmcData: IPmcData, questID: string): QuestStatus;
     /**
-     * returns true is the condition is satisfied
+    * Get status of a quest by quest id
+    * @param pmcData Profile to search
+    * @param questID Quest id to look up
+    * @returns QuestStauts enum
+    */
+    getQuestStatus(pmcData: IPmcData, questID: string): QuestStatus;
+    /**
+     * returns true is the level condition is satisfied
+     * @param playerLevel Players level
+     * @param condition Quest condition
+     * @returns true if player level is greater than or equal to quest
      */
-    evaluateLevel(pmcProfile: IPmcData, cond: AvailableForConditions): boolean;
+    doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean;
     getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[];
     /**
      * Increase skill points of a skill on player profile
diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/RagfairOfferHelper.d.ts
index 8d03bee..e9d72ca 100644
--- a/TypeScript/14AfterDBLoadHook/types/helpers/RagfairOfferHelper.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/helpers/RagfairOfferHelper.d.ts
@@ -22,12 +22,14 @@ import { ProfileHelper } from "./ProfileHelper";
 import { RagfairHelper } from "./RagfairHelper";
 import { RagfairServerHelper } from "./RagfairServerHelper";
 import { RagfairSortHelper } from "./RagfairSortHelper";
+import { TraderHelper } from "./TraderHelper";
 export declare class RagfairOfferHelper {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
     protected hashUtil: HashUtil;
     protected itemEventRouter: ItemEventRouter;
     protected databaseServer: DatabaseServer;
+    protected traderHelper: TraderHelper;
     protected saveServer: SaveServer;
     protected dialogueHelper: DialogueHelper;
     protected itemHelper: ItemHelper;
@@ -43,10 +45,10 @@ export declare class RagfairOfferHelper {
     protected static goodSoldTemplate: string;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, traderHelper: TraderHelper, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
     getValidOffers(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
     getOffersForBuild(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
-    processOffers(sessionID: string): boolean;
+    processOffersOnProfile(sessionID: string): boolean;
     protected getProfileOffers(sessionID: string): IRagfairOffer[];
     protected deleteOfferByOfferId(sessionID: string, offerId: string): void;
     protected completeOffer(sessionID: string, offer: IRagfairOffer, boughtAmount: number): IItemEventRouterResponse;
diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/RagfairSellHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/RagfairSellHelper.d.ts
index 6ec004a..91b8a20 100644
--- a/TypeScript/14AfterDBLoadHook/types/helpers/RagfairSellHelper.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/helpers/RagfairSellHelper.d.ts
@@ -11,6 +11,12 @@ export declare class RagfairSellHelper {
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     constructor(logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer);
-    calculateSellChance(baseChance: number, offerPrice: number, requirementsPriceInRub: number): number;
-    rollForSale(sellChance: number, count: number): SellResult[];
+    calculateSellChance(baseChancePercent: number, offerPriceRub: number, playerListedPriceRub: number): number;
+    /**
+     * Determine if the offer being listed will be sold
+     * @param sellChancePercent chance item will sell
+     * @param itemSellCount count of items to sell
+     * @returns Array of purchases of item(s) lsited
+     */
+    rollForSale(sellChancePercent: number, itemSellCount: number): SellResult[];
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/RagfairServerHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/RagfairServerHelper.d.ts
index e4939d1..a03cdda 100644
--- a/TypeScript/14AfterDBLoadHook/types/helpers/RagfairServerHelper.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/helpers/RagfairServerHelper.d.ts
@@ -6,6 +6,7 @@ import { IRagfairConfig } from "../models/spt/config/IRagfairConfig";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { SaveServer } from "../servers/SaveServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { LocaleService } from "../services/LocaleService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -13,6 +14,9 @@ import { RandomUtil } from "../utils/RandomUtil";
 import { DialogueHelper } from "./DialogueHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProfileHelper } from "./ProfileHelper";
+/**
+ * Helper class for common ragfair server actions
+ */
 export declare class RagfairServerHelper {
     protected randomUtil: RandomUtil;
     protected hashUtil: HashUtil;
@@ -23,11 +27,12 @@ export declare class RagfairServerHelper {
     protected localeService: LocaleService;
     protected dialogueHelper: DialogueHelper;
     protected jsonUtil: JsonUtil;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
     protected static goodsReturnedTemplate: string;
-    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, configServer: ConfigServer);
+    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Is item valid / on blacklist / quest item
      * @param itemDetails
diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/TradeHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/TradeHelper.d.ts
index 975062b..7ab9768 100644
--- a/TypeScript/14AfterDBLoadHook/types/helpers/TradeHelper.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/helpers/TradeHelper.d.ts
@@ -39,6 +39,12 @@ export declare class TradeHelper {
      * @returns
      */
     sellItem(pmcData: IPmcData, body: IProcessSellTradeRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment the assorts buy count by number of items purchased
+     * Show error on screen if player attepts to buy more than what the buy max allows
+     * @param assortBeingPurchased assort being bought
+     * @param itemsPurchasedCount number of items being bought
+     */
     protected incrementAssortBuyCount(assortBeingPurchased: Item, itemsPurchasedCount: number): void;
     protected checkPurchaseIsWithinTraderItemLimit(assortBeingPurchased: Item, assortId: string, count: number): void;
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/TraderAssortHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/TraderAssortHelper.d.ts
index 677dd66..025efd6 100644
--- a/TypeScript/14AfterDBLoadHook/types/helpers/TraderAssortHelper.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/helpers/TraderAssortHelper.d.ts
@@ -1,6 +1,5 @@
 import { RagfairAssortGenerator } from "../generators/RagfairAssortGenerator";
 import { RagfairOfferGenerator } from "../generators/RagfairOfferGenerator";
-import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ITrader, ITraderAssort } from "../models/eft/common/tables/ITrader";
 import { ITraderConfig } from "../models/spt/config/ITraderConfig";
@@ -41,12 +40,7 @@ export declare class TraderAssortHelper {
      * @param traderId traders id
      * @returns a traders' assorts
      */
-    getAssort(sessionId: string, traderId: string): ITraderAssort;
-    /**
-     * if the fence assorts have expired, re-generate them
-     * @param pmcProfile Players profile
-     */
-    refreshFenceAssortIfExpired(pmcProfile: IPmcData): void;
+    getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort;
     /**
      * Reset a traders assorts and move nextResupply value to future
      * Flag trader as needing a flea offer reset to be picked up by flea update() function
diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/TraderHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/TraderHelper.d.ts
index 6bda5cd..0dc93e8 100644
--- a/TypeScript/14AfterDBLoadHook/types/helpers/TraderHelper.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/helpers/TraderHelper.d.ts
@@ -65,7 +65,7 @@ export declare class TraderHelper {
      * @param item
      * @returns boolean
      */
-    protected isWeaponAndBelowTraderBuyDurability(traderID: string, item: Item): boolean;
+    protected isWeaponBelowTraderBuyDurability(traderID: string, item: Item): boolean;
     /**
      * Get the price of an item and all of its attached children
      * Take into account bonuses/adjsutments e.g. discounts
diff --git a/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/ITemplateItem.d.ts b/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/ITemplateItem.d.ts
index 23a1a14..6b2fa8f 100644
--- a/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/ITemplateItem.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/ITemplateItem.d.ts
@@ -34,6 +34,7 @@ export interface Props {
     LootExperience?: number;
     ExamineExperience?: number;
     HideEntrails?: boolean;
+    InsuranceDisabled?: boolean;
     RepairCost?: number;
     RepairSpeed?: number;
     ExtraSizeLeft?: number;
@@ -206,6 +207,7 @@ export interface Props {
     IsOneoff?: boolean;
     MustBoltBeOpennedForExternalReload?: boolean;
     MustBoltBeOpennedForInternalReload?: boolean;
+    NoFiremodeOnBoltcatch?: boolean;
     BoltAction?: boolean;
     HipAccuracyRestorationDelay?: number;
     HipAccuracyRestorationSpeed?: number;
diff --git a/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/ITrader.d.ts b/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/ITrader.d.ts
index a84f5af..37b2d61 100644
--- a/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/ITrader.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/ITrader.d.ts
@@ -67,6 +67,7 @@ export interface IBarterScheme {
     count: number;
     _tpl: string;
     onlyFunctional?: boolean;
+    sptQuestLocked?: boolean;
 }
 export interface ISuit {
     _id: string;
diff --git a/TypeScript/14AfterDBLoadHook/types/models/eft/ragfair/IRagfairOffer.d.ts b/TypeScript/14AfterDBLoadHook/types/models/eft/ragfair/IRagfairOffer.d.ts
index 63f655e..141b605 100644
--- a/TypeScript/14AfterDBLoadHook/types/models/eft/ragfair/IRagfairOffer.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/models/eft/ragfair/IRagfairOffer.d.ts
@@ -15,6 +15,8 @@ export interface IRagfairOffer {
     name?: string;
     shortName?: string;
     loyaltyLevel: number;
+    buyRestrictionMax?: number;
+    buyRestrictionCurrent?: number;
     locked: boolean;
     unlimitedCount: boolean;
     summaryCost: number;
diff --git a/TypeScript/14AfterDBLoadHook/types/models/enums/AmmoTypes.d.ts b/TypeScript/14AfterDBLoadHook/types/models/enums/AmmoTypes.d.ts
index b52ddcf..254b410 100644
--- a/TypeScript/14AfterDBLoadHook/types/models/enums/AmmoTypes.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/models/enums/AmmoTypes.d.ts
@@ -23,7 +23,7 @@ export declare enum Ammo762x54 {
     BT_GZH = "5e023d34e8a400319a28ed44",
     BS_GZH = "5e023d48186a883be655e551"
 }
-export declare enum Ammo338Lapua {
+export declare enum Ammo86x70 {
     TAC_X = "5fc382b6d6fa9c00c571bbc3",
     UCW = "5fc382c1016cce60e8341b20",
     AP = "5fc382a9d724d907e2077dab",
@@ -85,13 +85,13 @@ export declare enum Ammo9x21 {
     PE_GZH = "5a26ac06c4a282000c5a90a8",
     BT_GZH = "5a26ac0ec4a28200741e1e18"
 }
-export declare enum Ammo357Mag {
+export declare enum Ammo9x33R {
     FMJ = "62330b3ed4dc74626d570b95",
     HOLLOW_POINT = "62330bfadc5883093563729b",
     SOFT_POINT = "62330c40bdd19b369e1e53d1",
     JACKET_HP = "62330c18744e5e31df12f516"
 }
-export declare enum Ammo45ACP {
+export declare enum Ammo1143x23ACP {
     MATCH_FMJ = "5e81f423763d9f754677bf2e",
     HYDRA_SHOK = "5efb0fc6aeb21837e749c801",
     LASERMATCH_FMJ = "5efb0d4f4bc50b58e81710f3",
@@ -126,7 +126,7 @@ export declare enum Ammo556x45 {
     MK_318_MOD_0_SOST = "60194943740c5d77f6705eea",
     SSA_AP = "601949593ae8f707c4608daa"
 }
-export declare enum Ammo300Blackout {
+export declare enum Ammo762x35 {
     M62_TRACER = "619636be6db0f2477964e710",
     BCP_FMJ = "5fbe3ffdf8b6a877a729ea82",
     AP = "5fd20ff893a8961fc660a954",
diff --git a/TypeScript/14AfterDBLoadHook/types/models/enums/BaseClasses.d.ts b/TypeScript/14AfterDBLoadHook/types/models/enums/BaseClasses.d.ts
index e733bca..37c1398 100644
--- a/TypeScript/14AfterDBLoadHook/types/models/enums/BaseClasses.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/models/enums/BaseClasses.d.ts
@@ -68,6 +68,7 @@ export declare enum BaseClasses {
     ASSAULT_SCOPE = "55818add4bdc2d5b648b456f",
     REFLEX_SIGHT = "55818ad54bdc2ddc698b4569",
     TACTICAL_COMBO = "55818b164bdc2ddc698b456c",
+    FLASHLIGHT = "55818b084bdc2d5b648b4571",
     MAGAZINE = "5448bc234bdc2d3c308b4569",
     LIGHT_LASER = "55818b0e4bdc2dde698b456e",
     FLASH_HIDER = "550aa4bf4bdc2dd6348b456b",
diff --git a/TypeScript/14AfterDBLoadHook/types/models/enums/ConfigTypes.d.ts b/TypeScript/14AfterDBLoadHook/types/models/enums/ConfigTypes.d.ts
index 61d6f99..468ece5 100644
--- a/TypeScript/14AfterDBLoadHook/types/models/enums/ConfigTypes.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/models/enums/ConfigTypes.d.ts
@@ -8,6 +8,7 @@ export declare enum ConfigTypes {
     IN_RAID = "aki-inraid",
     INSURANCE = "aki-insurance",
     INVENTORY = "aki-inventory",
+    ITEM = "aki-item",
     LOCALE = "aki-locale",
     LOCATION = "aki-location",
     MATCH = "aki-match",
diff --git a/TypeScript/14AfterDBLoadHook/types/models/enums/ELocationName.d.ts b/TypeScript/14AfterDBLoadHook/types/models/enums/ELocationName.d.ts
index b56cc08..7ae7caa 100644
--- a/TypeScript/14AfterDBLoadHook/types/models/enums/ELocationName.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/models/enums/ELocationName.d.ts
@@ -1,5 +1,6 @@
 export declare enum ELocationName {
     FACTORY_DAY = "factory4_day",
+    FACTORY_NIGHT = "factory4_night",
     BIGMAP = "bigmap",
     WOODS = "Woods",
     SHORELINE = "Shoreline",
diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IBotConfig.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IBotConfig.d.ts
index e171087..f15fa73 100644
--- a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IBotConfig.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IBotConfig.d.ts
@@ -1,17 +1,31 @@
 import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
+import { IBotDurability } from "./IBotDurability";
+import { IPmcConfig } from "./IPmcConfig";
 export interface IBotConfig extends IBaseConfig {
     kind: "aki-bot";
+    /** How many variants of each bot should be generated on raid start */
     presetBatch: PresetBatch;
+    /** What bot types should be classified as bosses */
     bosses: string[];
-    durability: Durability;
+    /** Control weapon/armor durability min/max values for each bot type */
+    durability: IBotDurability;
+    /** Control the weighting of how expensive an average loot item is on a PMC or Scav */
     lootNValue: LootNvalue;
+    /** Control what bots are added to a bots revenge list key: bottype, value: bottypes to revenge on seeing their death */
     revenge: Record<string, string[]>;
-    pmc: PmcConfig;
+    /** PMC bot specific config settings */
+    pmc: IPmcConfig;
+    /** Control how many items are allowed to spawn on a bot
+     * key: bottype, value: <key: itemTpl: value: max item count> */
     itemSpawnLimits: Record<string, Record<string, number>>;
-    equipment: Record<string, Equipment>;
+    /** Blacklist/whitelist items on a bot */
+    equipment: Record<string, EquipmentFilters>;
+    /** Show a bots botType value after their name */
     showTypeInNickname: boolean;
+    /** Max number of bots that can be spawned in a raid at any one time */
     maxBotCap: number;
+    /** How many stacks of secret ammo should a bot have in its bot secure container */
     secureContainerAmmoStackCount: number;
 }
 export interface PresetBatch {
@@ -44,79 +58,22 @@ export interface PresetBatch {
     test: number;
     exUsec: number;
 }
-export interface Durability {
-    default: DefaultDurability;
-    pmc: PmcDurability;
-    boss: BotDurability;
-    follower: BotDurability;
-    assault: BotDurability;
-    cursedassault: BotDurability;
-    marksman: BotDurability;
-    pmcbot: BotDurability;
-    exusec: BotDurability;
-    sectantpriest: BotDurability;
-    sectantwarrior: BotDurability;
-}
-export interface DefaultDurability {
-    armor: DefaultArmor;
-    weapon: WeaponDurability;
-}
-export interface DefaultArmor {
-    maxDelta: number;
-    minDelta: number;
-}
-export interface WeaponDurability {
-    lowestMax: number;
-    highestMax: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface PmcDurability {
-    armor: PmcDurabilityArmor;
-    weapon: WeaponDurability;
-}
-export interface PmcDurabilityArmor {
-    lowestMaxPercent: number;
-    highestMaxPercent: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface BotDurability {
-    armor: ArmorDurability;
-    weapon: WeaponDurability;
-}
-export interface ArmorDurability {
-    maxDelta: number;
-    minDelta: number;
-}
 export interface LootNvalue {
     scav: number;
     pmc: number;
 }
-export interface PmcConfig {
-    dynamicLoot: PmcDynamicLoot;
-    difficulty: string;
-    looseWeaponInBackpackChancePercent: number;
-    looseWeaponInBackpackLootMinMax: MinMax;
-    isUsec: number;
-    chanceSameSideIsHostilePercent: number;
-    usecType: string;
-    bearType: string;
-    maxBackpackLootTotalRub: number;
-    maxPocketLootTotalRub: number;
-    maxVestLootTotalRub: number;
-    convertIntoPmcChance: Record<string, MinMax>;
-    enemyTypes: string[];
-}
-export interface PmcDynamicLoot {
-    whitelist: string[];
-    blacklist: string[];
-    moneyStackLimits: Record<string, number>;
-}
-export interface Equipment {
+export interface EquipmentFilters {
+    weaponModLimits: ModLimits;
+    randomisedWeaponModSlots?: string[];
     blacklist: EquipmentFilterDetails[];
     whitelist: EquipmentFilterDetails[];
 }
+export interface ModLimits {
+    /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */
+    scopeLimit?: number;
+    /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */
+    lightLaserLimit?: number;
+}
 export interface EquipmentFilterDetails {
     levelRange: MinMax;
     equipment: Record<string, string[]>;
diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IBotDurability.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IBotDurability.d.ts
new file mode 100644
index 0000000..38a47cc
--- /dev/null
+++ b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IBotDurability.d.ts
@@ -0,0 +1,47 @@
+export interface IBotDurability {
+    default: DefaultDurability;
+    pmc: PmcDurability;
+    boss: BotDurability;
+    follower: BotDurability;
+    assault: BotDurability;
+    cursedassault: BotDurability;
+    marksman: BotDurability;
+    pmcbot: BotDurability;
+    exusec: BotDurability;
+    gifter: BotDurability;
+    sectantpriest: BotDurability;
+    sectantwarrior: BotDurability;
+}
+/** Durability values to be used when a more specific bot type cant be found */
+export interface DefaultDurability {
+    armor: DefaultArmor;
+    weapon: WeaponDurability;
+}
+export interface DefaultArmor {
+    maxDelta: number;
+    minDelta: number;
+}
+export interface WeaponDurability {
+    lowestMax: number;
+    highestMax: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface PmcDurability {
+    armor: PmcDurabilityArmor;
+    weapon: WeaponDurability;
+}
+export interface PmcDurabilityArmor {
+    lowestMaxPercent: number;
+    highestMaxPercent: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface BotDurability {
+    armor: ArmorDurability;
+    weapon: WeaponDurability;
+}
+export interface ArmorDurability {
+    maxDelta: number;
+    minDelta: number;
+}
diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IItemConfig.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IItemConfig.d.ts
new file mode 100644
index 0000000..5ecccc2
--- /dev/null
+++ b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IItemConfig.d.ts
@@ -0,0 +1,5 @@
+import { IBaseConfig } from "./IBaseConfig";
+export interface IItemConfig extends IBaseConfig {
+    kind: "aki-item";
+    blacklist: string[];
+}
diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IPmcConfig.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IPmcConfig.d.ts
new file mode 100644
index 0000000..655b58d
--- /dev/null
+++ b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IPmcConfig.d.ts
@@ -0,0 +1,22 @@
+import { MinMax } from "../../common/MinMax";
+export interface IPmcConfig {
+    dynamicLoot: DynamicLoot;
+    useDifficultyOverride: boolean;
+    difficulty: string;
+    looseWeaponInBackpackChancePercent: number;
+    looseWeaponInBackpackLootMinMax: MinMax;
+    isUsec: number;
+    chanceSameSideIsHostilePercent: number;
+    usecType: string;
+    bearType: string;
+    maxBackpackLootTotalRub: number;
+    maxPocketLootTotalRub: number;
+    maxVestLootTotalRub: number;
+    convertIntoPmcChance: Record<string, MinMax>;
+    enemyTypes: string[];
+}
+export interface DynamicLoot {
+    whitelist: string[];
+    blacklist: string[];
+    moneyStackLimits: Record<string, number>;
+}
diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IQuestConfig.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IQuestConfig.d.ts
index be4a97b..45c9aae 100644
--- a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IQuestConfig.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IQuestConfig.d.ts
@@ -4,6 +4,8 @@ export interface IQuestConfig extends IBaseConfig {
     kind: "aki-quest";
     redeemTime: number;
     repeatableQuests: IRepeatableQuestConfig[];
+    bearOnlyQuests: string[];
+    usecOnlyQuests: string[];
 }
 export interface IRepeatableQuestConfig {
     name: string;
@@ -15,6 +17,10 @@ export interface IRepeatableQuestConfig {
     locations: Record<ELocationName, string[]>;
     traderWhitelist: ITraderWhitelist[];
     questConfig: IQuestConfig;
+    /** Item base types to block when generating rewards */
+    rewardBaseTypeBlacklist: string[];
+    /** Item tplIds to ignore when generating rewards */
+    rewardBlacklist: string[];
 }
 export interface IRewardScaling {
     levels: number[];
diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IRagfairConfig.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IRagfairConfig.d.ts
index 6369eda..3088717 100644
--- a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IRagfairConfig.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IRagfairConfig.d.ts
@@ -12,6 +12,7 @@ export interface Sell {
     chance: Chance;
     time: Time;
     reputation: Reputation;
+    simulatedSellHours: number;
 }
 export interface Chance {
     base: number;
diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/config/ITraderConfig.d.ts
index c8e8044..6b1c1e3 100644
--- a/TypeScript/14AfterDBLoadHook/types/models/spt/config/ITraderConfig.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/models/spt/config/ITraderConfig.d.ts
@@ -12,8 +12,10 @@ export interface UpdateTime {
     seconds: number;
 }
 export interface FenceConfig {
+    partialRefreshTimeSeconds: number;
+    partialRefreshChangePercent: number;
     assortSize: number;
-    maxPresetsCount: number;
+    maxPresetsPercent: number;
     presetPriceMult: number;
     blacklist: string[];
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/services/LootItem.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/services/LootItem.d.ts
new file mode 100644
index 0000000..2838472
--- /dev/null
+++ b/TypeScript/14AfterDBLoadHook/types/models/spt/services/LootItem.d.ts
@@ -0,0 +1,5 @@
+export declare class LootItem {
+    tpl: string;
+    isPreset: boolean;
+    stackCount: number;
+}
diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/services/LootRequest.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/14AfterDBLoadHook/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/14AfterDBLoadHook/types/services/BotEquipmentFilterService.d.ts b/TypeScript/14AfterDBLoadHook/types/services/BotEquipmentFilterService.d.ts
index e49645b..632f961 100644
--- a/TypeScript/14AfterDBLoadHook/types/services/BotEquipmentFilterService.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/services/BotEquipmentFilterService.d.ts
@@ -1,12 +1,12 @@
 import { IBotType } from "../models/eft/common/tables/IBotType";
-import { Equipment, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 export declare class BotEquipmentFilterService {
     protected logger: ILogger;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    protected botEquipmentFilterlists: Record<string, Equipment>;
+    protected botEquipmentFilterlists: Record<string, EquipmentFilters>;
     constructor(logger: ILogger, configServer: ConfigServer);
     /**
      * Filter a bots data to exclude equipment and cartridges defines in the botConfig
@@ -22,7 +22,7 @@ export declare class BotEquipmentFilterService {
      * @param playerLevel Level of the player
      * @returns EquipmentBlacklistDetails object
      */
-    protected getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
+    getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
     /**
      * Get the whitelist for a specific bot type that's within the players level
      * @param botRole Bot type
diff --git a/TypeScript/14AfterDBLoadHook/types/services/FenceService.d.ts b/TypeScript/14AfterDBLoadHook/types/services/FenceService.d.ts
index c9e325e..c940507 100644
--- a/TypeScript/14AfterDBLoadHook/types/services/FenceService.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/services/FenceService.d.ts
@@ -12,6 +12,11 @@ import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+import { ItemFilterService } from "./ItemFilterService";
+/**
+ * Handle actions surrounding Fence
+ * e.g. generating or refreshing assorts / get next refresh time
+ */
 export declare class FenceService {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
@@ -22,18 +27,64 @@ export declare class FenceService {
     protected handbookHelper: HandbookHelper;
     protected itemHelper: ItemHelper;
     protected presetHelper: PresetHelper;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected fenceAssort: ITraderAssort;
     protected traderConfig: ITraderConfig;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, configServer: ConfigServer);
+    protected nextMiniRefreshTimestamp: number;
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, itemFilterService: ItemFilterService, configServer: ConfigServer);
     protected setFenceAssort(fenceAssort: ITraderAssort): void;
-    getFenceAssorts(): ITraderAssort;
+    /**
+     * Get assorts player can purchase
+     * Adjust prices based on fence level of player
+     * @param pmcProfile Player profile
+     * @returns ITraderAssort
+     */
+    getFenceAssorts(pmcProfile: IPmcData): ITraderAssort;
+    /**
+     * Get fence assorts with no price adjustments based on fence rep
+     * @returns ITraderAssort
+     */
+    getRawFenceAssorts(): ITraderAssort;
+    /**
+     * Does fence need to perform a partial refresh because its passed the refresh timer defined in trader.json
+     * @returns true if it needs a partial refresh
+     */
+    needsPartialRefresh(): boolean;
+    /**
+     * Replace a percentage of fence assorts with freshly generated items
+     */
+    performPartialRefresh(): void;
+    /**
+     * Choose an item (not mod) at random and remove from assorts
+     */
+    protected removeRandomItemFromAssorts(): void;
+    /**
+     * Get an integer rounded count of items to replace based on percentrage from traderConfig value
+     * @param totalItemCount total item count
+     * @returns rounded int of items to replace
+     */
+    protected getCountOfItemsToReplace(totalItemCount: number): number;
     /**
      * Get the count of items fence offers
      * @returns number
      */
     getOfferCount(): number;
-    generateFenceAssortCache(pmcData: IPmcData): void;
+    /**
+     * Create a trader assort for fence
+     */
+    generateFenceAssortCache(): void;
+    /**
+     * Create skeleton to hold assort items
+     * @returns ITraderAssort object
+     */
+    protected createBaseTraderAssortItem(): ITraderAssort;
+    /**
+     * Hydrate result parameter object with generated assorts
+     * @param assortCount Number of assorts to generate
+     * @param assorts object to add assorts to
+     */
+    protected createAssorts(assortCount: number, assorts: ITraderAssort): void;
     /**
      * Get the next update timestamp for fence
      * @returns future timestamp
@@ -44,11 +95,14 @@ export declare class FenceService {
      */
     protected getFenceRefreshTime(): number;
     /**
-     * Get the fence level the passed in profile has
+     * Get fence level the passed in profile has
      * @param pmcData Player profile
-     * @returns FenceLevel
+     * @returns FenceLevel object
      */
     getFenceInfo(pmcData: IPmcData): FenceLevel;
+    /**
+     * Remove an assort from fence by id
+     * @param assortIdToRemove assort id to remove from fence assorts
+     */
     removeFenceOffer(assortIdToRemove: string): void;
-    updateFenceOffers(pmcData: IPmcData): void;
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/services/InsuranceService.d.ts b/TypeScript/14AfterDBLoadHook/types/services/InsuranceService.d.ts
index 171bf10..6be8a2f 100644
--- a/TypeScript/14AfterDBLoadHook/types/services/InsuranceService.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/services/InsuranceService.d.ts
@@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
 import { SecureContainerHelper } from "../helpers/SecureContainerHelper";
 import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
+import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData";
 import { IInsuranceConfig } from "../models/spt/config/IInsuranceConfig";
@@ -44,8 +45,22 @@ export declare class InsuranceService {
      * @param mapId Id of the map player died/exited that caused the insurance to be issued on
      */
     sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void;
+    /**
+     * Store lost gear post-raid inside profile
+     * @param pmcData player profile to store gear in
+     * @param offraidData post-raid request object
+     * @param preRaidGear gear player wore prior to raid
+     * @param sessionID Session id
+     */
     storeLostGear(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
     storeInsuredItemsForReturn(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
-    protected addGearToSend(pmcData: IPmcData, insuredItem: any, actualItem: any, sessionID: string): any;
+    /**
+     * Add gear item to InsuredItems array in player profile
+     * @param pmcData profile to store item in
+     * @param insuredItem Item to store in profile
+     * @param actualItem item to store
+     * @param sessionID Session id
+     */
+    protected addGearToSend(pmcData: IPmcData, insuredItem: InsuredItem, actualItem: Item, sessionID: string): void;
     getPremium(pmcData: IPmcData, inventoryItem: Item, traderId: string): number;
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/services/ItemFilterService.d.ts b/TypeScript/14AfterDBLoadHook/types/services/ItemFilterService.d.ts
new file mode 100644
index 0000000..c9c8ef3
--- /dev/null
+++ b/TypeScript/14AfterDBLoadHook/types/services/ItemFilterService.d.ts
@@ -0,0 +1,24 @@
+import { IItemConfig } from "../models/spt/config/IItemConfig";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+/** Centralise the handling of blacklisting items, uses blacklist found in config/item.json */
+export declare class ItemFilterService {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected configServer: ConfigServer;
+    protected blacklist: string[];
+    protected itemConfig: IItemConfig;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer);
+    /**
+     * Check if the provided template id is blacklisted in config/item.json
+     * @param tpl template id
+     * @returns true if blacklisted
+     */
+    isItemBlacklisted(tpl: string): boolean;
+    /**
+     * Return every template id blacklisted in config/item.json
+     * @returns string array of blacklisted tempalte ids
+     */
+    getBlacklistedItems(): string[];
+}
diff --git a/TypeScript/14AfterDBLoadHook/types/services/ProfileFixerService.d.ts b/TypeScript/14AfterDBLoadHook/types/services/ProfileFixerService.d.ts
index ed1dec7..9cb5a38 100644
--- a/TypeScript/14AfterDBLoadHook/types/services/ProfileFixerService.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/services/ProfileFixerService.d.ts
@@ -45,6 +45,11 @@ export declare class ProfileFixerService {
      * @param pmcProfile Profile to find and remove slots from
      */
     protected removeResourcesFromSlotsInHideoutWithoutLocationIndexValue(pmcProfile: IPmcData): void;
+    /**
+     * Hideout slots need to be in a specific order, locationIndex in ascending order
+     * @param pmcProfile profile to edit
+     */
+    protected reorderHideoutAreasWithResouceInputs(pmcProfile: IPmcData): void;
     /**
      * add in objects equal to the number of slots
      * @param areaType area to check
diff --git a/TypeScript/14AfterDBLoadHook/types/utils/HashUtil.d.ts b/TypeScript/14AfterDBLoadHook/types/utils/HashUtil.d.ts
index bacbf2a..a8500e1 100644
--- a/TypeScript/14AfterDBLoadHook/types/utils/HashUtil.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/utils/HashUtil.d.ts
@@ -4,8 +4,18 @@ import { TimeUtil } from "./TimeUtil";
 export declare class HashUtil {
     protected timeUtil: TimeUtil;
     constructor(timeUtil: TimeUtil);
+    /**
+     * Create a 24 character id using the sha256 algorithm + current timestamp
+     * @returns 24 character hash
+     */
     generate(): string;
     generateMd5ForData(data: string): string;
     generateSha1ForData(data: string): string;
+    /**
+     * Create a hash for the data parameter
+     * @param algorithm algorithm to use to hash
+     * @param data data to be hashed
+     * @returns hash value
+     */
     generateHashForData(algorithm: string, data: crypto.BinaryLike): string;
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/utils/RandomUtil.d.ts b/TypeScript/14AfterDBLoadHook/types/utils/RandomUtil.d.ts
index c24dd60..e35d21f 100644
--- a/TypeScript/14AfterDBLoadHook/types/utils/RandomUtil.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/utils/RandomUtil.d.ts
@@ -150,4 +150,10 @@ export declare class RandomUtil {
      */
     drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[];
     getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number;
+    /**
+     * Fisher-Yates shuffle an array
+     * @param array Array to shuffle
+     * @returns Shuffled array
+     */
+    shuffle<T>(array: Array<T>): Array<T>;
 }
diff --git a/TypeScript/14AfterDBLoadHook/types/utils/TimeUtil.d.ts b/TypeScript/14AfterDBLoadHook/types/utils/TimeUtil.d.ts
index f437f8a..1367e26 100644
--- a/TypeScript/14AfterDBLoadHook/types/utils/TimeUtil.d.ts
+++ b/TypeScript/14AfterDBLoadHook/types/utils/TimeUtil.d.ts
@@ -1,3 +1,6 @@
+/**
+ * Utility class to handle time related problems
+ */
 export declare class TimeUtil {
     static readonly oneHourAsSeconds = 3600;
     formatTime(date: Date): string;
@@ -19,4 +22,10 @@ export declare class TimeUtil {
      * @returns current date in format: 00.00.0000 (dd.mm.yyyy)
      */
     getDateMailFormat(): string;
+    /**
+     * Convert hours into seconds
+     * @param hours hours to convert to seconds
+     * @returns number
+     */
+    getHoursAsSeconds(hours: number): number;
 }
diff --git a/TypeScript/1LogToConsole/types/controllers/LocationController.d.ts b/TypeScript/1LogToConsole/types/controllers/LocationController.d.ts
index 76d6632..9db3205 100644
--- a/TypeScript/1LogToConsole/types/controllers/LocationController.d.ts
+++ b/TypeScript/1LogToConsole/types/controllers/LocationController.d.ts
@@ -1,8 +1,11 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
-import { AirDropLootItem } from "../models/spt/location/AirDropLootItem";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -12,11 +15,19 @@ export declare class LocationController {
     protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
-    getAirdropLoot(): AirDropLootItem[];
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/1LogToConsole/types/generators/LootGenerator.d.ts b/TypeScript/1LogToConsole/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/1LogToConsole/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/1LogToConsole/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/1LogToConsole/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/1LogToConsole/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/1LogToConsole/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/1LogToConsole/types/models/spt/services/LootItem.d.ts b/TypeScript/1LogToConsole/types/models/spt/services/LootItem.d.ts
new file mode 100644
index 0000000..2838472
--- /dev/null
+++ b/TypeScript/1LogToConsole/types/models/spt/services/LootItem.d.ts
@@ -0,0 +1,5 @@
+export declare class LootItem {
+    tpl: string;
+    isPreset: boolean;
+    stackCount: number;
+}
diff --git a/TypeScript/1LogToConsole/types/models/spt/services/LootRequest.d.ts b/TypeScript/1LogToConsole/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/1LogToConsole/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/2EditDatabase/types/controllers/LocationController.d.ts b/TypeScript/2EditDatabase/types/controllers/LocationController.d.ts
index 76d6632..9db3205 100644
--- a/TypeScript/2EditDatabase/types/controllers/LocationController.d.ts
+++ b/TypeScript/2EditDatabase/types/controllers/LocationController.d.ts
@@ -1,8 +1,11 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
-import { AirDropLootItem } from "../models/spt/location/AirDropLootItem";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -12,11 +15,19 @@ export declare class LocationController {
     protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
-    getAirdropLoot(): AirDropLootItem[];
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/2EditDatabase/types/generators/LootGenerator.d.ts b/TypeScript/2EditDatabase/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/2EditDatabase/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/2EditDatabase/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/2EditDatabase/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/2EditDatabase/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/2EditDatabase/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/2EditDatabase/types/models/spt/services/LootItem.d.ts b/TypeScript/2EditDatabase/types/models/spt/services/LootItem.d.ts
new file mode 100644
index 0000000..2838472
--- /dev/null
+++ b/TypeScript/2EditDatabase/types/models/spt/services/LootItem.d.ts
@@ -0,0 +1,5 @@
+export declare class LootItem {
+    tpl: string;
+    isPreset: boolean;
+    stackCount: number;
+}
diff --git a/TypeScript/2EditDatabase/types/models/spt/services/LootRequest.d.ts b/TypeScript/2EditDatabase/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/2EditDatabase/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/3GetSptConfigFile/types/controllers/LocationController.d.ts b/TypeScript/3GetSptConfigFile/types/controllers/LocationController.d.ts
index 76d6632..9db3205 100644
--- a/TypeScript/3GetSptConfigFile/types/controllers/LocationController.d.ts
+++ b/TypeScript/3GetSptConfigFile/types/controllers/LocationController.d.ts
@@ -1,8 +1,11 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
-import { AirDropLootItem } from "../models/spt/location/AirDropLootItem";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -12,11 +15,19 @@ export declare class LocationController {
     protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
-    getAirdropLoot(): AirDropLootItem[];
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/3GetSptConfigFile/types/generators/LootGenerator.d.ts b/TypeScript/3GetSptConfigFile/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/3GetSptConfigFile/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/3GetSptConfigFile/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/3GetSptConfigFile/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/3GetSptConfigFile/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/3GetSptConfigFile/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/3GetSptConfigFile/types/models/spt/services/LootItem.d.ts b/TypeScript/3GetSptConfigFile/types/models/spt/services/LootItem.d.ts
new file mode 100644
index 0000000..2838472
--- /dev/null
+++ b/TypeScript/3GetSptConfigFile/types/models/spt/services/LootItem.d.ts
@@ -0,0 +1,5 @@
+export declare class LootItem {
+    tpl: string;
+    isPreset: boolean;
+    stackCount: number;
+}
diff --git a/TypeScript/3GetSptConfigFile/types/models/spt/services/LootRequest.d.ts b/TypeScript/3GetSptConfigFile/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/3GetSptConfigFile/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/4UseACustomConfigFile/types/callbacks/LocationCallbacks.d.ts b/TypeScript/4UseACustomConfigFile/types/callbacks/LocationCallbacks.d.ts
index cc69369..6e0b538 100644
--- a/TypeScript/4UseACustomConfigFile/types/callbacks/LocationCallbacks.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/callbacks/LocationCallbacks.d.ts
@@ -11,4 +11,5 @@ export declare class LocationCallbacks {
     constructor(httpResponse: HttpResponseUtil, locationController: LocationController);
     getLocationData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<ILocationsGenerateAllResponse>;
     getLocation(url: string, info: IGetLocationRequestData, sessionID: string): IGetBodyResponseData<ILocationBase>;
+    getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): string;
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/callbacks/ProfileCallbacks.d.ts b/TypeScript/4UseACustomConfigFile/types/callbacks/ProfileCallbacks.d.ts
index 6a86fc0..183bb0a 100644
--- a/TypeScript/4UseACustomConfigFile/types/callbacks/ProfileCallbacks.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/callbacks/ProfileCallbacks.d.ts
@@ -1,5 +1,6 @@
 import { ProfileController } from "../controllers/ProfileController";
 import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData";
+import { IPmcData } from "../models/eft/common/IPmcData";
 import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData";
 import { INullResponseData } from "../models/eft/httpResponse/INullResponseData";
 import { IGetMiniProfileRequestData } from "../models/eft/launcher/IGetMiniProfileRequestData";
@@ -12,20 +13,51 @@ import { ISearchFriendResponse } from "../models/eft/profile/ISearchFriendRespon
 import { IValidateNicknameRequestData } from "../models/eft/profile/IValidateNicknameRequestData";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/** Handle profile related client events */
 export declare class ProfileCallbacks {
     protected httpResponse: HttpResponseUtil;
     protected timeUtil: TimeUtil;
     protected profileController: ProfileController;
     constructor(httpResponse: HttpResponseUtil, timeUtil: TimeUtil, profileController: ProfileController);
     createProfile(url: string, info: IProfileCreateRequestData, sessionID: string): IGetBodyResponseData<any>;
-    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
-    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
+    /**
+     * Get the complete player profile (scav + pmc character)
+     * @param url
+     * @param info Empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle the creation of a scav profile for player
+     * Occurs post-raid and when profile first created immediately after character details are confirmed by player
+     * @param url
+     * @param info empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle client/game/profile/voice/change event
+     * @param url
+     * @param info Change voice request object
+     * @param sessionID Session id
+     * @returns Client response
+     */
     changeVoice(url: string, info: IProfileChangeVoiceRequestData, sessionID: string): INullResponseData;
+    /**
+     * Handle client/game/profile/nickname/change event
+     * Client allows player to adjust their profile name
+     * @param url
+     * @param info Change nickname request object
+     * @param sessionID Session id
+     * @returns client response
+     */
     changeNickname(url: string, info: IProfileChangeNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     validateNickname(url: string, info: IValidateNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     getReservedNickname(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<string>;
     /**
-     * Called when creating a character, when you choose a character face/voice
+     * Called when creating a character when choosing a character face/voice
      * @param url
      * @param info response (empty)
      * @param sessionID
diff --git a/TypeScript/4UseACustomConfigFile/types/callbacks/RagfairCallbacks.d.ts b/TypeScript/4UseACustomConfigFile/types/callbacks/RagfairCallbacks.d.ts
index 3a405c9..c609f2f 100644
--- a/TypeScript/4UseACustomConfigFile/types/callbacks/RagfairCallbacks.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/callbacks/RagfairCallbacks.d.ts
@@ -19,6 +19,9 @@ import { ConfigServer } from "../servers/ConfigServer";
 import { RagfairServer } from "../servers/RagfairServer";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+/**
+ * Handle ragfair related callback events
+ */
 export declare class RagfairCallbacks extends OnLoadOnUpdate {
     protected httpResponse: HttpResponseUtil;
     protected logger: ILogger;
diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/InraidController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/InraidController.d.ts
index 82bb64d..102a2fb 100644
--- a/TypeScript/4UseACustomConfigFile/types/controllers/InraidController.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/controllers/InraidController.d.ts
@@ -35,6 +35,30 @@ export declare class InraidController {
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer);
     addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void;
     saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Handle updating the profile post-pmc raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Reduce body part hp to % of max
+     * @param pmcData profile to edit
+     * @param multipler multipler to apply to max health
+     */
+    protected reducePmcHealthToPercent(pmcData: IPmcData, multipler: number): void;
+    /**
+     * Handle updating the profile post-pscav raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePlayerScavProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Is the player dead after a raid - dead is anything other than "survived" / "runner"
+     * @param statusOnExit exit value from offraidData object
+     * @returns true if dead
+     */
+    protected isPlayerDead(statusOnExit: string): boolean;
     /**
      * Mark inventory items as FiR if player survived raid, otherwise remove FiR from them
      * @param offraidData Save Progress Request
diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/InventoryController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/InventoryController.d.ts
index f57f731..f564919 100644
--- a/TypeScript/4UseACustomConfigFile/types/controllers/InventoryController.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/controllers/InventoryController.d.ts
@@ -92,7 +92,11 @@ export declare class InventoryController {
      */
     toggleItem(pmcData: IPmcData, body: IInventoryToggleRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Handles Tagging of items (primary Containers).
+     * Add a tag to an inventory item
+     * @param pmcData profile with item to add tag to
+     * @param body tag request data
+     * @param sessionID session id
+     * @returns client response object
      */
     tagItem(pmcData: IPmcData, body: IInventoryTagRequestData, sessionID: string): IItemEventRouterResponse;
     bindItem(pmcData: IPmcData, body: IInventoryBindRequestData, sessionID: string): IItemEventRouterResponse;
diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/LocationController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/LocationController.d.ts
index 90b6d7a..9db3205 100644
--- a/TypeScript/4UseACustomConfigFile/types/controllers/LocationController.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/controllers/LocationController.d.ts
@@ -1,18 +1,33 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class LocationController {
     protected jsonUtil: JsonUtil;
+    protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/MatchController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/MatchController.d.ts
index e8585d9..cb40023 100644
--- a/TypeScript/4UseACustomConfigFile/types/controllers/MatchController.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/controllers/MatchController.d.ts
@@ -9,6 +9,7 @@ import { IGetProfileRequestData } from "../models/eft/match/IGetProfileRequestDa
 import { IJoinMatchRequestData } from "../models/eft/match/IJoinMatchRequestData";
 import { IJoinMatchResult } from "../models/eft/match/IJoinMatchResult";
 import { IStartOfflineRaidRequestData } from "../models/eft/match/IStartOffineRaidRequestData";
+import { IBotConfig } from "../models/spt/config/IBotConfig";
 import { IInRaidConfig } from "../models/spt/config/IInRaidConfig";
 import { IMatchConfig } from "../models/spt/config/IMatchConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
@@ -29,6 +30,7 @@ export declare class MatchController {
     protected applicationContext: ApplicationContext;
     protected matchConfig: IMatchConfig;
     protected inraidConfig: IInRaidConfig;
+    protected botConfig: IBotConfig;
     constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, applicationContext: ApplicationContext);
     getEnabled(): boolean;
     getProfile(info: IGetProfileRequestData): IPmcData[];
diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/QuestController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/QuestController.d.ts
index 2cbccfb..282f50e 100644
--- a/TypeScript/4UseACustomConfigFile/types/controllers/QuestController.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/controllers/QuestController.d.ts
@@ -39,16 +39,31 @@ export declare class QuestController {
      * @returns array of IQuest
      */
     getClientQuests(sessionID: string): IQuest[];
+    /**
+     * Is the quest for the opposite side the player is on
+     * @param side player side (usec/bear)
+     * @param questId questId to check
+     */
+    protected questIsForOtherSide(side: string, questId: string): boolean;
+    /**
+     * Handle the client accepting a quest and starting it
+     * Send starting rewards if any to player and
+     * Send start notification if any to player
+     * @param pmcData Profile to update
+     * @param acceptedQuest Quest accepted
+     * @param sessionID Session id
+     * @returns client response
+     */
     acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Remove completed quest from profile
+     * Update completed quest in profile
      * Add newly unlocked quests to profile
      * Also recalculate thier level due to exp rewards
      * @param pmcData Player profile
-     * @param body completed quest request
-     * @param sessionID session id
-     * @returns ItemEvent response
+     * @param body Completed quest request
+     * @param sessionID Session id
+     * @returns ItemEvent client response
      */
     completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
@@ -67,10 +82,20 @@ export declare class QuestController {
     protected getQuestsFailedByCompletingQuest(completedQuestId: string): IQuest[];
     /**
      * Fail the quests provided
+     * Update quest in profile, otherwise add fresh quest object with failed status
      * @param sessionID session id
      * @param pmcData player profile
      * @param questsToFail quests to fail
      */
     protected failQuests(sessionID: string, pmcData: IPmcData, questsToFail: IQuest[]): void;
     handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment a backend counter stored value by an amount,
+     * Create counter if it does not exist
+     * @param pmcData Profile to find backend counter in
+     * @param conditionId backend counter id to update
+     * @param questId quest id counter is associated with
+     * @param counterValue value to increment the backend counter with
+     */
+    protected updateProfileBackendCounterValue(pmcData: IPmcData, conditionId: string, questId: string, counterValue: number): void;
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/RagfairController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/RagfairController.d.ts
index c4ffc15..06af740 100644
--- a/TypeScript/4UseACustomConfigFile/types/controllers/RagfairController.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/controllers/RagfairController.d.ts
@@ -9,6 +9,7 @@ import { RagfairOfferHelper } from "../helpers/RagfairOfferHelper";
 import { RagfairSellHelper } from "../helpers/RagfairSellHelper";
 import { RagfairSortHelper } from "../helpers/RagfairSortHelper";
 import { RagfairTaxHelper } from "../helpers/RagfairTaxHelper";
+import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
@@ -33,6 +34,9 @@ import { RagfairPriceService } from "../services/RagfairPriceService";
 import { RagfairRequiredItemsService } from "../services/RagfairRequiredItemsService";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/**
+ * Handle RagfairCallback events
+ */
 export declare class RagfairController {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
@@ -52,14 +56,20 @@ export declare class RagfairController {
     protected handbookHelper: HandbookHelper;
     protected paymentHelper: PaymentHelper;
     protected inventoryHelper: InventoryHelper;
+    protected traderHelper: TraderHelper;
     protected ragfairHelper: RagfairHelper;
     protected ragfairOfferService: RagfairOfferService;
     protected ragfairRequiredItemsService: RagfairRequiredItemsService;
     protected ragfairOfferGenerator: RagfairOfferGenerator;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
     getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult;
+    /**
+     * Update a trader flea offer with buy restrictions stored in the traders assort
+     * @param offer flea offer to update
+     */
+    protected setTraderOfferPurchaseLimits(offer: IRagfairOffer): void;
     protected isLinkedSearch(info: ISearchRequestData): boolean;
     protected isRequiredSearch(info: ISearchRequestData): boolean;
     update(): void;
diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/RepeatableQuestController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/RepeatableQuestController.d.ts
index 98d05dd..4c31a3d 100644
--- a/TypeScript/4UseACustomConfigFile/types/controllers/RepeatableQuestController.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/controllers/RepeatableQuestController.d.ts
@@ -7,6 +7,7 @@ import { Exit } from "../models/eft/common/ILocationBase";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { TraderInfo } from "../models/eft/common/tables/IBotBase";
 import { ICompletion, ICompletionAvailableFor, IElimination, IEliminationCondition, IExploration, IExplorationCondition, IPmcDataRepeatableQuest, IRepeatableQuest, IReward, IRewards } from "../models/eft/common/tables/IRepeatableQuests";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
 import { IRepeatableQuestChangeRequest } from "../models/eft/quests/IRepeatableQuestChangeRequest";
 import { ELocationName } from "../models/enums/ELocationName";
@@ -15,6 +16,7 @@ import { ILogger } from "../models/spt/utils/ILogger";
 import { ItemEventRouter } from "../routers/ItemEventRouter";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { PaymentService } from "../services/PaymentService";
 import { ProfileFixerService } from "../services/ProfileFixerService";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -64,9 +66,10 @@ export declare class RepeatableQuestController {
     protected itemEventRouter: ItemEventRouter;
     protected paymentService: PaymentService;
     protected objectId: ObjectId;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
-    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, configServer: ConfigServer);
+    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint
      * Returns an array of objects in the format of repeatable quests to the client.
@@ -217,4 +220,16 @@ export declare class RepeatableQuestController {
     debugLogRepeatableQuestIds(pmcData: IPmcData): void;
     probabilityObjectArray<K, V>(configArrayInput: ProbabilityObject<K, V>[]): ProbabilityObjectArray<K, V>;
     changeRepeatableQuest(pmcDataIn: IPmcData, body: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
+     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
+     */
+    protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig): [string, ITemplateItem][];
+    /**
+     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
+     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
+     * @param {*} tpl template id of item to check
+     * @returns boolean: true if item is valid reward
+     */
+    isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig): boolean;
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/TraderController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/TraderController.d.ts
index 0162064..b79f55e 100644
--- a/TypeScript/4UseACustomConfigFile/types/controllers/TraderController.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/controllers/TraderController.d.ts
@@ -4,6 +4,7 @@ import { TraderHelper } from "../helpers/TraderHelper";
 import { IBarterScheme, ITraderAssort, ITraderBase } from "../models/eft/common/tables/ITrader";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { FenceService } from "../services/FenceService";
 import { TraderAssortService } from "../services/TraderAssortService";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
@@ -15,8 +16,9 @@ export declare class TraderController {
     protected traderHelper: TraderHelper;
     protected timeUtil: TimeUtil;
     protected traderAssortService: TraderAssortService;
+    protected fenceService: FenceService;
     protected jsonUtil: JsonUtil;
-    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, jsonUtil: JsonUtil);
+    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, fenceService: FenceService, jsonUtil: JsonUtil);
     /**
      * Runs when onLoad event is fired
      * Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
@@ -26,6 +28,7 @@ export declare class TraderController {
     /**
      * Runs when onUpdate is fired
      * If current time is > nextResupply(expire) time of trader, refresh traders assorts and
+     * Fence is handled slightly differently
      * @returns has run
      */
     update(): boolean;
diff --git a/TypeScript/4UseACustomConfigFile/types/di/Container.d.ts b/TypeScript/4UseACustomConfigFile/types/di/Container.d.ts
index 17791b0..98d1fa1 100644
--- a/TypeScript/4UseACustomConfigFile/types/di/Container.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/di/Container.d.ts
@@ -1,4 +1,7 @@
 import { DependencyContainer } from "tsyringe";
+/**
+ * Handle the registration of classes to be used by the Dependency Injection code
+ */
 export declare class Container {
     static registerTypes(depContainer: DependencyContainer): void;
     static registerListTypes(depContainer: DependencyContainer): void;
diff --git a/TypeScript/4UseACustomConfigFile/types/generators/BotGenerator.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/BotGenerator.d.ts
index a5fc0ad..7d58f95 100644
--- a/TypeScript/4UseACustomConfigFile/types/generators/BotGenerator.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/generators/BotGenerator.d.ts
@@ -40,7 +40,7 @@ export declare class BotGenerator {
      * @param botTemplate base bot template to use  (e.g. assault/pmcbot)
      * @returns
      */
-    generatePlayerScav(role: string, difficulty: string, botTemplate: IBotType): IBotBase;
+    generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase;
     generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[];
     /**
      * Choose if a bot should become a PMC by checking if bot type is allowed to become a Pmc in botConfig.convertFromChances and doing a random int check
@@ -58,7 +58,7 @@ export declare class BotGenerator {
      * @returns IBotBase object
      */
     protected getCloneOfBotBase(): IBotBase;
-    protected generateBot(bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
+    protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
     /**
      * Log the number of PMCs generated to the debug console
      */
diff --git a/TypeScript/4UseACustomConfigFile/types/generators/BotInventoryGenerator.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/BotInventoryGenerator.d.ts
index 35d1ee8..73f8ece 100644
--- a/TypeScript/4UseACustomConfigFile/types/generators/BotInventoryGenerator.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/generators/BotInventoryGenerator.d.ts
@@ -18,7 +18,7 @@ export declare class BotInventoryGenerator {
     protected botGeneratorHelper: BotGeneratorHelper;
     protected weightedRandomHelper: WeightedRandomHelper;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper);
-    generateInventory(templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
+    generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
     protected generateEquipment(equipmentSlot: string, equipmentPool: Record<string, number>, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void;
     protected generateInventoryBase(): PmcInventory;
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/generators/BotLootGenerator.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/BotLootGenerator.d.ts
index c6a3f29..5a2d144 100644
--- a/TypeScript/4UseACustomConfigFile/types/generators/BotLootGenerator.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/generators/BotLootGenerator.d.ts
@@ -24,7 +24,7 @@ export declare class BotLootGenerator {
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botLootCacheService: BotLootCacheService, configServer: ConfigServer);
-    generateLoot(templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
+    generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
     protected getRandomisedCount(min: number, max: number, nValue: number): number;
     /**
      * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached
@@ -47,7 +47,7 @@ export declare class BotLootGenerator {
      * @param botRole bots role, .e.g. pmcBot
      * @param isPmc are we generating for a pmc
      */
-    protected addLooseWeaponsToInventorySlot(botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
+    protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
     /**
      * Get a random item from the pool parameter using the biasedRandomNumber system
      * @param pool pool of items to pick an item from
diff --git a/TypeScript/4UseACustomConfigFile/types/generators/BotWeaponGenerator.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/BotWeaponGenerator.d.ts
index 9215214..49fa7bf 100644
--- a/TypeScript/4UseACustomConfigFile/types/generators/BotWeaponGenerator.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/generators/BotWeaponGenerator.d.ts
@@ -28,7 +28,18 @@ export declare class BotWeaponGenerator {
     protected botConfig: IBotConfig;
     constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer);
     /**
-     * Get a random weapon from a bots pool of weapons (weighted)
+     * Pick a random weapon based on weightings and generate a functional weapon
+     * @param equipmentSlot Primary/secondary/holster
+     * @param botTemplateInventory e.g. assault.json
+     * @param weaponParentId
+     * @param modChances
+     * @param botRole role of bot, e.g. assault/followerBully
+     * @param isPmc Is weapon generated for a pmc
+     * @returns GenerateWeaponResult object
+     */
+    generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    /**
+     * Get a random weighted weapon from a bots pool of weapons
      * @param equipmentSlot Primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
      * @returns weapon tpl
@@ -39,43 +50,24 @@ export declare class BotWeaponGenerator {
      * @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool())
      * @param equipmentSlot slot to fit into, primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
+     * @param weaponParentId ParentId of the weapon being generated
+     * @param modChances Dictionary of item types and % chance weapon will have that mod
+     * @param botRole e.g. assault/exusec
      * @param isPmc
      * @returns GenerateWeaponResult object
      */
-    generateWeaponByTpl(weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
     /**
-     * Generate an entirely random weapon
-     * @param equipmentSlot Primary/secondary/holster
-     * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
-     * @param isPmc
-     * @returns GenerateWeaponResult object
-     */
-    generateRandomWeapon(equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
-    /**
-     * Create array with weapon base as only element
-     * Add additional properties as required
-     * @param weaponTpl
-     * @param weaponParentId
-     * @param equipmentSlot
-     * @param weaponItemTemplate
+     * Create array with weapon base as only element and
+     * add additional properties based on weapon type
+     * @param weaponTpl Weapon tpl to create item with
+     * @param weaponParentId Weapons parent id
+     * @param equipmentSlot e.g. primary/secondary/holster
+     * @param weaponItemTemplate db template for weapon
      * @param botRole for durability values
-     * @returns
+     * @returns Base weapon item in array
      */
     constructWeaponBaseArray(weaponTpl: string, weaponParentId: string, equipmentSlot: string, weaponItemTemplate: ITemplateItem, botRole: string): Item[];
-    /**
-     * Add compatible magazines to an inventory based on a generated weapon
-     * @param weaponDetails
-     * @param magCounts
-     * @param inventory
-     * @param botRole the bot type we're getting generating extra mags for
-     */
-    addExtraMagazinesToInventory(weaponDetails: GenerateWeaponResult, magCounts: MinMax, inventory: PmcInventory, botRole: string): void;
     /**
      * Get the mods necessary to kit out a weapon to its preset level
      * @param weaponTpl weapon to find preset for
@@ -84,20 +76,32 @@ export declare class BotWeaponGenerator {
      * @returns array of weapon mods
      */
     protected getPresetWeaponMods(weaponTpl: string, equipmentSlot: string, weaponParentId: string, itemTemplate: ITemplateItem, botRole: string): Item[];
-    /** Checks if all required slots are occupied on a weapon and all it's mods */
+    /**
+     * Checks if all required slots are occupied on a weapon and all it's mods
+     * @param weaponItemArray Weapon + mods
+     * @returns true if valid
+     */
     protected isWeaponValid(weaponItemArray: Item[]): boolean;
     /**
      * Generates extra magazines or bullets (if magazine is internal) and adds them to TacticalVest and Pockets.
      * Additionally, adds extra bullets to SecuredContainer
-     * @param weaponMods
-     * @param weaponTemplate
-     * @param magCounts
-     * @param ammoTpl
-     * @param inventory
+     * @param weaponMods mods to attach to weapon
+     * @param weaponTemplate db template for weapon
+     * @param magCounts magazine count to add to inventory
+     * @param ammoTpl ammo templateId to add to magazines
+     * @param inventory inventory to add magazines to
      * @param botRole the bot type we're getting generating extra mags for
      * @returns
      */
-    protected generateExtraMagazines(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    addExtraMagazinesToInventory(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    /**
+     * Create a magazine using the parameters given
+     * @param magazineTpl Tpl of the magazine to create
+     * @param ammoTpl Ammo to add to magazine
+     * @param magTemplate template object of magazine
+     * @returns Item array
+     */
+    protected createMagazine(magazineTpl: string, ammoTpl: string, magTemplate: ITemplateItem): Item[];
     /**
      * Get a randomised number of bullets for a specific magazine
      * @param magCounts min and max count of magazines
@@ -138,10 +142,9 @@ export declare class BotWeaponGenerator {
      * Finds and return a compatible ammo tpl based on the bots ammo weightings (x.json/inventory/equipment/ammo)
      * @param ammo a list of ammo tpls the weapon can use
      * @param weaponTemplate the weapon we want to pick ammo for
-     * @param isPmc is the ammo being gathered for a pmc (runs pmc ammo filtering)
      * @returns an ammo tpl that works with the desired gun
      */
-    protected getCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem, isPmc: boolean): string;
+    protected getWeightedCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem): string;
     /**
      * Get a weapons compatible cartridge caliber
      * @param weaponTemplate Weapon to look up caliber of
diff --git a/TypeScript/4UseACustomConfigFile/types/generators/LocationGenerator.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/LocationGenerator.d.ts
index bd368b5..cc61dcf 100644
--- a/TypeScript/4UseACustomConfigFile/types/generators/LocationGenerator.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/generators/LocationGenerator.d.ts
@@ -3,10 +3,9 @@ import { GameEventHelper } from "../helpers/GameEventHelper";
 import { ItemHelper } from "../helpers/ItemHelper";
 import { PresetHelper } from "../helpers/PresetHelper";
 import { RagfairServerHelper } from "../helpers/RagfairServerHelper";
-import { ILooseLoot, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
+import { ILooseLoot, SpawnpointsForced, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IStaticAmmoDetails, IStaticContainerProps, IStaticForcedProps, IStaticLootDetails } from "../models/eft/common/tables/ILootBase";
-import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILocationConfig } from "../models/spt/config/ILocationConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
@@ -36,11 +35,19 @@ export declare class LocationGenerator {
     generateContainerLoot(containerIn: IStaticContainerProps, staticForced: IStaticForcedProps[], staticLootDist: Record<string, IStaticLootDetails>, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): IStaticContainerProps;
     protected getLooseLootMultiplerForLocation(location: string): number;
     protected getStaticLootMultiplerForLocation(location: string): number;
+    /**
+     * Create array of loose + forced loot using probability system
+     * @param dynamicLootDist
+     * @param staticAmmoDist
+     * @param locationName Location to generate loot for
+     * @returns Array of spawn points with loot in them
+     */
     generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): SpawnpointTemplate[];
+    /**
+     * Add forced spawn point loot into loot parameter array
+     * @param loot array to add forced loot to
+     * @param forcedSpawnPoints forced loot to add
+     */
+    protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[]): void;
     protected createItem(tpl: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, parentId?: string): IContainerItem;
-    protected getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
-    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
-    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
-    protected createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
-    protected createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/generators/LootGenerator.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/4UseACustomConfigFile/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/4UseACustomConfigFile/types/generators/PMCLootGenerator.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/PMCLootGenerator.d.ts
index 64e6f7f..b9f2a83 100644
--- a/TypeScript/4UseACustomConfigFile/types/generators/PMCLootGenerator.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/generators/PMCLootGenerator.d.ts
@@ -1,15 +1,21 @@
 import { ItemHelper } from "../helpers/ItemHelper";
-import { DatabaseServer } from "../servers/DatabaseServer";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+/**
+ * Handle the generation of dynamic PMC loot in pockets and backpacks
+ * and the removal of blacklisted items
+ */
 export declare class PMCLootGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected configServer: ConfigServer;
+    protected itemFilterService: ItemFilterService;
     protected pocketLootPool: string[];
     protected backpackLootPool: string[];
     protected botConfig: IBotConfig;
-    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer);
+    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer, itemFilterService: ItemFilterService);
     generatePMCPocketLootPool(): string[];
     generatePMCBackpackLootPool(): string[];
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/generators/ScavCaseRewardGenerator.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/ScavCaseRewardGenerator.d.ts
index c7d6ab7..89cb5c8 100644
--- a/TypeScript/4UseACustomConfigFile/types/generators/ScavCaseRewardGenerator.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/generators/ScavCaseRewardGenerator.d.ts
@@ -8,9 +8,13 @@ import { RewardCountAndPriceDetails, ScavCaseRewardCountsAndPrices } from "../mo
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { RagfairPriceService } from "../services/RagfairPriceService";
 import { HashUtil } from "../utils/HashUtil";
 import { RandomUtil } from "../utils/RandomUtil";
+/**
+ * Handle the creation of randomised scav case rewards
+ */
 export declare class ScavCaseRewardGenerator {
     protected logger: ILogger;
     protected randomUtil: RandomUtil;
@@ -18,9 +22,10 @@ export declare class ScavCaseRewardGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected ragfairPriceService: RagfairPriceService;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected scavCaseConfig: IScavCaseConfig;
-    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, configServer: ConfigServer);
+    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Create an array of rewards that will be given to the player upon completing their scav case build
      * @param body client request
diff --git a/TypeScript/4UseACustomConfigFile/types/generators/WeatherGenerator.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/WeatherGenerator.d.ts
index 44cecbb..8ddbe49 100644
--- a/TypeScript/4UseACustomConfigFile/types/generators/WeatherGenerator.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/generators/WeatherGenerator.d.ts
@@ -1,7 +1,7 @@
 import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IWeatherData } from "../models/eft/weather/IWeatherData";
 import { IWeatherConfig } from "../models/spt/config/IWeatherConfig";
+import { ConfigServer } from "../servers/ConfigServer";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class WeatherGenerator {
@@ -21,11 +21,16 @@ export declare class WeatherGenerator {
     protected getAcceleratedTime(computedDate: Date): string;
     /**
      * Get current time formatted to fit BSGs requirement
-     * @param computedDate
+     * @param computedDate date to format into bsg style
      * @returns
      */
     protected getNormalTime(computedDate: Date): string;
-    generateWeather(data: IWeatherData): IWeatherData;
+    /**
+     * Return randomised Weather data
+     * @param weatherData weather input data
+     * @returns Randomised weather data
+     */
+    generateWeather(weatherData: IWeatherData): IWeatherData;
     protected getWeightedFog(): string;
     protected getWeightedRain(): number;
     protected getRandomFloat(node: string): number;
diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/AssortHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/AssortHelper.d.ts
index 15586b9..bfc157f 100644
--- a/TypeScript/4UseACustomConfigFile/types/helpers/AssortHelper.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/helpers/AssortHelper.d.ts
@@ -17,7 +17,7 @@ export declare class AssortHelper {
      * @param assort assort items from a trader
      * @returns assort items minus locked quest assorts
      */
-    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort): ITraderAssort;
+    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort, flea?: boolean): ITraderAssort;
     /**
      * Remove assorts from a trader that have not been unlocked yet
      * @param pmcProfile player profile
@@ -32,5 +32,5 @@ export declare class AssortHelper {
      * @param itemID item id to remove from asort
      * @returns Modified assort
      */
-    removeItemFromAssort(assort: ITraderAssort, itemID: string): ITraderAssort;
+    removeItemFromAssort(assort: ITraderAssort, itemID: string, flea?: boolean): ITraderAssort;
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/BotGeneratorHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/BotGeneratorHelper.d.ts
index 3cd7256..eb0d215 100644
--- a/TypeScript/4UseACustomConfigFile/types/helpers/BotGeneratorHelper.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/helpers/BotGeneratorHelper.d.ts
@@ -3,10 +3,12 @@ import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"
 import { Mods, ModsChances } from "../models/eft/common/tables/IBotType";
 import { Item, Repairable, Upd } from "../models/eft/common/tables/IItem";
 import { Grid, ITemplateItem, Slot } from "../models/eft/common/tables/ITemplateItem";
-import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
@@ -14,6 +16,7 @@ import { ContainerHelper } from "./ContainerHelper";
 import { InventoryHelper } from "./InventoryHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProbabilityHelper } from "./ProbabilityHelper";
+import { ProfileHelper } from "./ProfileHelper";
 export declare class BotGeneratorHelper {
     protected logger: ILogger;
     protected jsonUtil: JsonUtil;
@@ -25,10 +28,76 @@ export declare class BotGeneratorHelper {
     protected itemHelper: ItemHelper;
     protected inventoryHelper: InventoryHelper;
     protected containerHelper: ContainerHelper;
+    protected botEquipmentFilterService: BotEquipmentFilterService;
+    protected itemFilterService: ItemFilterService;
+    protected profileHelper: ProfileHelper;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, configServer: ConfigServer);
-    generateModsForItem(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, configServer: ConfigServer);
+    /**
+     * TODO - very similar to generateModsForWeapon
+     * Check mods are compatible and add to array
+     * @param equipment Equipment item to add mods to
+     * @param modPool Mod list to choose frm
+     * @param parentId parentid of item to add mod to
+     * @param parentTemplate template objet of item to add mods to
+     * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type
+     * @returns Item + compatible mods as an array
+     */
+    generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    /**
+     * TODO - very similar to generateModsForEquipment
+     * @param sessionId session id
+     * @param weapon Weapon to add mods to
+     * @param modPool pool of compatible mods to attach to gun
+     * @param weaponParentId parentId of weapon
+     * @param parentTemplate
+     * @param modSpawnChances
+     * @param ammoTpl ammo tpl to use when generating magazines/cartridges
+     * @param botRole role of bot weapon is generated for
+     * @returns Weapon with mods
+     */
+    generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[];
+    /**
+     * Generate a pool of mods for this bots mod type if bot has values inside `randomisedWeaponModSlots` array found in bot.json/equipment[botrole]
+     * @param allowedMods Mods to be added to mod pool
+     * @param botEquipBlacklist blacklist of items not allowed to be added to mod pool
+     * @param modSlot Slot to generate mods for
+     * @param itemModPool base mod pool to replace values of
+     */
+    protected generateDynamicModPool(allowedMods: string[], botEquipBlacklist: EquipmentFilterDetails, modSlot: string, itemModPool: Record<string, string[]>): void;
+    /**
+     * Check if the specific item type on the weapon has reached the set limit
+     * @param modTpl item to check is limited
+     * @param currentCount current number of this item on gun
+     * @param maxLimit mod limit allowed
+     * @param botRole role of bot we're checking weapon of
+     * @returns true if limit reached
+     */
+    protected weaponModLimitReached(modTpl: string, currentCount: {
+        count: number;
+    }, maxLimit: number, botRole: string): boolean;
+    /**
+     * log errors if mod is not valid for a slot
+     * @param modTpl
+     * @param found
+     * @param itemSlot
+     * @param modTemplate
+     * @param modSlot
+     * @param parentTemplate
+     * @returns true if valid
+     */
+    protected isModValidForSlot(modTpl: string, found: boolean, itemSlot: Slot, modTemplate: ITemplateItem, modSlot: string, parentTemplate: ITemplateItem): boolean;
+    /**
+     * Create a mod item with parameters as properties
+     * @param modId _id
+     * @param modTpl _tpl
+     * @param parentId parentId
+     * @param modSlot slotId
+     * @param modTemplate Used to add additional properites in the upd object
+     * @returns Item object
+     */
+    protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item;
     /**
      * Is this magazine cylinder related (revolvers and grenade launchers)
      * @param magazineParentName the name of the magazines parent
@@ -62,11 +131,11 @@ export declare class BotGeneratorHelper {
      * Those magazines (e.g. 60dc519adf4c47305f6d410d) have a "Cartridges" entry with a _max_count=0.
      * Ammo is not put into the magazine directly but assigned to the magazine's slots: The "camora_xxx" slots.
      * This function is a helper called by generateModsForItem for mods with parent type "CylinderMagazine"
-     *
-     * @param {object}      items               The items where the CylinderMagazine's camora are appended to
-     * @param {object}      modPool             modPool which should include available cartrigdes
-     * @param {string}      parentId            The CylinderMagazine's UID
-     * @param {object}      parentTemplate      The CylinderMagazine's template
+     * @param items The items where the CylinderMagazine's camora are appended to
+     * @param modPool modPool which should include available cartrigdes
+     * @param parentId The CylinderMagazine's UID
+     * @param parentTemplate The CylinderMagazine's template
+     * @returns
      */
     protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void;
     /**
@@ -75,6 +144,13 @@ export declare class BotGeneratorHelper {
      * @returns string array of shells fro luitple camora sources
      */
     protected mergeCamoraPoolsTogether(camorasWithShells: Record<string, string[]>): string[];
+    /**
+     * Adds properties to an item
+     * e.g. Repairable / HasHinge / Foldable / MaxDurability
+     * @param itemTemplate
+     * @param botRole Used by weapons to randomise the durability values
+     * @returns Item Upd object with extra properties
+     */
     generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): {
         upd?: Upd;
     };
@@ -93,12 +169,6 @@ export declare class BotGeneratorHelper {
      */
     protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable;
     protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string;
-    /**
-     * Sort by spawn chance, highest to lowest, higher is more common
-     * @param unsortedModArray String array to sort
-     * @returns Sorted string array
-     */
-    protected sortModArray(unsortedModArray: string[]): string[];
     /**
      * Can an item be added to an item without issue
      * @param items
@@ -117,8 +187,15 @@ export declare class BotGeneratorHelper {
      * @returns a `boolean` indicating item was added
      */
     addItemWithChildrenToEquipmentSlot(equipmentSlots: string[], parentId: string, parentTpl: string, itemWithChildren: Item[], inventory: PmcInventory): boolean;
+    /**
+     * is the provided item allowed inside a container
+     * @param slot location item wants to be placed in
+     * @param itemTpl item being placed
+     * @returns true if allowed
+     */
     protected itemAllowedInContainer(slot: Grid, itemTpl: string): boolean;
 }
+/** TODO - move into own class */
 export declare class ExhaustableArray<T> {
     private itemPool;
     private randomUtil;
diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/HideoutHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/HideoutHelper.d.ts
index 36e4009..7495a6a 100644
--- a/TypeScript/4UseACustomConfigFile/types/helpers/HideoutHelper.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/helpers/HideoutHelper.d.ts
@@ -44,14 +44,72 @@ export declare class HideoutHelper {
     initProduction(recipeId: string, productionTime: number): Production;
     isProductionType(productive: Productive): productive is Production;
     applyPlayerUpgradesBonuses(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * TODO:
+     * After looking at the skills there doesnt seem to be a configuration per skill to boost
+     * the XP gain PER skill. I THINK you should be able to put the variable "SkillProgress" (just like health has it)
+     * and be able to tune the skill gain PER skill, but I havent tested it and Im not sure!
+     * @param pmcData
+     * @param bonus
+     */
     protected applySkillXPBoost(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * Process a players hideout, update areas that use resources + increment production timers
+     * @param sessionID Session id
+     */
     updatePlayerHideout(sessionID: string): void;
+    /**
+     * Update progress timer for water collector
+     * @param pmcData profile to update
+     * @param productionId id of water collection production to update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateWaterCollectorProductionTimer(pmcData: IPmcData, productionId: string, hideoutProperties: {
+        btcFarmCGs?: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Iterate over productions and update their progress timers
+     * @param pmcData Profile to check for productions and update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Update progress timer for scav case
+     * @param pmcData Profile to update
+     * @param productionId Id of scav case production to update
+     */
+    protected updateScavCaseProductionTimer(pmcData: IPmcData, productionId: string): void;
+    /**
+     * Iterate over hideout areas that use resources (fuel/filters etc) and update associated values
+     * @param sessionID Session id
+     * @param pmcData Profile to update areas of
+     * @param hideoutProperties hideout properties
+     */
+    protected updateAreasWithResources(sessionID: string, pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
     protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
     protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
-    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): HideoutArea;
-    protected updateWaterFilters(waterFilterArea: HideoutArea, pwProd: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
+    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): void;
+    /**
+     * Adjust water filter objects resourceValue or delete when they reach 0 resource
+     * @param waterFilterArea water filter area to update
+     * @param production production object
+     * @param isGeneratorOn is generatory enabled
+     * @param pmcData Player profile
+     * @returns Updated HideoutArea object
+     */
+    protected updateWaterFilters(waterFilterArea: HideoutArea, production: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
     protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
-    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): HideoutArea;
+    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): void;
     protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
     protected getBTCSlots(pmcData: IPmcData): number;
     protected getManagementSkillsSlots(): number;
diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/InRaidHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/InRaidHelper.d.ts
index b382e30..962df38 100644
--- a/TypeScript/4UseACustomConfigFile/types/helpers/InRaidHelper.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/helpers/InRaidHelper.d.ts
@@ -18,18 +18,6 @@ export declare class InRaidHelper {
     protected paymentHelper: PaymentHelper;
     protected profileFixerService: ProfileFixerService;
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper, profileFixerService: ProfileFixerService);
-    /**
-     * Reset the SPT inraid property stored in a profile to 'none'
-     * @param sessionID Session id
-     */
-    protected removePlayer(sessionID: string): void;
-    /**
-     * Some maps have one-time-use keys (e.g. Labs
-     * Remove the relevant key from an inventory based on the post-raid request data passed in
-     * @param offraidData post-raid data
-     * @param sessionID Session id
-     */
-    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
     /**
      * Check an array of items and add an upd object to money items with a stack count of 1
      * Single stack money items have no upd object and thus no StackObjectsCount, causing issues
@@ -54,6 +42,18 @@ export declare class InRaidHelper {
      * @returns Reset profile object
      */
     updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData;
+    /**
+     * Some maps have one-time-use keys (e.g. Labs
+     * Remove the relevant key from an inventory based on the post-raid request data passed in
+     * @param offraidData post-raid data
+     * @param sessionID Session id
+     */
+    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Set the SPT inraid location Profile property to 'none'
+     * @param sessionID Session id
+     */
+    protected setPlayerInRaidLocationStatusToNone(sessionID: string): void;
     /**
      * Adds SpawnedInSession property to items found in a raid
      * Removes SpawnedInSession for non-scav players if item was taken into raid with SpawnedInSession = true
@@ -95,5 +95,10 @@ export declare class InRaidHelper {
      * @returns true if item is kept after death
      */
     isItemKeptAfterDeath(slotId: string): boolean;
+    /**
+     * Return the equipped items from a players inventory
+     * @param items Players inventory to search through
+     * @returns an array of equipped items
+     */
     getPlayerGear(items: Item[]): Item[];
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/ItemHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/ItemHelper.d.ts
index 1701c62..de10892 100644
--- a/TypeScript/4UseACustomConfigFile/types/helpers/ItemHelper.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/helpers/ItemHelper.d.ts
@@ -1,35 +1,30 @@
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item, Repairable } from "../models/eft/common/tables/IItem";
+import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase";
 import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+import { MathUtil } from "../utils/MathUtil";
+import { ObjectId } from "../utils/ObjectId";
+import { RandomUtil } from "../utils/RandomUtil";
 declare class ItemHelper {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
     protected jsonUtil: JsonUtil;
+    protected randomUtil: RandomUtil;
+    protected objectId: ObjectId;
+    protected mathUtil: MathUtil;
     protected databaseServer: DatabaseServer;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer);
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer);
     /**
      * Checks if a id is a valid item. Valid meaning that it's an item that be stored in stash
      * @param       {string}    tpl       the template id / tpl
      * @returns                             boolean; true for items that may be in player posession and not quest items
      */
     isValidItem(tpl: string, invalidBaseTypes?: string[]): boolean;
-    /**
-     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
-     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
-     * @param {*} tpl template id of item to check
-     * @returns boolean: true if item is valid reward
-     */
-    isValidRewardItem(tpl: string): boolean;
-    /**
-     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
-     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
-     */
-    getRewardableItems(): [string, ITemplateItem][];
     /**
      * Check if the tpl / template Id provided is a descendent of the baseclass
      *
@@ -196,6 +191,22 @@ declare class ItemHelper {
      * @returns ItemSize object (width and height)
      */
     getItemSize(items: Item[], rootItemId: string): ItemHelper.ItemSize;
+    /**
+     * Get a random cartridge from an items Filter property
+     * @param item
+     * @returns
+     */
+    getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
+    createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
+    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
+    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
+    createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
+    /**
+     * Get the size of a stack, return 1 if no stack object count property found
+     * @param item Item to get stack size of
+     * @returns size of stack
+     */
+    getItemStackSize(item: Item): number;
 }
 declare namespace ItemHelper {
     interface ItemSize {
diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/ProfileHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/ProfileHelper.d.ts
index 9d4ff98..9c6560a 100644
--- a/TypeScript/4UseACustomConfigFile/types/helpers/ProfileHelper.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/helpers/ProfileHelper.d.ts
@@ -24,6 +24,19 @@ export declare class ProfileHelper {
     constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, fenceService: FenceService);
     resetProfileQuestCondition(sessionID: string, conditionId: string): void;
     getCompleteProfile(sessionID: string): IPmcData[];
+    /**
+     * Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
+     * Server saves the post-raid changes prior to the xp screen getting the profile, this results in the xp screen using
+     * the now updated profile values as a base, meaning it shows x2 xp gained
+     * Instead, clone the post-raid profile (so we dont alter its values), apply the pre-raid xp values to the cloned objects and return
+     * Delete snapshot of pre-raid profile prior to returning profile data
+     * @param sessionId Session id
+     * @param output pmc and scav profiles array
+     * @param pmcProfile post-raid pmc profile
+     * @param scavProfile post-raid scav profile
+     * @returns updated profile array
+     */
+    protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
     isNicknameTaken(info: IValidateNicknameRequestData, sessionID: string): boolean;
     /**
      * Add experience to a PMC inside the players profile
diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/QuestHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/QuestHelper.d.ts
index 32e55ec..d66d150 100644
--- a/TypeScript/4UseACustomConfigFile/types/helpers/QuestHelper.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/helpers/QuestHelper.d.ts
@@ -36,11 +36,20 @@ export declare class QuestHelper {
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
     constructor(logger: ILogger, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, itemHelper: ItemHelper, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, localeService: LocaleService, ragfairServerHelper: RagfairServerHelper, dialogueHelper: DialogueHelper, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, traderHelper: TraderHelper, configServer: ConfigServer);
-    questStatus(pmcData: IPmcData, questID: string): QuestStatus;
     /**
-     * returns true is the condition is satisfied
+    * Get status of a quest by quest id
+    * @param pmcData Profile to search
+    * @param questID Quest id to look up
+    * @returns QuestStauts enum
+    */
+    getQuestStatus(pmcData: IPmcData, questID: string): QuestStatus;
+    /**
+     * returns true is the level condition is satisfied
+     * @param playerLevel Players level
+     * @param condition Quest condition
+     * @returns true if player level is greater than or equal to quest
      */
-    evaluateLevel(pmcProfile: IPmcData, cond: AvailableForConditions): boolean;
+    doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean;
     getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[];
     /**
      * Increase skill points of a skill on player profile
diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/RagfairOfferHelper.d.ts
index 8d03bee..e9d72ca 100644
--- a/TypeScript/4UseACustomConfigFile/types/helpers/RagfairOfferHelper.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/helpers/RagfairOfferHelper.d.ts
@@ -22,12 +22,14 @@ import { ProfileHelper } from "./ProfileHelper";
 import { RagfairHelper } from "./RagfairHelper";
 import { RagfairServerHelper } from "./RagfairServerHelper";
 import { RagfairSortHelper } from "./RagfairSortHelper";
+import { TraderHelper } from "./TraderHelper";
 export declare class RagfairOfferHelper {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
     protected hashUtil: HashUtil;
     protected itemEventRouter: ItemEventRouter;
     protected databaseServer: DatabaseServer;
+    protected traderHelper: TraderHelper;
     protected saveServer: SaveServer;
     protected dialogueHelper: DialogueHelper;
     protected itemHelper: ItemHelper;
@@ -43,10 +45,10 @@ export declare class RagfairOfferHelper {
     protected static goodSoldTemplate: string;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, traderHelper: TraderHelper, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
     getValidOffers(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
     getOffersForBuild(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
-    processOffers(sessionID: string): boolean;
+    processOffersOnProfile(sessionID: string): boolean;
     protected getProfileOffers(sessionID: string): IRagfairOffer[];
     protected deleteOfferByOfferId(sessionID: string, offerId: string): void;
     protected completeOffer(sessionID: string, offer: IRagfairOffer, boughtAmount: number): IItemEventRouterResponse;
diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/RagfairSellHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/RagfairSellHelper.d.ts
index 6ec004a..91b8a20 100644
--- a/TypeScript/4UseACustomConfigFile/types/helpers/RagfairSellHelper.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/helpers/RagfairSellHelper.d.ts
@@ -11,6 +11,12 @@ export declare class RagfairSellHelper {
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     constructor(logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer);
-    calculateSellChance(baseChance: number, offerPrice: number, requirementsPriceInRub: number): number;
-    rollForSale(sellChance: number, count: number): SellResult[];
+    calculateSellChance(baseChancePercent: number, offerPriceRub: number, playerListedPriceRub: number): number;
+    /**
+     * Determine if the offer being listed will be sold
+     * @param sellChancePercent chance item will sell
+     * @param itemSellCount count of items to sell
+     * @returns Array of purchases of item(s) lsited
+     */
+    rollForSale(sellChancePercent: number, itemSellCount: number): SellResult[];
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/RagfairServerHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/RagfairServerHelper.d.ts
index e4939d1..a03cdda 100644
--- a/TypeScript/4UseACustomConfigFile/types/helpers/RagfairServerHelper.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/helpers/RagfairServerHelper.d.ts
@@ -6,6 +6,7 @@ import { IRagfairConfig } from "../models/spt/config/IRagfairConfig";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { SaveServer } from "../servers/SaveServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { LocaleService } from "../services/LocaleService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -13,6 +14,9 @@ import { RandomUtil } from "../utils/RandomUtil";
 import { DialogueHelper } from "./DialogueHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProfileHelper } from "./ProfileHelper";
+/**
+ * Helper class for common ragfair server actions
+ */
 export declare class RagfairServerHelper {
     protected randomUtil: RandomUtil;
     protected hashUtil: HashUtil;
@@ -23,11 +27,12 @@ export declare class RagfairServerHelper {
     protected localeService: LocaleService;
     protected dialogueHelper: DialogueHelper;
     protected jsonUtil: JsonUtil;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
     protected static goodsReturnedTemplate: string;
-    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, configServer: ConfigServer);
+    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Is item valid / on blacklist / quest item
      * @param itemDetails
diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/TradeHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/TradeHelper.d.ts
index 975062b..7ab9768 100644
--- a/TypeScript/4UseACustomConfigFile/types/helpers/TradeHelper.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/helpers/TradeHelper.d.ts
@@ -39,6 +39,12 @@ export declare class TradeHelper {
      * @returns
      */
     sellItem(pmcData: IPmcData, body: IProcessSellTradeRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment the assorts buy count by number of items purchased
+     * Show error on screen if player attepts to buy more than what the buy max allows
+     * @param assortBeingPurchased assort being bought
+     * @param itemsPurchasedCount number of items being bought
+     */
     protected incrementAssortBuyCount(assortBeingPurchased: Item, itemsPurchasedCount: number): void;
     protected checkPurchaseIsWithinTraderItemLimit(assortBeingPurchased: Item, assortId: string, count: number): void;
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/TraderAssortHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/TraderAssortHelper.d.ts
index 677dd66..025efd6 100644
--- a/TypeScript/4UseACustomConfigFile/types/helpers/TraderAssortHelper.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/helpers/TraderAssortHelper.d.ts
@@ -1,6 +1,5 @@
 import { RagfairAssortGenerator } from "../generators/RagfairAssortGenerator";
 import { RagfairOfferGenerator } from "../generators/RagfairOfferGenerator";
-import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ITrader, ITraderAssort } from "../models/eft/common/tables/ITrader";
 import { ITraderConfig } from "../models/spt/config/ITraderConfig";
@@ -41,12 +40,7 @@ export declare class TraderAssortHelper {
      * @param traderId traders id
      * @returns a traders' assorts
      */
-    getAssort(sessionId: string, traderId: string): ITraderAssort;
-    /**
-     * if the fence assorts have expired, re-generate them
-     * @param pmcProfile Players profile
-     */
-    refreshFenceAssortIfExpired(pmcProfile: IPmcData): void;
+    getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort;
     /**
      * Reset a traders assorts and move nextResupply value to future
      * Flag trader as needing a flea offer reset to be picked up by flea update() function
diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/TraderHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/TraderHelper.d.ts
index 6bda5cd..0dc93e8 100644
--- a/TypeScript/4UseACustomConfigFile/types/helpers/TraderHelper.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/helpers/TraderHelper.d.ts
@@ -65,7 +65,7 @@ export declare class TraderHelper {
      * @param item
      * @returns boolean
      */
-    protected isWeaponAndBelowTraderBuyDurability(traderID: string, item: Item): boolean;
+    protected isWeaponBelowTraderBuyDurability(traderID: string, item: Item): boolean;
     /**
      * Get the price of an item and all of its attached children
      * Take into account bonuses/adjsutments e.g. discounts
diff --git a/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/ITemplateItem.d.ts b/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/ITemplateItem.d.ts
index 23a1a14..6b2fa8f 100644
--- a/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/ITemplateItem.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/ITemplateItem.d.ts
@@ -34,6 +34,7 @@ export interface Props {
     LootExperience?: number;
     ExamineExperience?: number;
     HideEntrails?: boolean;
+    InsuranceDisabled?: boolean;
     RepairCost?: number;
     RepairSpeed?: number;
     ExtraSizeLeft?: number;
@@ -206,6 +207,7 @@ export interface Props {
     IsOneoff?: boolean;
     MustBoltBeOpennedForExternalReload?: boolean;
     MustBoltBeOpennedForInternalReload?: boolean;
+    NoFiremodeOnBoltcatch?: boolean;
     BoltAction?: boolean;
     HipAccuracyRestorationDelay?: number;
     HipAccuracyRestorationSpeed?: number;
diff --git a/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/ITrader.d.ts b/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/ITrader.d.ts
index a84f5af..37b2d61 100644
--- a/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/ITrader.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/ITrader.d.ts
@@ -67,6 +67,7 @@ export interface IBarterScheme {
     count: number;
     _tpl: string;
     onlyFunctional?: boolean;
+    sptQuestLocked?: boolean;
 }
 export interface ISuit {
     _id: string;
diff --git a/TypeScript/4UseACustomConfigFile/types/models/eft/ragfair/IRagfairOffer.d.ts b/TypeScript/4UseACustomConfigFile/types/models/eft/ragfair/IRagfairOffer.d.ts
index 63f655e..141b605 100644
--- a/TypeScript/4UseACustomConfigFile/types/models/eft/ragfair/IRagfairOffer.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/models/eft/ragfair/IRagfairOffer.d.ts
@@ -15,6 +15,8 @@ export interface IRagfairOffer {
     name?: string;
     shortName?: string;
     loyaltyLevel: number;
+    buyRestrictionMax?: number;
+    buyRestrictionCurrent?: number;
     locked: boolean;
     unlimitedCount: boolean;
     summaryCost: number;
diff --git a/TypeScript/4UseACustomConfigFile/types/models/enums/AmmoTypes.d.ts b/TypeScript/4UseACustomConfigFile/types/models/enums/AmmoTypes.d.ts
index b52ddcf..254b410 100644
--- a/TypeScript/4UseACustomConfigFile/types/models/enums/AmmoTypes.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/models/enums/AmmoTypes.d.ts
@@ -23,7 +23,7 @@ export declare enum Ammo762x54 {
     BT_GZH = "5e023d34e8a400319a28ed44",
     BS_GZH = "5e023d48186a883be655e551"
 }
-export declare enum Ammo338Lapua {
+export declare enum Ammo86x70 {
     TAC_X = "5fc382b6d6fa9c00c571bbc3",
     UCW = "5fc382c1016cce60e8341b20",
     AP = "5fc382a9d724d907e2077dab",
@@ -85,13 +85,13 @@ export declare enum Ammo9x21 {
     PE_GZH = "5a26ac06c4a282000c5a90a8",
     BT_GZH = "5a26ac0ec4a28200741e1e18"
 }
-export declare enum Ammo357Mag {
+export declare enum Ammo9x33R {
     FMJ = "62330b3ed4dc74626d570b95",
     HOLLOW_POINT = "62330bfadc5883093563729b",
     SOFT_POINT = "62330c40bdd19b369e1e53d1",
     JACKET_HP = "62330c18744e5e31df12f516"
 }
-export declare enum Ammo45ACP {
+export declare enum Ammo1143x23ACP {
     MATCH_FMJ = "5e81f423763d9f754677bf2e",
     HYDRA_SHOK = "5efb0fc6aeb21837e749c801",
     LASERMATCH_FMJ = "5efb0d4f4bc50b58e81710f3",
@@ -126,7 +126,7 @@ export declare enum Ammo556x45 {
     MK_318_MOD_0_SOST = "60194943740c5d77f6705eea",
     SSA_AP = "601949593ae8f707c4608daa"
 }
-export declare enum Ammo300Blackout {
+export declare enum Ammo762x35 {
     M62_TRACER = "619636be6db0f2477964e710",
     BCP_FMJ = "5fbe3ffdf8b6a877a729ea82",
     AP = "5fd20ff893a8961fc660a954",
diff --git a/TypeScript/4UseACustomConfigFile/types/models/enums/BaseClasses.d.ts b/TypeScript/4UseACustomConfigFile/types/models/enums/BaseClasses.d.ts
index e733bca..37c1398 100644
--- a/TypeScript/4UseACustomConfigFile/types/models/enums/BaseClasses.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/models/enums/BaseClasses.d.ts
@@ -68,6 +68,7 @@ export declare enum BaseClasses {
     ASSAULT_SCOPE = "55818add4bdc2d5b648b456f",
     REFLEX_SIGHT = "55818ad54bdc2ddc698b4569",
     TACTICAL_COMBO = "55818b164bdc2ddc698b456c",
+    FLASHLIGHT = "55818b084bdc2d5b648b4571",
     MAGAZINE = "5448bc234bdc2d3c308b4569",
     LIGHT_LASER = "55818b0e4bdc2dde698b456e",
     FLASH_HIDER = "550aa4bf4bdc2dd6348b456b",
diff --git a/TypeScript/4UseACustomConfigFile/types/models/enums/ConfigTypes.d.ts b/TypeScript/4UseACustomConfigFile/types/models/enums/ConfigTypes.d.ts
index 61d6f99..468ece5 100644
--- a/TypeScript/4UseACustomConfigFile/types/models/enums/ConfigTypes.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/models/enums/ConfigTypes.d.ts
@@ -8,6 +8,7 @@ export declare enum ConfigTypes {
     IN_RAID = "aki-inraid",
     INSURANCE = "aki-insurance",
     INVENTORY = "aki-inventory",
+    ITEM = "aki-item",
     LOCALE = "aki-locale",
     LOCATION = "aki-location",
     MATCH = "aki-match",
diff --git a/TypeScript/4UseACustomConfigFile/types/models/enums/ELocationName.d.ts b/TypeScript/4UseACustomConfigFile/types/models/enums/ELocationName.d.ts
index b56cc08..7ae7caa 100644
--- a/TypeScript/4UseACustomConfigFile/types/models/enums/ELocationName.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/models/enums/ELocationName.d.ts
@@ -1,5 +1,6 @@
 export declare enum ELocationName {
     FACTORY_DAY = "factory4_day",
+    FACTORY_NIGHT = "factory4_night",
     BIGMAP = "bigmap",
     WOODS = "Woods",
     SHORELINE = "Shoreline",
diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IBotConfig.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IBotConfig.d.ts
index e171087..f15fa73 100644
--- a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IBotConfig.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IBotConfig.d.ts
@@ -1,17 +1,31 @@
 import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
+import { IBotDurability } from "./IBotDurability";
+import { IPmcConfig } from "./IPmcConfig";
 export interface IBotConfig extends IBaseConfig {
     kind: "aki-bot";
+    /** How many variants of each bot should be generated on raid start */
     presetBatch: PresetBatch;
+    /** What bot types should be classified as bosses */
     bosses: string[];
-    durability: Durability;
+    /** Control weapon/armor durability min/max values for each bot type */
+    durability: IBotDurability;
+    /** Control the weighting of how expensive an average loot item is on a PMC or Scav */
     lootNValue: LootNvalue;
+    /** Control what bots are added to a bots revenge list key: bottype, value: bottypes to revenge on seeing their death */
     revenge: Record<string, string[]>;
-    pmc: PmcConfig;
+    /** PMC bot specific config settings */
+    pmc: IPmcConfig;
+    /** Control how many items are allowed to spawn on a bot
+     * key: bottype, value: <key: itemTpl: value: max item count> */
     itemSpawnLimits: Record<string, Record<string, number>>;
-    equipment: Record<string, Equipment>;
+    /** Blacklist/whitelist items on a bot */
+    equipment: Record<string, EquipmentFilters>;
+    /** Show a bots botType value after their name */
     showTypeInNickname: boolean;
+    /** Max number of bots that can be spawned in a raid at any one time */
     maxBotCap: number;
+    /** How many stacks of secret ammo should a bot have in its bot secure container */
     secureContainerAmmoStackCount: number;
 }
 export interface PresetBatch {
@@ -44,79 +58,22 @@ export interface PresetBatch {
     test: number;
     exUsec: number;
 }
-export interface Durability {
-    default: DefaultDurability;
-    pmc: PmcDurability;
-    boss: BotDurability;
-    follower: BotDurability;
-    assault: BotDurability;
-    cursedassault: BotDurability;
-    marksman: BotDurability;
-    pmcbot: BotDurability;
-    exusec: BotDurability;
-    sectantpriest: BotDurability;
-    sectantwarrior: BotDurability;
-}
-export interface DefaultDurability {
-    armor: DefaultArmor;
-    weapon: WeaponDurability;
-}
-export interface DefaultArmor {
-    maxDelta: number;
-    minDelta: number;
-}
-export interface WeaponDurability {
-    lowestMax: number;
-    highestMax: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface PmcDurability {
-    armor: PmcDurabilityArmor;
-    weapon: WeaponDurability;
-}
-export interface PmcDurabilityArmor {
-    lowestMaxPercent: number;
-    highestMaxPercent: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface BotDurability {
-    armor: ArmorDurability;
-    weapon: WeaponDurability;
-}
-export interface ArmorDurability {
-    maxDelta: number;
-    minDelta: number;
-}
 export interface LootNvalue {
     scav: number;
     pmc: number;
 }
-export interface PmcConfig {
-    dynamicLoot: PmcDynamicLoot;
-    difficulty: string;
-    looseWeaponInBackpackChancePercent: number;
-    looseWeaponInBackpackLootMinMax: MinMax;
-    isUsec: number;
-    chanceSameSideIsHostilePercent: number;
-    usecType: string;
-    bearType: string;
-    maxBackpackLootTotalRub: number;
-    maxPocketLootTotalRub: number;
-    maxVestLootTotalRub: number;
-    convertIntoPmcChance: Record<string, MinMax>;
-    enemyTypes: string[];
-}
-export interface PmcDynamicLoot {
-    whitelist: string[];
-    blacklist: string[];
-    moneyStackLimits: Record<string, number>;
-}
-export interface Equipment {
+export interface EquipmentFilters {
+    weaponModLimits: ModLimits;
+    randomisedWeaponModSlots?: string[];
     blacklist: EquipmentFilterDetails[];
     whitelist: EquipmentFilterDetails[];
 }
+export interface ModLimits {
+    /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */
+    scopeLimit?: number;
+    /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */
+    lightLaserLimit?: number;
+}
 export interface EquipmentFilterDetails {
     levelRange: MinMax;
     equipment: Record<string, string[]>;
diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IBotDurability.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IBotDurability.d.ts
new file mode 100644
index 0000000..38a47cc
--- /dev/null
+++ b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IBotDurability.d.ts
@@ -0,0 +1,47 @@
+export interface IBotDurability {
+    default: DefaultDurability;
+    pmc: PmcDurability;
+    boss: BotDurability;
+    follower: BotDurability;
+    assault: BotDurability;
+    cursedassault: BotDurability;
+    marksman: BotDurability;
+    pmcbot: BotDurability;
+    exusec: BotDurability;
+    gifter: BotDurability;
+    sectantpriest: BotDurability;
+    sectantwarrior: BotDurability;
+}
+/** Durability values to be used when a more specific bot type cant be found */
+export interface DefaultDurability {
+    armor: DefaultArmor;
+    weapon: WeaponDurability;
+}
+export interface DefaultArmor {
+    maxDelta: number;
+    minDelta: number;
+}
+export interface WeaponDurability {
+    lowestMax: number;
+    highestMax: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface PmcDurability {
+    armor: PmcDurabilityArmor;
+    weapon: WeaponDurability;
+}
+export interface PmcDurabilityArmor {
+    lowestMaxPercent: number;
+    highestMaxPercent: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface BotDurability {
+    armor: ArmorDurability;
+    weapon: WeaponDurability;
+}
+export interface ArmorDurability {
+    maxDelta: number;
+    minDelta: number;
+}
diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IItemConfig.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IItemConfig.d.ts
new file mode 100644
index 0000000..5ecccc2
--- /dev/null
+++ b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IItemConfig.d.ts
@@ -0,0 +1,5 @@
+import { IBaseConfig } from "./IBaseConfig";
+export interface IItemConfig extends IBaseConfig {
+    kind: "aki-item";
+    blacklist: string[];
+}
diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IPmcConfig.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IPmcConfig.d.ts
new file mode 100644
index 0000000..655b58d
--- /dev/null
+++ b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IPmcConfig.d.ts
@@ -0,0 +1,22 @@
+import { MinMax } from "../../common/MinMax";
+export interface IPmcConfig {
+    dynamicLoot: DynamicLoot;
+    useDifficultyOverride: boolean;
+    difficulty: string;
+    looseWeaponInBackpackChancePercent: number;
+    looseWeaponInBackpackLootMinMax: MinMax;
+    isUsec: number;
+    chanceSameSideIsHostilePercent: number;
+    usecType: string;
+    bearType: string;
+    maxBackpackLootTotalRub: number;
+    maxPocketLootTotalRub: number;
+    maxVestLootTotalRub: number;
+    convertIntoPmcChance: Record<string, MinMax>;
+    enemyTypes: string[];
+}
+export interface DynamicLoot {
+    whitelist: string[];
+    blacklist: string[];
+    moneyStackLimits: Record<string, number>;
+}
diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IQuestConfig.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IQuestConfig.d.ts
index be4a97b..45c9aae 100644
--- a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IQuestConfig.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IQuestConfig.d.ts
@@ -4,6 +4,8 @@ export interface IQuestConfig extends IBaseConfig {
     kind: "aki-quest";
     redeemTime: number;
     repeatableQuests: IRepeatableQuestConfig[];
+    bearOnlyQuests: string[];
+    usecOnlyQuests: string[];
 }
 export interface IRepeatableQuestConfig {
     name: string;
@@ -15,6 +17,10 @@ export interface IRepeatableQuestConfig {
     locations: Record<ELocationName, string[]>;
     traderWhitelist: ITraderWhitelist[];
     questConfig: IQuestConfig;
+    /** Item base types to block when generating rewards */
+    rewardBaseTypeBlacklist: string[];
+    /** Item tplIds to ignore when generating rewards */
+    rewardBlacklist: string[];
 }
 export interface IRewardScaling {
     levels: number[];
diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IRagfairConfig.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IRagfairConfig.d.ts
index 6369eda..3088717 100644
--- a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IRagfairConfig.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IRagfairConfig.d.ts
@@ -12,6 +12,7 @@ export interface Sell {
     chance: Chance;
     time: Time;
     reputation: Reputation;
+    simulatedSellHours: number;
 }
 export interface Chance {
     base: number;
diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/config/ITraderConfig.d.ts
index c8e8044..6b1c1e3 100644
--- a/TypeScript/4UseACustomConfigFile/types/models/spt/config/ITraderConfig.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/models/spt/config/ITraderConfig.d.ts
@@ -12,8 +12,10 @@ export interface UpdateTime {
     seconds: number;
 }
 export interface FenceConfig {
+    partialRefreshTimeSeconds: number;
+    partialRefreshChangePercent: number;
     assortSize: number;
-    maxPresetsCount: number;
+    maxPresetsPercent: number;
     presetPriceMult: number;
     blacklist: string[];
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/services/LootItem.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/services/LootItem.d.ts
new file mode 100644
index 0000000..2838472
--- /dev/null
+++ b/TypeScript/4UseACustomConfigFile/types/models/spt/services/LootItem.d.ts
@@ -0,0 +1,5 @@
+export declare class LootItem {
+    tpl: string;
+    isPreset: boolean;
+    stackCount: number;
+}
diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/services/LootRequest.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/4UseACustomConfigFile/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/4UseACustomConfigFile/types/services/BotEquipmentFilterService.d.ts b/TypeScript/4UseACustomConfigFile/types/services/BotEquipmentFilterService.d.ts
index e49645b..632f961 100644
--- a/TypeScript/4UseACustomConfigFile/types/services/BotEquipmentFilterService.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/services/BotEquipmentFilterService.d.ts
@@ -1,12 +1,12 @@
 import { IBotType } from "../models/eft/common/tables/IBotType";
-import { Equipment, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 export declare class BotEquipmentFilterService {
     protected logger: ILogger;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    protected botEquipmentFilterlists: Record<string, Equipment>;
+    protected botEquipmentFilterlists: Record<string, EquipmentFilters>;
     constructor(logger: ILogger, configServer: ConfigServer);
     /**
      * Filter a bots data to exclude equipment and cartridges defines in the botConfig
@@ -22,7 +22,7 @@ export declare class BotEquipmentFilterService {
      * @param playerLevel Level of the player
      * @returns EquipmentBlacklistDetails object
      */
-    protected getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
+    getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
     /**
      * Get the whitelist for a specific bot type that's within the players level
      * @param botRole Bot type
diff --git a/TypeScript/4UseACustomConfigFile/types/services/FenceService.d.ts b/TypeScript/4UseACustomConfigFile/types/services/FenceService.d.ts
index c9e325e..c940507 100644
--- a/TypeScript/4UseACustomConfigFile/types/services/FenceService.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/services/FenceService.d.ts
@@ -12,6 +12,11 @@ import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+import { ItemFilterService } from "./ItemFilterService";
+/**
+ * Handle actions surrounding Fence
+ * e.g. generating or refreshing assorts / get next refresh time
+ */
 export declare class FenceService {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
@@ -22,18 +27,64 @@ export declare class FenceService {
     protected handbookHelper: HandbookHelper;
     protected itemHelper: ItemHelper;
     protected presetHelper: PresetHelper;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected fenceAssort: ITraderAssort;
     protected traderConfig: ITraderConfig;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, configServer: ConfigServer);
+    protected nextMiniRefreshTimestamp: number;
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, itemFilterService: ItemFilterService, configServer: ConfigServer);
     protected setFenceAssort(fenceAssort: ITraderAssort): void;
-    getFenceAssorts(): ITraderAssort;
+    /**
+     * Get assorts player can purchase
+     * Adjust prices based on fence level of player
+     * @param pmcProfile Player profile
+     * @returns ITraderAssort
+     */
+    getFenceAssorts(pmcProfile: IPmcData): ITraderAssort;
+    /**
+     * Get fence assorts with no price adjustments based on fence rep
+     * @returns ITraderAssort
+     */
+    getRawFenceAssorts(): ITraderAssort;
+    /**
+     * Does fence need to perform a partial refresh because its passed the refresh timer defined in trader.json
+     * @returns true if it needs a partial refresh
+     */
+    needsPartialRefresh(): boolean;
+    /**
+     * Replace a percentage of fence assorts with freshly generated items
+     */
+    performPartialRefresh(): void;
+    /**
+     * Choose an item (not mod) at random and remove from assorts
+     */
+    protected removeRandomItemFromAssorts(): void;
+    /**
+     * Get an integer rounded count of items to replace based on percentrage from traderConfig value
+     * @param totalItemCount total item count
+     * @returns rounded int of items to replace
+     */
+    protected getCountOfItemsToReplace(totalItemCount: number): number;
     /**
      * Get the count of items fence offers
      * @returns number
      */
     getOfferCount(): number;
-    generateFenceAssortCache(pmcData: IPmcData): void;
+    /**
+     * Create a trader assort for fence
+     */
+    generateFenceAssortCache(): void;
+    /**
+     * Create skeleton to hold assort items
+     * @returns ITraderAssort object
+     */
+    protected createBaseTraderAssortItem(): ITraderAssort;
+    /**
+     * Hydrate result parameter object with generated assorts
+     * @param assortCount Number of assorts to generate
+     * @param assorts object to add assorts to
+     */
+    protected createAssorts(assortCount: number, assorts: ITraderAssort): void;
     /**
      * Get the next update timestamp for fence
      * @returns future timestamp
@@ -44,11 +95,14 @@ export declare class FenceService {
      */
     protected getFenceRefreshTime(): number;
     /**
-     * Get the fence level the passed in profile has
+     * Get fence level the passed in profile has
      * @param pmcData Player profile
-     * @returns FenceLevel
+     * @returns FenceLevel object
      */
     getFenceInfo(pmcData: IPmcData): FenceLevel;
+    /**
+     * Remove an assort from fence by id
+     * @param assortIdToRemove assort id to remove from fence assorts
+     */
     removeFenceOffer(assortIdToRemove: string): void;
-    updateFenceOffers(pmcData: IPmcData): void;
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/services/InsuranceService.d.ts b/TypeScript/4UseACustomConfigFile/types/services/InsuranceService.d.ts
index 171bf10..6be8a2f 100644
--- a/TypeScript/4UseACustomConfigFile/types/services/InsuranceService.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/services/InsuranceService.d.ts
@@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
 import { SecureContainerHelper } from "../helpers/SecureContainerHelper";
 import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
+import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData";
 import { IInsuranceConfig } from "../models/spt/config/IInsuranceConfig";
@@ -44,8 +45,22 @@ export declare class InsuranceService {
      * @param mapId Id of the map player died/exited that caused the insurance to be issued on
      */
     sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void;
+    /**
+     * Store lost gear post-raid inside profile
+     * @param pmcData player profile to store gear in
+     * @param offraidData post-raid request object
+     * @param preRaidGear gear player wore prior to raid
+     * @param sessionID Session id
+     */
     storeLostGear(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
     storeInsuredItemsForReturn(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
-    protected addGearToSend(pmcData: IPmcData, insuredItem: any, actualItem: any, sessionID: string): any;
+    /**
+     * Add gear item to InsuredItems array in player profile
+     * @param pmcData profile to store item in
+     * @param insuredItem Item to store in profile
+     * @param actualItem item to store
+     * @param sessionID Session id
+     */
+    protected addGearToSend(pmcData: IPmcData, insuredItem: InsuredItem, actualItem: Item, sessionID: string): void;
     getPremium(pmcData: IPmcData, inventoryItem: Item, traderId: string): number;
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/services/ItemFilterService.d.ts b/TypeScript/4UseACustomConfigFile/types/services/ItemFilterService.d.ts
new file mode 100644
index 0000000..c9c8ef3
--- /dev/null
+++ b/TypeScript/4UseACustomConfigFile/types/services/ItemFilterService.d.ts
@@ -0,0 +1,24 @@
+import { IItemConfig } from "../models/spt/config/IItemConfig";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+/** Centralise the handling of blacklisting items, uses blacklist found in config/item.json */
+export declare class ItemFilterService {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected configServer: ConfigServer;
+    protected blacklist: string[];
+    protected itemConfig: IItemConfig;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer);
+    /**
+     * Check if the provided template id is blacklisted in config/item.json
+     * @param tpl template id
+     * @returns true if blacklisted
+     */
+    isItemBlacklisted(tpl: string): boolean;
+    /**
+     * Return every template id blacklisted in config/item.json
+     * @returns string array of blacklisted tempalte ids
+     */
+    getBlacklistedItems(): string[];
+}
diff --git a/TypeScript/4UseACustomConfigFile/types/services/ProfileFixerService.d.ts b/TypeScript/4UseACustomConfigFile/types/services/ProfileFixerService.d.ts
index ed1dec7..9cb5a38 100644
--- a/TypeScript/4UseACustomConfigFile/types/services/ProfileFixerService.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/services/ProfileFixerService.d.ts
@@ -45,6 +45,11 @@ export declare class ProfileFixerService {
      * @param pmcProfile Profile to find and remove slots from
      */
     protected removeResourcesFromSlotsInHideoutWithoutLocationIndexValue(pmcProfile: IPmcData): void;
+    /**
+     * Hideout slots need to be in a specific order, locationIndex in ascending order
+     * @param pmcProfile profile to edit
+     */
+    protected reorderHideoutAreasWithResouceInputs(pmcProfile: IPmcData): void;
     /**
      * add in objects equal to the number of slots
      * @param areaType area to check
diff --git a/TypeScript/4UseACustomConfigFile/types/utils/HashUtil.d.ts b/TypeScript/4UseACustomConfigFile/types/utils/HashUtil.d.ts
index bacbf2a..a8500e1 100644
--- a/TypeScript/4UseACustomConfigFile/types/utils/HashUtil.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/utils/HashUtil.d.ts
@@ -4,8 +4,18 @@ import { TimeUtil } from "./TimeUtil";
 export declare class HashUtil {
     protected timeUtil: TimeUtil;
     constructor(timeUtil: TimeUtil);
+    /**
+     * Create a 24 character id using the sha256 algorithm + current timestamp
+     * @returns 24 character hash
+     */
     generate(): string;
     generateMd5ForData(data: string): string;
     generateSha1ForData(data: string): string;
+    /**
+     * Create a hash for the data parameter
+     * @param algorithm algorithm to use to hash
+     * @param data data to be hashed
+     * @returns hash value
+     */
     generateHashForData(algorithm: string, data: crypto.BinaryLike): string;
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/utils/RandomUtil.d.ts b/TypeScript/4UseACustomConfigFile/types/utils/RandomUtil.d.ts
index c24dd60..e35d21f 100644
--- a/TypeScript/4UseACustomConfigFile/types/utils/RandomUtil.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/utils/RandomUtil.d.ts
@@ -150,4 +150,10 @@ export declare class RandomUtil {
      */
     drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[];
     getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number;
+    /**
+     * Fisher-Yates shuffle an array
+     * @param array Array to shuffle
+     * @returns Shuffled array
+     */
+    shuffle<T>(array: Array<T>): Array<T>;
 }
diff --git a/TypeScript/4UseACustomConfigFile/types/utils/TimeUtil.d.ts b/TypeScript/4UseACustomConfigFile/types/utils/TimeUtil.d.ts
index f437f8a..1367e26 100644
--- a/TypeScript/4UseACustomConfigFile/types/utils/TimeUtil.d.ts
+++ b/TypeScript/4UseACustomConfigFile/types/utils/TimeUtil.d.ts
@@ -1,3 +1,6 @@
+/**
+ * Utility class to handle time related problems
+ */
 export declare class TimeUtil {
     static readonly oneHourAsSeconds = 3600;
     formatTime(date: Date): string;
@@ -19,4 +22,10 @@ export declare class TimeUtil {
      * @returns current date in format: 00.00.0000 (dd.mm.yyyy)
      */
     getDateMailFormat(): string;
+    /**
+     * Convert hours into seconds
+     * @param hours hours to convert to seconds
+     * @returns number
+     */
+    getHoursAsSeconds(hours: number): number;
 }
diff --git a/TypeScript/5ReplaceMethod/types/callbacks/LocationCallbacks.d.ts b/TypeScript/5ReplaceMethod/types/callbacks/LocationCallbacks.d.ts
index cc69369..6e0b538 100644
--- a/TypeScript/5ReplaceMethod/types/callbacks/LocationCallbacks.d.ts
+++ b/TypeScript/5ReplaceMethod/types/callbacks/LocationCallbacks.d.ts
@@ -11,4 +11,5 @@ export declare class LocationCallbacks {
     constructor(httpResponse: HttpResponseUtil, locationController: LocationController);
     getLocationData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<ILocationsGenerateAllResponse>;
     getLocation(url: string, info: IGetLocationRequestData, sessionID: string): IGetBodyResponseData<ILocationBase>;
+    getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): string;
 }
diff --git a/TypeScript/5ReplaceMethod/types/callbacks/ProfileCallbacks.d.ts b/TypeScript/5ReplaceMethod/types/callbacks/ProfileCallbacks.d.ts
index 6a86fc0..183bb0a 100644
--- a/TypeScript/5ReplaceMethod/types/callbacks/ProfileCallbacks.d.ts
+++ b/TypeScript/5ReplaceMethod/types/callbacks/ProfileCallbacks.d.ts
@@ -1,5 +1,6 @@
 import { ProfileController } from "../controllers/ProfileController";
 import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData";
+import { IPmcData } from "../models/eft/common/IPmcData";
 import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData";
 import { INullResponseData } from "../models/eft/httpResponse/INullResponseData";
 import { IGetMiniProfileRequestData } from "../models/eft/launcher/IGetMiniProfileRequestData";
@@ -12,20 +13,51 @@ import { ISearchFriendResponse } from "../models/eft/profile/ISearchFriendRespon
 import { IValidateNicknameRequestData } from "../models/eft/profile/IValidateNicknameRequestData";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/** Handle profile related client events */
 export declare class ProfileCallbacks {
     protected httpResponse: HttpResponseUtil;
     protected timeUtil: TimeUtil;
     protected profileController: ProfileController;
     constructor(httpResponse: HttpResponseUtil, timeUtil: TimeUtil, profileController: ProfileController);
     createProfile(url: string, info: IProfileCreateRequestData, sessionID: string): IGetBodyResponseData<any>;
-    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
-    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
+    /**
+     * Get the complete player profile (scav + pmc character)
+     * @param url
+     * @param info Empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle the creation of a scav profile for player
+     * Occurs post-raid and when profile first created immediately after character details are confirmed by player
+     * @param url
+     * @param info empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle client/game/profile/voice/change event
+     * @param url
+     * @param info Change voice request object
+     * @param sessionID Session id
+     * @returns Client response
+     */
     changeVoice(url: string, info: IProfileChangeVoiceRequestData, sessionID: string): INullResponseData;
+    /**
+     * Handle client/game/profile/nickname/change event
+     * Client allows player to adjust their profile name
+     * @param url
+     * @param info Change nickname request object
+     * @param sessionID Session id
+     * @returns client response
+     */
     changeNickname(url: string, info: IProfileChangeNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     validateNickname(url: string, info: IValidateNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     getReservedNickname(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<string>;
     /**
-     * Called when creating a character, when you choose a character face/voice
+     * Called when creating a character when choosing a character face/voice
      * @param url
      * @param info response (empty)
      * @param sessionID
diff --git a/TypeScript/5ReplaceMethod/types/callbacks/RagfairCallbacks.d.ts b/TypeScript/5ReplaceMethod/types/callbacks/RagfairCallbacks.d.ts
index 3a405c9..c609f2f 100644
--- a/TypeScript/5ReplaceMethod/types/callbacks/RagfairCallbacks.d.ts
+++ b/TypeScript/5ReplaceMethod/types/callbacks/RagfairCallbacks.d.ts
@@ -19,6 +19,9 @@ import { ConfigServer } from "../servers/ConfigServer";
 import { RagfairServer } from "../servers/RagfairServer";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+/**
+ * Handle ragfair related callback events
+ */
 export declare class RagfairCallbacks extends OnLoadOnUpdate {
     protected httpResponse: HttpResponseUtil;
     protected logger: ILogger;
diff --git a/TypeScript/5ReplaceMethod/types/controllers/InraidController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/InraidController.d.ts
index 82bb64d..102a2fb 100644
--- a/TypeScript/5ReplaceMethod/types/controllers/InraidController.d.ts
+++ b/TypeScript/5ReplaceMethod/types/controllers/InraidController.d.ts
@@ -35,6 +35,30 @@ export declare class InraidController {
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer);
     addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void;
     saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Handle updating the profile post-pmc raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Reduce body part hp to % of max
+     * @param pmcData profile to edit
+     * @param multipler multipler to apply to max health
+     */
+    protected reducePmcHealthToPercent(pmcData: IPmcData, multipler: number): void;
+    /**
+     * Handle updating the profile post-pscav raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePlayerScavProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Is the player dead after a raid - dead is anything other than "survived" / "runner"
+     * @param statusOnExit exit value from offraidData object
+     * @returns true if dead
+     */
+    protected isPlayerDead(statusOnExit: string): boolean;
     /**
      * Mark inventory items as FiR if player survived raid, otherwise remove FiR from them
      * @param offraidData Save Progress Request
diff --git a/TypeScript/5ReplaceMethod/types/controllers/InventoryController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/InventoryController.d.ts
index f57f731..f564919 100644
--- a/TypeScript/5ReplaceMethod/types/controllers/InventoryController.d.ts
+++ b/TypeScript/5ReplaceMethod/types/controllers/InventoryController.d.ts
@@ -92,7 +92,11 @@ export declare class InventoryController {
      */
     toggleItem(pmcData: IPmcData, body: IInventoryToggleRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Handles Tagging of items (primary Containers).
+     * Add a tag to an inventory item
+     * @param pmcData profile with item to add tag to
+     * @param body tag request data
+     * @param sessionID session id
+     * @returns client response object
      */
     tagItem(pmcData: IPmcData, body: IInventoryTagRequestData, sessionID: string): IItemEventRouterResponse;
     bindItem(pmcData: IPmcData, body: IInventoryBindRequestData, sessionID: string): IItemEventRouterResponse;
diff --git a/TypeScript/5ReplaceMethod/types/controllers/LocationController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/LocationController.d.ts
index 90b6d7a..9db3205 100644
--- a/TypeScript/5ReplaceMethod/types/controllers/LocationController.d.ts
+++ b/TypeScript/5ReplaceMethod/types/controllers/LocationController.d.ts
@@ -1,18 +1,33 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class LocationController {
     protected jsonUtil: JsonUtil;
+    protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/5ReplaceMethod/types/controllers/MatchController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/MatchController.d.ts
index e8585d9..cb40023 100644
--- a/TypeScript/5ReplaceMethod/types/controllers/MatchController.d.ts
+++ b/TypeScript/5ReplaceMethod/types/controllers/MatchController.d.ts
@@ -9,6 +9,7 @@ import { IGetProfileRequestData } from "../models/eft/match/IGetProfileRequestDa
 import { IJoinMatchRequestData } from "../models/eft/match/IJoinMatchRequestData";
 import { IJoinMatchResult } from "../models/eft/match/IJoinMatchResult";
 import { IStartOfflineRaidRequestData } from "../models/eft/match/IStartOffineRaidRequestData";
+import { IBotConfig } from "../models/spt/config/IBotConfig";
 import { IInRaidConfig } from "../models/spt/config/IInRaidConfig";
 import { IMatchConfig } from "../models/spt/config/IMatchConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
@@ -29,6 +30,7 @@ export declare class MatchController {
     protected applicationContext: ApplicationContext;
     protected matchConfig: IMatchConfig;
     protected inraidConfig: IInRaidConfig;
+    protected botConfig: IBotConfig;
     constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, applicationContext: ApplicationContext);
     getEnabled(): boolean;
     getProfile(info: IGetProfileRequestData): IPmcData[];
diff --git a/TypeScript/5ReplaceMethod/types/controllers/QuestController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/QuestController.d.ts
index 2cbccfb..282f50e 100644
--- a/TypeScript/5ReplaceMethod/types/controllers/QuestController.d.ts
+++ b/TypeScript/5ReplaceMethod/types/controllers/QuestController.d.ts
@@ -39,16 +39,31 @@ export declare class QuestController {
      * @returns array of IQuest
      */
     getClientQuests(sessionID: string): IQuest[];
+    /**
+     * Is the quest for the opposite side the player is on
+     * @param side player side (usec/bear)
+     * @param questId questId to check
+     */
+    protected questIsForOtherSide(side: string, questId: string): boolean;
+    /**
+     * Handle the client accepting a quest and starting it
+     * Send starting rewards if any to player and
+     * Send start notification if any to player
+     * @param pmcData Profile to update
+     * @param acceptedQuest Quest accepted
+     * @param sessionID Session id
+     * @returns client response
+     */
     acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Remove completed quest from profile
+     * Update completed quest in profile
      * Add newly unlocked quests to profile
      * Also recalculate thier level due to exp rewards
      * @param pmcData Player profile
-     * @param body completed quest request
-     * @param sessionID session id
-     * @returns ItemEvent response
+     * @param body Completed quest request
+     * @param sessionID Session id
+     * @returns ItemEvent client response
      */
     completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
@@ -67,10 +82,20 @@ export declare class QuestController {
     protected getQuestsFailedByCompletingQuest(completedQuestId: string): IQuest[];
     /**
      * Fail the quests provided
+     * Update quest in profile, otherwise add fresh quest object with failed status
      * @param sessionID session id
      * @param pmcData player profile
      * @param questsToFail quests to fail
      */
     protected failQuests(sessionID: string, pmcData: IPmcData, questsToFail: IQuest[]): void;
     handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment a backend counter stored value by an amount,
+     * Create counter if it does not exist
+     * @param pmcData Profile to find backend counter in
+     * @param conditionId backend counter id to update
+     * @param questId quest id counter is associated with
+     * @param counterValue value to increment the backend counter with
+     */
+    protected updateProfileBackendCounterValue(pmcData: IPmcData, conditionId: string, questId: string, counterValue: number): void;
 }
diff --git a/TypeScript/5ReplaceMethod/types/controllers/RagfairController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/RagfairController.d.ts
index c4ffc15..06af740 100644
--- a/TypeScript/5ReplaceMethod/types/controllers/RagfairController.d.ts
+++ b/TypeScript/5ReplaceMethod/types/controllers/RagfairController.d.ts
@@ -9,6 +9,7 @@ import { RagfairOfferHelper } from "../helpers/RagfairOfferHelper";
 import { RagfairSellHelper } from "../helpers/RagfairSellHelper";
 import { RagfairSortHelper } from "../helpers/RagfairSortHelper";
 import { RagfairTaxHelper } from "../helpers/RagfairTaxHelper";
+import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
@@ -33,6 +34,9 @@ import { RagfairPriceService } from "../services/RagfairPriceService";
 import { RagfairRequiredItemsService } from "../services/RagfairRequiredItemsService";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/**
+ * Handle RagfairCallback events
+ */
 export declare class RagfairController {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
@@ -52,14 +56,20 @@ export declare class RagfairController {
     protected handbookHelper: HandbookHelper;
     protected paymentHelper: PaymentHelper;
     protected inventoryHelper: InventoryHelper;
+    protected traderHelper: TraderHelper;
     protected ragfairHelper: RagfairHelper;
     protected ragfairOfferService: RagfairOfferService;
     protected ragfairRequiredItemsService: RagfairRequiredItemsService;
     protected ragfairOfferGenerator: RagfairOfferGenerator;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
     getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult;
+    /**
+     * Update a trader flea offer with buy restrictions stored in the traders assort
+     * @param offer flea offer to update
+     */
+    protected setTraderOfferPurchaseLimits(offer: IRagfairOffer): void;
     protected isLinkedSearch(info: ISearchRequestData): boolean;
     protected isRequiredSearch(info: ISearchRequestData): boolean;
     update(): void;
diff --git a/TypeScript/5ReplaceMethod/types/controllers/RepeatableQuestController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/RepeatableQuestController.d.ts
index 98d05dd..4c31a3d 100644
--- a/TypeScript/5ReplaceMethod/types/controllers/RepeatableQuestController.d.ts
+++ b/TypeScript/5ReplaceMethod/types/controllers/RepeatableQuestController.d.ts
@@ -7,6 +7,7 @@ import { Exit } from "../models/eft/common/ILocationBase";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { TraderInfo } from "../models/eft/common/tables/IBotBase";
 import { ICompletion, ICompletionAvailableFor, IElimination, IEliminationCondition, IExploration, IExplorationCondition, IPmcDataRepeatableQuest, IRepeatableQuest, IReward, IRewards } from "../models/eft/common/tables/IRepeatableQuests";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
 import { IRepeatableQuestChangeRequest } from "../models/eft/quests/IRepeatableQuestChangeRequest";
 import { ELocationName } from "../models/enums/ELocationName";
@@ -15,6 +16,7 @@ import { ILogger } from "../models/spt/utils/ILogger";
 import { ItemEventRouter } from "../routers/ItemEventRouter";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { PaymentService } from "../services/PaymentService";
 import { ProfileFixerService } from "../services/ProfileFixerService";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -64,9 +66,10 @@ export declare class RepeatableQuestController {
     protected itemEventRouter: ItemEventRouter;
     protected paymentService: PaymentService;
     protected objectId: ObjectId;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
-    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, configServer: ConfigServer);
+    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint
      * Returns an array of objects in the format of repeatable quests to the client.
@@ -217,4 +220,16 @@ export declare class RepeatableQuestController {
     debugLogRepeatableQuestIds(pmcData: IPmcData): void;
     probabilityObjectArray<K, V>(configArrayInput: ProbabilityObject<K, V>[]): ProbabilityObjectArray<K, V>;
     changeRepeatableQuest(pmcDataIn: IPmcData, body: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
+     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
+     */
+    protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig): [string, ITemplateItem][];
+    /**
+     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
+     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
+     * @param {*} tpl template id of item to check
+     * @returns boolean: true if item is valid reward
+     */
+    isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig): boolean;
 }
diff --git a/TypeScript/5ReplaceMethod/types/controllers/TraderController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/TraderController.d.ts
index 0162064..b79f55e 100644
--- a/TypeScript/5ReplaceMethod/types/controllers/TraderController.d.ts
+++ b/TypeScript/5ReplaceMethod/types/controllers/TraderController.d.ts
@@ -4,6 +4,7 @@ import { TraderHelper } from "../helpers/TraderHelper";
 import { IBarterScheme, ITraderAssort, ITraderBase } from "../models/eft/common/tables/ITrader";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { FenceService } from "../services/FenceService";
 import { TraderAssortService } from "../services/TraderAssortService";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
@@ -15,8 +16,9 @@ export declare class TraderController {
     protected traderHelper: TraderHelper;
     protected timeUtil: TimeUtil;
     protected traderAssortService: TraderAssortService;
+    protected fenceService: FenceService;
     protected jsonUtil: JsonUtil;
-    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, jsonUtil: JsonUtil);
+    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, fenceService: FenceService, jsonUtil: JsonUtil);
     /**
      * Runs when onLoad event is fired
      * Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
@@ -26,6 +28,7 @@ export declare class TraderController {
     /**
      * Runs when onUpdate is fired
      * If current time is > nextResupply(expire) time of trader, refresh traders assorts and
+     * Fence is handled slightly differently
      * @returns has run
      */
     update(): boolean;
diff --git a/TypeScript/5ReplaceMethod/types/di/Container.d.ts b/TypeScript/5ReplaceMethod/types/di/Container.d.ts
index 17791b0..98d1fa1 100644
--- a/TypeScript/5ReplaceMethod/types/di/Container.d.ts
+++ b/TypeScript/5ReplaceMethod/types/di/Container.d.ts
@@ -1,4 +1,7 @@
 import { DependencyContainer } from "tsyringe";
+/**
+ * Handle the registration of classes to be used by the Dependency Injection code
+ */
 export declare class Container {
     static registerTypes(depContainer: DependencyContainer): void;
     static registerListTypes(depContainer: DependencyContainer): void;
diff --git a/TypeScript/5ReplaceMethod/types/generators/BotGenerator.d.ts b/TypeScript/5ReplaceMethod/types/generators/BotGenerator.d.ts
index a5fc0ad..7d58f95 100644
--- a/TypeScript/5ReplaceMethod/types/generators/BotGenerator.d.ts
+++ b/TypeScript/5ReplaceMethod/types/generators/BotGenerator.d.ts
@@ -40,7 +40,7 @@ export declare class BotGenerator {
      * @param botTemplate base bot template to use  (e.g. assault/pmcbot)
      * @returns
      */
-    generatePlayerScav(role: string, difficulty: string, botTemplate: IBotType): IBotBase;
+    generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase;
     generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[];
     /**
      * Choose if a bot should become a PMC by checking if bot type is allowed to become a Pmc in botConfig.convertFromChances and doing a random int check
@@ -58,7 +58,7 @@ export declare class BotGenerator {
      * @returns IBotBase object
      */
     protected getCloneOfBotBase(): IBotBase;
-    protected generateBot(bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
+    protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
     /**
      * Log the number of PMCs generated to the debug console
      */
diff --git a/TypeScript/5ReplaceMethod/types/generators/BotInventoryGenerator.d.ts b/TypeScript/5ReplaceMethod/types/generators/BotInventoryGenerator.d.ts
index 35d1ee8..73f8ece 100644
--- a/TypeScript/5ReplaceMethod/types/generators/BotInventoryGenerator.d.ts
+++ b/TypeScript/5ReplaceMethod/types/generators/BotInventoryGenerator.d.ts
@@ -18,7 +18,7 @@ export declare class BotInventoryGenerator {
     protected botGeneratorHelper: BotGeneratorHelper;
     protected weightedRandomHelper: WeightedRandomHelper;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper);
-    generateInventory(templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
+    generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
     protected generateEquipment(equipmentSlot: string, equipmentPool: Record<string, number>, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void;
     protected generateInventoryBase(): PmcInventory;
 }
diff --git a/TypeScript/5ReplaceMethod/types/generators/BotLootGenerator.d.ts b/TypeScript/5ReplaceMethod/types/generators/BotLootGenerator.d.ts
index c6a3f29..5a2d144 100644
--- a/TypeScript/5ReplaceMethod/types/generators/BotLootGenerator.d.ts
+++ b/TypeScript/5ReplaceMethod/types/generators/BotLootGenerator.d.ts
@@ -24,7 +24,7 @@ export declare class BotLootGenerator {
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botLootCacheService: BotLootCacheService, configServer: ConfigServer);
-    generateLoot(templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
+    generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
     protected getRandomisedCount(min: number, max: number, nValue: number): number;
     /**
      * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached
@@ -47,7 +47,7 @@ export declare class BotLootGenerator {
      * @param botRole bots role, .e.g. pmcBot
      * @param isPmc are we generating for a pmc
      */
-    protected addLooseWeaponsToInventorySlot(botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
+    protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
     /**
      * Get a random item from the pool parameter using the biasedRandomNumber system
      * @param pool pool of items to pick an item from
diff --git a/TypeScript/5ReplaceMethod/types/generators/BotWeaponGenerator.d.ts b/TypeScript/5ReplaceMethod/types/generators/BotWeaponGenerator.d.ts
index 9215214..49fa7bf 100644
--- a/TypeScript/5ReplaceMethod/types/generators/BotWeaponGenerator.d.ts
+++ b/TypeScript/5ReplaceMethod/types/generators/BotWeaponGenerator.d.ts
@@ -28,7 +28,18 @@ export declare class BotWeaponGenerator {
     protected botConfig: IBotConfig;
     constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer);
     /**
-     * Get a random weapon from a bots pool of weapons (weighted)
+     * Pick a random weapon based on weightings and generate a functional weapon
+     * @param equipmentSlot Primary/secondary/holster
+     * @param botTemplateInventory e.g. assault.json
+     * @param weaponParentId
+     * @param modChances
+     * @param botRole role of bot, e.g. assault/followerBully
+     * @param isPmc Is weapon generated for a pmc
+     * @returns GenerateWeaponResult object
+     */
+    generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    /**
+     * Get a random weighted weapon from a bots pool of weapons
      * @param equipmentSlot Primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
      * @returns weapon tpl
@@ -39,43 +50,24 @@ export declare class BotWeaponGenerator {
      * @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool())
      * @param equipmentSlot slot to fit into, primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
+     * @param weaponParentId ParentId of the weapon being generated
+     * @param modChances Dictionary of item types and % chance weapon will have that mod
+     * @param botRole e.g. assault/exusec
      * @param isPmc
      * @returns GenerateWeaponResult object
      */
-    generateWeaponByTpl(weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
     /**
-     * Generate an entirely random weapon
-     * @param equipmentSlot Primary/secondary/holster
-     * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
-     * @param isPmc
-     * @returns GenerateWeaponResult object
-     */
-    generateRandomWeapon(equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
-    /**
-     * Create array with weapon base as only element
-     * Add additional properties as required
-     * @param weaponTpl
-     * @param weaponParentId
-     * @param equipmentSlot
-     * @param weaponItemTemplate
+     * Create array with weapon base as only element and
+     * add additional properties based on weapon type
+     * @param weaponTpl Weapon tpl to create item with
+     * @param weaponParentId Weapons parent id
+     * @param equipmentSlot e.g. primary/secondary/holster
+     * @param weaponItemTemplate db template for weapon
      * @param botRole for durability values
-     * @returns
+     * @returns Base weapon item in array
      */
     constructWeaponBaseArray(weaponTpl: string, weaponParentId: string, equipmentSlot: string, weaponItemTemplate: ITemplateItem, botRole: string): Item[];
-    /**
-     * Add compatible magazines to an inventory based on a generated weapon
-     * @param weaponDetails
-     * @param magCounts
-     * @param inventory
-     * @param botRole the bot type we're getting generating extra mags for
-     */
-    addExtraMagazinesToInventory(weaponDetails: GenerateWeaponResult, magCounts: MinMax, inventory: PmcInventory, botRole: string): void;
     /**
      * Get the mods necessary to kit out a weapon to its preset level
      * @param weaponTpl weapon to find preset for
@@ -84,20 +76,32 @@ export declare class BotWeaponGenerator {
      * @returns array of weapon mods
      */
     protected getPresetWeaponMods(weaponTpl: string, equipmentSlot: string, weaponParentId: string, itemTemplate: ITemplateItem, botRole: string): Item[];
-    /** Checks if all required slots are occupied on a weapon and all it's mods */
+    /**
+     * Checks if all required slots are occupied on a weapon and all it's mods
+     * @param weaponItemArray Weapon + mods
+     * @returns true if valid
+     */
     protected isWeaponValid(weaponItemArray: Item[]): boolean;
     /**
      * Generates extra magazines or bullets (if magazine is internal) and adds them to TacticalVest and Pockets.
      * Additionally, adds extra bullets to SecuredContainer
-     * @param weaponMods
-     * @param weaponTemplate
-     * @param magCounts
-     * @param ammoTpl
-     * @param inventory
+     * @param weaponMods mods to attach to weapon
+     * @param weaponTemplate db template for weapon
+     * @param magCounts magazine count to add to inventory
+     * @param ammoTpl ammo templateId to add to magazines
+     * @param inventory inventory to add magazines to
      * @param botRole the bot type we're getting generating extra mags for
      * @returns
      */
-    protected generateExtraMagazines(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    addExtraMagazinesToInventory(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    /**
+     * Create a magazine using the parameters given
+     * @param magazineTpl Tpl of the magazine to create
+     * @param ammoTpl Ammo to add to magazine
+     * @param magTemplate template object of magazine
+     * @returns Item array
+     */
+    protected createMagazine(magazineTpl: string, ammoTpl: string, magTemplate: ITemplateItem): Item[];
     /**
      * Get a randomised number of bullets for a specific magazine
      * @param magCounts min and max count of magazines
@@ -138,10 +142,9 @@ export declare class BotWeaponGenerator {
      * Finds and return a compatible ammo tpl based on the bots ammo weightings (x.json/inventory/equipment/ammo)
      * @param ammo a list of ammo tpls the weapon can use
      * @param weaponTemplate the weapon we want to pick ammo for
-     * @param isPmc is the ammo being gathered for a pmc (runs pmc ammo filtering)
      * @returns an ammo tpl that works with the desired gun
      */
-    protected getCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem, isPmc: boolean): string;
+    protected getWeightedCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem): string;
     /**
      * Get a weapons compatible cartridge caliber
      * @param weaponTemplate Weapon to look up caliber of
diff --git a/TypeScript/5ReplaceMethod/types/generators/LocationGenerator.d.ts b/TypeScript/5ReplaceMethod/types/generators/LocationGenerator.d.ts
index bd368b5..cc61dcf 100644
--- a/TypeScript/5ReplaceMethod/types/generators/LocationGenerator.d.ts
+++ b/TypeScript/5ReplaceMethod/types/generators/LocationGenerator.d.ts
@@ -3,10 +3,9 @@ import { GameEventHelper } from "../helpers/GameEventHelper";
 import { ItemHelper } from "../helpers/ItemHelper";
 import { PresetHelper } from "../helpers/PresetHelper";
 import { RagfairServerHelper } from "../helpers/RagfairServerHelper";
-import { ILooseLoot, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
+import { ILooseLoot, SpawnpointsForced, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IStaticAmmoDetails, IStaticContainerProps, IStaticForcedProps, IStaticLootDetails } from "../models/eft/common/tables/ILootBase";
-import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILocationConfig } from "../models/spt/config/ILocationConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
@@ -36,11 +35,19 @@ export declare class LocationGenerator {
     generateContainerLoot(containerIn: IStaticContainerProps, staticForced: IStaticForcedProps[], staticLootDist: Record<string, IStaticLootDetails>, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): IStaticContainerProps;
     protected getLooseLootMultiplerForLocation(location: string): number;
     protected getStaticLootMultiplerForLocation(location: string): number;
+    /**
+     * Create array of loose + forced loot using probability system
+     * @param dynamicLootDist
+     * @param staticAmmoDist
+     * @param locationName Location to generate loot for
+     * @returns Array of spawn points with loot in them
+     */
     generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): SpawnpointTemplate[];
+    /**
+     * Add forced spawn point loot into loot parameter array
+     * @param loot array to add forced loot to
+     * @param forcedSpawnPoints forced loot to add
+     */
+    protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[]): void;
     protected createItem(tpl: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, parentId?: string): IContainerItem;
-    protected getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
-    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
-    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
-    protected createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
-    protected createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
 }
diff --git a/TypeScript/5ReplaceMethod/types/generators/LootGenerator.d.ts b/TypeScript/5ReplaceMethod/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/5ReplaceMethod/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/5ReplaceMethod/types/generators/PMCLootGenerator.d.ts b/TypeScript/5ReplaceMethod/types/generators/PMCLootGenerator.d.ts
index 64e6f7f..b9f2a83 100644
--- a/TypeScript/5ReplaceMethod/types/generators/PMCLootGenerator.d.ts
+++ b/TypeScript/5ReplaceMethod/types/generators/PMCLootGenerator.d.ts
@@ -1,15 +1,21 @@
 import { ItemHelper } from "../helpers/ItemHelper";
-import { DatabaseServer } from "../servers/DatabaseServer";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+/**
+ * Handle the generation of dynamic PMC loot in pockets and backpacks
+ * and the removal of blacklisted items
+ */
 export declare class PMCLootGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected configServer: ConfigServer;
+    protected itemFilterService: ItemFilterService;
     protected pocketLootPool: string[];
     protected backpackLootPool: string[];
     protected botConfig: IBotConfig;
-    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer);
+    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer, itemFilterService: ItemFilterService);
     generatePMCPocketLootPool(): string[];
     generatePMCBackpackLootPool(): string[];
 }
diff --git a/TypeScript/5ReplaceMethod/types/generators/ScavCaseRewardGenerator.d.ts b/TypeScript/5ReplaceMethod/types/generators/ScavCaseRewardGenerator.d.ts
index c7d6ab7..89cb5c8 100644
--- a/TypeScript/5ReplaceMethod/types/generators/ScavCaseRewardGenerator.d.ts
+++ b/TypeScript/5ReplaceMethod/types/generators/ScavCaseRewardGenerator.d.ts
@@ -8,9 +8,13 @@ import { RewardCountAndPriceDetails, ScavCaseRewardCountsAndPrices } from "../mo
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { RagfairPriceService } from "../services/RagfairPriceService";
 import { HashUtil } from "../utils/HashUtil";
 import { RandomUtil } from "../utils/RandomUtil";
+/**
+ * Handle the creation of randomised scav case rewards
+ */
 export declare class ScavCaseRewardGenerator {
     protected logger: ILogger;
     protected randomUtil: RandomUtil;
@@ -18,9 +22,10 @@ export declare class ScavCaseRewardGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected ragfairPriceService: RagfairPriceService;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected scavCaseConfig: IScavCaseConfig;
-    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, configServer: ConfigServer);
+    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Create an array of rewards that will be given to the player upon completing their scav case build
      * @param body client request
diff --git a/TypeScript/5ReplaceMethod/types/generators/WeatherGenerator.d.ts b/TypeScript/5ReplaceMethod/types/generators/WeatherGenerator.d.ts
index 44cecbb..8ddbe49 100644
--- a/TypeScript/5ReplaceMethod/types/generators/WeatherGenerator.d.ts
+++ b/TypeScript/5ReplaceMethod/types/generators/WeatherGenerator.d.ts
@@ -1,7 +1,7 @@
 import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IWeatherData } from "../models/eft/weather/IWeatherData";
 import { IWeatherConfig } from "../models/spt/config/IWeatherConfig";
+import { ConfigServer } from "../servers/ConfigServer";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class WeatherGenerator {
@@ -21,11 +21,16 @@ export declare class WeatherGenerator {
     protected getAcceleratedTime(computedDate: Date): string;
     /**
      * Get current time formatted to fit BSGs requirement
-     * @param computedDate
+     * @param computedDate date to format into bsg style
      * @returns
      */
     protected getNormalTime(computedDate: Date): string;
-    generateWeather(data: IWeatherData): IWeatherData;
+    /**
+     * Return randomised Weather data
+     * @param weatherData weather input data
+     * @returns Randomised weather data
+     */
+    generateWeather(weatherData: IWeatherData): IWeatherData;
     protected getWeightedFog(): string;
     protected getWeightedRain(): number;
     protected getRandomFloat(node: string): number;
diff --git a/TypeScript/5ReplaceMethod/types/helpers/AssortHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/AssortHelper.d.ts
index 15586b9..bfc157f 100644
--- a/TypeScript/5ReplaceMethod/types/helpers/AssortHelper.d.ts
+++ b/TypeScript/5ReplaceMethod/types/helpers/AssortHelper.d.ts
@@ -17,7 +17,7 @@ export declare class AssortHelper {
      * @param assort assort items from a trader
      * @returns assort items minus locked quest assorts
      */
-    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort): ITraderAssort;
+    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort, flea?: boolean): ITraderAssort;
     /**
      * Remove assorts from a trader that have not been unlocked yet
      * @param pmcProfile player profile
@@ -32,5 +32,5 @@ export declare class AssortHelper {
      * @param itemID item id to remove from asort
      * @returns Modified assort
      */
-    removeItemFromAssort(assort: ITraderAssort, itemID: string): ITraderAssort;
+    removeItemFromAssort(assort: ITraderAssort, itemID: string, flea?: boolean): ITraderAssort;
 }
diff --git a/TypeScript/5ReplaceMethod/types/helpers/BotGeneratorHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/BotGeneratorHelper.d.ts
index 3cd7256..eb0d215 100644
--- a/TypeScript/5ReplaceMethod/types/helpers/BotGeneratorHelper.d.ts
+++ b/TypeScript/5ReplaceMethod/types/helpers/BotGeneratorHelper.d.ts
@@ -3,10 +3,12 @@ import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"
 import { Mods, ModsChances } from "../models/eft/common/tables/IBotType";
 import { Item, Repairable, Upd } from "../models/eft/common/tables/IItem";
 import { Grid, ITemplateItem, Slot } from "../models/eft/common/tables/ITemplateItem";
-import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
@@ -14,6 +16,7 @@ import { ContainerHelper } from "./ContainerHelper";
 import { InventoryHelper } from "./InventoryHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProbabilityHelper } from "./ProbabilityHelper";
+import { ProfileHelper } from "./ProfileHelper";
 export declare class BotGeneratorHelper {
     protected logger: ILogger;
     protected jsonUtil: JsonUtil;
@@ -25,10 +28,76 @@ export declare class BotGeneratorHelper {
     protected itemHelper: ItemHelper;
     protected inventoryHelper: InventoryHelper;
     protected containerHelper: ContainerHelper;
+    protected botEquipmentFilterService: BotEquipmentFilterService;
+    protected itemFilterService: ItemFilterService;
+    protected profileHelper: ProfileHelper;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, configServer: ConfigServer);
-    generateModsForItem(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, configServer: ConfigServer);
+    /**
+     * TODO - very similar to generateModsForWeapon
+     * Check mods are compatible and add to array
+     * @param equipment Equipment item to add mods to
+     * @param modPool Mod list to choose frm
+     * @param parentId parentid of item to add mod to
+     * @param parentTemplate template objet of item to add mods to
+     * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type
+     * @returns Item + compatible mods as an array
+     */
+    generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    /**
+     * TODO - very similar to generateModsForEquipment
+     * @param sessionId session id
+     * @param weapon Weapon to add mods to
+     * @param modPool pool of compatible mods to attach to gun
+     * @param weaponParentId parentId of weapon
+     * @param parentTemplate
+     * @param modSpawnChances
+     * @param ammoTpl ammo tpl to use when generating magazines/cartridges
+     * @param botRole role of bot weapon is generated for
+     * @returns Weapon with mods
+     */
+    generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[];
+    /**
+     * Generate a pool of mods for this bots mod type if bot has values inside `randomisedWeaponModSlots` array found in bot.json/equipment[botrole]
+     * @param allowedMods Mods to be added to mod pool
+     * @param botEquipBlacklist blacklist of items not allowed to be added to mod pool
+     * @param modSlot Slot to generate mods for
+     * @param itemModPool base mod pool to replace values of
+     */
+    protected generateDynamicModPool(allowedMods: string[], botEquipBlacklist: EquipmentFilterDetails, modSlot: string, itemModPool: Record<string, string[]>): void;
+    /**
+     * Check if the specific item type on the weapon has reached the set limit
+     * @param modTpl item to check is limited
+     * @param currentCount current number of this item on gun
+     * @param maxLimit mod limit allowed
+     * @param botRole role of bot we're checking weapon of
+     * @returns true if limit reached
+     */
+    protected weaponModLimitReached(modTpl: string, currentCount: {
+        count: number;
+    }, maxLimit: number, botRole: string): boolean;
+    /**
+     * log errors if mod is not valid for a slot
+     * @param modTpl
+     * @param found
+     * @param itemSlot
+     * @param modTemplate
+     * @param modSlot
+     * @param parentTemplate
+     * @returns true if valid
+     */
+    protected isModValidForSlot(modTpl: string, found: boolean, itemSlot: Slot, modTemplate: ITemplateItem, modSlot: string, parentTemplate: ITemplateItem): boolean;
+    /**
+     * Create a mod item with parameters as properties
+     * @param modId _id
+     * @param modTpl _tpl
+     * @param parentId parentId
+     * @param modSlot slotId
+     * @param modTemplate Used to add additional properites in the upd object
+     * @returns Item object
+     */
+    protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item;
     /**
      * Is this magazine cylinder related (revolvers and grenade launchers)
      * @param magazineParentName the name of the magazines parent
@@ -62,11 +131,11 @@ export declare class BotGeneratorHelper {
      * Those magazines (e.g. 60dc519adf4c47305f6d410d) have a "Cartridges" entry with a _max_count=0.
      * Ammo is not put into the magazine directly but assigned to the magazine's slots: The "camora_xxx" slots.
      * This function is a helper called by generateModsForItem for mods with parent type "CylinderMagazine"
-     *
-     * @param {object}      items               The items where the CylinderMagazine's camora are appended to
-     * @param {object}      modPool             modPool which should include available cartrigdes
-     * @param {string}      parentId            The CylinderMagazine's UID
-     * @param {object}      parentTemplate      The CylinderMagazine's template
+     * @param items The items where the CylinderMagazine's camora are appended to
+     * @param modPool modPool which should include available cartrigdes
+     * @param parentId The CylinderMagazine's UID
+     * @param parentTemplate The CylinderMagazine's template
+     * @returns
      */
     protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void;
     /**
@@ -75,6 +144,13 @@ export declare class BotGeneratorHelper {
      * @returns string array of shells fro luitple camora sources
      */
     protected mergeCamoraPoolsTogether(camorasWithShells: Record<string, string[]>): string[];
+    /**
+     * Adds properties to an item
+     * e.g. Repairable / HasHinge / Foldable / MaxDurability
+     * @param itemTemplate
+     * @param botRole Used by weapons to randomise the durability values
+     * @returns Item Upd object with extra properties
+     */
     generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): {
         upd?: Upd;
     };
@@ -93,12 +169,6 @@ export declare class BotGeneratorHelper {
      */
     protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable;
     protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string;
-    /**
-     * Sort by spawn chance, highest to lowest, higher is more common
-     * @param unsortedModArray String array to sort
-     * @returns Sorted string array
-     */
-    protected sortModArray(unsortedModArray: string[]): string[];
     /**
      * Can an item be added to an item without issue
      * @param items
@@ -117,8 +187,15 @@ export declare class BotGeneratorHelper {
      * @returns a `boolean` indicating item was added
      */
     addItemWithChildrenToEquipmentSlot(equipmentSlots: string[], parentId: string, parentTpl: string, itemWithChildren: Item[], inventory: PmcInventory): boolean;
+    /**
+     * is the provided item allowed inside a container
+     * @param slot location item wants to be placed in
+     * @param itemTpl item being placed
+     * @returns true if allowed
+     */
     protected itemAllowedInContainer(slot: Grid, itemTpl: string): boolean;
 }
+/** TODO - move into own class */
 export declare class ExhaustableArray<T> {
     private itemPool;
     private randomUtil;
diff --git a/TypeScript/5ReplaceMethod/types/helpers/HideoutHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/HideoutHelper.d.ts
index 36e4009..7495a6a 100644
--- a/TypeScript/5ReplaceMethod/types/helpers/HideoutHelper.d.ts
+++ b/TypeScript/5ReplaceMethod/types/helpers/HideoutHelper.d.ts
@@ -44,14 +44,72 @@ export declare class HideoutHelper {
     initProduction(recipeId: string, productionTime: number): Production;
     isProductionType(productive: Productive): productive is Production;
     applyPlayerUpgradesBonuses(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * TODO:
+     * After looking at the skills there doesnt seem to be a configuration per skill to boost
+     * the XP gain PER skill. I THINK you should be able to put the variable "SkillProgress" (just like health has it)
+     * and be able to tune the skill gain PER skill, but I havent tested it and Im not sure!
+     * @param pmcData
+     * @param bonus
+     */
     protected applySkillXPBoost(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * Process a players hideout, update areas that use resources + increment production timers
+     * @param sessionID Session id
+     */
     updatePlayerHideout(sessionID: string): void;
+    /**
+     * Update progress timer for water collector
+     * @param pmcData profile to update
+     * @param productionId id of water collection production to update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateWaterCollectorProductionTimer(pmcData: IPmcData, productionId: string, hideoutProperties: {
+        btcFarmCGs?: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Iterate over productions and update their progress timers
+     * @param pmcData Profile to check for productions and update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Update progress timer for scav case
+     * @param pmcData Profile to update
+     * @param productionId Id of scav case production to update
+     */
+    protected updateScavCaseProductionTimer(pmcData: IPmcData, productionId: string): void;
+    /**
+     * Iterate over hideout areas that use resources (fuel/filters etc) and update associated values
+     * @param sessionID Session id
+     * @param pmcData Profile to update areas of
+     * @param hideoutProperties hideout properties
+     */
+    protected updateAreasWithResources(sessionID: string, pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
     protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
     protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
-    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): HideoutArea;
-    protected updateWaterFilters(waterFilterArea: HideoutArea, pwProd: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
+    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): void;
+    /**
+     * Adjust water filter objects resourceValue or delete when they reach 0 resource
+     * @param waterFilterArea water filter area to update
+     * @param production production object
+     * @param isGeneratorOn is generatory enabled
+     * @param pmcData Player profile
+     * @returns Updated HideoutArea object
+     */
+    protected updateWaterFilters(waterFilterArea: HideoutArea, production: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
     protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
-    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): HideoutArea;
+    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): void;
     protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
     protected getBTCSlots(pmcData: IPmcData): number;
     protected getManagementSkillsSlots(): number;
diff --git a/TypeScript/5ReplaceMethod/types/helpers/InRaidHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/InRaidHelper.d.ts
index b382e30..962df38 100644
--- a/TypeScript/5ReplaceMethod/types/helpers/InRaidHelper.d.ts
+++ b/TypeScript/5ReplaceMethod/types/helpers/InRaidHelper.d.ts
@@ -18,18 +18,6 @@ export declare class InRaidHelper {
     protected paymentHelper: PaymentHelper;
     protected profileFixerService: ProfileFixerService;
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper, profileFixerService: ProfileFixerService);
-    /**
-     * Reset the SPT inraid property stored in a profile to 'none'
-     * @param sessionID Session id
-     */
-    protected removePlayer(sessionID: string): void;
-    /**
-     * Some maps have one-time-use keys (e.g. Labs
-     * Remove the relevant key from an inventory based on the post-raid request data passed in
-     * @param offraidData post-raid data
-     * @param sessionID Session id
-     */
-    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
     /**
      * Check an array of items and add an upd object to money items with a stack count of 1
      * Single stack money items have no upd object and thus no StackObjectsCount, causing issues
@@ -54,6 +42,18 @@ export declare class InRaidHelper {
      * @returns Reset profile object
      */
     updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData;
+    /**
+     * Some maps have one-time-use keys (e.g. Labs
+     * Remove the relevant key from an inventory based on the post-raid request data passed in
+     * @param offraidData post-raid data
+     * @param sessionID Session id
+     */
+    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Set the SPT inraid location Profile property to 'none'
+     * @param sessionID Session id
+     */
+    protected setPlayerInRaidLocationStatusToNone(sessionID: string): void;
     /**
      * Adds SpawnedInSession property to items found in a raid
      * Removes SpawnedInSession for non-scav players if item was taken into raid with SpawnedInSession = true
@@ -95,5 +95,10 @@ export declare class InRaidHelper {
      * @returns true if item is kept after death
      */
     isItemKeptAfterDeath(slotId: string): boolean;
+    /**
+     * Return the equipped items from a players inventory
+     * @param items Players inventory to search through
+     * @returns an array of equipped items
+     */
     getPlayerGear(items: Item[]): Item[];
 }
diff --git a/TypeScript/5ReplaceMethod/types/helpers/ItemHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/ItemHelper.d.ts
index 1701c62..de10892 100644
--- a/TypeScript/5ReplaceMethod/types/helpers/ItemHelper.d.ts
+++ b/TypeScript/5ReplaceMethod/types/helpers/ItemHelper.d.ts
@@ -1,35 +1,30 @@
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item, Repairable } from "../models/eft/common/tables/IItem";
+import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase";
 import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+import { MathUtil } from "../utils/MathUtil";
+import { ObjectId } from "../utils/ObjectId";
+import { RandomUtil } from "../utils/RandomUtil";
 declare class ItemHelper {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
     protected jsonUtil: JsonUtil;
+    protected randomUtil: RandomUtil;
+    protected objectId: ObjectId;
+    protected mathUtil: MathUtil;
     protected databaseServer: DatabaseServer;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer);
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer);
     /**
      * Checks if a id is a valid item. Valid meaning that it's an item that be stored in stash
      * @param       {string}    tpl       the template id / tpl
      * @returns                             boolean; true for items that may be in player posession and not quest items
      */
     isValidItem(tpl: string, invalidBaseTypes?: string[]): boolean;
-    /**
-     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
-     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
-     * @param {*} tpl template id of item to check
-     * @returns boolean: true if item is valid reward
-     */
-    isValidRewardItem(tpl: string): boolean;
-    /**
-     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
-     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
-     */
-    getRewardableItems(): [string, ITemplateItem][];
     /**
      * Check if the tpl / template Id provided is a descendent of the baseclass
      *
@@ -196,6 +191,22 @@ declare class ItemHelper {
      * @returns ItemSize object (width and height)
      */
     getItemSize(items: Item[], rootItemId: string): ItemHelper.ItemSize;
+    /**
+     * Get a random cartridge from an items Filter property
+     * @param item
+     * @returns
+     */
+    getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
+    createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
+    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
+    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
+    createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
+    /**
+     * Get the size of a stack, return 1 if no stack object count property found
+     * @param item Item to get stack size of
+     * @returns size of stack
+     */
+    getItemStackSize(item: Item): number;
 }
 declare namespace ItemHelper {
     interface ItemSize {
diff --git a/TypeScript/5ReplaceMethod/types/helpers/ProfileHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/ProfileHelper.d.ts
index 9d4ff98..9c6560a 100644
--- a/TypeScript/5ReplaceMethod/types/helpers/ProfileHelper.d.ts
+++ b/TypeScript/5ReplaceMethod/types/helpers/ProfileHelper.d.ts
@@ -24,6 +24,19 @@ export declare class ProfileHelper {
     constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, fenceService: FenceService);
     resetProfileQuestCondition(sessionID: string, conditionId: string): void;
     getCompleteProfile(sessionID: string): IPmcData[];
+    /**
+     * Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
+     * Server saves the post-raid changes prior to the xp screen getting the profile, this results in the xp screen using
+     * the now updated profile values as a base, meaning it shows x2 xp gained
+     * Instead, clone the post-raid profile (so we dont alter its values), apply the pre-raid xp values to the cloned objects and return
+     * Delete snapshot of pre-raid profile prior to returning profile data
+     * @param sessionId Session id
+     * @param output pmc and scav profiles array
+     * @param pmcProfile post-raid pmc profile
+     * @param scavProfile post-raid scav profile
+     * @returns updated profile array
+     */
+    protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
     isNicknameTaken(info: IValidateNicknameRequestData, sessionID: string): boolean;
     /**
      * Add experience to a PMC inside the players profile
diff --git a/TypeScript/5ReplaceMethod/types/helpers/QuestHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/QuestHelper.d.ts
index 32e55ec..d66d150 100644
--- a/TypeScript/5ReplaceMethod/types/helpers/QuestHelper.d.ts
+++ b/TypeScript/5ReplaceMethod/types/helpers/QuestHelper.d.ts
@@ -36,11 +36,20 @@ export declare class QuestHelper {
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
     constructor(logger: ILogger, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, itemHelper: ItemHelper, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, localeService: LocaleService, ragfairServerHelper: RagfairServerHelper, dialogueHelper: DialogueHelper, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, traderHelper: TraderHelper, configServer: ConfigServer);
-    questStatus(pmcData: IPmcData, questID: string): QuestStatus;
     /**
-     * returns true is the condition is satisfied
+    * Get status of a quest by quest id
+    * @param pmcData Profile to search
+    * @param questID Quest id to look up
+    * @returns QuestStauts enum
+    */
+    getQuestStatus(pmcData: IPmcData, questID: string): QuestStatus;
+    /**
+     * returns true is the level condition is satisfied
+     * @param playerLevel Players level
+     * @param condition Quest condition
+     * @returns true if player level is greater than or equal to quest
      */
-    evaluateLevel(pmcProfile: IPmcData, cond: AvailableForConditions): boolean;
+    doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean;
     getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[];
     /**
      * Increase skill points of a skill on player profile
diff --git a/TypeScript/5ReplaceMethod/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/RagfairOfferHelper.d.ts
index 8d03bee..e9d72ca 100644
--- a/TypeScript/5ReplaceMethod/types/helpers/RagfairOfferHelper.d.ts
+++ b/TypeScript/5ReplaceMethod/types/helpers/RagfairOfferHelper.d.ts
@@ -22,12 +22,14 @@ import { ProfileHelper } from "./ProfileHelper";
 import { RagfairHelper } from "./RagfairHelper";
 import { RagfairServerHelper } from "./RagfairServerHelper";
 import { RagfairSortHelper } from "./RagfairSortHelper";
+import { TraderHelper } from "./TraderHelper";
 export declare class RagfairOfferHelper {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
     protected hashUtil: HashUtil;
     protected itemEventRouter: ItemEventRouter;
     protected databaseServer: DatabaseServer;
+    protected traderHelper: TraderHelper;
     protected saveServer: SaveServer;
     protected dialogueHelper: DialogueHelper;
     protected itemHelper: ItemHelper;
@@ -43,10 +45,10 @@ export declare class RagfairOfferHelper {
     protected static goodSoldTemplate: string;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, traderHelper: TraderHelper, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
     getValidOffers(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
     getOffersForBuild(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
-    processOffers(sessionID: string): boolean;
+    processOffersOnProfile(sessionID: string): boolean;
     protected getProfileOffers(sessionID: string): IRagfairOffer[];
     protected deleteOfferByOfferId(sessionID: string, offerId: string): void;
     protected completeOffer(sessionID: string, offer: IRagfairOffer, boughtAmount: number): IItemEventRouterResponse;
diff --git a/TypeScript/5ReplaceMethod/types/helpers/RagfairSellHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/RagfairSellHelper.d.ts
index 6ec004a..91b8a20 100644
--- a/TypeScript/5ReplaceMethod/types/helpers/RagfairSellHelper.d.ts
+++ b/TypeScript/5ReplaceMethod/types/helpers/RagfairSellHelper.d.ts
@@ -11,6 +11,12 @@ export declare class RagfairSellHelper {
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     constructor(logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer);
-    calculateSellChance(baseChance: number, offerPrice: number, requirementsPriceInRub: number): number;
-    rollForSale(sellChance: number, count: number): SellResult[];
+    calculateSellChance(baseChancePercent: number, offerPriceRub: number, playerListedPriceRub: number): number;
+    /**
+     * Determine if the offer being listed will be sold
+     * @param sellChancePercent chance item will sell
+     * @param itemSellCount count of items to sell
+     * @returns Array of purchases of item(s) lsited
+     */
+    rollForSale(sellChancePercent: number, itemSellCount: number): SellResult[];
 }
diff --git a/TypeScript/5ReplaceMethod/types/helpers/RagfairServerHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/RagfairServerHelper.d.ts
index e4939d1..a03cdda 100644
--- a/TypeScript/5ReplaceMethod/types/helpers/RagfairServerHelper.d.ts
+++ b/TypeScript/5ReplaceMethod/types/helpers/RagfairServerHelper.d.ts
@@ -6,6 +6,7 @@ import { IRagfairConfig } from "../models/spt/config/IRagfairConfig";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { SaveServer } from "../servers/SaveServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { LocaleService } from "../services/LocaleService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -13,6 +14,9 @@ import { RandomUtil } from "../utils/RandomUtil";
 import { DialogueHelper } from "./DialogueHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProfileHelper } from "./ProfileHelper";
+/**
+ * Helper class for common ragfair server actions
+ */
 export declare class RagfairServerHelper {
     protected randomUtil: RandomUtil;
     protected hashUtil: HashUtil;
@@ -23,11 +27,12 @@ export declare class RagfairServerHelper {
     protected localeService: LocaleService;
     protected dialogueHelper: DialogueHelper;
     protected jsonUtil: JsonUtil;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
     protected static goodsReturnedTemplate: string;
-    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, configServer: ConfigServer);
+    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Is item valid / on blacklist / quest item
      * @param itemDetails
diff --git a/TypeScript/5ReplaceMethod/types/helpers/TradeHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/TradeHelper.d.ts
index 975062b..7ab9768 100644
--- a/TypeScript/5ReplaceMethod/types/helpers/TradeHelper.d.ts
+++ b/TypeScript/5ReplaceMethod/types/helpers/TradeHelper.d.ts
@@ -39,6 +39,12 @@ export declare class TradeHelper {
      * @returns
      */
     sellItem(pmcData: IPmcData, body: IProcessSellTradeRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment the assorts buy count by number of items purchased
+     * Show error on screen if player attepts to buy more than what the buy max allows
+     * @param assortBeingPurchased assort being bought
+     * @param itemsPurchasedCount number of items being bought
+     */
     protected incrementAssortBuyCount(assortBeingPurchased: Item, itemsPurchasedCount: number): void;
     protected checkPurchaseIsWithinTraderItemLimit(assortBeingPurchased: Item, assortId: string, count: number): void;
 }
diff --git a/TypeScript/5ReplaceMethod/types/helpers/TraderAssortHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/TraderAssortHelper.d.ts
index 677dd66..025efd6 100644
--- a/TypeScript/5ReplaceMethod/types/helpers/TraderAssortHelper.d.ts
+++ b/TypeScript/5ReplaceMethod/types/helpers/TraderAssortHelper.d.ts
@@ -1,6 +1,5 @@
 import { RagfairAssortGenerator } from "../generators/RagfairAssortGenerator";
 import { RagfairOfferGenerator } from "../generators/RagfairOfferGenerator";
-import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ITrader, ITraderAssort } from "../models/eft/common/tables/ITrader";
 import { ITraderConfig } from "../models/spt/config/ITraderConfig";
@@ -41,12 +40,7 @@ export declare class TraderAssortHelper {
      * @param traderId traders id
      * @returns a traders' assorts
      */
-    getAssort(sessionId: string, traderId: string): ITraderAssort;
-    /**
-     * if the fence assorts have expired, re-generate them
-     * @param pmcProfile Players profile
-     */
-    refreshFenceAssortIfExpired(pmcProfile: IPmcData): void;
+    getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort;
     /**
      * Reset a traders assorts and move nextResupply value to future
      * Flag trader as needing a flea offer reset to be picked up by flea update() function
diff --git a/TypeScript/5ReplaceMethod/types/helpers/TraderHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/TraderHelper.d.ts
index 6bda5cd..0dc93e8 100644
--- a/TypeScript/5ReplaceMethod/types/helpers/TraderHelper.d.ts
+++ b/TypeScript/5ReplaceMethod/types/helpers/TraderHelper.d.ts
@@ -65,7 +65,7 @@ export declare class TraderHelper {
      * @param item
      * @returns boolean
      */
-    protected isWeaponAndBelowTraderBuyDurability(traderID: string, item: Item): boolean;
+    protected isWeaponBelowTraderBuyDurability(traderID: string, item: Item): boolean;
     /**
      * Get the price of an item and all of its attached children
      * Take into account bonuses/adjsutments e.g. discounts
diff --git a/TypeScript/5ReplaceMethod/types/models/eft/common/tables/ITemplateItem.d.ts b/TypeScript/5ReplaceMethod/types/models/eft/common/tables/ITemplateItem.d.ts
index 23a1a14..6b2fa8f 100644
--- a/TypeScript/5ReplaceMethod/types/models/eft/common/tables/ITemplateItem.d.ts
+++ b/TypeScript/5ReplaceMethod/types/models/eft/common/tables/ITemplateItem.d.ts
@@ -34,6 +34,7 @@ export interface Props {
     LootExperience?: number;
     ExamineExperience?: number;
     HideEntrails?: boolean;
+    InsuranceDisabled?: boolean;
     RepairCost?: number;
     RepairSpeed?: number;
     ExtraSizeLeft?: number;
@@ -206,6 +207,7 @@ export interface Props {
     IsOneoff?: boolean;
     MustBoltBeOpennedForExternalReload?: boolean;
     MustBoltBeOpennedForInternalReload?: boolean;
+    NoFiremodeOnBoltcatch?: boolean;
     BoltAction?: boolean;
     HipAccuracyRestorationDelay?: number;
     HipAccuracyRestorationSpeed?: number;
diff --git a/TypeScript/5ReplaceMethod/types/models/eft/common/tables/ITrader.d.ts b/TypeScript/5ReplaceMethod/types/models/eft/common/tables/ITrader.d.ts
index a84f5af..37b2d61 100644
--- a/TypeScript/5ReplaceMethod/types/models/eft/common/tables/ITrader.d.ts
+++ b/TypeScript/5ReplaceMethod/types/models/eft/common/tables/ITrader.d.ts
@@ -67,6 +67,7 @@ export interface IBarterScheme {
     count: number;
     _tpl: string;
     onlyFunctional?: boolean;
+    sptQuestLocked?: boolean;
 }
 export interface ISuit {
     _id: string;
diff --git a/TypeScript/5ReplaceMethod/types/models/eft/ragfair/IRagfairOffer.d.ts b/TypeScript/5ReplaceMethod/types/models/eft/ragfair/IRagfairOffer.d.ts
index 63f655e..141b605 100644
--- a/TypeScript/5ReplaceMethod/types/models/eft/ragfair/IRagfairOffer.d.ts
+++ b/TypeScript/5ReplaceMethod/types/models/eft/ragfair/IRagfairOffer.d.ts
@@ -15,6 +15,8 @@ export interface IRagfairOffer {
     name?: string;
     shortName?: string;
     loyaltyLevel: number;
+    buyRestrictionMax?: number;
+    buyRestrictionCurrent?: number;
     locked: boolean;
     unlimitedCount: boolean;
     summaryCost: number;
diff --git a/TypeScript/5ReplaceMethod/types/models/enums/AmmoTypes.d.ts b/TypeScript/5ReplaceMethod/types/models/enums/AmmoTypes.d.ts
index b52ddcf..254b410 100644
--- a/TypeScript/5ReplaceMethod/types/models/enums/AmmoTypes.d.ts
+++ b/TypeScript/5ReplaceMethod/types/models/enums/AmmoTypes.d.ts
@@ -23,7 +23,7 @@ export declare enum Ammo762x54 {
     BT_GZH = "5e023d34e8a400319a28ed44",
     BS_GZH = "5e023d48186a883be655e551"
 }
-export declare enum Ammo338Lapua {
+export declare enum Ammo86x70 {
     TAC_X = "5fc382b6d6fa9c00c571bbc3",
     UCW = "5fc382c1016cce60e8341b20",
     AP = "5fc382a9d724d907e2077dab",
@@ -85,13 +85,13 @@ export declare enum Ammo9x21 {
     PE_GZH = "5a26ac06c4a282000c5a90a8",
     BT_GZH = "5a26ac0ec4a28200741e1e18"
 }
-export declare enum Ammo357Mag {
+export declare enum Ammo9x33R {
     FMJ = "62330b3ed4dc74626d570b95",
     HOLLOW_POINT = "62330bfadc5883093563729b",
     SOFT_POINT = "62330c40bdd19b369e1e53d1",
     JACKET_HP = "62330c18744e5e31df12f516"
 }
-export declare enum Ammo45ACP {
+export declare enum Ammo1143x23ACP {
     MATCH_FMJ = "5e81f423763d9f754677bf2e",
     HYDRA_SHOK = "5efb0fc6aeb21837e749c801",
     LASERMATCH_FMJ = "5efb0d4f4bc50b58e81710f3",
@@ -126,7 +126,7 @@ export declare enum Ammo556x45 {
     MK_318_MOD_0_SOST = "60194943740c5d77f6705eea",
     SSA_AP = "601949593ae8f707c4608daa"
 }
-export declare enum Ammo300Blackout {
+export declare enum Ammo762x35 {
     M62_TRACER = "619636be6db0f2477964e710",
     BCP_FMJ = "5fbe3ffdf8b6a877a729ea82",
     AP = "5fd20ff893a8961fc660a954",
diff --git a/TypeScript/5ReplaceMethod/types/models/enums/BaseClasses.d.ts b/TypeScript/5ReplaceMethod/types/models/enums/BaseClasses.d.ts
index e733bca..37c1398 100644
--- a/TypeScript/5ReplaceMethod/types/models/enums/BaseClasses.d.ts
+++ b/TypeScript/5ReplaceMethod/types/models/enums/BaseClasses.d.ts
@@ -68,6 +68,7 @@ export declare enum BaseClasses {
     ASSAULT_SCOPE = "55818add4bdc2d5b648b456f",
     REFLEX_SIGHT = "55818ad54bdc2ddc698b4569",
     TACTICAL_COMBO = "55818b164bdc2ddc698b456c",
+    FLASHLIGHT = "55818b084bdc2d5b648b4571",
     MAGAZINE = "5448bc234bdc2d3c308b4569",
     LIGHT_LASER = "55818b0e4bdc2dde698b456e",
     FLASH_HIDER = "550aa4bf4bdc2dd6348b456b",
diff --git a/TypeScript/5ReplaceMethod/types/models/enums/ConfigTypes.d.ts b/TypeScript/5ReplaceMethod/types/models/enums/ConfigTypes.d.ts
index 61d6f99..468ece5 100644
--- a/TypeScript/5ReplaceMethod/types/models/enums/ConfigTypes.d.ts
+++ b/TypeScript/5ReplaceMethod/types/models/enums/ConfigTypes.d.ts
@@ -8,6 +8,7 @@ export declare enum ConfigTypes {
     IN_RAID = "aki-inraid",
     INSURANCE = "aki-insurance",
     INVENTORY = "aki-inventory",
+    ITEM = "aki-item",
     LOCALE = "aki-locale",
     LOCATION = "aki-location",
     MATCH = "aki-match",
diff --git a/TypeScript/5ReplaceMethod/types/models/enums/ELocationName.d.ts b/TypeScript/5ReplaceMethod/types/models/enums/ELocationName.d.ts
index b56cc08..7ae7caa 100644
--- a/TypeScript/5ReplaceMethod/types/models/enums/ELocationName.d.ts
+++ b/TypeScript/5ReplaceMethod/types/models/enums/ELocationName.d.ts
@@ -1,5 +1,6 @@
 export declare enum ELocationName {
     FACTORY_DAY = "factory4_day",
+    FACTORY_NIGHT = "factory4_night",
     BIGMAP = "bigmap",
     WOODS = "Woods",
     SHORELINE = "Shoreline",
diff --git a/TypeScript/5ReplaceMethod/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/5ReplaceMethod/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/5ReplaceMethod/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/5ReplaceMethod/types/models/spt/config/IBotConfig.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/config/IBotConfig.d.ts
index e171087..f15fa73 100644
--- a/TypeScript/5ReplaceMethod/types/models/spt/config/IBotConfig.d.ts
+++ b/TypeScript/5ReplaceMethod/types/models/spt/config/IBotConfig.d.ts
@@ -1,17 +1,31 @@
 import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
+import { IBotDurability } from "./IBotDurability";
+import { IPmcConfig } from "./IPmcConfig";
 export interface IBotConfig extends IBaseConfig {
     kind: "aki-bot";
+    /** How many variants of each bot should be generated on raid start */
     presetBatch: PresetBatch;
+    /** What bot types should be classified as bosses */
     bosses: string[];
-    durability: Durability;
+    /** Control weapon/armor durability min/max values for each bot type */
+    durability: IBotDurability;
+    /** Control the weighting of how expensive an average loot item is on a PMC or Scav */
     lootNValue: LootNvalue;
+    /** Control what bots are added to a bots revenge list key: bottype, value: bottypes to revenge on seeing their death */
     revenge: Record<string, string[]>;
-    pmc: PmcConfig;
+    /** PMC bot specific config settings */
+    pmc: IPmcConfig;
+    /** Control how many items are allowed to spawn on a bot
+     * key: bottype, value: <key: itemTpl: value: max item count> */
     itemSpawnLimits: Record<string, Record<string, number>>;
-    equipment: Record<string, Equipment>;
+    /** Blacklist/whitelist items on a bot */
+    equipment: Record<string, EquipmentFilters>;
+    /** Show a bots botType value after their name */
     showTypeInNickname: boolean;
+    /** Max number of bots that can be spawned in a raid at any one time */
     maxBotCap: number;
+    /** How many stacks of secret ammo should a bot have in its bot secure container */
     secureContainerAmmoStackCount: number;
 }
 export interface PresetBatch {
@@ -44,79 +58,22 @@ export interface PresetBatch {
     test: number;
     exUsec: number;
 }
-export interface Durability {
-    default: DefaultDurability;
-    pmc: PmcDurability;
-    boss: BotDurability;
-    follower: BotDurability;
-    assault: BotDurability;
-    cursedassault: BotDurability;
-    marksman: BotDurability;
-    pmcbot: BotDurability;
-    exusec: BotDurability;
-    sectantpriest: BotDurability;
-    sectantwarrior: BotDurability;
-}
-export interface DefaultDurability {
-    armor: DefaultArmor;
-    weapon: WeaponDurability;
-}
-export interface DefaultArmor {
-    maxDelta: number;
-    minDelta: number;
-}
-export interface WeaponDurability {
-    lowestMax: number;
-    highestMax: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface PmcDurability {
-    armor: PmcDurabilityArmor;
-    weapon: WeaponDurability;
-}
-export interface PmcDurabilityArmor {
-    lowestMaxPercent: number;
-    highestMaxPercent: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface BotDurability {
-    armor: ArmorDurability;
-    weapon: WeaponDurability;
-}
-export interface ArmorDurability {
-    maxDelta: number;
-    minDelta: number;
-}
 export interface LootNvalue {
     scav: number;
     pmc: number;
 }
-export interface PmcConfig {
-    dynamicLoot: PmcDynamicLoot;
-    difficulty: string;
-    looseWeaponInBackpackChancePercent: number;
-    looseWeaponInBackpackLootMinMax: MinMax;
-    isUsec: number;
-    chanceSameSideIsHostilePercent: number;
-    usecType: string;
-    bearType: string;
-    maxBackpackLootTotalRub: number;
-    maxPocketLootTotalRub: number;
-    maxVestLootTotalRub: number;
-    convertIntoPmcChance: Record<string, MinMax>;
-    enemyTypes: string[];
-}
-export interface PmcDynamicLoot {
-    whitelist: string[];
-    blacklist: string[];
-    moneyStackLimits: Record<string, number>;
-}
-export interface Equipment {
+export interface EquipmentFilters {
+    weaponModLimits: ModLimits;
+    randomisedWeaponModSlots?: string[];
     blacklist: EquipmentFilterDetails[];
     whitelist: EquipmentFilterDetails[];
 }
+export interface ModLimits {
+    /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */
+    scopeLimit?: number;
+    /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */
+    lightLaserLimit?: number;
+}
 export interface EquipmentFilterDetails {
     levelRange: MinMax;
     equipment: Record<string, string[]>;
diff --git a/TypeScript/5ReplaceMethod/types/models/spt/config/IBotDurability.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/config/IBotDurability.d.ts
new file mode 100644
index 0000000..38a47cc
--- /dev/null
+++ b/TypeScript/5ReplaceMethod/types/models/spt/config/IBotDurability.d.ts
@@ -0,0 +1,47 @@
+export interface IBotDurability {
+    default: DefaultDurability;
+    pmc: PmcDurability;
+    boss: BotDurability;
+    follower: BotDurability;
+    assault: BotDurability;
+    cursedassault: BotDurability;
+    marksman: BotDurability;
+    pmcbot: BotDurability;
+    exusec: BotDurability;
+    gifter: BotDurability;
+    sectantpriest: BotDurability;
+    sectantwarrior: BotDurability;
+}
+/** Durability values to be used when a more specific bot type cant be found */
+export interface DefaultDurability {
+    armor: DefaultArmor;
+    weapon: WeaponDurability;
+}
+export interface DefaultArmor {
+    maxDelta: number;
+    minDelta: number;
+}
+export interface WeaponDurability {
+    lowestMax: number;
+    highestMax: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface PmcDurability {
+    armor: PmcDurabilityArmor;
+    weapon: WeaponDurability;
+}
+export interface PmcDurabilityArmor {
+    lowestMaxPercent: number;
+    highestMaxPercent: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface BotDurability {
+    armor: ArmorDurability;
+    weapon: WeaponDurability;
+}
+export interface ArmorDurability {
+    maxDelta: number;
+    minDelta: number;
+}
diff --git a/TypeScript/5ReplaceMethod/types/models/spt/config/IItemConfig.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/config/IItemConfig.d.ts
new file mode 100644
index 0000000..5ecccc2
--- /dev/null
+++ b/TypeScript/5ReplaceMethod/types/models/spt/config/IItemConfig.d.ts
@@ -0,0 +1,5 @@
+import { IBaseConfig } from "./IBaseConfig";
+export interface IItemConfig extends IBaseConfig {
+    kind: "aki-item";
+    blacklist: string[];
+}
diff --git a/TypeScript/5ReplaceMethod/types/models/spt/config/IPmcConfig.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/config/IPmcConfig.d.ts
new file mode 100644
index 0000000..655b58d
--- /dev/null
+++ b/TypeScript/5ReplaceMethod/types/models/spt/config/IPmcConfig.d.ts
@@ -0,0 +1,22 @@
+import { MinMax } from "../../common/MinMax";
+export interface IPmcConfig {
+    dynamicLoot: DynamicLoot;
+    useDifficultyOverride: boolean;
+    difficulty: string;
+    looseWeaponInBackpackChancePercent: number;
+    looseWeaponInBackpackLootMinMax: MinMax;
+    isUsec: number;
+    chanceSameSideIsHostilePercent: number;
+    usecType: string;
+    bearType: string;
+    maxBackpackLootTotalRub: number;
+    maxPocketLootTotalRub: number;
+    maxVestLootTotalRub: number;
+    convertIntoPmcChance: Record<string, MinMax>;
+    enemyTypes: string[];
+}
+export interface DynamicLoot {
+    whitelist: string[];
+    blacklist: string[];
+    moneyStackLimits: Record<string, number>;
+}
diff --git a/TypeScript/5ReplaceMethod/types/models/spt/config/IQuestConfig.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/config/IQuestConfig.d.ts
index be4a97b..45c9aae 100644
--- a/TypeScript/5ReplaceMethod/types/models/spt/config/IQuestConfig.d.ts
+++ b/TypeScript/5ReplaceMethod/types/models/spt/config/IQuestConfig.d.ts
@@ -4,6 +4,8 @@ export interface IQuestConfig extends IBaseConfig {
     kind: "aki-quest";
     redeemTime: number;
     repeatableQuests: IRepeatableQuestConfig[];
+    bearOnlyQuests: string[];
+    usecOnlyQuests: string[];
 }
 export interface IRepeatableQuestConfig {
     name: string;
@@ -15,6 +17,10 @@ export interface IRepeatableQuestConfig {
     locations: Record<ELocationName, string[]>;
     traderWhitelist: ITraderWhitelist[];
     questConfig: IQuestConfig;
+    /** Item base types to block when generating rewards */
+    rewardBaseTypeBlacklist: string[];
+    /** Item tplIds to ignore when generating rewards */
+    rewardBlacklist: string[];
 }
 export interface IRewardScaling {
     levels: number[];
diff --git a/TypeScript/5ReplaceMethod/types/models/spt/config/IRagfairConfig.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/config/IRagfairConfig.d.ts
index 6369eda..3088717 100644
--- a/TypeScript/5ReplaceMethod/types/models/spt/config/IRagfairConfig.d.ts
+++ b/TypeScript/5ReplaceMethod/types/models/spt/config/IRagfairConfig.d.ts
@@ -12,6 +12,7 @@ export interface Sell {
     chance: Chance;
     time: Time;
     reputation: Reputation;
+    simulatedSellHours: number;
 }
 export interface Chance {
     base: number;
diff --git a/TypeScript/5ReplaceMethod/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/config/ITraderConfig.d.ts
index c8e8044..6b1c1e3 100644
--- a/TypeScript/5ReplaceMethod/types/models/spt/config/ITraderConfig.d.ts
+++ b/TypeScript/5ReplaceMethod/types/models/spt/config/ITraderConfig.d.ts
@@ -12,8 +12,10 @@ export interface UpdateTime {
     seconds: number;
 }
 export interface FenceConfig {
+    partialRefreshTimeSeconds: number;
+    partialRefreshChangePercent: number;
     assortSize: number;
-    maxPresetsCount: number;
+    maxPresetsPercent: number;
     presetPriceMult: number;
     blacklist: string[];
 }
diff --git a/TypeScript/5ReplaceMethod/types/models/spt/services/LootItem.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/services/LootItem.d.ts
new file mode 100644
index 0000000..2838472
--- /dev/null
+++ b/TypeScript/5ReplaceMethod/types/models/spt/services/LootItem.d.ts
@@ -0,0 +1,5 @@
+export declare class LootItem {
+    tpl: string;
+    isPreset: boolean;
+    stackCount: number;
+}
diff --git a/TypeScript/5ReplaceMethod/types/models/spt/services/LootRequest.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/5ReplaceMethod/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/5ReplaceMethod/types/services/BotEquipmentFilterService.d.ts b/TypeScript/5ReplaceMethod/types/services/BotEquipmentFilterService.d.ts
index e49645b..632f961 100644
--- a/TypeScript/5ReplaceMethod/types/services/BotEquipmentFilterService.d.ts
+++ b/TypeScript/5ReplaceMethod/types/services/BotEquipmentFilterService.d.ts
@@ -1,12 +1,12 @@
 import { IBotType } from "../models/eft/common/tables/IBotType";
-import { Equipment, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 export declare class BotEquipmentFilterService {
     protected logger: ILogger;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    protected botEquipmentFilterlists: Record<string, Equipment>;
+    protected botEquipmentFilterlists: Record<string, EquipmentFilters>;
     constructor(logger: ILogger, configServer: ConfigServer);
     /**
      * Filter a bots data to exclude equipment and cartridges defines in the botConfig
@@ -22,7 +22,7 @@ export declare class BotEquipmentFilterService {
      * @param playerLevel Level of the player
      * @returns EquipmentBlacklistDetails object
      */
-    protected getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
+    getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
     /**
      * Get the whitelist for a specific bot type that's within the players level
      * @param botRole Bot type
diff --git a/TypeScript/5ReplaceMethod/types/services/FenceService.d.ts b/TypeScript/5ReplaceMethod/types/services/FenceService.d.ts
index c9e325e..c940507 100644
--- a/TypeScript/5ReplaceMethod/types/services/FenceService.d.ts
+++ b/TypeScript/5ReplaceMethod/types/services/FenceService.d.ts
@@ -12,6 +12,11 @@ import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+import { ItemFilterService } from "./ItemFilterService";
+/**
+ * Handle actions surrounding Fence
+ * e.g. generating or refreshing assorts / get next refresh time
+ */
 export declare class FenceService {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
@@ -22,18 +27,64 @@ export declare class FenceService {
     protected handbookHelper: HandbookHelper;
     protected itemHelper: ItemHelper;
     protected presetHelper: PresetHelper;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected fenceAssort: ITraderAssort;
     protected traderConfig: ITraderConfig;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, configServer: ConfigServer);
+    protected nextMiniRefreshTimestamp: number;
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, itemFilterService: ItemFilterService, configServer: ConfigServer);
     protected setFenceAssort(fenceAssort: ITraderAssort): void;
-    getFenceAssorts(): ITraderAssort;
+    /**
+     * Get assorts player can purchase
+     * Adjust prices based on fence level of player
+     * @param pmcProfile Player profile
+     * @returns ITraderAssort
+     */
+    getFenceAssorts(pmcProfile: IPmcData): ITraderAssort;
+    /**
+     * Get fence assorts with no price adjustments based on fence rep
+     * @returns ITraderAssort
+     */
+    getRawFenceAssorts(): ITraderAssort;
+    /**
+     * Does fence need to perform a partial refresh because its passed the refresh timer defined in trader.json
+     * @returns true if it needs a partial refresh
+     */
+    needsPartialRefresh(): boolean;
+    /**
+     * Replace a percentage of fence assorts with freshly generated items
+     */
+    performPartialRefresh(): void;
+    /**
+     * Choose an item (not mod) at random and remove from assorts
+     */
+    protected removeRandomItemFromAssorts(): void;
+    /**
+     * Get an integer rounded count of items to replace based on percentrage from traderConfig value
+     * @param totalItemCount total item count
+     * @returns rounded int of items to replace
+     */
+    protected getCountOfItemsToReplace(totalItemCount: number): number;
     /**
      * Get the count of items fence offers
      * @returns number
      */
     getOfferCount(): number;
-    generateFenceAssortCache(pmcData: IPmcData): void;
+    /**
+     * Create a trader assort for fence
+     */
+    generateFenceAssortCache(): void;
+    /**
+     * Create skeleton to hold assort items
+     * @returns ITraderAssort object
+     */
+    protected createBaseTraderAssortItem(): ITraderAssort;
+    /**
+     * Hydrate result parameter object with generated assorts
+     * @param assortCount Number of assorts to generate
+     * @param assorts object to add assorts to
+     */
+    protected createAssorts(assortCount: number, assorts: ITraderAssort): void;
     /**
      * Get the next update timestamp for fence
      * @returns future timestamp
@@ -44,11 +95,14 @@ export declare class FenceService {
      */
     protected getFenceRefreshTime(): number;
     /**
-     * Get the fence level the passed in profile has
+     * Get fence level the passed in profile has
      * @param pmcData Player profile
-     * @returns FenceLevel
+     * @returns FenceLevel object
      */
     getFenceInfo(pmcData: IPmcData): FenceLevel;
+    /**
+     * Remove an assort from fence by id
+     * @param assortIdToRemove assort id to remove from fence assorts
+     */
     removeFenceOffer(assortIdToRemove: string): void;
-    updateFenceOffers(pmcData: IPmcData): void;
 }
diff --git a/TypeScript/5ReplaceMethod/types/services/InsuranceService.d.ts b/TypeScript/5ReplaceMethod/types/services/InsuranceService.d.ts
index 171bf10..6be8a2f 100644
--- a/TypeScript/5ReplaceMethod/types/services/InsuranceService.d.ts
+++ b/TypeScript/5ReplaceMethod/types/services/InsuranceService.d.ts
@@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
 import { SecureContainerHelper } from "../helpers/SecureContainerHelper";
 import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
+import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData";
 import { IInsuranceConfig } from "../models/spt/config/IInsuranceConfig";
@@ -44,8 +45,22 @@ export declare class InsuranceService {
      * @param mapId Id of the map player died/exited that caused the insurance to be issued on
      */
     sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void;
+    /**
+     * Store lost gear post-raid inside profile
+     * @param pmcData player profile to store gear in
+     * @param offraidData post-raid request object
+     * @param preRaidGear gear player wore prior to raid
+     * @param sessionID Session id
+     */
     storeLostGear(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
     storeInsuredItemsForReturn(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
-    protected addGearToSend(pmcData: IPmcData, insuredItem: any, actualItem: any, sessionID: string): any;
+    /**
+     * Add gear item to InsuredItems array in player profile
+     * @param pmcData profile to store item in
+     * @param insuredItem Item to store in profile
+     * @param actualItem item to store
+     * @param sessionID Session id
+     */
+    protected addGearToSend(pmcData: IPmcData, insuredItem: InsuredItem, actualItem: Item, sessionID: string): void;
     getPremium(pmcData: IPmcData, inventoryItem: Item, traderId: string): number;
 }
diff --git a/TypeScript/5ReplaceMethod/types/services/ItemFilterService.d.ts b/TypeScript/5ReplaceMethod/types/services/ItemFilterService.d.ts
new file mode 100644
index 0000000..c9c8ef3
--- /dev/null
+++ b/TypeScript/5ReplaceMethod/types/services/ItemFilterService.d.ts
@@ -0,0 +1,24 @@
+import { IItemConfig } from "../models/spt/config/IItemConfig";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+/** Centralise the handling of blacklisting items, uses blacklist found in config/item.json */
+export declare class ItemFilterService {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected configServer: ConfigServer;
+    protected blacklist: string[];
+    protected itemConfig: IItemConfig;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer);
+    /**
+     * Check if the provided template id is blacklisted in config/item.json
+     * @param tpl template id
+     * @returns true if blacklisted
+     */
+    isItemBlacklisted(tpl: string): boolean;
+    /**
+     * Return every template id blacklisted in config/item.json
+     * @returns string array of blacklisted tempalte ids
+     */
+    getBlacklistedItems(): string[];
+}
diff --git a/TypeScript/5ReplaceMethod/types/services/ProfileFixerService.d.ts b/TypeScript/5ReplaceMethod/types/services/ProfileFixerService.d.ts
index ed1dec7..9cb5a38 100644
--- a/TypeScript/5ReplaceMethod/types/services/ProfileFixerService.d.ts
+++ b/TypeScript/5ReplaceMethod/types/services/ProfileFixerService.d.ts
@@ -45,6 +45,11 @@ export declare class ProfileFixerService {
      * @param pmcProfile Profile to find and remove slots from
      */
     protected removeResourcesFromSlotsInHideoutWithoutLocationIndexValue(pmcProfile: IPmcData): void;
+    /**
+     * Hideout slots need to be in a specific order, locationIndex in ascending order
+     * @param pmcProfile profile to edit
+     */
+    protected reorderHideoutAreasWithResouceInputs(pmcProfile: IPmcData): void;
     /**
      * add in objects equal to the number of slots
      * @param areaType area to check
diff --git a/TypeScript/5ReplaceMethod/types/utils/HashUtil.d.ts b/TypeScript/5ReplaceMethod/types/utils/HashUtil.d.ts
index bacbf2a..a8500e1 100644
--- a/TypeScript/5ReplaceMethod/types/utils/HashUtil.d.ts
+++ b/TypeScript/5ReplaceMethod/types/utils/HashUtil.d.ts
@@ -4,8 +4,18 @@ import { TimeUtil } from "./TimeUtil";
 export declare class HashUtil {
     protected timeUtil: TimeUtil;
     constructor(timeUtil: TimeUtil);
+    /**
+     * Create a 24 character id using the sha256 algorithm + current timestamp
+     * @returns 24 character hash
+     */
     generate(): string;
     generateMd5ForData(data: string): string;
     generateSha1ForData(data: string): string;
+    /**
+     * Create a hash for the data parameter
+     * @param algorithm algorithm to use to hash
+     * @param data data to be hashed
+     * @returns hash value
+     */
     generateHashForData(algorithm: string, data: crypto.BinaryLike): string;
 }
diff --git a/TypeScript/5ReplaceMethod/types/utils/RandomUtil.d.ts b/TypeScript/5ReplaceMethod/types/utils/RandomUtil.d.ts
index c24dd60..e35d21f 100644
--- a/TypeScript/5ReplaceMethod/types/utils/RandomUtil.d.ts
+++ b/TypeScript/5ReplaceMethod/types/utils/RandomUtil.d.ts
@@ -150,4 +150,10 @@ export declare class RandomUtil {
      */
     drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[];
     getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number;
+    /**
+     * Fisher-Yates shuffle an array
+     * @param array Array to shuffle
+     * @returns Shuffled array
+     */
+    shuffle<T>(array: Array<T>): Array<T>;
 }
diff --git a/TypeScript/5ReplaceMethod/types/utils/TimeUtil.d.ts b/TypeScript/5ReplaceMethod/types/utils/TimeUtil.d.ts
index f437f8a..1367e26 100644
--- a/TypeScript/5ReplaceMethod/types/utils/TimeUtil.d.ts
+++ b/TypeScript/5ReplaceMethod/types/utils/TimeUtil.d.ts
@@ -1,3 +1,6 @@
+/**
+ * Utility class to handle time related problems
+ */
 export declare class TimeUtil {
     static readonly oneHourAsSeconds = 3600;
     formatTime(date: Date): string;
@@ -19,4 +22,10 @@ export declare class TimeUtil {
      * @returns current date in format: 00.00.0000 (dd.mm.yyyy)
      */
     getDateMailFormat(): string;
+    /**
+     * Convert hours into seconds
+     * @param hours hours to convert to seconds
+     * @returns number
+     */
+    getHoursAsSeconds(hours: number): number;
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/callbacks/LocationCallbacks.d.ts b/TypeScript/6ReferenceAnotherClass/types/callbacks/LocationCallbacks.d.ts
index cc69369..6e0b538 100644
--- a/TypeScript/6ReferenceAnotherClass/types/callbacks/LocationCallbacks.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/callbacks/LocationCallbacks.d.ts
@@ -11,4 +11,5 @@ export declare class LocationCallbacks {
     constructor(httpResponse: HttpResponseUtil, locationController: LocationController);
     getLocationData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<ILocationsGenerateAllResponse>;
     getLocation(url: string, info: IGetLocationRequestData, sessionID: string): IGetBodyResponseData<ILocationBase>;
+    getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): string;
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/callbacks/ProfileCallbacks.d.ts b/TypeScript/6ReferenceAnotherClass/types/callbacks/ProfileCallbacks.d.ts
index 6a86fc0..183bb0a 100644
--- a/TypeScript/6ReferenceAnotherClass/types/callbacks/ProfileCallbacks.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/callbacks/ProfileCallbacks.d.ts
@@ -1,5 +1,6 @@
 import { ProfileController } from "../controllers/ProfileController";
 import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData";
+import { IPmcData } from "../models/eft/common/IPmcData";
 import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData";
 import { INullResponseData } from "../models/eft/httpResponse/INullResponseData";
 import { IGetMiniProfileRequestData } from "../models/eft/launcher/IGetMiniProfileRequestData";
@@ -12,20 +13,51 @@ import { ISearchFriendResponse } from "../models/eft/profile/ISearchFriendRespon
 import { IValidateNicknameRequestData } from "../models/eft/profile/IValidateNicknameRequestData";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/** Handle profile related client events */
 export declare class ProfileCallbacks {
     protected httpResponse: HttpResponseUtil;
     protected timeUtil: TimeUtil;
     protected profileController: ProfileController;
     constructor(httpResponse: HttpResponseUtil, timeUtil: TimeUtil, profileController: ProfileController);
     createProfile(url: string, info: IProfileCreateRequestData, sessionID: string): IGetBodyResponseData<any>;
-    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
-    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
+    /**
+     * Get the complete player profile (scav + pmc character)
+     * @param url
+     * @param info Empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle the creation of a scav profile for player
+     * Occurs post-raid and when profile first created immediately after character details are confirmed by player
+     * @param url
+     * @param info empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle client/game/profile/voice/change event
+     * @param url
+     * @param info Change voice request object
+     * @param sessionID Session id
+     * @returns Client response
+     */
     changeVoice(url: string, info: IProfileChangeVoiceRequestData, sessionID: string): INullResponseData;
+    /**
+     * Handle client/game/profile/nickname/change event
+     * Client allows player to adjust their profile name
+     * @param url
+     * @param info Change nickname request object
+     * @param sessionID Session id
+     * @returns client response
+     */
     changeNickname(url: string, info: IProfileChangeNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     validateNickname(url: string, info: IValidateNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     getReservedNickname(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<string>;
     /**
-     * Called when creating a character, when you choose a character face/voice
+     * Called when creating a character when choosing a character face/voice
      * @param url
      * @param info response (empty)
      * @param sessionID
diff --git a/TypeScript/6ReferenceAnotherClass/types/callbacks/RagfairCallbacks.d.ts b/TypeScript/6ReferenceAnotherClass/types/callbacks/RagfairCallbacks.d.ts
index 3a405c9..c609f2f 100644
--- a/TypeScript/6ReferenceAnotherClass/types/callbacks/RagfairCallbacks.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/callbacks/RagfairCallbacks.d.ts
@@ -19,6 +19,9 @@ import { ConfigServer } from "../servers/ConfigServer";
 import { RagfairServer } from "../servers/RagfairServer";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+/**
+ * Handle ragfair related callback events
+ */
 export declare class RagfairCallbacks extends OnLoadOnUpdate {
     protected httpResponse: HttpResponseUtil;
     protected logger: ILogger;
diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/InraidController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/InraidController.d.ts
index 82bb64d..102a2fb 100644
--- a/TypeScript/6ReferenceAnotherClass/types/controllers/InraidController.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/controllers/InraidController.d.ts
@@ -35,6 +35,30 @@ export declare class InraidController {
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer);
     addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void;
     saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Handle updating the profile post-pmc raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Reduce body part hp to % of max
+     * @param pmcData profile to edit
+     * @param multipler multipler to apply to max health
+     */
+    protected reducePmcHealthToPercent(pmcData: IPmcData, multipler: number): void;
+    /**
+     * Handle updating the profile post-pscav raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePlayerScavProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Is the player dead after a raid - dead is anything other than "survived" / "runner"
+     * @param statusOnExit exit value from offraidData object
+     * @returns true if dead
+     */
+    protected isPlayerDead(statusOnExit: string): boolean;
     /**
      * Mark inventory items as FiR if player survived raid, otherwise remove FiR from them
      * @param offraidData Save Progress Request
diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/InventoryController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/InventoryController.d.ts
index f57f731..f564919 100644
--- a/TypeScript/6ReferenceAnotherClass/types/controllers/InventoryController.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/controllers/InventoryController.d.ts
@@ -92,7 +92,11 @@ export declare class InventoryController {
      */
     toggleItem(pmcData: IPmcData, body: IInventoryToggleRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Handles Tagging of items (primary Containers).
+     * Add a tag to an inventory item
+     * @param pmcData profile with item to add tag to
+     * @param body tag request data
+     * @param sessionID session id
+     * @returns client response object
      */
     tagItem(pmcData: IPmcData, body: IInventoryTagRequestData, sessionID: string): IItemEventRouterResponse;
     bindItem(pmcData: IPmcData, body: IInventoryBindRequestData, sessionID: string): IItemEventRouterResponse;
diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/LocationController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/LocationController.d.ts
index 90b6d7a..9db3205 100644
--- a/TypeScript/6ReferenceAnotherClass/types/controllers/LocationController.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/controllers/LocationController.d.ts
@@ -1,18 +1,33 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class LocationController {
     protected jsonUtil: JsonUtil;
+    protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/MatchController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/MatchController.d.ts
index e8585d9..cb40023 100644
--- a/TypeScript/6ReferenceAnotherClass/types/controllers/MatchController.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/controllers/MatchController.d.ts
@@ -9,6 +9,7 @@ import { IGetProfileRequestData } from "../models/eft/match/IGetProfileRequestDa
 import { IJoinMatchRequestData } from "../models/eft/match/IJoinMatchRequestData";
 import { IJoinMatchResult } from "../models/eft/match/IJoinMatchResult";
 import { IStartOfflineRaidRequestData } from "../models/eft/match/IStartOffineRaidRequestData";
+import { IBotConfig } from "../models/spt/config/IBotConfig";
 import { IInRaidConfig } from "../models/spt/config/IInRaidConfig";
 import { IMatchConfig } from "../models/spt/config/IMatchConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
@@ -29,6 +30,7 @@ export declare class MatchController {
     protected applicationContext: ApplicationContext;
     protected matchConfig: IMatchConfig;
     protected inraidConfig: IInRaidConfig;
+    protected botConfig: IBotConfig;
     constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, applicationContext: ApplicationContext);
     getEnabled(): boolean;
     getProfile(info: IGetProfileRequestData): IPmcData[];
diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/QuestController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/QuestController.d.ts
index 2cbccfb..282f50e 100644
--- a/TypeScript/6ReferenceAnotherClass/types/controllers/QuestController.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/controllers/QuestController.d.ts
@@ -39,16 +39,31 @@ export declare class QuestController {
      * @returns array of IQuest
      */
     getClientQuests(sessionID: string): IQuest[];
+    /**
+     * Is the quest for the opposite side the player is on
+     * @param side player side (usec/bear)
+     * @param questId questId to check
+     */
+    protected questIsForOtherSide(side: string, questId: string): boolean;
+    /**
+     * Handle the client accepting a quest and starting it
+     * Send starting rewards if any to player and
+     * Send start notification if any to player
+     * @param pmcData Profile to update
+     * @param acceptedQuest Quest accepted
+     * @param sessionID Session id
+     * @returns client response
+     */
     acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Remove completed quest from profile
+     * Update completed quest in profile
      * Add newly unlocked quests to profile
      * Also recalculate thier level due to exp rewards
      * @param pmcData Player profile
-     * @param body completed quest request
-     * @param sessionID session id
-     * @returns ItemEvent response
+     * @param body Completed quest request
+     * @param sessionID Session id
+     * @returns ItemEvent client response
      */
     completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
@@ -67,10 +82,20 @@ export declare class QuestController {
     protected getQuestsFailedByCompletingQuest(completedQuestId: string): IQuest[];
     /**
      * Fail the quests provided
+     * Update quest in profile, otherwise add fresh quest object with failed status
      * @param sessionID session id
      * @param pmcData player profile
      * @param questsToFail quests to fail
      */
     protected failQuests(sessionID: string, pmcData: IPmcData, questsToFail: IQuest[]): void;
     handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment a backend counter stored value by an amount,
+     * Create counter if it does not exist
+     * @param pmcData Profile to find backend counter in
+     * @param conditionId backend counter id to update
+     * @param questId quest id counter is associated with
+     * @param counterValue value to increment the backend counter with
+     */
+    protected updateProfileBackendCounterValue(pmcData: IPmcData, conditionId: string, questId: string, counterValue: number): void;
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/RagfairController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/RagfairController.d.ts
index c4ffc15..06af740 100644
--- a/TypeScript/6ReferenceAnotherClass/types/controllers/RagfairController.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/controllers/RagfairController.d.ts
@@ -9,6 +9,7 @@ import { RagfairOfferHelper } from "../helpers/RagfairOfferHelper";
 import { RagfairSellHelper } from "../helpers/RagfairSellHelper";
 import { RagfairSortHelper } from "../helpers/RagfairSortHelper";
 import { RagfairTaxHelper } from "../helpers/RagfairTaxHelper";
+import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
@@ -33,6 +34,9 @@ import { RagfairPriceService } from "../services/RagfairPriceService";
 import { RagfairRequiredItemsService } from "../services/RagfairRequiredItemsService";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/**
+ * Handle RagfairCallback events
+ */
 export declare class RagfairController {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
@@ -52,14 +56,20 @@ export declare class RagfairController {
     protected handbookHelper: HandbookHelper;
     protected paymentHelper: PaymentHelper;
     protected inventoryHelper: InventoryHelper;
+    protected traderHelper: TraderHelper;
     protected ragfairHelper: RagfairHelper;
     protected ragfairOfferService: RagfairOfferService;
     protected ragfairRequiredItemsService: RagfairRequiredItemsService;
     protected ragfairOfferGenerator: RagfairOfferGenerator;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
     getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult;
+    /**
+     * Update a trader flea offer with buy restrictions stored in the traders assort
+     * @param offer flea offer to update
+     */
+    protected setTraderOfferPurchaseLimits(offer: IRagfairOffer): void;
     protected isLinkedSearch(info: ISearchRequestData): boolean;
     protected isRequiredSearch(info: ISearchRequestData): boolean;
     update(): void;
diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/RepeatableQuestController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/RepeatableQuestController.d.ts
index 98d05dd..4c31a3d 100644
--- a/TypeScript/6ReferenceAnotherClass/types/controllers/RepeatableQuestController.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/controllers/RepeatableQuestController.d.ts
@@ -7,6 +7,7 @@ import { Exit } from "../models/eft/common/ILocationBase";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { TraderInfo } from "../models/eft/common/tables/IBotBase";
 import { ICompletion, ICompletionAvailableFor, IElimination, IEliminationCondition, IExploration, IExplorationCondition, IPmcDataRepeatableQuest, IRepeatableQuest, IReward, IRewards } from "../models/eft/common/tables/IRepeatableQuests";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
 import { IRepeatableQuestChangeRequest } from "../models/eft/quests/IRepeatableQuestChangeRequest";
 import { ELocationName } from "../models/enums/ELocationName";
@@ -15,6 +16,7 @@ import { ILogger } from "../models/spt/utils/ILogger";
 import { ItemEventRouter } from "../routers/ItemEventRouter";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { PaymentService } from "../services/PaymentService";
 import { ProfileFixerService } from "../services/ProfileFixerService";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -64,9 +66,10 @@ export declare class RepeatableQuestController {
     protected itemEventRouter: ItemEventRouter;
     protected paymentService: PaymentService;
     protected objectId: ObjectId;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
-    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, configServer: ConfigServer);
+    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint
      * Returns an array of objects in the format of repeatable quests to the client.
@@ -217,4 +220,16 @@ export declare class RepeatableQuestController {
     debugLogRepeatableQuestIds(pmcData: IPmcData): void;
     probabilityObjectArray<K, V>(configArrayInput: ProbabilityObject<K, V>[]): ProbabilityObjectArray<K, V>;
     changeRepeatableQuest(pmcDataIn: IPmcData, body: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
+     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
+     */
+    protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig): [string, ITemplateItem][];
+    /**
+     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
+     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
+     * @param {*} tpl template id of item to check
+     * @returns boolean: true if item is valid reward
+     */
+    isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig): boolean;
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/TraderController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/TraderController.d.ts
index 0162064..b79f55e 100644
--- a/TypeScript/6ReferenceAnotherClass/types/controllers/TraderController.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/controllers/TraderController.d.ts
@@ -4,6 +4,7 @@ import { TraderHelper } from "../helpers/TraderHelper";
 import { IBarterScheme, ITraderAssort, ITraderBase } from "../models/eft/common/tables/ITrader";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { FenceService } from "../services/FenceService";
 import { TraderAssortService } from "../services/TraderAssortService";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
@@ -15,8 +16,9 @@ export declare class TraderController {
     protected traderHelper: TraderHelper;
     protected timeUtil: TimeUtil;
     protected traderAssortService: TraderAssortService;
+    protected fenceService: FenceService;
     protected jsonUtil: JsonUtil;
-    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, jsonUtil: JsonUtil);
+    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, fenceService: FenceService, jsonUtil: JsonUtil);
     /**
      * Runs when onLoad event is fired
      * Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
@@ -26,6 +28,7 @@ export declare class TraderController {
     /**
      * Runs when onUpdate is fired
      * If current time is > nextResupply(expire) time of trader, refresh traders assorts and
+     * Fence is handled slightly differently
      * @returns has run
      */
     update(): boolean;
diff --git a/TypeScript/6ReferenceAnotherClass/types/di/Container.d.ts b/TypeScript/6ReferenceAnotherClass/types/di/Container.d.ts
index 17791b0..98d1fa1 100644
--- a/TypeScript/6ReferenceAnotherClass/types/di/Container.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/di/Container.d.ts
@@ -1,4 +1,7 @@
 import { DependencyContainer } from "tsyringe";
+/**
+ * Handle the registration of classes to be used by the Dependency Injection code
+ */
 export declare class Container {
     static registerTypes(depContainer: DependencyContainer): void;
     static registerListTypes(depContainer: DependencyContainer): void;
diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/BotGenerator.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/BotGenerator.d.ts
index a5fc0ad..7d58f95 100644
--- a/TypeScript/6ReferenceAnotherClass/types/generators/BotGenerator.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/generators/BotGenerator.d.ts
@@ -40,7 +40,7 @@ export declare class BotGenerator {
      * @param botTemplate base bot template to use  (e.g. assault/pmcbot)
      * @returns
      */
-    generatePlayerScav(role: string, difficulty: string, botTemplate: IBotType): IBotBase;
+    generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase;
     generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[];
     /**
      * Choose if a bot should become a PMC by checking if bot type is allowed to become a Pmc in botConfig.convertFromChances and doing a random int check
@@ -58,7 +58,7 @@ export declare class BotGenerator {
      * @returns IBotBase object
      */
     protected getCloneOfBotBase(): IBotBase;
-    protected generateBot(bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
+    protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
     /**
      * Log the number of PMCs generated to the debug console
      */
diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/BotInventoryGenerator.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/BotInventoryGenerator.d.ts
index 35d1ee8..73f8ece 100644
--- a/TypeScript/6ReferenceAnotherClass/types/generators/BotInventoryGenerator.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/generators/BotInventoryGenerator.d.ts
@@ -18,7 +18,7 @@ export declare class BotInventoryGenerator {
     protected botGeneratorHelper: BotGeneratorHelper;
     protected weightedRandomHelper: WeightedRandomHelper;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper);
-    generateInventory(templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
+    generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
     protected generateEquipment(equipmentSlot: string, equipmentPool: Record<string, number>, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void;
     protected generateInventoryBase(): PmcInventory;
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/BotLootGenerator.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/BotLootGenerator.d.ts
index c6a3f29..5a2d144 100644
--- a/TypeScript/6ReferenceAnotherClass/types/generators/BotLootGenerator.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/generators/BotLootGenerator.d.ts
@@ -24,7 +24,7 @@ export declare class BotLootGenerator {
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botLootCacheService: BotLootCacheService, configServer: ConfigServer);
-    generateLoot(templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
+    generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
     protected getRandomisedCount(min: number, max: number, nValue: number): number;
     /**
      * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached
@@ -47,7 +47,7 @@ export declare class BotLootGenerator {
      * @param botRole bots role, .e.g. pmcBot
      * @param isPmc are we generating for a pmc
      */
-    protected addLooseWeaponsToInventorySlot(botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
+    protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
     /**
      * Get a random item from the pool parameter using the biasedRandomNumber system
      * @param pool pool of items to pick an item from
diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/BotWeaponGenerator.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/BotWeaponGenerator.d.ts
index 9215214..49fa7bf 100644
--- a/TypeScript/6ReferenceAnotherClass/types/generators/BotWeaponGenerator.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/generators/BotWeaponGenerator.d.ts
@@ -28,7 +28,18 @@ export declare class BotWeaponGenerator {
     protected botConfig: IBotConfig;
     constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer);
     /**
-     * Get a random weapon from a bots pool of weapons (weighted)
+     * Pick a random weapon based on weightings and generate a functional weapon
+     * @param equipmentSlot Primary/secondary/holster
+     * @param botTemplateInventory e.g. assault.json
+     * @param weaponParentId
+     * @param modChances
+     * @param botRole role of bot, e.g. assault/followerBully
+     * @param isPmc Is weapon generated for a pmc
+     * @returns GenerateWeaponResult object
+     */
+    generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    /**
+     * Get a random weighted weapon from a bots pool of weapons
      * @param equipmentSlot Primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
      * @returns weapon tpl
@@ -39,43 +50,24 @@ export declare class BotWeaponGenerator {
      * @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool())
      * @param equipmentSlot slot to fit into, primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
+     * @param weaponParentId ParentId of the weapon being generated
+     * @param modChances Dictionary of item types and % chance weapon will have that mod
+     * @param botRole e.g. assault/exusec
      * @param isPmc
      * @returns GenerateWeaponResult object
      */
-    generateWeaponByTpl(weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
     /**
-     * Generate an entirely random weapon
-     * @param equipmentSlot Primary/secondary/holster
-     * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
-     * @param isPmc
-     * @returns GenerateWeaponResult object
-     */
-    generateRandomWeapon(equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
-    /**
-     * Create array with weapon base as only element
-     * Add additional properties as required
-     * @param weaponTpl
-     * @param weaponParentId
-     * @param equipmentSlot
-     * @param weaponItemTemplate
+     * Create array with weapon base as only element and
+     * add additional properties based on weapon type
+     * @param weaponTpl Weapon tpl to create item with
+     * @param weaponParentId Weapons parent id
+     * @param equipmentSlot e.g. primary/secondary/holster
+     * @param weaponItemTemplate db template for weapon
      * @param botRole for durability values
-     * @returns
+     * @returns Base weapon item in array
      */
     constructWeaponBaseArray(weaponTpl: string, weaponParentId: string, equipmentSlot: string, weaponItemTemplate: ITemplateItem, botRole: string): Item[];
-    /**
-     * Add compatible magazines to an inventory based on a generated weapon
-     * @param weaponDetails
-     * @param magCounts
-     * @param inventory
-     * @param botRole the bot type we're getting generating extra mags for
-     */
-    addExtraMagazinesToInventory(weaponDetails: GenerateWeaponResult, magCounts: MinMax, inventory: PmcInventory, botRole: string): void;
     /**
      * Get the mods necessary to kit out a weapon to its preset level
      * @param weaponTpl weapon to find preset for
@@ -84,20 +76,32 @@ export declare class BotWeaponGenerator {
      * @returns array of weapon mods
      */
     protected getPresetWeaponMods(weaponTpl: string, equipmentSlot: string, weaponParentId: string, itemTemplate: ITemplateItem, botRole: string): Item[];
-    /** Checks if all required slots are occupied on a weapon and all it's mods */
+    /**
+     * Checks if all required slots are occupied on a weapon and all it's mods
+     * @param weaponItemArray Weapon + mods
+     * @returns true if valid
+     */
     protected isWeaponValid(weaponItemArray: Item[]): boolean;
     /**
      * Generates extra magazines or bullets (if magazine is internal) and adds them to TacticalVest and Pockets.
      * Additionally, adds extra bullets to SecuredContainer
-     * @param weaponMods
-     * @param weaponTemplate
-     * @param magCounts
-     * @param ammoTpl
-     * @param inventory
+     * @param weaponMods mods to attach to weapon
+     * @param weaponTemplate db template for weapon
+     * @param magCounts magazine count to add to inventory
+     * @param ammoTpl ammo templateId to add to magazines
+     * @param inventory inventory to add magazines to
      * @param botRole the bot type we're getting generating extra mags for
      * @returns
      */
-    protected generateExtraMagazines(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    addExtraMagazinesToInventory(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    /**
+     * Create a magazine using the parameters given
+     * @param magazineTpl Tpl of the magazine to create
+     * @param ammoTpl Ammo to add to magazine
+     * @param magTemplate template object of magazine
+     * @returns Item array
+     */
+    protected createMagazine(magazineTpl: string, ammoTpl: string, magTemplate: ITemplateItem): Item[];
     /**
      * Get a randomised number of bullets for a specific magazine
      * @param magCounts min and max count of magazines
@@ -138,10 +142,9 @@ export declare class BotWeaponGenerator {
      * Finds and return a compatible ammo tpl based on the bots ammo weightings (x.json/inventory/equipment/ammo)
      * @param ammo a list of ammo tpls the weapon can use
      * @param weaponTemplate the weapon we want to pick ammo for
-     * @param isPmc is the ammo being gathered for a pmc (runs pmc ammo filtering)
      * @returns an ammo tpl that works with the desired gun
      */
-    protected getCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem, isPmc: boolean): string;
+    protected getWeightedCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem): string;
     /**
      * Get a weapons compatible cartridge caliber
      * @param weaponTemplate Weapon to look up caliber of
diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/LocationGenerator.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/LocationGenerator.d.ts
index bd368b5..cc61dcf 100644
--- a/TypeScript/6ReferenceAnotherClass/types/generators/LocationGenerator.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/generators/LocationGenerator.d.ts
@@ -3,10 +3,9 @@ import { GameEventHelper } from "../helpers/GameEventHelper";
 import { ItemHelper } from "../helpers/ItemHelper";
 import { PresetHelper } from "../helpers/PresetHelper";
 import { RagfairServerHelper } from "../helpers/RagfairServerHelper";
-import { ILooseLoot, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
+import { ILooseLoot, SpawnpointsForced, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IStaticAmmoDetails, IStaticContainerProps, IStaticForcedProps, IStaticLootDetails } from "../models/eft/common/tables/ILootBase";
-import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILocationConfig } from "../models/spt/config/ILocationConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
@@ -36,11 +35,19 @@ export declare class LocationGenerator {
     generateContainerLoot(containerIn: IStaticContainerProps, staticForced: IStaticForcedProps[], staticLootDist: Record<string, IStaticLootDetails>, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): IStaticContainerProps;
     protected getLooseLootMultiplerForLocation(location: string): number;
     protected getStaticLootMultiplerForLocation(location: string): number;
+    /**
+     * Create array of loose + forced loot using probability system
+     * @param dynamicLootDist
+     * @param staticAmmoDist
+     * @param locationName Location to generate loot for
+     * @returns Array of spawn points with loot in them
+     */
     generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): SpawnpointTemplate[];
+    /**
+     * Add forced spawn point loot into loot parameter array
+     * @param loot array to add forced loot to
+     * @param forcedSpawnPoints forced loot to add
+     */
+    protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[]): void;
     protected createItem(tpl: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, parentId?: string): IContainerItem;
-    protected getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
-    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
-    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
-    protected createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
-    protected createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/LootGenerator.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/6ReferenceAnotherClass/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/PMCLootGenerator.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/PMCLootGenerator.d.ts
index 64e6f7f..b9f2a83 100644
--- a/TypeScript/6ReferenceAnotherClass/types/generators/PMCLootGenerator.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/generators/PMCLootGenerator.d.ts
@@ -1,15 +1,21 @@
 import { ItemHelper } from "../helpers/ItemHelper";
-import { DatabaseServer } from "../servers/DatabaseServer";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+/**
+ * Handle the generation of dynamic PMC loot in pockets and backpacks
+ * and the removal of blacklisted items
+ */
 export declare class PMCLootGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected configServer: ConfigServer;
+    protected itemFilterService: ItemFilterService;
     protected pocketLootPool: string[];
     protected backpackLootPool: string[];
     protected botConfig: IBotConfig;
-    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer);
+    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer, itemFilterService: ItemFilterService);
     generatePMCPocketLootPool(): string[];
     generatePMCBackpackLootPool(): string[];
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/ScavCaseRewardGenerator.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/ScavCaseRewardGenerator.d.ts
index c7d6ab7..89cb5c8 100644
--- a/TypeScript/6ReferenceAnotherClass/types/generators/ScavCaseRewardGenerator.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/generators/ScavCaseRewardGenerator.d.ts
@@ -8,9 +8,13 @@ import { RewardCountAndPriceDetails, ScavCaseRewardCountsAndPrices } from "../mo
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { RagfairPriceService } from "../services/RagfairPriceService";
 import { HashUtil } from "../utils/HashUtil";
 import { RandomUtil } from "../utils/RandomUtil";
+/**
+ * Handle the creation of randomised scav case rewards
+ */
 export declare class ScavCaseRewardGenerator {
     protected logger: ILogger;
     protected randomUtil: RandomUtil;
@@ -18,9 +22,10 @@ export declare class ScavCaseRewardGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected ragfairPriceService: RagfairPriceService;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected scavCaseConfig: IScavCaseConfig;
-    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, configServer: ConfigServer);
+    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Create an array of rewards that will be given to the player upon completing their scav case build
      * @param body client request
diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/WeatherGenerator.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/WeatherGenerator.d.ts
index 44cecbb..8ddbe49 100644
--- a/TypeScript/6ReferenceAnotherClass/types/generators/WeatherGenerator.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/generators/WeatherGenerator.d.ts
@@ -1,7 +1,7 @@
 import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IWeatherData } from "../models/eft/weather/IWeatherData";
 import { IWeatherConfig } from "../models/spt/config/IWeatherConfig";
+import { ConfigServer } from "../servers/ConfigServer";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class WeatherGenerator {
@@ -21,11 +21,16 @@ export declare class WeatherGenerator {
     protected getAcceleratedTime(computedDate: Date): string;
     /**
      * Get current time formatted to fit BSGs requirement
-     * @param computedDate
+     * @param computedDate date to format into bsg style
      * @returns
      */
     protected getNormalTime(computedDate: Date): string;
-    generateWeather(data: IWeatherData): IWeatherData;
+    /**
+     * Return randomised Weather data
+     * @param weatherData weather input data
+     * @returns Randomised weather data
+     */
+    generateWeather(weatherData: IWeatherData): IWeatherData;
     protected getWeightedFog(): string;
     protected getWeightedRain(): number;
     protected getRandomFloat(node: string): number;
diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/AssortHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/AssortHelper.d.ts
index 15586b9..bfc157f 100644
--- a/TypeScript/6ReferenceAnotherClass/types/helpers/AssortHelper.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/helpers/AssortHelper.d.ts
@@ -17,7 +17,7 @@ export declare class AssortHelper {
      * @param assort assort items from a trader
      * @returns assort items minus locked quest assorts
      */
-    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort): ITraderAssort;
+    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort, flea?: boolean): ITraderAssort;
     /**
      * Remove assorts from a trader that have not been unlocked yet
      * @param pmcProfile player profile
@@ -32,5 +32,5 @@ export declare class AssortHelper {
      * @param itemID item id to remove from asort
      * @returns Modified assort
      */
-    removeItemFromAssort(assort: ITraderAssort, itemID: string): ITraderAssort;
+    removeItemFromAssort(assort: ITraderAssort, itemID: string, flea?: boolean): ITraderAssort;
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/BotGeneratorHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/BotGeneratorHelper.d.ts
index 3cd7256..eb0d215 100644
--- a/TypeScript/6ReferenceAnotherClass/types/helpers/BotGeneratorHelper.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/helpers/BotGeneratorHelper.d.ts
@@ -3,10 +3,12 @@ import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"
 import { Mods, ModsChances } from "../models/eft/common/tables/IBotType";
 import { Item, Repairable, Upd } from "../models/eft/common/tables/IItem";
 import { Grid, ITemplateItem, Slot } from "../models/eft/common/tables/ITemplateItem";
-import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
@@ -14,6 +16,7 @@ import { ContainerHelper } from "./ContainerHelper";
 import { InventoryHelper } from "./InventoryHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProbabilityHelper } from "./ProbabilityHelper";
+import { ProfileHelper } from "./ProfileHelper";
 export declare class BotGeneratorHelper {
     protected logger: ILogger;
     protected jsonUtil: JsonUtil;
@@ -25,10 +28,76 @@ export declare class BotGeneratorHelper {
     protected itemHelper: ItemHelper;
     protected inventoryHelper: InventoryHelper;
     protected containerHelper: ContainerHelper;
+    protected botEquipmentFilterService: BotEquipmentFilterService;
+    protected itemFilterService: ItemFilterService;
+    protected profileHelper: ProfileHelper;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, configServer: ConfigServer);
-    generateModsForItem(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, configServer: ConfigServer);
+    /**
+     * TODO - very similar to generateModsForWeapon
+     * Check mods are compatible and add to array
+     * @param equipment Equipment item to add mods to
+     * @param modPool Mod list to choose frm
+     * @param parentId parentid of item to add mod to
+     * @param parentTemplate template objet of item to add mods to
+     * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type
+     * @returns Item + compatible mods as an array
+     */
+    generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    /**
+     * TODO - very similar to generateModsForEquipment
+     * @param sessionId session id
+     * @param weapon Weapon to add mods to
+     * @param modPool pool of compatible mods to attach to gun
+     * @param weaponParentId parentId of weapon
+     * @param parentTemplate
+     * @param modSpawnChances
+     * @param ammoTpl ammo tpl to use when generating magazines/cartridges
+     * @param botRole role of bot weapon is generated for
+     * @returns Weapon with mods
+     */
+    generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[];
+    /**
+     * Generate a pool of mods for this bots mod type if bot has values inside `randomisedWeaponModSlots` array found in bot.json/equipment[botrole]
+     * @param allowedMods Mods to be added to mod pool
+     * @param botEquipBlacklist blacklist of items not allowed to be added to mod pool
+     * @param modSlot Slot to generate mods for
+     * @param itemModPool base mod pool to replace values of
+     */
+    protected generateDynamicModPool(allowedMods: string[], botEquipBlacklist: EquipmentFilterDetails, modSlot: string, itemModPool: Record<string, string[]>): void;
+    /**
+     * Check if the specific item type on the weapon has reached the set limit
+     * @param modTpl item to check is limited
+     * @param currentCount current number of this item on gun
+     * @param maxLimit mod limit allowed
+     * @param botRole role of bot we're checking weapon of
+     * @returns true if limit reached
+     */
+    protected weaponModLimitReached(modTpl: string, currentCount: {
+        count: number;
+    }, maxLimit: number, botRole: string): boolean;
+    /**
+     * log errors if mod is not valid for a slot
+     * @param modTpl
+     * @param found
+     * @param itemSlot
+     * @param modTemplate
+     * @param modSlot
+     * @param parentTemplate
+     * @returns true if valid
+     */
+    protected isModValidForSlot(modTpl: string, found: boolean, itemSlot: Slot, modTemplate: ITemplateItem, modSlot: string, parentTemplate: ITemplateItem): boolean;
+    /**
+     * Create a mod item with parameters as properties
+     * @param modId _id
+     * @param modTpl _tpl
+     * @param parentId parentId
+     * @param modSlot slotId
+     * @param modTemplate Used to add additional properites in the upd object
+     * @returns Item object
+     */
+    protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item;
     /**
      * Is this magazine cylinder related (revolvers and grenade launchers)
      * @param magazineParentName the name of the magazines parent
@@ -62,11 +131,11 @@ export declare class BotGeneratorHelper {
      * Those magazines (e.g. 60dc519adf4c47305f6d410d) have a "Cartridges" entry with a _max_count=0.
      * Ammo is not put into the magazine directly but assigned to the magazine's slots: The "camora_xxx" slots.
      * This function is a helper called by generateModsForItem for mods with parent type "CylinderMagazine"
-     *
-     * @param {object}      items               The items where the CylinderMagazine's camora are appended to
-     * @param {object}      modPool             modPool which should include available cartrigdes
-     * @param {string}      parentId            The CylinderMagazine's UID
-     * @param {object}      parentTemplate      The CylinderMagazine's template
+     * @param items The items where the CylinderMagazine's camora are appended to
+     * @param modPool modPool which should include available cartrigdes
+     * @param parentId The CylinderMagazine's UID
+     * @param parentTemplate The CylinderMagazine's template
+     * @returns
      */
     protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void;
     /**
@@ -75,6 +144,13 @@ export declare class BotGeneratorHelper {
      * @returns string array of shells fro luitple camora sources
      */
     protected mergeCamoraPoolsTogether(camorasWithShells: Record<string, string[]>): string[];
+    /**
+     * Adds properties to an item
+     * e.g. Repairable / HasHinge / Foldable / MaxDurability
+     * @param itemTemplate
+     * @param botRole Used by weapons to randomise the durability values
+     * @returns Item Upd object with extra properties
+     */
     generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): {
         upd?: Upd;
     };
@@ -93,12 +169,6 @@ export declare class BotGeneratorHelper {
      */
     protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable;
     protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string;
-    /**
-     * Sort by spawn chance, highest to lowest, higher is more common
-     * @param unsortedModArray String array to sort
-     * @returns Sorted string array
-     */
-    protected sortModArray(unsortedModArray: string[]): string[];
     /**
      * Can an item be added to an item without issue
      * @param items
@@ -117,8 +187,15 @@ export declare class BotGeneratorHelper {
      * @returns a `boolean` indicating item was added
      */
     addItemWithChildrenToEquipmentSlot(equipmentSlots: string[], parentId: string, parentTpl: string, itemWithChildren: Item[], inventory: PmcInventory): boolean;
+    /**
+     * is the provided item allowed inside a container
+     * @param slot location item wants to be placed in
+     * @param itemTpl item being placed
+     * @returns true if allowed
+     */
     protected itemAllowedInContainer(slot: Grid, itemTpl: string): boolean;
 }
+/** TODO - move into own class */
 export declare class ExhaustableArray<T> {
     private itemPool;
     private randomUtil;
diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/HideoutHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/HideoutHelper.d.ts
index 36e4009..7495a6a 100644
--- a/TypeScript/6ReferenceAnotherClass/types/helpers/HideoutHelper.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/helpers/HideoutHelper.d.ts
@@ -44,14 +44,72 @@ export declare class HideoutHelper {
     initProduction(recipeId: string, productionTime: number): Production;
     isProductionType(productive: Productive): productive is Production;
     applyPlayerUpgradesBonuses(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * TODO:
+     * After looking at the skills there doesnt seem to be a configuration per skill to boost
+     * the XP gain PER skill. I THINK you should be able to put the variable "SkillProgress" (just like health has it)
+     * and be able to tune the skill gain PER skill, but I havent tested it and Im not sure!
+     * @param pmcData
+     * @param bonus
+     */
     protected applySkillXPBoost(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * Process a players hideout, update areas that use resources + increment production timers
+     * @param sessionID Session id
+     */
     updatePlayerHideout(sessionID: string): void;
+    /**
+     * Update progress timer for water collector
+     * @param pmcData profile to update
+     * @param productionId id of water collection production to update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateWaterCollectorProductionTimer(pmcData: IPmcData, productionId: string, hideoutProperties: {
+        btcFarmCGs?: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Iterate over productions and update their progress timers
+     * @param pmcData Profile to check for productions and update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Update progress timer for scav case
+     * @param pmcData Profile to update
+     * @param productionId Id of scav case production to update
+     */
+    protected updateScavCaseProductionTimer(pmcData: IPmcData, productionId: string): void;
+    /**
+     * Iterate over hideout areas that use resources (fuel/filters etc) and update associated values
+     * @param sessionID Session id
+     * @param pmcData Profile to update areas of
+     * @param hideoutProperties hideout properties
+     */
+    protected updateAreasWithResources(sessionID: string, pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
     protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
     protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
-    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): HideoutArea;
-    protected updateWaterFilters(waterFilterArea: HideoutArea, pwProd: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
+    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): void;
+    /**
+     * Adjust water filter objects resourceValue or delete when they reach 0 resource
+     * @param waterFilterArea water filter area to update
+     * @param production production object
+     * @param isGeneratorOn is generatory enabled
+     * @param pmcData Player profile
+     * @returns Updated HideoutArea object
+     */
+    protected updateWaterFilters(waterFilterArea: HideoutArea, production: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
     protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
-    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): HideoutArea;
+    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): void;
     protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
     protected getBTCSlots(pmcData: IPmcData): number;
     protected getManagementSkillsSlots(): number;
diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/InRaidHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/InRaidHelper.d.ts
index b382e30..962df38 100644
--- a/TypeScript/6ReferenceAnotherClass/types/helpers/InRaidHelper.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/helpers/InRaidHelper.d.ts
@@ -18,18 +18,6 @@ export declare class InRaidHelper {
     protected paymentHelper: PaymentHelper;
     protected profileFixerService: ProfileFixerService;
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper, profileFixerService: ProfileFixerService);
-    /**
-     * Reset the SPT inraid property stored in a profile to 'none'
-     * @param sessionID Session id
-     */
-    protected removePlayer(sessionID: string): void;
-    /**
-     * Some maps have one-time-use keys (e.g. Labs
-     * Remove the relevant key from an inventory based on the post-raid request data passed in
-     * @param offraidData post-raid data
-     * @param sessionID Session id
-     */
-    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
     /**
      * Check an array of items and add an upd object to money items with a stack count of 1
      * Single stack money items have no upd object and thus no StackObjectsCount, causing issues
@@ -54,6 +42,18 @@ export declare class InRaidHelper {
      * @returns Reset profile object
      */
     updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData;
+    /**
+     * Some maps have one-time-use keys (e.g. Labs
+     * Remove the relevant key from an inventory based on the post-raid request data passed in
+     * @param offraidData post-raid data
+     * @param sessionID Session id
+     */
+    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Set the SPT inraid location Profile property to 'none'
+     * @param sessionID Session id
+     */
+    protected setPlayerInRaidLocationStatusToNone(sessionID: string): void;
     /**
      * Adds SpawnedInSession property to items found in a raid
      * Removes SpawnedInSession for non-scav players if item was taken into raid with SpawnedInSession = true
@@ -95,5 +95,10 @@ export declare class InRaidHelper {
      * @returns true if item is kept after death
      */
     isItemKeptAfterDeath(slotId: string): boolean;
+    /**
+     * Return the equipped items from a players inventory
+     * @param items Players inventory to search through
+     * @returns an array of equipped items
+     */
     getPlayerGear(items: Item[]): Item[];
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/ItemHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/ItemHelper.d.ts
index 1701c62..de10892 100644
--- a/TypeScript/6ReferenceAnotherClass/types/helpers/ItemHelper.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/helpers/ItemHelper.d.ts
@@ -1,35 +1,30 @@
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item, Repairable } from "../models/eft/common/tables/IItem";
+import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase";
 import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+import { MathUtil } from "../utils/MathUtil";
+import { ObjectId } from "../utils/ObjectId";
+import { RandomUtil } from "../utils/RandomUtil";
 declare class ItemHelper {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
     protected jsonUtil: JsonUtil;
+    protected randomUtil: RandomUtil;
+    protected objectId: ObjectId;
+    protected mathUtil: MathUtil;
     protected databaseServer: DatabaseServer;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer);
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer);
     /**
      * Checks if a id is a valid item. Valid meaning that it's an item that be stored in stash
      * @param       {string}    tpl       the template id / tpl
      * @returns                             boolean; true for items that may be in player posession and not quest items
      */
     isValidItem(tpl: string, invalidBaseTypes?: string[]): boolean;
-    /**
-     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
-     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
-     * @param {*} tpl template id of item to check
-     * @returns boolean: true if item is valid reward
-     */
-    isValidRewardItem(tpl: string): boolean;
-    /**
-     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
-     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
-     */
-    getRewardableItems(): [string, ITemplateItem][];
     /**
      * Check if the tpl / template Id provided is a descendent of the baseclass
      *
@@ -196,6 +191,22 @@ declare class ItemHelper {
      * @returns ItemSize object (width and height)
      */
     getItemSize(items: Item[], rootItemId: string): ItemHelper.ItemSize;
+    /**
+     * Get a random cartridge from an items Filter property
+     * @param item
+     * @returns
+     */
+    getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
+    createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
+    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
+    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
+    createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
+    /**
+     * Get the size of a stack, return 1 if no stack object count property found
+     * @param item Item to get stack size of
+     * @returns size of stack
+     */
+    getItemStackSize(item: Item): number;
 }
 declare namespace ItemHelper {
     interface ItemSize {
diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/ProfileHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/ProfileHelper.d.ts
index 9d4ff98..9c6560a 100644
--- a/TypeScript/6ReferenceAnotherClass/types/helpers/ProfileHelper.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/helpers/ProfileHelper.d.ts
@@ -24,6 +24,19 @@ export declare class ProfileHelper {
     constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, fenceService: FenceService);
     resetProfileQuestCondition(sessionID: string, conditionId: string): void;
     getCompleteProfile(sessionID: string): IPmcData[];
+    /**
+     * Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
+     * Server saves the post-raid changes prior to the xp screen getting the profile, this results in the xp screen using
+     * the now updated profile values as a base, meaning it shows x2 xp gained
+     * Instead, clone the post-raid profile (so we dont alter its values), apply the pre-raid xp values to the cloned objects and return
+     * Delete snapshot of pre-raid profile prior to returning profile data
+     * @param sessionId Session id
+     * @param output pmc and scav profiles array
+     * @param pmcProfile post-raid pmc profile
+     * @param scavProfile post-raid scav profile
+     * @returns updated profile array
+     */
+    protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
     isNicknameTaken(info: IValidateNicknameRequestData, sessionID: string): boolean;
     /**
      * Add experience to a PMC inside the players profile
diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/QuestHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/QuestHelper.d.ts
index 32e55ec..d66d150 100644
--- a/TypeScript/6ReferenceAnotherClass/types/helpers/QuestHelper.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/helpers/QuestHelper.d.ts
@@ -36,11 +36,20 @@ export declare class QuestHelper {
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
     constructor(logger: ILogger, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, itemHelper: ItemHelper, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, localeService: LocaleService, ragfairServerHelper: RagfairServerHelper, dialogueHelper: DialogueHelper, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, traderHelper: TraderHelper, configServer: ConfigServer);
-    questStatus(pmcData: IPmcData, questID: string): QuestStatus;
     /**
-     * returns true is the condition is satisfied
+    * Get status of a quest by quest id
+    * @param pmcData Profile to search
+    * @param questID Quest id to look up
+    * @returns QuestStauts enum
+    */
+    getQuestStatus(pmcData: IPmcData, questID: string): QuestStatus;
+    /**
+     * returns true is the level condition is satisfied
+     * @param playerLevel Players level
+     * @param condition Quest condition
+     * @returns true if player level is greater than or equal to quest
      */
-    evaluateLevel(pmcProfile: IPmcData, cond: AvailableForConditions): boolean;
+    doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean;
     getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[];
     /**
      * Increase skill points of a skill on player profile
diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairOfferHelper.d.ts
index 8d03bee..e9d72ca 100644
--- a/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairOfferHelper.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairOfferHelper.d.ts
@@ -22,12 +22,14 @@ import { ProfileHelper } from "./ProfileHelper";
 import { RagfairHelper } from "./RagfairHelper";
 import { RagfairServerHelper } from "./RagfairServerHelper";
 import { RagfairSortHelper } from "./RagfairSortHelper";
+import { TraderHelper } from "./TraderHelper";
 export declare class RagfairOfferHelper {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
     protected hashUtil: HashUtil;
     protected itemEventRouter: ItemEventRouter;
     protected databaseServer: DatabaseServer;
+    protected traderHelper: TraderHelper;
     protected saveServer: SaveServer;
     protected dialogueHelper: DialogueHelper;
     protected itemHelper: ItemHelper;
@@ -43,10 +45,10 @@ export declare class RagfairOfferHelper {
     protected static goodSoldTemplate: string;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, traderHelper: TraderHelper, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
     getValidOffers(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
     getOffersForBuild(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
-    processOffers(sessionID: string): boolean;
+    processOffersOnProfile(sessionID: string): boolean;
     protected getProfileOffers(sessionID: string): IRagfairOffer[];
     protected deleteOfferByOfferId(sessionID: string, offerId: string): void;
     protected completeOffer(sessionID: string, offer: IRagfairOffer, boughtAmount: number): IItemEventRouterResponse;
diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairSellHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairSellHelper.d.ts
index 6ec004a..91b8a20 100644
--- a/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairSellHelper.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairSellHelper.d.ts
@@ -11,6 +11,12 @@ export declare class RagfairSellHelper {
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     constructor(logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer);
-    calculateSellChance(baseChance: number, offerPrice: number, requirementsPriceInRub: number): number;
-    rollForSale(sellChance: number, count: number): SellResult[];
+    calculateSellChance(baseChancePercent: number, offerPriceRub: number, playerListedPriceRub: number): number;
+    /**
+     * Determine if the offer being listed will be sold
+     * @param sellChancePercent chance item will sell
+     * @param itemSellCount count of items to sell
+     * @returns Array of purchases of item(s) lsited
+     */
+    rollForSale(sellChancePercent: number, itemSellCount: number): SellResult[];
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairServerHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairServerHelper.d.ts
index e4939d1..a03cdda 100644
--- a/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairServerHelper.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairServerHelper.d.ts
@@ -6,6 +6,7 @@ import { IRagfairConfig } from "../models/spt/config/IRagfairConfig";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { SaveServer } from "../servers/SaveServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { LocaleService } from "../services/LocaleService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -13,6 +14,9 @@ import { RandomUtil } from "../utils/RandomUtil";
 import { DialogueHelper } from "./DialogueHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProfileHelper } from "./ProfileHelper";
+/**
+ * Helper class for common ragfair server actions
+ */
 export declare class RagfairServerHelper {
     protected randomUtil: RandomUtil;
     protected hashUtil: HashUtil;
@@ -23,11 +27,12 @@ export declare class RagfairServerHelper {
     protected localeService: LocaleService;
     protected dialogueHelper: DialogueHelper;
     protected jsonUtil: JsonUtil;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
     protected static goodsReturnedTemplate: string;
-    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, configServer: ConfigServer);
+    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Is item valid / on blacklist / quest item
      * @param itemDetails
diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/TradeHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/TradeHelper.d.ts
index 975062b..7ab9768 100644
--- a/TypeScript/6ReferenceAnotherClass/types/helpers/TradeHelper.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/helpers/TradeHelper.d.ts
@@ -39,6 +39,12 @@ export declare class TradeHelper {
      * @returns
      */
     sellItem(pmcData: IPmcData, body: IProcessSellTradeRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment the assorts buy count by number of items purchased
+     * Show error on screen if player attepts to buy more than what the buy max allows
+     * @param assortBeingPurchased assort being bought
+     * @param itemsPurchasedCount number of items being bought
+     */
     protected incrementAssortBuyCount(assortBeingPurchased: Item, itemsPurchasedCount: number): void;
     protected checkPurchaseIsWithinTraderItemLimit(assortBeingPurchased: Item, assortId: string, count: number): void;
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/TraderAssortHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/TraderAssortHelper.d.ts
index 677dd66..025efd6 100644
--- a/TypeScript/6ReferenceAnotherClass/types/helpers/TraderAssortHelper.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/helpers/TraderAssortHelper.d.ts
@@ -1,6 +1,5 @@
 import { RagfairAssortGenerator } from "../generators/RagfairAssortGenerator";
 import { RagfairOfferGenerator } from "../generators/RagfairOfferGenerator";
-import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ITrader, ITraderAssort } from "../models/eft/common/tables/ITrader";
 import { ITraderConfig } from "../models/spt/config/ITraderConfig";
@@ -41,12 +40,7 @@ export declare class TraderAssortHelper {
      * @param traderId traders id
      * @returns a traders' assorts
      */
-    getAssort(sessionId: string, traderId: string): ITraderAssort;
-    /**
-     * if the fence assorts have expired, re-generate them
-     * @param pmcProfile Players profile
-     */
-    refreshFenceAssortIfExpired(pmcProfile: IPmcData): void;
+    getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort;
     /**
      * Reset a traders assorts and move nextResupply value to future
      * Flag trader as needing a flea offer reset to be picked up by flea update() function
diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/TraderHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/TraderHelper.d.ts
index 6bda5cd..0dc93e8 100644
--- a/TypeScript/6ReferenceAnotherClass/types/helpers/TraderHelper.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/helpers/TraderHelper.d.ts
@@ -65,7 +65,7 @@ export declare class TraderHelper {
      * @param item
      * @returns boolean
      */
-    protected isWeaponAndBelowTraderBuyDurability(traderID: string, item: Item): boolean;
+    protected isWeaponBelowTraderBuyDurability(traderID: string, item: Item): boolean;
     /**
      * Get the price of an item and all of its attached children
      * Take into account bonuses/adjsutments e.g. discounts
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/ITemplateItem.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/ITemplateItem.d.ts
index 23a1a14..6b2fa8f 100644
--- a/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/ITemplateItem.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/ITemplateItem.d.ts
@@ -34,6 +34,7 @@ export interface Props {
     LootExperience?: number;
     ExamineExperience?: number;
     HideEntrails?: boolean;
+    InsuranceDisabled?: boolean;
     RepairCost?: number;
     RepairSpeed?: number;
     ExtraSizeLeft?: number;
@@ -206,6 +207,7 @@ export interface Props {
     IsOneoff?: boolean;
     MustBoltBeOpennedForExternalReload?: boolean;
     MustBoltBeOpennedForInternalReload?: boolean;
+    NoFiremodeOnBoltcatch?: boolean;
     BoltAction?: boolean;
     HipAccuracyRestorationDelay?: number;
     HipAccuracyRestorationSpeed?: number;
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/ITrader.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/ITrader.d.ts
index a84f5af..37b2d61 100644
--- a/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/ITrader.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/ITrader.d.ts
@@ -67,6 +67,7 @@ export interface IBarterScheme {
     count: number;
     _tpl: string;
     onlyFunctional?: boolean;
+    sptQuestLocked?: boolean;
 }
 export interface ISuit {
     _id: string;
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/eft/ragfair/IRagfairOffer.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/eft/ragfair/IRagfairOffer.d.ts
index 63f655e..141b605 100644
--- a/TypeScript/6ReferenceAnotherClass/types/models/eft/ragfair/IRagfairOffer.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/models/eft/ragfair/IRagfairOffer.d.ts
@@ -15,6 +15,8 @@ export interface IRagfairOffer {
     name?: string;
     shortName?: string;
     loyaltyLevel: number;
+    buyRestrictionMax?: number;
+    buyRestrictionCurrent?: number;
     locked: boolean;
     unlimitedCount: boolean;
     summaryCost: number;
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/enums/AmmoTypes.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/enums/AmmoTypes.d.ts
index b52ddcf..254b410 100644
--- a/TypeScript/6ReferenceAnotherClass/types/models/enums/AmmoTypes.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/models/enums/AmmoTypes.d.ts
@@ -23,7 +23,7 @@ export declare enum Ammo762x54 {
     BT_GZH = "5e023d34e8a400319a28ed44",
     BS_GZH = "5e023d48186a883be655e551"
 }
-export declare enum Ammo338Lapua {
+export declare enum Ammo86x70 {
     TAC_X = "5fc382b6d6fa9c00c571bbc3",
     UCW = "5fc382c1016cce60e8341b20",
     AP = "5fc382a9d724d907e2077dab",
@@ -85,13 +85,13 @@ export declare enum Ammo9x21 {
     PE_GZH = "5a26ac06c4a282000c5a90a8",
     BT_GZH = "5a26ac0ec4a28200741e1e18"
 }
-export declare enum Ammo357Mag {
+export declare enum Ammo9x33R {
     FMJ = "62330b3ed4dc74626d570b95",
     HOLLOW_POINT = "62330bfadc5883093563729b",
     SOFT_POINT = "62330c40bdd19b369e1e53d1",
     JACKET_HP = "62330c18744e5e31df12f516"
 }
-export declare enum Ammo45ACP {
+export declare enum Ammo1143x23ACP {
     MATCH_FMJ = "5e81f423763d9f754677bf2e",
     HYDRA_SHOK = "5efb0fc6aeb21837e749c801",
     LASERMATCH_FMJ = "5efb0d4f4bc50b58e81710f3",
@@ -126,7 +126,7 @@ export declare enum Ammo556x45 {
     MK_318_MOD_0_SOST = "60194943740c5d77f6705eea",
     SSA_AP = "601949593ae8f707c4608daa"
 }
-export declare enum Ammo300Blackout {
+export declare enum Ammo762x35 {
     M62_TRACER = "619636be6db0f2477964e710",
     BCP_FMJ = "5fbe3ffdf8b6a877a729ea82",
     AP = "5fd20ff893a8961fc660a954",
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/enums/BaseClasses.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/enums/BaseClasses.d.ts
index e733bca..37c1398 100644
--- a/TypeScript/6ReferenceAnotherClass/types/models/enums/BaseClasses.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/models/enums/BaseClasses.d.ts
@@ -68,6 +68,7 @@ export declare enum BaseClasses {
     ASSAULT_SCOPE = "55818add4bdc2d5b648b456f",
     REFLEX_SIGHT = "55818ad54bdc2ddc698b4569",
     TACTICAL_COMBO = "55818b164bdc2ddc698b456c",
+    FLASHLIGHT = "55818b084bdc2d5b648b4571",
     MAGAZINE = "5448bc234bdc2d3c308b4569",
     LIGHT_LASER = "55818b0e4bdc2dde698b456e",
     FLASH_HIDER = "550aa4bf4bdc2dd6348b456b",
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/enums/ConfigTypes.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/enums/ConfigTypes.d.ts
index 61d6f99..468ece5 100644
--- a/TypeScript/6ReferenceAnotherClass/types/models/enums/ConfigTypes.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/models/enums/ConfigTypes.d.ts
@@ -8,6 +8,7 @@ export declare enum ConfigTypes {
     IN_RAID = "aki-inraid",
     INSURANCE = "aki-insurance",
     INVENTORY = "aki-inventory",
+    ITEM = "aki-item",
     LOCALE = "aki-locale",
     LOCATION = "aki-location",
     MATCH = "aki-match",
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/enums/ELocationName.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/enums/ELocationName.d.ts
index b56cc08..7ae7caa 100644
--- a/TypeScript/6ReferenceAnotherClass/types/models/enums/ELocationName.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/models/enums/ELocationName.d.ts
@@ -1,5 +1,6 @@
 export declare enum ELocationName {
     FACTORY_DAY = "factory4_day",
+    FACTORY_NIGHT = "factory4_night",
     BIGMAP = "bigmap",
     WOODS = "Woods",
     SHORELINE = "Shoreline",
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IBotConfig.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IBotConfig.d.ts
index e171087..f15fa73 100644
--- a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IBotConfig.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IBotConfig.d.ts
@@ -1,17 +1,31 @@
 import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
+import { IBotDurability } from "./IBotDurability";
+import { IPmcConfig } from "./IPmcConfig";
 export interface IBotConfig extends IBaseConfig {
     kind: "aki-bot";
+    /** How many variants of each bot should be generated on raid start */
     presetBatch: PresetBatch;
+    /** What bot types should be classified as bosses */
     bosses: string[];
-    durability: Durability;
+    /** Control weapon/armor durability min/max values for each bot type */
+    durability: IBotDurability;
+    /** Control the weighting of how expensive an average loot item is on a PMC or Scav */
     lootNValue: LootNvalue;
+    /** Control what bots are added to a bots revenge list key: bottype, value: bottypes to revenge on seeing their death */
     revenge: Record<string, string[]>;
-    pmc: PmcConfig;
+    /** PMC bot specific config settings */
+    pmc: IPmcConfig;
+    /** Control how many items are allowed to spawn on a bot
+     * key: bottype, value: <key: itemTpl: value: max item count> */
     itemSpawnLimits: Record<string, Record<string, number>>;
-    equipment: Record<string, Equipment>;
+    /** Blacklist/whitelist items on a bot */
+    equipment: Record<string, EquipmentFilters>;
+    /** Show a bots botType value after their name */
     showTypeInNickname: boolean;
+    /** Max number of bots that can be spawned in a raid at any one time */
     maxBotCap: number;
+    /** How many stacks of secret ammo should a bot have in its bot secure container */
     secureContainerAmmoStackCount: number;
 }
 export interface PresetBatch {
@@ -44,79 +58,22 @@ export interface PresetBatch {
     test: number;
     exUsec: number;
 }
-export interface Durability {
-    default: DefaultDurability;
-    pmc: PmcDurability;
-    boss: BotDurability;
-    follower: BotDurability;
-    assault: BotDurability;
-    cursedassault: BotDurability;
-    marksman: BotDurability;
-    pmcbot: BotDurability;
-    exusec: BotDurability;
-    sectantpriest: BotDurability;
-    sectantwarrior: BotDurability;
-}
-export interface DefaultDurability {
-    armor: DefaultArmor;
-    weapon: WeaponDurability;
-}
-export interface DefaultArmor {
-    maxDelta: number;
-    minDelta: number;
-}
-export interface WeaponDurability {
-    lowestMax: number;
-    highestMax: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface PmcDurability {
-    armor: PmcDurabilityArmor;
-    weapon: WeaponDurability;
-}
-export interface PmcDurabilityArmor {
-    lowestMaxPercent: number;
-    highestMaxPercent: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface BotDurability {
-    armor: ArmorDurability;
-    weapon: WeaponDurability;
-}
-export interface ArmorDurability {
-    maxDelta: number;
-    minDelta: number;
-}
 export interface LootNvalue {
     scav: number;
     pmc: number;
 }
-export interface PmcConfig {
-    dynamicLoot: PmcDynamicLoot;
-    difficulty: string;
-    looseWeaponInBackpackChancePercent: number;
-    looseWeaponInBackpackLootMinMax: MinMax;
-    isUsec: number;
-    chanceSameSideIsHostilePercent: number;
-    usecType: string;
-    bearType: string;
-    maxBackpackLootTotalRub: number;
-    maxPocketLootTotalRub: number;
-    maxVestLootTotalRub: number;
-    convertIntoPmcChance: Record<string, MinMax>;
-    enemyTypes: string[];
-}
-export interface PmcDynamicLoot {
-    whitelist: string[];
-    blacklist: string[];
-    moneyStackLimits: Record<string, number>;
-}
-export interface Equipment {
+export interface EquipmentFilters {
+    weaponModLimits: ModLimits;
+    randomisedWeaponModSlots?: string[];
     blacklist: EquipmentFilterDetails[];
     whitelist: EquipmentFilterDetails[];
 }
+export interface ModLimits {
+    /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */
+    scopeLimit?: number;
+    /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */
+    lightLaserLimit?: number;
+}
 export interface EquipmentFilterDetails {
     levelRange: MinMax;
     equipment: Record<string, string[]>;
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IBotDurability.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IBotDurability.d.ts
new file mode 100644
index 0000000..38a47cc
--- /dev/null
+++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IBotDurability.d.ts
@@ -0,0 +1,47 @@
+export interface IBotDurability {
+    default: DefaultDurability;
+    pmc: PmcDurability;
+    boss: BotDurability;
+    follower: BotDurability;
+    assault: BotDurability;
+    cursedassault: BotDurability;
+    marksman: BotDurability;
+    pmcbot: BotDurability;
+    exusec: BotDurability;
+    gifter: BotDurability;
+    sectantpriest: BotDurability;
+    sectantwarrior: BotDurability;
+}
+/** Durability values to be used when a more specific bot type cant be found */
+export interface DefaultDurability {
+    armor: DefaultArmor;
+    weapon: WeaponDurability;
+}
+export interface DefaultArmor {
+    maxDelta: number;
+    minDelta: number;
+}
+export interface WeaponDurability {
+    lowestMax: number;
+    highestMax: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface PmcDurability {
+    armor: PmcDurabilityArmor;
+    weapon: WeaponDurability;
+}
+export interface PmcDurabilityArmor {
+    lowestMaxPercent: number;
+    highestMaxPercent: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface BotDurability {
+    armor: ArmorDurability;
+    weapon: WeaponDurability;
+}
+export interface ArmorDurability {
+    maxDelta: number;
+    minDelta: number;
+}
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IItemConfig.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IItemConfig.d.ts
new file mode 100644
index 0000000..5ecccc2
--- /dev/null
+++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IItemConfig.d.ts
@@ -0,0 +1,5 @@
+import { IBaseConfig } from "./IBaseConfig";
+export interface IItemConfig extends IBaseConfig {
+    kind: "aki-item";
+    blacklist: string[];
+}
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IPmcConfig.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IPmcConfig.d.ts
new file mode 100644
index 0000000..655b58d
--- /dev/null
+++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IPmcConfig.d.ts
@@ -0,0 +1,22 @@
+import { MinMax } from "../../common/MinMax";
+export interface IPmcConfig {
+    dynamicLoot: DynamicLoot;
+    useDifficultyOverride: boolean;
+    difficulty: string;
+    looseWeaponInBackpackChancePercent: number;
+    looseWeaponInBackpackLootMinMax: MinMax;
+    isUsec: number;
+    chanceSameSideIsHostilePercent: number;
+    usecType: string;
+    bearType: string;
+    maxBackpackLootTotalRub: number;
+    maxPocketLootTotalRub: number;
+    maxVestLootTotalRub: number;
+    convertIntoPmcChance: Record<string, MinMax>;
+    enemyTypes: string[];
+}
+export interface DynamicLoot {
+    whitelist: string[];
+    blacklist: string[];
+    moneyStackLimits: Record<string, number>;
+}
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IQuestConfig.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IQuestConfig.d.ts
index be4a97b..45c9aae 100644
--- a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IQuestConfig.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IQuestConfig.d.ts
@@ -4,6 +4,8 @@ export interface IQuestConfig extends IBaseConfig {
     kind: "aki-quest";
     redeemTime: number;
     repeatableQuests: IRepeatableQuestConfig[];
+    bearOnlyQuests: string[];
+    usecOnlyQuests: string[];
 }
 export interface IRepeatableQuestConfig {
     name: string;
@@ -15,6 +17,10 @@ export interface IRepeatableQuestConfig {
     locations: Record<ELocationName, string[]>;
     traderWhitelist: ITraderWhitelist[];
     questConfig: IQuestConfig;
+    /** Item base types to block when generating rewards */
+    rewardBaseTypeBlacklist: string[];
+    /** Item tplIds to ignore when generating rewards */
+    rewardBlacklist: string[];
 }
 export interface IRewardScaling {
     levels: number[];
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IRagfairConfig.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IRagfairConfig.d.ts
index 6369eda..3088717 100644
--- a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IRagfairConfig.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IRagfairConfig.d.ts
@@ -12,6 +12,7 @@ export interface Sell {
     chance: Chance;
     time: Time;
     reputation: Reputation;
+    simulatedSellHours: number;
 }
 export interface Chance {
     base: number;
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ITraderConfig.d.ts
index c8e8044..6b1c1e3 100644
--- a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ITraderConfig.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ITraderConfig.d.ts
@@ -12,8 +12,10 @@ export interface UpdateTime {
     seconds: number;
 }
 export interface FenceConfig {
+    partialRefreshTimeSeconds: number;
+    partialRefreshChangePercent: number;
     assortSize: number;
-    maxPresetsCount: number;
+    maxPresetsPercent: number;
     presetPriceMult: number;
     blacklist: string[];
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/services/LootItem.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/services/LootItem.d.ts
new file mode 100644
index 0000000..2838472
--- /dev/null
+++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/services/LootItem.d.ts
@@ -0,0 +1,5 @@
+export declare class LootItem {
+    tpl: string;
+    isPreset: boolean;
+    stackCount: number;
+}
diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/services/LootRequest.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/6ReferenceAnotherClass/types/services/BotEquipmentFilterService.d.ts b/TypeScript/6ReferenceAnotherClass/types/services/BotEquipmentFilterService.d.ts
index e49645b..632f961 100644
--- a/TypeScript/6ReferenceAnotherClass/types/services/BotEquipmentFilterService.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/services/BotEquipmentFilterService.d.ts
@@ -1,12 +1,12 @@
 import { IBotType } from "../models/eft/common/tables/IBotType";
-import { Equipment, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 export declare class BotEquipmentFilterService {
     protected logger: ILogger;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    protected botEquipmentFilterlists: Record<string, Equipment>;
+    protected botEquipmentFilterlists: Record<string, EquipmentFilters>;
     constructor(logger: ILogger, configServer: ConfigServer);
     /**
      * Filter a bots data to exclude equipment and cartridges defines in the botConfig
@@ -22,7 +22,7 @@ export declare class BotEquipmentFilterService {
      * @param playerLevel Level of the player
      * @returns EquipmentBlacklistDetails object
      */
-    protected getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
+    getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
     /**
      * Get the whitelist for a specific bot type that's within the players level
      * @param botRole Bot type
diff --git a/TypeScript/6ReferenceAnotherClass/types/services/FenceService.d.ts b/TypeScript/6ReferenceAnotherClass/types/services/FenceService.d.ts
index c9e325e..c940507 100644
--- a/TypeScript/6ReferenceAnotherClass/types/services/FenceService.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/services/FenceService.d.ts
@@ -12,6 +12,11 @@ import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+import { ItemFilterService } from "./ItemFilterService";
+/**
+ * Handle actions surrounding Fence
+ * e.g. generating or refreshing assorts / get next refresh time
+ */
 export declare class FenceService {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
@@ -22,18 +27,64 @@ export declare class FenceService {
     protected handbookHelper: HandbookHelper;
     protected itemHelper: ItemHelper;
     protected presetHelper: PresetHelper;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected fenceAssort: ITraderAssort;
     protected traderConfig: ITraderConfig;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, configServer: ConfigServer);
+    protected nextMiniRefreshTimestamp: number;
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, itemFilterService: ItemFilterService, configServer: ConfigServer);
     protected setFenceAssort(fenceAssort: ITraderAssort): void;
-    getFenceAssorts(): ITraderAssort;
+    /**
+     * Get assorts player can purchase
+     * Adjust prices based on fence level of player
+     * @param pmcProfile Player profile
+     * @returns ITraderAssort
+     */
+    getFenceAssorts(pmcProfile: IPmcData): ITraderAssort;
+    /**
+     * Get fence assorts with no price adjustments based on fence rep
+     * @returns ITraderAssort
+     */
+    getRawFenceAssorts(): ITraderAssort;
+    /**
+     * Does fence need to perform a partial refresh because its passed the refresh timer defined in trader.json
+     * @returns true if it needs a partial refresh
+     */
+    needsPartialRefresh(): boolean;
+    /**
+     * Replace a percentage of fence assorts with freshly generated items
+     */
+    performPartialRefresh(): void;
+    /**
+     * Choose an item (not mod) at random and remove from assorts
+     */
+    protected removeRandomItemFromAssorts(): void;
+    /**
+     * Get an integer rounded count of items to replace based on percentrage from traderConfig value
+     * @param totalItemCount total item count
+     * @returns rounded int of items to replace
+     */
+    protected getCountOfItemsToReplace(totalItemCount: number): number;
     /**
      * Get the count of items fence offers
      * @returns number
      */
     getOfferCount(): number;
-    generateFenceAssortCache(pmcData: IPmcData): void;
+    /**
+     * Create a trader assort for fence
+     */
+    generateFenceAssortCache(): void;
+    /**
+     * Create skeleton to hold assort items
+     * @returns ITraderAssort object
+     */
+    protected createBaseTraderAssortItem(): ITraderAssort;
+    /**
+     * Hydrate result parameter object with generated assorts
+     * @param assortCount Number of assorts to generate
+     * @param assorts object to add assorts to
+     */
+    protected createAssorts(assortCount: number, assorts: ITraderAssort): void;
     /**
      * Get the next update timestamp for fence
      * @returns future timestamp
@@ -44,11 +95,14 @@ export declare class FenceService {
      */
     protected getFenceRefreshTime(): number;
     /**
-     * Get the fence level the passed in profile has
+     * Get fence level the passed in profile has
      * @param pmcData Player profile
-     * @returns FenceLevel
+     * @returns FenceLevel object
      */
     getFenceInfo(pmcData: IPmcData): FenceLevel;
+    /**
+     * Remove an assort from fence by id
+     * @param assortIdToRemove assort id to remove from fence assorts
+     */
     removeFenceOffer(assortIdToRemove: string): void;
-    updateFenceOffers(pmcData: IPmcData): void;
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/services/InsuranceService.d.ts b/TypeScript/6ReferenceAnotherClass/types/services/InsuranceService.d.ts
index 171bf10..6be8a2f 100644
--- a/TypeScript/6ReferenceAnotherClass/types/services/InsuranceService.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/services/InsuranceService.d.ts
@@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
 import { SecureContainerHelper } from "../helpers/SecureContainerHelper";
 import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
+import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData";
 import { IInsuranceConfig } from "../models/spt/config/IInsuranceConfig";
@@ -44,8 +45,22 @@ export declare class InsuranceService {
      * @param mapId Id of the map player died/exited that caused the insurance to be issued on
      */
     sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void;
+    /**
+     * Store lost gear post-raid inside profile
+     * @param pmcData player profile to store gear in
+     * @param offraidData post-raid request object
+     * @param preRaidGear gear player wore prior to raid
+     * @param sessionID Session id
+     */
     storeLostGear(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
     storeInsuredItemsForReturn(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
-    protected addGearToSend(pmcData: IPmcData, insuredItem: any, actualItem: any, sessionID: string): any;
+    /**
+     * Add gear item to InsuredItems array in player profile
+     * @param pmcData profile to store item in
+     * @param insuredItem Item to store in profile
+     * @param actualItem item to store
+     * @param sessionID Session id
+     */
+    protected addGearToSend(pmcData: IPmcData, insuredItem: InsuredItem, actualItem: Item, sessionID: string): void;
     getPremium(pmcData: IPmcData, inventoryItem: Item, traderId: string): number;
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/services/ItemFilterService.d.ts b/TypeScript/6ReferenceAnotherClass/types/services/ItemFilterService.d.ts
new file mode 100644
index 0000000..c9c8ef3
--- /dev/null
+++ b/TypeScript/6ReferenceAnotherClass/types/services/ItemFilterService.d.ts
@@ -0,0 +1,24 @@
+import { IItemConfig } from "../models/spt/config/IItemConfig";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+/** Centralise the handling of blacklisting items, uses blacklist found in config/item.json */
+export declare class ItemFilterService {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected configServer: ConfigServer;
+    protected blacklist: string[];
+    protected itemConfig: IItemConfig;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer);
+    /**
+     * Check if the provided template id is blacklisted in config/item.json
+     * @param tpl template id
+     * @returns true if blacklisted
+     */
+    isItemBlacklisted(tpl: string): boolean;
+    /**
+     * Return every template id blacklisted in config/item.json
+     * @returns string array of blacklisted tempalte ids
+     */
+    getBlacklistedItems(): string[];
+}
diff --git a/TypeScript/6ReferenceAnotherClass/types/services/ProfileFixerService.d.ts b/TypeScript/6ReferenceAnotherClass/types/services/ProfileFixerService.d.ts
index ed1dec7..9cb5a38 100644
--- a/TypeScript/6ReferenceAnotherClass/types/services/ProfileFixerService.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/services/ProfileFixerService.d.ts
@@ -45,6 +45,11 @@ export declare class ProfileFixerService {
      * @param pmcProfile Profile to find and remove slots from
      */
     protected removeResourcesFromSlotsInHideoutWithoutLocationIndexValue(pmcProfile: IPmcData): void;
+    /**
+     * Hideout slots need to be in a specific order, locationIndex in ascending order
+     * @param pmcProfile profile to edit
+     */
+    protected reorderHideoutAreasWithResouceInputs(pmcProfile: IPmcData): void;
     /**
      * add in objects equal to the number of slots
      * @param areaType area to check
diff --git a/TypeScript/6ReferenceAnotherClass/types/utils/HashUtil.d.ts b/TypeScript/6ReferenceAnotherClass/types/utils/HashUtil.d.ts
index bacbf2a..a8500e1 100644
--- a/TypeScript/6ReferenceAnotherClass/types/utils/HashUtil.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/utils/HashUtil.d.ts
@@ -4,8 +4,18 @@ import { TimeUtil } from "./TimeUtil";
 export declare class HashUtil {
     protected timeUtil: TimeUtil;
     constructor(timeUtil: TimeUtil);
+    /**
+     * Create a 24 character id using the sha256 algorithm + current timestamp
+     * @returns 24 character hash
+     */
     generate(): string;
     generateMd5ForData(data: string): string;
     generateSha1ForData(data: string): string;
+    /**
+     * Create a hash for the data parameter
+     * @param algorithm algorithm to use to hash
+     * @param data data to be hashed
+     * @returns hash value
+     */
     generateHashForData(algorithm: string, data: crypto.BinaryLike): string;
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/utils/RandomUtil.d.ts b/TypeScript/6ReferenceAnotherClass/types/utils/RandomUtil.d.ts
index c24dd60..e35d21f 100644
--- a/TypeScript/6ReferenceAnotherClass/types/utils/RandomUtil.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/utils/RandomUtil.d.ts
@@ -150,4 +150,10 @@ export declare class RandomUtil {
      */
     drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[];
     getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number;
+    /**
+     * Fisher-Yates shuffle an array
+     * @param array Array to shuffle
+     * @returns Shuffled array
+     */
+    shuffle<T>(array: Array<T>): Array<T>;
 }
diff --git a/TypeScript/6ReferenceAnotherClass/types/utils/TimeUtil.d.ts b/TypeScript/6ReferenceAnotherClass/types/utils/TimeUtil.d.ts
index f437f8a..1367e26 100644
--- a/TypeScript/6ReferenceAnotherClass/types/utils/TimeUtil.d.ts
+++ b/TypeScript/6ReferenceAnotherClass/types/utils/TimeUtil.d.ts
@@ -1,3 +1,6 @@
+/**
+ * Utility class to handle time related problems
+ */
 export declare class TimeUtil {
     static readonly oneHourAsSeconds = 3600;
     formatTime(date: Date): string;
@@ -19,4 +22,10 @@ export declare class TimeUtil {
      * @returns current date in format: 00.00.0000 (dd.mm.yyyy)
      */
     getDateMailFormat(): string;
+    /**
+     * Convert hours into seconds
+     * @param hours hours to convert to seconds
+     * @returns number
+     */
+    getHoursAsSeconds(hours: number): number;
 }
diff --git a/TypeScript/7OnLoadHook/types/callbacks/LocationCallbacks.d.ts b/TypeScript/7OnLoadHook/types/callbacks/LocationCallbacks.d.ts
index cc69369..6e0b538 100644
--- a/TypeScript/7OnLoadHook/types/callbacks/LocationCallbacks.d.ts
+++ b/TypeScript/7OnLoadHook/types/callbacks/LocationCallbacks.d.ts
@@ -11,4 +11,5 @@ export declare class LocationCallbacks {
     constructor(httpResponse: HttpResponseUtil, locationController: LocationController);
     getLocationData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<ILocationsGenerateAllResponse>;
     getLocation(url: string, info: IGetLocationRequestData, sessionID: string): IGetBodyResponseData<ILocationBase>;
+    getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): string;
 }
diff --git a/TypeScript/7OnLoadHook/types/callbacks/ProfileCallbacks.d.ts b/TypeScript/7OnLoadHook/types/callbacks/ProfileCallbacks.d.ts
index 6a86fc0..183bb0a 100644
--- a/TypeScript/7OnLoadHook/types/callbacks/ProfileCallbacks.d.ts
+++ b/TypeScript/7OnLoadHook/types/callbacks/ProfileCallbacks.d.ts
@@ -1,5 +1,6 @@
 import { ProfileController } from "../controllers/ProfileController";
 import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData";
+import { IPmcData } from "../models/eft/common/IPmcData";
 import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData";
 import { INullResponseData } from "../models/eft/httpResponse/INullResponseData";
 import { IGetMiniProfileRequestData } from "../models/eft/launcher/IGetMiniProfileRequestData";
@@ -12,20 +13,51 @@ import { ISearchFriendResponse } from "../models/eft/profile/ISearchFriendRespon
 import { IValidateNicknameRequestData } from "../models/eft/profile/IValidateNicknameRequestData";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/** Handle profile related client events */
 export declare class ProfileCallbacks {
     protected httpResponse: HttpResponseUtil;
     protected timeUtil: TimeUtil;
     protected profileController: ProfileController;
     constructor(httpResponse: HttpResponseUtil, timeUtil: TimeUtil, profileController: ProfileController);
     createProfile(url: string, info: IProfileCreateRequestData, sessionID: string): IGetBodyResponseData<any>;
-    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
-    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
+    /**
+     * Get the complete player profile (scav + pmc character)
+     * @param url
+     * @param info Empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle the creation of a scav profile for player
+     * Occurs post-raid and when profile first created immediately after character details are confirmed by player
+     * @param url
+     * @param info empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle client/game/profile/voice/change event
+     * @param url
+     * @param info Change voice request object
+     * @param sessionID Session id
+     * @returns Client response
+     */
     changeVoice(url: string, info: IProfileChangeVoiceRequestData, sessionID: string): INullResponseData;
+    /**
+     * Handle client/game/profile/nickname/change event
+     * Client allows player to adjust their profile name
+     * @param url
+     * @param info Change nickname request object
+     * @param sessionID Session id
+     * @returns client response
+     */
     changeNickname(url: string, info: IProfileChangeNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     validateNickname(url: string, info: IValidateNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     getReservedNickname(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<string>;
     /**
-     * Called when creating a character, when you choose a character face/voice
+     * Called when creating a character when choosing a character face/voice
      * @param url
      * @param info response (empty)
      * @param sessionID
diff --git a/TypeScript/7OnLoadHook/types/callbacks/RagfairCallbacks.d.ts b/TypeScript/7OnLoadHook/types/callbacks/RagfairCallbacks.d.ts
index 3a405c9..c609f2f 100644
--- a/TypeScript/7OnLoadHook/types/callbacks/RagfairCallbacks.d.ts
+++ b/TypeScript/7OnLoadHook/types/callbacks/RagfairCallbacks.d.ts
@@ -19,6 +19,9 @@ import { ConfigServer } from "../servers/ConfigServer";
 import { RagfairServer } from "../servers/RagfairServer";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+/**
+ * Handle ragfair related callback events
+ */
 export declare class RagfairCallbacks extends OnLoadOnUpdate {
     protected httpResponse: HttpResponseUtil;
     protected logger: ILogger;
diff --git a/TypeScript/7OnLoadHook/types/controllers/InraidController.d.ts b/TypeScript/7OnLoadHook/types/controllers/InraidController.d.ts
index 82bb64d..102a2fb 100644
--- a/TypeScript/7OnLoadHook/types/controllers/InraidController.d.ts
+++ b/TypeScript/7OnLoadHook/types/controllers/InraidController.d.ts
@@ -35,6 +35,30 @@ export declare class InraidController {
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer);
     addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void;
     saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Handle updating the profile post-pmc raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Reduce body part hp to % of max
+     * @param pmcData profile to edit
+     * @param multipler multipler to apply to max health
+     */
+    protected reducePmcHealthToPercent(pmcData: IPmcData, multipler: number): void;
+    /**
+     * Handle updating the profile post-pscav raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePlayerScavProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Is the player dead after a raid - dead is anything other than "survived" / "runner"
+     * @param statusOnExit exit value from offraidData object
+     * @returns true if dead
+     */
+    protected isPlayerDead(statusOnExit: string): boolean;
     /**
      * Mark inventory items as FiR if player survived raid, otherwise remove FiR from them
      * @param offraidData Save Progress Request
diff --git a/TypeScript/7OnLoadHook/types/controllers/InventoryController.d.ts b/TypeScript/7OnLoadHook/types/controllers/InventoryController.d.ts
index f57f731..f564919 100644
--- a/TypeScript/7OnLoadHook/types/controllers/InventoryController.d.ts
+++ b/TypeScript/7OnLoadHook/types/controllers/InventoryController.d.ts
@@ -92,7 +92,11 @@ export declare class InventoryController {
      */
     toggleItem(pmcData: IPmcData, body: IInventoryToggleRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Handles Tagging of items (primary Containers).
+     * Add a tag to an inventory item
+     * @param pmcData profile with item to add tag to
+     * @param body tag request data
+     * @param sessionID session id
+     * @returns client response object
      */
     tagItem(pmcData: IPmcData, body: IInventoryTagRequestData, sessionID: string): IItemEventRouterResponse;
     bindItem(pmcData: IPmcData, body: IInventoryBindRequestData, sessionID: string): IItemEventRouterResponse;
diff --git a/TypeScript/7OnLoadHook/types/controllers/LocationController.d.ts b/TypeScript/7OnLoadHook/types/controllers/LocationController.d.ts
index 90b6d7a..9db3205 100644
--- a/TypeScript/7OnLoadHook/types/controllers/LocationController.d.ts
+++ b/TypeScript/7OnLoadHook/types/controllers/LocationController.d.ts
@@ -1,18 +1,33 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class LocationController {
     protected jsonUtil: JsonUtil;
+    protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/7OnLoadHook/types/controllers/MatchController.d.ts b/TypeScript/7OnLoadHook/types/controllers/MatchController.d.ts
index e8585d9..cb40023 100644
--- a/TypeScript/7OnLoadHook/types/controllers/MatchController.d.ts
+++ b/TypeScript/7OnLoadHook/types/controllers/MatchController.d.ts
@@ -9,6 +9,7 @@ import { IGetProfileRequestData } from "../models/eft/match/IGetProfileRequestDa
 import { IJoinMatchRequestData } from "../models/eft/match/IJoinMatchRequestData";
 import { IJoinMatchResult } from "../models/eft/match/IJoinMatchResult";
 import { IStartOfflineRaidRequestData } from "../models/eft/match/IStartOffineRaidRequestData";
+import { IBotConfig } from "../models/spt/config/IBotConfig";
 import { IInRaidConfig } from "../models/spt/config/IInRaidConfig";
 import { IMatchConfig } from "../models/spt/config/IMatchConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
@@ -29,6 +30,7 @@ export declare class MatchController {
     protected applicationContext: ApplicationContext;
     protected matchConfig: IMatchConfig;
     protected inraidConfig: IInRaidConfig;
+    protected botConfig: IBotConfig;
     constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, applicationContext: ApplicationContext);
     getEnabled(): boolean;
     getProfile(info: IGetProfileRequestData): IPmcData[];
diff --git a/TypeScript/7OnLoadHook/types/controllers/QuestController.d.ts b/TypeScript/7OnLoadHook/types/controllers/QuestController.d.ts
index 2cbccfb..282f50e 100644
--- a/TypeScript/7OnLoadHook/types/controllers/QuestController.d.ts
+++ b/TypeScript/7OnLoadHook/types/controllers/QuestController.d.ts
@@ -39,16 +39,31 @@ export declare class QuestController {
      * @returns array of IQuest
      */
     getClientQuests(sessionID: string): IQuest[];
+    /**
+     * Is the quest for the opposite side the player is on
+     * @param side player side (usec/bear)
+     * @param questId questId to check
+     */
+    protected questIsForOtherSide(side: string, questId: string): boolean;
+    /**
+     * Handle the client accepting a quest and starting it
+     * Send starting rewards if any to player and
+     * Send start notification if any to player
+     * @param pmcData Profile to update
+     * @param acceptedQuest Quest accepted
+     * @param sessionID Session id
+     * @returns client response
+     */
     acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Remove completed quest from profile
+     * Update completed quest in profile
      * Add newly unlocked quests to profile
      * Also recalculate thier level due to exp rewards
      * @param pmcData Player profile
-     * @param body completed quest request
-     * @param sessionID session id
-     * @returns ItemEvent response
+     * @param body Completed quest request
+     * @param sessionID Session id
+     * @returns ItemEvent client response
      */
     completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
@@ -67,10 +82,20 @@ export declare class QuestController {
     protected getQuestsFailedByCompletingQuest(completedQuestId: string): IQuest[];
     /**
      * Fail the quests provided
+     * Update quest in profile, otherwise add fresh quest object with failed status
      * @param sessionID session id
      * @param pmcData player profile
      * @param questsToFail quests to fail
      */
     protected failQuests(sessionID: string, pmcData: IPmcData, questsToFail: IQuest[]): void;
     handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment a backend counter stored value by an amount,
+     * Create counter if it does not exist
+     * @param pmcData Profile to find backend counter in
+     * @param conditionId backend counter id to update
+     * @param questId quest id counter is associated with
+     * @param counterValue value to increment the backend counter with
+     */
+    protected updateProfileBackendCounterValue(pmcData: IPmcData, conditionId: string, questId: string, counterValue: number): void;
 }
diff --git a/TypeScript/7OnLoadHook/types/controllers/RagfairController.d.ts b/TypeScript/7OnLoadHook/types/controllers/RagfairController.d.ts
index c4ffc15..06af740 100644
--- a/TypeScript/7OnLoadHook/types/controllers/RagfairController.d.ts
+++ b/TypeScript/7OnLoadHook/types/controllers/RagfairController.d.ts
@@ -9,6 +9,7 @@ import { RagfairOfferHelper } from "../helpers/RagfairOfferHelper";
 import { RagfairSellHelper } from "../helpers/RagfairSellHelper";
 import { RagfairSortHelper } from "../helpers/RagfairSortHelper";
 import { RagfairTaxHelper } from "../helpers/RagfairTaxHelper";
+import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
@@ -33,6 +34,9 @@ import { RagfairPriceService } from "../services/RagfairPriceService";
 import { RagfairRequiredItemsService } from "../services/RagfairRequiredItemsService";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/**
+ * Handle RagfairCallback events
+ */
 export declare class RagfairController {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
@@ -52,14 +56,20 @@ export declare class RagfairController {
     protected handbookHelper: HandbookHelper;
     protected paymentHelper: PaymentHelper;
     protected inventoryHelper: InventoryHelper;
+    protected traderHelper: TraderHelper;
     protected ragfairHelper: RagfairHelper;
     protected ragfairOfferService: RagfairOfferService;
     protected ragfairRequiredItemsService: RagfairRequiredItemsService;
     protected ragfairOfferGenerator: RagfairOfferGenerator;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
     getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult;
+    /**
+     * Update a trader flea offer with buy restrictions stored in the traders assort
+     * @param offer flea offer to update
+     */
+    protected setTraderOfferPurchaseLimits(offer: IRagfairOffer): void;
     protected isLinkedSearch(info: ISearchRequestData): boolean;
     protected isRequiredSearch(info: ISearchRequestData): boolean;
     update(): void;
diff --git a/TypeScript/7OnLoadHook/types/controllers/RepeatableQuestController.d.ts b/TypeScript/7OnLoadHook/types/controllers/RepeatableQuestController.d.ts
index 98d05dd..4c31a3d 100644
--- a/TypeScript/7OnLoadHook/types/controllers/RepeatableQuestController.d.ts
+++ b/TypeScript/7OnLoadHook/types/controllers/RepeatableQuestController.d.ts
@@ -7,6 +7,7 @@ import { Exit } from "../models/eft/common/ILocationBase";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { TraderInfo } from "../models/eft/common/tables/IBotBase";
 import { ICompletion, ICompletionAvailableFor, IElimination, IEliminationCondition, IExploration, IExplorationCondition, IPmcDataRepeatableQuest, IRepeatableQuest, IReward, IRewards } from "../models/eft/common/tables/IRepeatableQuests";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
 import { IRepeatableQuestChangeRequest } from "../models/eft/quests/IRepeatableQuestChangeRequest";
 import { ELocationName } from "../models/enums/ELocationName";
@@ -15,6 +16,7 @@ import { ILogger } from "../models/spt/utils/ILogger";
 import { ItemEventRouter } from "../routers/ItemEventRouter";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { PaymentService } from "../services/PaymentService";
 import { ProfileFixerService } from "../services/ProfileFixerService";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -64,9 +66,10 @@ export declare class RepeatableQuestController {
     protected itemEventRouter: ItemEventRouter;
     protected paymentService: PaymentService;
     protected objectId: ObjectId;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
-    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, configServer: ConfigServer);
+    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint
      * Returns an array of objects in the format of repeatable quests to the client.
@@ -217,4 +220,16 @@ export declare class RepeatableQuestController {
     debugLogRepeatableQuestIds(pmcData: IPmcData): void;
     probabilityObjectArray<K, V>(configArrayInput: ProbabilityObject<K, V>[]): ProbabilityObjectArray<K, V>;
     changeRepeatableQuest(pmcDataIn: IPmcData, body: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
+     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
+     */
+    protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig): [string, ITemplateItem][];
+    /**
+     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
+     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
+     * @param {*} tpl template id of item to check
+     * @returns boolean: true if item is valid reward
+     */
+    isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig): boolean;
 }
diff --git a/TypeScript/7OnLoadHook/types/controllers/TraderController.d.ts b/TypeScript/7OnLoadHook/types/controllers/TraderController.d.ts
index 0162064..b79f55e 100644
--- a/TypeScript/7OnLoadHook/types/controllers/TraderController.d.ts
+++ b/TypeScript/7OnLoadHook/types/controllers/TraderController.d.ts
@@ -4,6 +4,7 @@ import { TraderHelper } from "../helpers/TraderHelper";
 import { IBarterScheme, ITraderAssort, ITraderBase } from "../models/eft/common/tables/ITrader";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { FenceService } from "../services/FenceService";
 import { TraderAssortService } from "../services/TraderAssortService";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
@@ -15,8 +16,9 @@ export declare class TraderController {
     protected traderHelper: TraderHelper;
     protected timeUtil: TimeUtil;
     protected traderAssortService: TraderAssortService;
+    protected fenceService: FenceService;
     protected jsonUtil: JsonUtil;
-    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, jsonUtil: JsonUtil);
+    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, fenceService: FenceService, jsonUtil: JsonUtil);
     /**
      * Runs when onLoad event is fired
      * Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
@@ -26,6 +28,7 @@ export declare class TraderController {
     /**
      * Runs when onUpdate is fired
      * If current time is > nextResupply(expire) time of trader, refresh traders assorts and
+     * Fence is handled slightly differently
      * @returns has run
      */
     update(): boolean;
diff --git a/TypeScript/7OnLoadHook/types/di/Container.d.ts b/TypeScript/7OnLoadHook/types/di/Container.d.ts
index 17791b0..98d1fa1 100644
--- a/TypeScript/7OnLoadHook/types/di/Container.d.ts
+++ b/TypeScript/7OnLoadHook/types/di/Container.d.ts
@@ -1,4 +1,7 @@
 import { DependencyContainer } from "tsyringe";
+/**
+ * Handle the registration of classes to be used by the Dependency Injection code
+ */
 export declare class Container {
     static registerTypes(depContainer: DependencyContainer): void;
     static registerListTypes(depContainer: DependencyContainer): void;
diff --git a/TypeScript/7OnLoadHook/types/generators/BotGenerator.d.ts b/TypeScript/7OnLoadHook/types/generators/BotGenerator.d.ts
index a5fc0ad..7d58f95 100644
--- a/TypeScript/7OnLoadHook/types/generators/BotGenerator.d.ts
+++ b/TypeScript/7OnLoadHook/types/generators/BotGenerator.d.ts
@@ -40,7 +40,7 @@ export declare class BotGenerator {
      * @param botTemplate base bot template to use  (e.g. assault/pmcbot)
      * @returns
      */
-    generatePlayerScav(role: string, difficulty: string, botTemplate: IBotType): IBotBase;
+    generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase;
     generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[];
     /**
      * Choose if a bot should become a PMC by checking if bot type is allowed to become a Pmc in botConfig.convertFromChances and doing a random int check
@@ -58,7 +58,7 @@ export declare class BotGenerator {
      * @returns IBotBase object
      */
     protected getCloneOfBotBase(): IBotBase;
-    protected generateBot(bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
+    protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
     /**
      * Log the number of PMCs generated to the debug console
      */
diff --git a/TypeScript/7OnLoadHook/types/generators/BotInventoryGenerator.d.ts b/TypeScript/7OnLoadHook/types/generators/BotInventoryGenerator.d.ts
index 35d1ee8..73f8ece 100644
--- a/TypeScript/7OnLoadHook/types/generators/BotInventoryGenerator.d.ts
+++ b/TypeScript/7OnLoadHook/types/generators/BotInventoryGenerator.d.ts
@@ -18,7 +18,7 @@ export declare class BotInventoryGenerator {
     protected botGeneratorHelper: BotGeneratorHelper;
     protected weightedRandomHelper: WeightedRandomHelper;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper);
-    generateInventory(templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
+    generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
     protected generateEquipment(equipmentSlot: string, equipmentPool: Record<string, number>, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void;
     protected generateInventoryBase(): PmcInventory;
 }
diff --git a/TypeScript/7OnLoadHook/types/generators/BotLootGenerator.d.ts b/TypeScript/7OnLoadHook/types/generators/BotLootGenerator.d.ts
index c6a3f29..5a2d144 100644
--- a/TypeScript/7OnLoadHook/types/generators/BotLootGenerator.d.ts
+++ b/TypeScript/7OnLoadHook/types/generators/BotLootGenerator.d.ts
@@ -24,7 +24,7 @@ export declare class BotLootGenerator {
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botLootCacheService: BotLootCacheService, configServer: ConfigServer);
-    generateLoot(templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
+    generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
     protected getRandomisedCount(min: number, max: number, nValue: number): number;
     /**
      * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached
@@ -47,7 +47,7 @@ export declare class BotLootGenerator {
      * @param botRole bots role, .e.g. pmcBot
      * @param isPmc are we generating for a pmc
      */
-    protected addLooseWeaponsToInventorySlot(botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
+    protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
     /**
      * Get a random item from the pool parameter using the biasedRandomNumber system
      * @param pool pool of items to pick an item from
diff --git a/TypeScript/7OnLoadHook/types/generators/BotWeaponGenerator.d.ts b/TypeScript/7OnLoadHook/types/generators/BotWeaponGenerator.d.ts
index 9215214..49fa7bf 100644
--- a/TypeScript/7OnLoadHook/types/generators/BotWeaponGenerator.d.ts
+++ b/TypeScript/7OnLoadHook/types/generators/BotWeaponGenerator.d.ts
@@ -28,7 +28,18 @@ export declare class BotWeaponGenerator {
     protected botConfig: IBotConfig;
     constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer);
     /**
-     * Get a random weapon from a bots pool of weapons (weighted)
+     * Pick a random weapon based on weightings and generate a functional weapon
+     * @param equipmentSlot Primary/secondary/holster
+     * @param botTemplateInventory e.g. assault.json
+     * @param weaponParentId
+     * @param modChances
+     * @param botRole role of bot, e.g. assault/followerBully
+     * @param isPmc Is weapon generated for a pmc
+     * @returns GenerateWeaponResult object
+     */
+    generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    /**
+     * Get a random weighted weapon from a bots pool of weapons
      * @param equipmentSlot Primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
      * @returns weapon tpl
@@ -39,43 +50,24 @@ export declare class BotWeaponGenerator {
      * @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool())
      * @param equipmentSlot slot to fit into, primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
+     * @param weaponParentId ParentId of the weapon being generated
+     * @param modChances Dictionary of item types and % chance weapon will have that mod
+     * @param botRole e.g. assault/exusec
      * @param isPmc
      * @returns GenerateWeaponResult object
      */
-    generateWeaponByTpl(weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
     /**
-     * Generate an entirely random weapon
-     * @param equipmentSlot Primary/secondary/holster
-     * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
-     * @param isPmc
-     * @returns GenerateWeaponResult object
-     */
-    generateRandomWeapon(equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
-    /**
-     * Create array with weapon base as only element
-     * Add additional properties as required
-     * @param weaponTpl
-     * @param weaponParentId
-     * @param equipmentSlot
-     * @param weaponItemTemplate
+     * Create array with weapon base as only element and
+     * add additional properties based on weapon type
+     * @param weaponTpl Weapon tpl to create item with
+     * @param weaponParentId Weapons parent id
+     * @param equipmentSlot e.g. primary/secondary/holster
+     * @param weaponItemTemplate db template for weapon
      * @param botRole for durability values
-     * @returns
+     * @returns Base weapon item in array
      */
     constructWeaponBaseArray(weaponTpl: string, weaponParentId: string, equipmentSlot: string, weaponItemTemplate: ITemplateItem, botRole: string): Item[];
-    /**
-     * Add compatible magazines to an inventory based on a generated weapon
-     * @param weaponDetails
-     * @param magCounts
-     * @param inventory
-     * @param botRole the bot type we're getting generating extra mags for
-     */
-    addExtraMagazinesToInventory(weaponDetails: GenerateWeaponResult, magCounts: MinMax, inventory: PmcInventory, botRole: string): void;
     /**
      * Get the mods necessary to kit out a weapon to its preset level
      * @param weaponTpl weapon to find preset for
@@ -84,20 +76,32 @@ export declare class BotWeaponGenerator {
      * @returns array of weapon mods
      */
     protected getPresetWeaponMods(weaponTpl: string, equipmentSlot: string, weaponParentId: string, itemTemplate: ITemplateItem, botRole: string): Item[];
-    /** Checks if all required slots are occupied on a weapon and all it's mods */
+    /**
+     * Checks if all required slots are occupied on a weapon and all it's mods
+     * @param weaponItemArray Weapon + mods
+     * @returns true if valid
+     */
     protected isWeaponValid(weaponItemArray: Item[]): boolean;
     /**
      * Generates extra magazines or bullets (if magazine is internal) and adds them to TacticalVest and Pockets.
      * Additionally, adds extra bullets to SecuredContainer
-     * @param weaponMods
-     * @param weaponTemplate
-     * @param magCounts
-     * @param ammoTpl
-     * @param inventory
+     * @param weaponMods mods to attach to weapon
+     * @param weaponTemplate db template for weapon
+     * @param magCounts magazine count to add to inventory
+     * @param ammoTpl ammo templateId to add to magazines
+     * @param inventory inventory to add magazines to
      * @param botRole the bot type we're getting generating extra mags for
      * @returns
      */
-    protected generateExtraMagazines(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    addExtraMagazinesToInventory(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    /**
+     * Create a magazine using the parameters given
+     * @param magazineTpl Tpl of the magazine to create
+     * @param ammoTpl Ammo to add to magazine
+     * @param magTemplate template object of magazine
+     * @returns Item array
+     */
+    protected createMagazine(magazineTpl: string, ammoTpl: string, magTemplate: ITemplateItem): Item[];
     /**
      * Get a randomised number of bullets for a specific magazine
      * @param magCounts min and max count of magazines
@@ -138,10 +142,9 @@ export declare class BotWeaponGenerator {
      * Finds and return a compatible ammo tpl based on the bots ammo weightings (x.json/inventory/equipment/ammo)
      * @param ammo a list of ammo tpls the weapon can use
      * @param weaponTemplate the weapon we want to pick ammo for
-     * @param isPmc is the ammo being gathered for a pmc (runs pmc ammo filtering)
      * @returns an ammo tpl that works with the desired gun
      */
-    protected getCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem, isPmc: boolean): string;
+    protected getWeightedCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem): string;
     /**
      * Get a weapons compatible cartridge caliber
      * @param weaponTemplate Weapon to look up caliber of
diff --git a/TypeScript/7OnLoadHook/types/generators/LocationGenerator.d.ts b/TypeScript/7OnLoadHook/types/generators/LocationGenerator.d.ts
index bd368b5..cc61dcf 100644
--- a/TypeScript/7OnLoadHook/types/generators/LocationGenerator.d.ts
+++ b/TypeScript/7OnLoadHook/types/generators/LocationGenerator.d.ts
@@ -3,10 +3,9 @@ import { GameEventHelper } from "../helpers/GameEventHelper";
 import { ItemHelper } from "../helpers/ItemHelper";
 import { PresetHelper } from "../helpers/PresetHelper";
 import { RagfairServerHelper } from "../helpers/RagfairServerHelper";
-import { ILooseLoot, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
+import { ILooseLoot, SpawnpointsForced, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IStaticAmmoDetails, IStaticContainerProps, IStaticForcedProps, IStaticLootDetails } from "../models/eft/common/tables/ILootBase";
-import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILocationConfig } from "../models/spt/config/ILocationConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
@@ -36,11 +35,19 @@ export declare class LocationGenerator {
     generateContainerLoot(containerIn: IStaticContainerProps, staticForced: IStaticForcedProps[], staticLootDist: Record<string, IStaticLootDetails>, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): IStaticContainerProps;
     protected getLooseLootMultiplerForLocation(location: string): number;
     protected getStaticLootMultiplerForLocation(location: string): number;
+    /**
+     * Create array of loose + forced loot using probability system
+     * @param dynamicLootDist
+     * @param staticAmmoDist
+     * @param locationName Location to generate loot for
+     * @returns Array of spawn points with loot in them
+     */
     generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): SpawnpointTemplate[];
+    /**
+     * Add forced spawn point loot into loot parameter array
+     * @param loot array to add forced loot to
+     * @param forcedSpawnPoints forced loot to add
+     */
+    protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[]): void;
     protected createItem(tpl: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, parentId?: string): IContainerItem;
-    protected getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
-    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
-    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
-    protected createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
-    protected createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
 }
diff --git a/TypeScript/7OnLoadHook/types/generators/LootGenerator.d.ts b/TypeScript/7OnLoadHook/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/7OnLoadHook/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/7OnLoadHook/types/generators/PMCLootGenerator.d.ts b/TypeScript/7OnLoadHook/types/generators/PMCLootGenerator.d.ts
index 64e6f7f..b9f2a83 100644
--- a/TypeScript/7OnLoadHook/types/generators/PMCLootGenerator.d.ts
+++ b/TypeScript/7OnLoadHook/types/generators/PMCLootGenerator.d.ts
@@ -1,15 +1,21 @@
 import { ItemHelper } from "../helpers/ItemHelper";
-import { DatabaseServer } from "../servers/DatabaseServer";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+/**
+ * Handle the generation of dynamic PMC loot in pockets and backpacks
+ * and the removal of blacklisted items
+ */
 export declare class PMCLootGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected configServer: ConfigServer;
+    protected itemFilterService: ItemFilterService;
     protected pocketLootPool: string[];
     protected backpackLootPool: string[];
     protected botConfig: IBotConfig;
-    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer);
+    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer, itemFilterService: ItemFilterService);
     generatePMCPocketLootPool(): string[];
     generatePMCBackpackLootPool(): string[];
 }
diff --git a/TypeScript/7OnLoadHook/types/generators/ScavCaseRewardGenerator.d.ts b/TypeScript/7OnLoadHook/types/generators/ScavCaseRewardGenerator.d.ts
index c7d6ab7..89cb5c8 100644
--- a/TypeScript/7OnLoadHook/types/generators/ScavCaseRewardGenerator.d.ts
+++ b/TypeScript/7OnLoadHook/types/generators/ScavCaseRewardGenerator.d.ts
@@ -8,9 +8,13 @@ import { RewardCountAndPriceDetails, ScavCaseRewardCountsAndPrices } from "../mo
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { RagfairPriceService } from "../services/RagfairPriceService";
 import { HashUtil } from "../utils/HashUtil";
 import { RandomUtil } from "../utils/RandomUtil";
+/**
+ * Handle the creation of randomised scav case rewards
+ */
 export declare class ScavCaseRewardGenerator {
     protected logger: ILogger;
     protected randomUtil: RandomUtil;
@@ -18,9 +22,10 @@ export declare class ScavCaseRewardGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected ragfairPriceService: RagfairPriceService;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected scavCaseConfig: IScavCaseConfig;
-    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, configServer: ConfigServer);
+    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Create an array of rewards that will be given to the player upon completing their scav case build
      * @param body client request
diff --git a/TypeScript/7OnLoadHook/types/generators/WeatherGenerator.d.ts b/TypeScript/7OnLoadHook/types/generators/WeatherGenerator.d.ts
index 44cecbb..8ddbe49 100644
--- a/TypeScript/7OnLoadHook/types/generators/WeatherGenerator.d.ts
+++ b/TypeScript/7OnLoadHook/types/generators/WeatherGenerator.d.ts
@@ -1,7 +1,7 @@
 import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IWeatherData } from "../models/eft/weather/IWeatherData";
 import { IWeatherConfig } from "../models/spt/config/IWeatherConfig";
+import { ConfigServer } from "../servers/ConfigServer";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class WeatherGenerator {
@@ -21,11 +21,16 @@ export declare class WeatherGenerator {
     protected getAcceleratedTime(computedDate: Date): string;
     /**
      * Get current time formatted to fit BSGs requirement
-     * @param computedDate
+     * @param computedDate date to format into bsg style
      * @returns
      */
     protected getNormalTime(computedDate: Date): string;
-    generateWeather(data: IWeatherData): IWeatherData;
+    /**
+     * Return randomised Weather data
+     * @param weatherData weather input data
+     * @returns Randomised weather data
+     */
+    generateWeather(weatherData: IWeatherData): IWeatherData;
     protected getWeightedFog(): string;
     protected getWeightedRain(): number;
     protected getRandomFloat(node: string): number;
diff --git a/TypeScript/7OnLoadHook/types/helpers/AssortHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/AssortHelper.d.ts
index 15586b9..bfc157f 100644
--- a/TypeScript/7OnLoadHook/types/helpers/AssortHelper.d.ts
+++ b/TypeScript/7OnLoadHook/types/helpers/AssortHelper.d.ts
@@ -17,7 +17,7 @@ export declare class AssortHelper {
      * @param assort assort items from a trader
      * @returns assort items minus locked quest assorts
      */
-    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort): ITraderAssort;
+    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort, flea?: boolean): ITraderAssort;
     /**
      * Remove assorts from a trader that have not been unlocked yet
      * @param pmcProfile player profile
@@ -32,5 +32,5 @@ export declare class AssortHelper {
      * @param itemID item id to remove from asort
      * @returns Modified assort
      */
-    removeItemFromAssort(assort: ITraderAssort, itemID: string): ITraderAssort;
+    removeItemFromAssort(assort: ITraderAssort, itemID: string, flea?: boolean): ITraderAssort;
 }
diff --git a/TypeScript/7OnLoadHook/types/helpers/BotGeneratorHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/BotGeneratorHelper.d.ts
index 3cd7256..eb0d215 100644
--- a/TypeScript/7OnLoadHook/types/helpers/BotGeneratorHelper.d.ts
+++ b/TypeScript/7OnLoadHook/types/helpers/BotGeneratorHelper.d.ts
@@ -3,10 +3,12 @@ import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"
 import { Mods, ModsChances } from "../models/eft/common/tables/IBotType";
 import { Item, Repairable, Upd } from "../models/eft/common/tables/IItem";
 import { Grid, ITemplateItem, Slot } from "../models/eft/common/tables/ITemplateItem";
-import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
@@ -14,6 +16,7 @@ import { ContainerHelper } from "./ContainerHelper";
 import { InventoryHelper } from "./InventoryHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProbabilityHelper } from "./ProbabilityHelper";
+import { ProfileHelper } from "./ProfileHelper";
 export declare class BotGeneratorHelper {
     protected logger: ILogger;
     protected jsonUtil: JsonUtil;
@@ -25,10 +28,76 @@ export declare class BotGeneratorHelper {
     protected itemHelper: ItemHelper;
     protected inventoryHelper: InventoryHelper;
     protected containerHelper: ContainerHelper;
+    protected botEquipmentFilterService: BotEquipmentFilterService;
+    protected itemFilterService: ItemFilterService;
+    protected profileHelper: ProfileHelper;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, configServer: ConfigServer);
-    generateModsForItem(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, configServer: ConfigServer);
+    /**
+     * TODO - very similar to generateModsForWeapon
+     * Check mods are compatible and add to array
+     * @param equipment Equipment item to add mods to
+     * @param modPool Mod list to choose frm
+     * @param parentId parentid of item to add mod to
+     * @param parentTemplate template objet of item to add mods to
+     * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type
+     * @returns Item + compatible mods as an array
+     */
+    generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    /**
+     * TODO - very similar to generateModsForEquipment
+     * @param sessionId session id
+     * @param weapon Weapon to add mods to
+     * @param modPool pool of compatible mods to attach to gun
+     * @param weaponParentId parentId of weapon
+     * @param parentTemplate
+     * @param modSpawnChances
+     * @param ammoTpl ammo tpl to use when generating magazines/cartridges
+     * @param botRole role of bot weapon is generated for
+     * @returns Weapon with mods
+     */
+    generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[];
+    /**
+     * Generate a pool of mods for this bots mod type if bot has values inside `randomisedWeaponModSlots` array found in bot.json/equipment[botrole]
+     * @param allowedMods Mods to be added to mod pool
+     * @param botEquipBlacklist blacklist of items not allowed to be added to mod pool
+     * @param modSlot Slot to generate mods for
+     * @param itemModPool base mod pool to replace values of
+     */
+    protected generateDynamicModPool(allowedMods: string[], botEquipBlacklist: EquipmentFilterDetails, modSlot: string, itemModPool: Record<string, string[]>): void;
+    /**
+     * Check if the specific item type on the weapon has reached the set limit
+     * @param modTpl item to check is limited
+     * @param currentCount current number of this item on gun
+     * @param maxLimit mod limit allowed
+     * @param botRole role of bot we're checking weapon of
+     * @returns true if limit reached
+     */
+    protected weaponModLimitReached(modTpl: string, currentCount: {
+        count: number;
+    }, maxLimit: number, botRole: string): boolean;
+    /**
+     * log errors if mod is not valid for a slot
+     * @param modTpl
+     * @param found
+     * @param itemSlot
+     * @param modTemplate
+     * @param modSlot
+     * @param parentTemplate
+     * @returns true if valid
+     */
+    protected isModValidForSlot(modTpl: string, found: boolean, itemSlot: Slot, modTemplate: ITemplateItem, modSlot: string, parentTemplate: ITemplateItem): boolean;
+    /**
+     * Create a mod item with parameters as properties
+     * @param modId _id
+     * @param modTpl _tpl
+     * @param parentId parentId
+     * @param modSlot slotId
+     * @param modTemplate Used to add additional properites in the upd object
+     * @returns Item object
+     */
+    protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item;
     /**
      * Is this magazine cylinder related (revolvers and grenade launchers)
      * @param magazineParentName the name of the magazines parent
@@ -62,11 +131,11 @@ export declare class BotGeneratorHelper {
      * Those magazines (e.g. 60dc519adf4c47305f6d410d) have a "Cartridges" entry with a _max_count=0.
      * Ammo is not put into the magazine directly but assigned to the magazine's slots: The "camora_xxx" slots.
      * This function is a helper called by generateModsForItem for mods with parent type "CylinderMagazine"
-     *
-     * @param {object}      items               The items where the CylinderMagazine's camora are appended to
-     * @param {object}      modPool             modPool which should include available cartrigdes
-     * @param {string}      parentId            The CylinderMagazine's UID
-     * @param {object}      parentTemplate      The CylinderMagazine's template
+     * @param items The items where the CylinderMagazine's camora are appended to
+     * @param modPool modPool which should include available cartrigdes
+     * @param parentId The CylinderMagazine's UID
+     * @param parentTemplate The CylinderMagazine's template
+     * @returns
      */
     protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void;
     /**
@@ -75,6 +144,13 @@ export declare class BotGeneratorHelper {
      * @returns string array of shells fro luitple camora sources
      */
     protected mergeCamoraPoolsTogether(camorasWithShells: Record<string, string[]>): string[];
+    /**
+     * Adds properties to an item
+     * e.g. Repairable / HasHinge / Foldable / MaxDurability
+     * @param itemTemplate
+     * @param botRole Used by weapons to randomise the durability values
+     * @returns Item Upd object with extra properties
+     */
     generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): {
         upd?: Upd;
     };
@@ -93,12 +169,6 @@ export declare class BotGeneratorHelper {
      */
     protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable;
     protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string;
-    /**
-     * Sort by spawn chance, highest to lowest, higher is more common
-     * @param unsortedModArray String array to sort
-     * @returns Sorted string array
-     */
-    protected sortModArray(unsortedModArray: string[]): string[];
     /**
      * Can an item be added to an item without issue
      * @param items
@@ -117,8 +187,15 @@ export declare class BotGeneratorHelper {
      * @returns a `boolean` indicating item was added
      */
     addItemWithChildrenToEquipmentSlot(equipmentSlots: string[], parentId: string, parentTpl: string, itemWithChildren: Item[], inventory: PmcInventory): boolean;
+    /**
+     * is the provided item allowed inside a container
+     * @param slot location item wants to be placed in
+     * @param itemTpl item being placed
+     * @returns true if allowed
+     */
     protected itemAllowedInContainer(slot: Grid, itemTpl: string): boolean;
 }
+/** TODO - move into own class */
 export declare class ExhaustableArray<T> {
     private itemPool;
     private randomUtil;
diff --git a/TypeScript/7OnLoadHook/types/helpers/HideoutHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/HideoutHelper.d.ts
index 36e4009..7495a6a 100644
--- a/TypeScript/7OnLoadHook/types/helpers/HideoutHelper.d.ts
+++ b/TypeScript/7OnLoadHook/types/helpers/HideoutHelper.d.ts
@@ -44,14 +44,72 @@ export declare class HideoutHelper {
     initProduction(recipeId: string, productionTime: number): Production;
     isProductionType(productive: Productive): productive is Production;
     applyPlayerUpgradesBonuses(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * TODO:
+     * After looking at the skills there doesnt seem to be a configuration per skill to boost
+     * the XP gain PER skill. I THINK you should be able to put the variable "SkillProgress" (just like health has it)
+     * and be able to tune the skill gain PER skill, but I havent tested it and Im not sure!
+     * @param pmcData
+     * @param bonus
+     */
     protected applySkillXPBoost(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * Process a players hideout, update areas that use resources + increment production timers
+     * @param sessionID Session id
+     */
     updatePlayerHideout(sessionID: string): void;
+    /**
+     * Update progress timer for water collector
+     * @param pmcData profile to update
+     * @param productionId id of water collection production to update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateWaterCollectorProductionTimer(pmcData: IPmcData, productionId: string, hideoutProperties: {
+        btcFarmCGs?: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Iterate over productions and update their progress timers
+     * @param pmcData Profile to check for productions and update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Update progress timer for scav case
+     * @param pmcData Profile to update
+     * @param productionId Id of scav case production to update
+     */
+    protected updateScavCaseProductionTimer(pmcData: IPmcData, productionId: string): void;
+    /**
+     * Iterate over hideout areas that use resources (fuel/filters etc) and update associated values
+     * @param sessionID Session id
+     * @param pmcData Profile to update areas of
+     * @param hideoutProperties hideout properties
+     */
+    protected updateAreasWithResources(sessionID: string, pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
     protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
     protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
-    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): HideoutArea;
-    protected updateWaterFilters(waterFilterArea: HideoutArea, pwProd: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
+    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): void;
+    /**
+     * Adjust water filter objects resourceValue or delete when they reach 0 resource
+     * @param waterFilterArea water filter area to update
+     * @param production production object
+     * @param isGeneratorOn is generatory enabled
+     * @param pmcData Player profile
+     * @returns Updated HideoutArea object
+     */
+    protected updateWaterFilters(waterFilterArea: HideoutArea, production: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
     protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
-    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): HideoutArea;
+    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): void;
     protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
     protected getBTCSlots(pmcData: IPmcData): number;
     protected getManagementSkillsSlots(): number;
diff --git a/TypeScript/7OnLoadHook/types/helpers/InRaidHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/InRaidHelper.d.ts
index b382e30..962df38 100644
--- a/TypeScript/7OnLoadHook/types/helpers/InRaidHelper.d.ts
+++ b/TypeScript/7OnLoadHook/types/helpers/InRaidHelper.d.ts
@@ -18,18 +18,6 @@ export declare class InRaidHelper {
     protected paymentHelper: PaymentHelper;
     protected profileFixerService: ProfileFixerService;
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper, profileFixerService: ProfileFixerService);
-    /**
-     * Reset the SPT inraid property stored in a profile to 'none'
-     * @param sessionID Session id
-     */
-    protected removePlayer(sessionID: string): void;
-    /**
-     * Some maps have one-time-use keys (e.g. Labs
-     * Remove the relevant key from an inventory based on the post-raid request data passed in
-     * @param offraidData post-raid data
-     * @param sessionID Session id
-     */
-    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
     /**
      * Check an array of items and add an upd object to money items with a stack count of 1
      * Single stack money items have no upd object and thus no StackObjectsCount, causing issues
@@ -54,6 +42,18 @@ export declare class InRaidHelper {
      * @returns Reset profile object
      */
     updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData;
+    /**
+     * Some maps have one-time-use keys (e.g. Labs
+     * Remove the relevant key from an inventory based on the post-raid request data passed in
+     * @param offraidData post-raid data
+     * @param sessionID Session id
+     */
+    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Set the SPT inraid location Profile property to 'none'
+     * @param sessionID Session id
+     */
+    protected setPlayerInRaidLocationStatusToNone(sessionID: string): void;
     /**
      * Adds SpawnedInSession property to items found in a raid
      * Removes SpawnedInSession for non-scav players if item was taken into raid with SpawnedInSession = true
@@ -95,5 +95,10 @@ export declare class InRaidHelper {
      * @returns true if item is kept after death
      */
     isItemKeptAfterDeath(slotId: string): boolean;
+    /**
+     * Return the equipped items from a players inventory
+     * @param items Players inventory to search through
+     * @returns an array of equipped items
+     */
     getPlayerGear(items: Item[]): Item[];
 }
diff --git a/TypeScript/7OnLoadHook/types/helpers/ItemHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/ItemHelper.d.ts
index 1701c62..de10892 100644
--- a/TypeScript/7OnLoadHook/types/helpers/ItemHelper.d.ts
+++ b/TypeScript/7OnLoadHook/types/helpers/ItemHelper.d.ts
@@ -1,35 +1,30 @@
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item, Repairable } from "../models/eft/common/tables/IItem";
+import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase";
 import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+import { MathUtil } from "../utils/MathUtil";
+import { ObjectId } from "../utils/ObjectId";
+import { RandomUtil } from "../utils/RandomUtil";
 declare class ItemHelper {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
     protected jsonUtil: JsonUtil;
+    protected randomUtil: RandomUtil;
+    protected objectId: ObjectId;
+    protected mathUtil: MathUtil;
     protected databaseServer: DatabaseServer;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer);
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer);
     /**
      * Checks if a id is a valid item. Valid meaning that it's an item that be stored in stash
      * @param       {string}    tpl       the template id / tpl
      * @returns                             boolean; true for items that may be in player posession and not quest items
      */
     isValidItem(tpl: string, invalidBaseTypes?: string[]): boolean;
-    /**
-     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
-     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
-     * @param {*} tpl template id of item to check
-     * @returns boolean: true if item is valid reward
-     */
-    isValidRewardItem(tpl: string): boolean;
-    /**
-     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
-     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
-     */
-    getRewardableItems(): [string, ITemplateItem][];
     /**
      * Check if the tpl / template Id provided is a descendent of the baseclass
      *
@@ -196,6 +191,22 @@ declare class ItemHelper {
      * @returns ItemSize object (width and height)
      */
     getItemSize(items: Item[], rootItemId: string): ItemHelper.ItemSize;
+    /**
+     * Get a random cartridge from an items Filter property
+     * @param item
+     * @returns
+     */
+    getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
+    createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
+    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
+    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
+    createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
+    /**
+     * Get the size of a stack, return 1 if no stack object count property found
+     * @param item Item to get stack size of
+     * @returns size of stack
+     */
+    getItemStackSize(item: Item): number;
 }
 declare namespace ItemHelper {
     interface ItemSize {
diff --git a/TypeScript/7OnLoadHook/types/helpers/ProfileHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/ProfileHelper.d.ts
index 9d4ff98..9c6560a 100644
--- a/TypeScript/7OnLoadHook/types/helpers/ProfileHelper.d.ts
+++ b/TypeScript/7OnLoadHook/types/helpers/ProfileHelper.d.ts
@@ -24,6 +24,19 @@ export declare class ProfileHelper {
     constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, fenceService: FenceService);
     resetProfileQuestCondition(sessionID: string, conditionId: string): void;
     getCompleteProfile(sessionID: string): IPmcData[];
+    /**
+     * Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
+     * Server saves the post-raid changes prior to the xp screen getting the profile, this results in the xp screen using
+     * the now updated profile values as a base, meaning it shows x2 xp gained
+     * Instead, clone the post-raid profile (so we dont alter its values), apply the pre-raid xp values to the cloned objects and return
+     * Delete snapshot of pre-raid profile prior to returning profile data
+     * @param sessionId Session id
+     * @param output pmc and scav profiles array
+     * @param pmcProfile post-raid pmc profile
+     * @param scavProfile post-raid scav profile
+     * @returns updated profile array
+     */
+    protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
     isNicknameTaken(info: IValidateNicknameRequestData, sessionID: string): boolean;
     /**
      * Add experience to a PMC inside the players profile
diff --git a/TypeScript/7OnLoadHook/types/helpers/QuestHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/QuestHelper.d.ts
index 32e55ec..d66d150 100644
--- a/TypeScript/7OnLoadHook/types/helpers/QuestHelper.d.ts
+++ b/TypeScript/7OnLoadHook/types/helpers/QuestHelper.d.ts
@@ -36,11 +36,20 @@ export declare class QuestHelper {
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
     constructor(logger: ILogger, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, itemHelper: ItemHelper, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, localeService: LocaleService, ragfairServerHelper: RagfairServerHelper, dialogueHelper: DialogueHelper, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, traderHelper: TraderHelper, configServer: ConfigServer);
-    questStatus(pmcData: IPmcData, questID: string): QuestStatus;
     /**
-     * returns true is the condition is satisfied
+    * Get status of a quest by quest id
+    * @param pmcData Profile to search
+    * @param questID Quest id to look up
+    * @returns QuestStauts enum
+    */
+    getQuestStatus(pmcData: IPmcData, questID: string): QuestStatus;
+    /**
+     * returns true is the level condition is satisfied
+     * @param playerLevel Players level
+     * @param condition Quest condition
+     * @returns true if player level is greater than or equal to quest
      */
-    evaluateLevel(pmcProfile: IPmcData, cond: AvailableForConditions): boolean;
+    doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean;
     getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[];
     /**
      * Increase skill points of a skill on player profile
diff --git a/TypeScript/7OnLoadHook/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/RagfairOfferHelper.d.ts
index 8d03bee..e9d72ca 100644
--- a/TypeScript/7OnLoadHook/types/helpers/RagfairOfferHelper.d.ts
+++ b/TypeScript/7OnLoadHook/types/helpers/RagfairOfferHelper.d.ts
@@ -22,12 +22,14 @@ import { ProfileHelper } from "./ProfileHelper";
 import { RagfairHelper } from "./RagfairHelper";
 import { RagfairServerHelper } from "./RagfairServerHelper";
 import { RagfairSortHelper } from "./RagfairSortHelper";
+import { TraderHelper } from "./TraderHelper";
 export declare class RagfairOfferHelper {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
     protected hashUtil: HashUtil;
     protected itemEventRouter: ItemEventRouter;
     protected databaseServer: DatabaseServer;
+    protected traderHelper: TraderHelper;
     protected saveServer: SaveServer;
     protected dialogueHelper: DialogueHelper;
     protected itemHelper: ItemHelper;
@@ -43,10 +45,10 @@ export declare class RagfairOfferHelper {
     protected static goodSoldTemplate: string;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, traderHelper: TraderHelper, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
     getValidOffers(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
     getOffersForBuild(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
-    processOffers(sessionID: string): boolean;
+    processOffersOnProfile(sessionID: string): boolean;
     protected getProfileOffers(sessionID: string): IRagfairOffer[];
     protected deleteOfferByOfferId(sessionID: string, offerId: string): void;
     protected completeOffer(sessionID: string, offer: IRagfairOffer, boughtAmount: number): IItemEventRouterResponse;
diff --git a/TypeScript/7OnLoadHook/types/helpers/RagfairSellHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/RagfairSellHelper.d.ts
index 6ec004a..91b8a20 100644
--- a/TypeScript/7OnLoadHook/types/helpers/RagfairSellHelper.d.ts
+++ b/TypeScript/7OnLoadHook/types/helpers/RagfairSellHelper.d.ts
@@ -11,6 +11,12 @@ export declare class RagfairSellHelper {
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     constructor(logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer);
-    calculateSellChance(baseChance: number, offerPrice: number, requirementsPriceInRub: number): number;
-    rollForSale(sellChance: number, count: number): SellResult[];
+    calculateSellChance(baseChancePercent: number, offerPriceRub: number, playerListedPriceRub: number): number;
+    /**
+     * Determine if the offer being listed will be sold
+     * @param sellChancePercent chance item will sell
+     * @param itemSellCount count of items to sell
+     * @returns Array of purchases of item(s) lsited
+     */
+    rollForSale(sellChancePercent: number, itemSellCount: number): SellResult[];
 }
diff --git a/TypeScript/7OnLoadHook/types/helpers/RagfairServerHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/RagfairServerHelper.d.ts
index e4939d1..a03cdda 100644
--- a/TypeScript/7OnLoadHook/types/helpers/RagfairServerHelper.d.ts
+++ b/TypeScript/7OnLoadHook/types/helpers/RagfairServerHelper.d.ts
@@ -6,6 +6,7 @@ import { IRagfairConfig } from "../models/spt/config/IRagfairConfig";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { SaveServer } from "../servers/SaveServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { LocaleService } from "../services/LocaleService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -13,6 +14,9 @@ import { RandomUtil } from "../utils/RandomUtil";
 import { DialogueHelper } from "./DialogueHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProfileHelper } from "./ProfileHelper";
+/**
+ * Helper class for common ragfair server actions
+ */
 export declare class RagfairServerHelper {
     protected randomUtil: RandomUtil;
     protected hashUtil: HashUtil;
@@ -23,11 +27,12 @@ export declare class RagfairServerHelper {
     protected localeService: LocaleService;
     protected dialogueHelper: DialogueHelper;
     protected jsonUtil: JsonUtil;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
     protected static goodsReturnedTemplate: string;
-    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, configServer: ConfigServer);
+    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Is item valid / on blacklist / quest item
      * @param itemDetails
diff --git a/TypeScript/7OnLoadHook/types/helpers/TradeHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/TradeHelper.d.ts
index 975062b..7ab9768 100644
--- a/TypeScript/7OnLoadHook/types/helpers/TradeHelper.d.ts
+++ b/TypeScript/7OnLoadHook/types/helpers/TradeHelper.d.ts
@@ -39,6 +39,12 @@ export declare class TradeHelper {
      * @returns
      */
     sellItem(pmcData: IPmcData, body: IProcessSellTradeRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment the assorts buy count by number of items purchased
+     * Show error on screen if player attepts to buy more than what the buy max allows
+     * @param assortBeingPurchased assort being bought
+     * @param itemsPurchasedCount number of items being bought
+     */
     protected incrementAssortBuyCount(assortBeingPurchased: Item, itemsPurchasedCount: number): void;
     protected checkPurchaseIsWithinTraderItemLimit(assortBeingPurchased: Item, assortId: string, count: number): void;
 }
diff --git a/TypeScript/7OnLoadHook/types/helpers/TraderAssortHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/TraderAssortHelper.d.ts
index 677dd66..025efd6 100644
--- a/TypeScript/7OnLoadHook/types/helpers/TraderAssortHelper.d.ts
+++ b/TypeScript/7OnLoadHook/types/helpers/TraderAssortHelper.d.ts
@@ -1,6 +1,5 @@
 import { RagfairAssortGenerator } from "../generators/RagfairAssortGenerator";
 import { RagfairOfferGenerator } from "../generators/RagfairOfferGenerator";
-import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ITrader, ITraderAssort } from "../models/eft/common/tables/ITrader";
 import { ITraderConfig } from "../models/spt/config/ITraderConfig";
@@ -41,12 +40,7 @@ export declare class TraderAssortHelper {
      * @param traderId traders id
      * @returns a traders' assorts
      */
-    getAssort(sessionId: string, traderId: string): ITraderAssort;
-    /**
-     * if the fence assorts have expired, re-generate them
-     * @param pmcProfile Players profile
-     */
-    refreshFenceAssortIfExpired(pmcProfile: IPmcData): void;
+    getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort;
     /**
      * Reset a traders assorts and move nextResupply value to future
      * Flag trader as needing a flea offer reset to be picked up by flea update() function
diff --git a/TypeScript/7OnLoadHook/types/helpers/TraderHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/TraderHelper.d.ts
index 6bda5cd..0dc93e8 100644
--- a/TypeScript/7OnLoadHook/types/helpers/TraderHelper.d.ts
+++ b/TypeScript/7OnLoadHook/types/helpers/TraderHelper.d.ts
@@ -65,7 +65,7 @@ export declare class TraderHelper {
      * @param item
      * @returns boolean
      */
-    protected isWeaponAndBelowTraderBuyDurability(traderID: string, item: Item): boolean;
+    protected isWeaponBelowTraderBuyDurability(traderID: string, item: Item): boolean;
     /**
      * Get the price of an item and all of its attached children
      * Take into account bonuses/adjsutments e.g. discounts
diff --git a/TypeScript/7OnLoadHook/types/models/eft/common/tables/ITemplateItem.d.ts b/TypeScript/7OnLoadHook/types/models/eft/common/tables/ITemplateItem.d.ts
index 23a1a14..6b2fa8f 100644
--- a/TypeScript/7OnLoadHook/types/models/eft/common/tables/ITemplateItem.d.ts
+++ b/TypeScript/7OnLoadHook/types/models/eft/common/tables/ITemplateItem.d.ts
@@ -34,6 +34,7 @@ export interface Props {
     LootExperience?: number;
     ExamineExperience?: number;
     HideEntrails?: boolean;
+    InsuranceDisabled?: boolean;
     RepairCost?: number;
     RepairSpeed?: number;
     ExtraSizeLeft?: number;
@@ -206,6 +207,7 @@ export interface Props {
     IsOneoff?: boolean;
     MustBoltBeOpennedForExternalReload?: boolean;
     MustBoltBeOpennedForInternalReload?: boolean;
+    NoFiremodeOnBoltcatch?: boolean;
     BoltAction?: boolean;
     HipAccuracyRestorationDelay?: number;
     HipAccuracyRestorationSpeed?: number;
diff --git a/TypeScript/7OnLoadHook/types/models/eft/common/tables/ITrader.d.ts b/TypeScript/7OnLoadHook/types/models/eft/common/tables/ITrader.d.ts
index a84f5af..37b2d61 100644
--- a/TypeScript/7OnLoadHook/types/models/eft/common/tables/ITrader.d.ts
+++ b/TypeScript/7OnLoadHook/types/models/eft/common/tables/ITrader.d.ts
@@ -67,6 +67,7 @@ export interface IBarterScheme {
     count: number;
     _tpl: string;
     onlyFunctional?: boolean;
+    sptQuestLocked?: boolean;
 }
 export interface ISuit {
     _id: string;
diff --git a/TypeScript/7OnLoadHook/types/models/eft/ragfair/IRagfairOffer.d.ts b/TypeScript/7OnLoadHook/types/models/eft/ragfair/IRagfairOffer.d.ts
index 63f655e..141b605 100644
--- a/TypeScript/7OnLoadHook/types/models/eft/ragfair/IRagfairOffer.d.ts
+++ b/TypeScript/7OnLoadHook/types/models/eft/ragfair/IRagfairOffer.d.ts
@@ -15,6 +15,8 @@ export interface IRagfairOffer {
     name?: string;
     shortName?: string;
     loyaltyLevel: number;
+    buyRestrictionMax?: number;
+    buyRestrictionCurrent?: number;
     locked: boolean;
     unlimitedCount: boolean;
     summaryCost: number;
diff --git a/TypeScript/7OnLoadHook/types/models/enums/AmmoTypes.d.ts b/TypeScript/7OnLoadHook/types/models/enums/AmmoTypes.d.ts
index b52ddcf..254b410 100644
--- a/TypeScript/7OnLoadHook/types/models/enums/AmmoTypes.d.ts
+++ b/TypeScript/7OnLoadHook/types/models/enums/AmmoTypes.d.ts
@@ -23,7 +23,7 @@ export declare enum Ammo762x54 {
     BT_GZH = "5e023d34e8a400319a28ed44",
     BS_GZH = "5e023d48186a883be655e551"
 }
-export declare enum Ammo338Lapua {
+export declare enum Ammo86x70 {
     TAC_X = "5fc382b6d6fa9c00c571bbc3",
     UCW = "5fc382c1016cce60e8341b20",
     AP = "5fc382a9d724d907e2077dab",
@@ -85,13 +85,13 @@ export declare enum Ammo9x21 {
     PE_GZH = "5a26ac06c4a282000c5a90a8",
     BT_GZH = "5a26ac0ec4a28200741e1e18"
 }
-export declare enum Ammo357Mag {
+export declare enum Ammo9x33R {
     FMJ = "62330b3ed4dc74626d570b95",
     HOLLOW_POINT = "62330bfadc5883093563729b",
     SOFT_POINT = "62330c40bdd19b369e1e53d1",
     JACKET_HP = "62330c18744e5e31df12f516"
 }
-export declare enum Ammo45ACP {
+export declare enum Ammo1143x23ACP {
     MATCH_FMJ = "5e81f423763d9f754677bf2e",
     HYDRA_SHOK = "5efb0fc6aeb21837e749c801",
     LASERMATCH_FMJ = "5efb0d4f4bc50b58e81710f3",
@@ -126,7 +126,7 @@ export declare enum Ammo556x45 {
     MK_318_MOD_0_SOST = "60194943740c5d77f6705eea",
     SSA_AP = "601949593ae8f707c4608daa"
 }
-export declare enum Ammo300Blackout {
+export declare enum Ammo762x35 {
     M62_TRACER = "619636be6db0f2477964e710",
     BCP_FMJ = "5fbe3ffdf8b6a877a729ea82",
     AP = "5fd20ff893a8961fc660a954",
diff --git a/TypeScript/7OnLoadHook/types/models/enums/BaseClasses.d.ts b/TypeScript/7OnLoadHook/types/models/enums/BaseClasses.d.ts
index e733bca..37c1398 100644
--- a/TypeScript/7OnLoadHook/types/models/enums/BaseClasses.d.ts
+++ b/TypeScript/7OnLoadHook/types/models/enums/BaseClasses.d.ts
@@ -68,6 +68,7 @@ export declare enum BaseClasses {
     ASSAULT_SCOPE = "55818add4bdc2d5b648b456f",
     REFLEX_SIGHT = "55818ad54bdc2ddc698b4569",
     TACTICAL_COMBO = "55818b164bdc2ddc698b456c",
+    FLASHLIGHT = "55818b084bdc2d5b648b4571",
     MAGAZINE = "5448bc234bdc2d3c308b4569",
     LIGHT_LASER = "55818b0e4bdc2dde698b456e",
     FLASH_HIDER = "550aa4bf4bdc2dd6348b456b",
diff --git a/TypeScript/7OnLoadHook/types/models/enums/ConfigTypes.d.ts b/TypeScript/7OnLoadHook/types/models/enums/ConfigTypes.d.ts
index 61d6f99..468ece5 100644
--- a/TypeScript/7OnLoadHook/types/models/enums/ConfigTypes.d.ts
+++ b/TypeScript/7OnLoadHook/types/models/enums/ConfigTypes.d.ts
@@ -8,6 +8,7 @@ export declare enum ConfigTypes {
     IN_RAID = "aki-inraid",
     INSURANCE = "aki-insurance",
     INVENTORY = "aki-inventory",
+    ITEM = "aki-item",
     LOCALE = "aki-locale",
     LOCATION = "aki-location",
     MATCH = "aki-match",
diff --git a/TypeScript/7OnLoadHook/types/models/enums/ELocationName.d.ts b/TypeScript/7OnLoadHook/types/models/enums/ELocationName.d.ts
index b56cc08..7ae7caa 100644
--- a/TypeScript/7OnLoadHook/types/models/enums/ELocationName.d.ts
+++ b/TypeScript/7OnLoadHook/types/models/enums/ELocationName.d.ts
@@ -1,5 +1,6 @@
 export declare enum ELocationName {
     FACTORY_DAY = "factory4_day",
+    FACTORY_NIGHT = "factory4_night",
     BIGMAP = "bigmap",
     WOODS = "Woods",
     SHORELINE = "Shoreline",
diff --git a/TypeScript/7OnLoadHook/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/7OnLoadHook/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/7OnLoadHook/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/7OnLoadHook/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/7OnLoadHook/types/models/spt/config/IBotConfig.d.ts b/TypeScript/7OnLoadHook/types/models/spt/config/IBotConfig.d.ts
index e171087..f15fa73 100644
--- a/TypeScript/7OnLoadHook/types/models/spt/config/IBotConfig.d.ts
+++ b/TypeScript/7OnLoadHook/types/models/spt/config/IBotConfig.d.ts
@@ -1,17 +1,31 @@
 import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
+import { IBotDurability } from "./IBotDurability";
+import { IPmcConfig } from "./IPmcConfig";
 export interface IBotConfig extends IBaseConfig {
     kind: "aki-bot";
+    /** How many variants of each bot should be generated on raid start */
     presetBatch: PresetBatch;
+    /** What bot types should be classified as bosses */
     bosses: string[];
-    durability: Durability;
+    /** Control weapon/armor durability min/max values for each bot type */
+    durability: IBotDurability;
+    /** Control the weighting of how expensive an average loot item is on a PMC or Scav */
     lootNValue: LootNvalue;
+    /** Control what bots are added to a bots revenge list key: bottype, value: bottypes to revenge on seeing their death */
     revenge: Record<string, string[]>;
-    pmc: PmcConfig;
+    /** PMC bot specific config settings */
+    pmc: IPmcConfig;
+    /** Control how many items are allowed to spawn on a bot
+     * key: bottype, value: <key: itemTpl: value: max item count> */
     itemSpawnLimits: Record<string, Record<string, number>>;
-    equipment: Record<string, Equipment>;
+    /** Blacklist/whitelist items on a bot */
+    equipment: Record<string, EquipmentFilters>;
+    /** Show a bots botType value after their name */
     showTypeInNickname: boolean;
+    /** Max number of bots that can be spawned in a raid at any one time */
     maxBotCap: number;
+    /** How many stacks of secret ammo should a bot have in its bot secure container */
     secureContainerAmmoStackCount: number;
 }
 export interface PresetBatch {
@@ -44,79 +58,22 @@ export interface PresetBatch {
     test: number;
     exUsec: number;
 }
-export interface Durability {
-    default: DefaultDurability;
-    pmc: PmcDurability;
-    boss: BotDurability;
-    follower: BotDurability;
-    assault: BotDurability;
-    cursedassault: BotDurability;
-    marksman: BotDurability;
-    pmcbot: BotDurability;
-    exusec: BotDurability;
-    sectantpriest: BotDurability;
-    sectantwarrior: BotDurability;
-}
-export interface DefaultDurability {
-    armor: DefaultArmor;
-    weapon: WeaponDurability;
-}
-export interface DefaultArmor {
-    maxDelta: number;
-    minDelta: number;
-}
-export interface WeaponDurability {
-    lowestMax: number;
-    highestMax: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface PmcDurability {
-    armor: PmcDurabilityArmor;
-    weapon: WeaponDurability;
-}
-export interface PmcDurabilityArmor {
-    lowestMaxPercent: number;
-    highestMaxPercent: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface BotDurability {
-    armor: ArmorDurability;
-    weapon: WeaponDurability;
-}
-export interface ArmorDurability {
-    maxDelta: number;
-    minDelta: number;
-}
 export interface LootNvalue {
     scav: number;
     pmc: number;
 }
-export interface PmcConfig {
-    dynamicLoot: PmcDynamicLoot;
-    difficulty: string;
-    looseWeaponInBackpackChancePercent: number;
-    looseWeaponInBackpackLootMinMax: MinMax;
-    isUsec: number;
-    chanceSameSideIsHostilePercent: number;
-    usecType: string;
-    bearType: string;
-    maxBackpackLootTotalRub: number;
-    maxPocketLootTotalRub: number;
-    maxVestLootTotalRub: number;
-    convertIntoPmcChance: Record<string, MinMax>;
-    enemyTypes: string[];
-}
-export interface PmcDynamicLoot {
-    whitelist: string[];
-    blacklist: string[];
-    moneyStackLimits: Record<string, number>;
-}
-export interface Equipment {
+export interface EquipmentFilters {
+    weaponModLimits: ModLimits;
+    randomisedWeaponModSlots?: string[];
     blacklist: EquipmentFilterDetails[];
     whitelist: EquipmentFilterDetails[];
 }
+export interface ModLimits {
+    /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */
+    scopeLimit?: number;
+    /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */
+    lightLaserLimit?: number;
+}
 export interface EquipmentFilterDetails {
     levelRange: MinMax;
     equipment: Record<string, string[]>;
diff --git a/TypeScript/7OnLoadHook/types/models/spt/config/IBotDurability.d.ts b/TypeScript/7OnLoadHook/types/models/spt/config/IBotDurability.d.ts
new file mode 100644
index 0000000..38a47cc
--- /dev/null
+++ b/TypeScript/7OnLoadHook/types/models/spt/config/IBotDurability.d.ts
@@ -0,0 +1,47 @@
+export interface IBotDurability {
+    default: DefaultDurability;
+    pmc: PmcDurability;
+    boss: BotDurability;
+    follower: BotDurability;
+    assault: BotDurability;
+    cursedassault: BotDurability;
+    marksman: BotDurability;
+    pmcbot: BotDurability;
+    exusec: BotDurability;
+    gifter: BotDurability;
+    sectantpriest: BotDurability;
+    sectantwarrior: BotDurability;
+}
+/** Durability values to be used when a more specific bot type cant be found */
+export interface DefaultDurability {
+    armor: DefaultArmor;
+    weapon: WeaponDurability;
+}
+export interface DefaultArmor {
+    maxDelta: number;
+    minDelta: number;
+}
+export interface WeaponDurability {
+    lowestMax: number;
+    highestMax: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface PmcDurability {
+    armor: PmcDurabilityArmor;
+    weapon: WeaponDurability;
+}
+export interface PmcDurabilityArmor {
+    lowestMaxPercent: number;
+    highestMaxPercent: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface BotDurability {
+    armor: ArmorDurability;
+    weapon: WeaponDurability;
+}
+export interface ArmorDurability {
+    maxDelta: number;
+    minDelta: number;
+}
diff --git a/TypeScript/7OnLoadHook/types/models/spt/config/IItemConfig.d.ts b/TypeScript/7OnLoadHook/types/models/spt/config/IItemConfig.d.ts
new file mode 100644
index 0000000..5ecccc2
--- /dev/null
+++ b/TypeScript/7OnLoadHook/types/models/spt/config/IItemConfig.d.ts
@@ -0,0 +1,5 @@
+import { IBaseConfig } from "./IBaseConfig";
+export interface IItemConfig extends IBaseConfig {
+    kind: "aki-item";
+    blacklist: string[];
+}
diff --git a/TypeScript/7OnLoadHook/types/models/spt/config/IPmcConfig.d.ts b/TypeScript/7OnLoadHook/types/models/spt/config/IPmcConfig.d.ts
new file mode 100644
index 0000000..655b58d
--- /dev/null
+++ b/TypeScript/7OnLoadHook/types/models/spt/config/IPmcConfig.d.ts
@@ -0,0 +1,22 @@
+import { MinMax } from "../../common/MinMax";
+export interface IPmcConfig {
+    dynamicLoot: DynamicLoot;
+    useDifficultyOverride: boolean;
+    difficulty: string;
+    looseWeaponInBackpackChancePercent: number;
+    looseWeaponInBackpackLootMinMax: MinMax;
+    isUsec: number;
+    chanceSameSideIsHostilePercent: number;
+    usecType: string;
+    bearType: string;
+    maxBackpackLootTotalRub: number;
+    maxPocketLootTotalRub: number;
+    maxVestLootTotalRub: number;
+    convertIntoPmcChance: Record<string, MinMax>;
+    enemyTypes: string[];
+}
+export interface DynamicLoot {
+    whitelist: string[];
+    blacklist: string[];
+    moneyStackLimits: Record<string, number>;
+}
diff --git a/TypeScript/7OnLoadHook/types/models/spt/config/IQuestConfig.d.ts b/TypeScript/7OnLoadHook/types/models/spt/config/IQuestConfig.d.ts
index be4a97b..45c9aae 100644
--- a/TypeScript/7OnLoadHook/types/models/spt/config/IQuestConfig.d.ts
+++ b/TypeScript/7OnLoadHook/types/models/spt/config/IQuestConfig.d.ts
@@ -4,6 +4,8 @@ export interface IQuestConfig extends IBaseConfig {
     kind: "aki-quest";
     redeemTime: number;
     repeatableQuests: IRepeatableQuestConfig[];
+    bearOnlyQuests: string[];
+    usecOnlyQuests: string[];
 }
 export interface IRepeatableQuestConfig {
     name: string;
@@ -15,6 +17,10 @@ export interface IRepeatableQuestConfig {
     locations: Record<ELocationName, string[]>;
     traderWhitelist: ITraderWhitelist[];
     questConfig: IQuestConfig;
+    /** Item base types to block when generating rewards */
+    rewardBaseTypeBlacklist: string[];
+    /** Item tplIds to ignore when generating rewards */
+    rewardBlacklist: string[];
 }
 export interface IRewardScaling {
     levels: number[];
diff --git a/TypeScript/7OnLoadHook/types/models/spt/config/IRagfairConfig.d.ts b/TypeScript/7OnLoadHook/types/models/spt/config/IRagfairConfig.d.ts
index 6369eda..3088717 100644
--- a/TypeScript/7OnLoadHook/types/models/spt/config/IRagfairConfig.d.ts
+++ b/TypeScript/7OnLoadHook/types/models/spt/config/IRagfairConfig.d.ts
@@ -12,6 +12,7 @@ export interface Sell {
     chance: Chance;
     time: Time;
     reputation: Reputation;
+    simulatedSellHours: number;
 }
 export interface Chance {
     base: number;
diff --git a/TypeScript/7OnLoadHook/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/7OnLoadHook/types/models/spt/config/ITraderConfig.d.ts
index c8e8044..6b1c1e3 100644
--- a/TypeScript/7OnLoadHook/types/models/spt/config/ITraderConfig.d.ts
+++ b/TypeScript/7OnLoadHook/types/models/spt/config/ITraderConfig.d.ts
@@ -12,8 +12,10 @@ export interface UpdateTime {
     seconds: number;
 }
 export interface FenceConfig {
+    partialRefreshTimeSeconds: number;
+    partialRefreshChangePercent: number;
     assortSize: number;
-    maxPresetsCount: number;
+    maxPresetsPercent: number;
     presetPriceMult: number;
     blacklist: string[];
 }
diff --git a/TypeScript/7OnLoadHook/types/models/spt/services/LootItem.d.ts b/TypeScript/7OnLoadHook/types/models/spt/services/LootItem.d.ts
new file mode 100644
index 0000000..2838472
--- /dev/null
+++ b/TypeScript/7OnLoadHook/types/models/spt/services/LootItem.d.ts
@@ -0,0 +1,5 @@
+export declare class LootItem {
+    tpl: string;
+    isPreset: boolean;
+    stackCount: number;
+}
diff --git a/TypeScript/7OnLoadHook/types/models/spt/services/LootRequest.d.ts b/TypeScript/7OnLoadHook/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/7OnLoadHook/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/7OnLoadHook/types/services/BotEquipmentFilterService.d.ts b/TypeScript/7OnLoadHook/types/services/BotEquipmentFilterService.d.ts
index e49645b..632f961 100644
--- a/TypeScript/7OnLoadHook/types/services/BotEquipmentFilterService.d.ts
+++ b/TypeScript/7OnLoadHook/types/services/BotEquipmentFilterService.d.ts
@@ -1,12 +1,12 @@
 import { IBotType } from "../models/eft/common/tables/IBotType";
-import { Equipment, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 export declare class BotEquipmentFilterService {
     protected logger: ILogger;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    protected botEquipmentFilterlists: Record<string, Equipment>;
+    protected botEquipmentFilterlists: Record<string, EquipmentFilters>;
     constructor(logger: ILogger, configServer: ConfigServer);
     /**
      * Filter a bots data to exclude equipment and cartridges defines in the botConfig
@@ -22,7 +22,7 @@ export declare class BotEquipmentFilterService {
      * @param playerLevel Level of the player
      * @returns EquipmentBlacklistDetails object
      */
-    protected getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
+    getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
     /**
      * Get the whitelist for a specific bot type that's within the players level
      * @param botRole Bot type
diff --git a/TypeScript/7OnLoadHook/types/services/FenceService.d.ts b/TypeScript/7OnLoadHook/types/services/FenceService.d.ts
index c9e325e..c940507 100644
--- a/TypeScript/7OnLoadHook/types/services/FenceService.d.ts
+++ b/TypeScript/7OnLoadHook/types/services/FenceService.d.ts
@@ -12,6 +12,11 @@ import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+import { ItemFilterService } from "./ItemFilterService";
+/**
+ * Handle actions surrounding Fence
+ * e.g. generating or refreshing assorts / get next refresh time
+ */
 export declare class FenceService {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
@@ -22,18 +27,64 @@ export declare class FenceService {
     protected handbookHelper: HandbookHelper;
     protected itemHelper: ItemHelper;
     protected presetHelper: PresetHelper;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected fenceAssort: ITraderAssort;
     protected traderConfig: ITraderConfig;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, configServer: ConfigServer);
+    protected nextMiniRefreshTimestamp: number;
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, itemFilterService: ItemFilterService, configServer: ConfigServer);
     protected setFenceAssort(fenceAssort: ITraderAssort): void;
-    getFenceAssorts(): ITraderAssort;
+    /**
+     * Get assorts player can purchase
+     * Adjust prices based on fence level of player
+     * @param pmcProfile Player profile
+     * @returns ITraderAssort
+     */
+    getFenceAssorts(pmcProfile: IPmcData): ITraderAssort;
+    /**
+     * Get fence assorts with no price adjustments based on fence rep
+     * @returns ITraderAssort
+     */
+    getRawFenceAssorts(): ITraderAssort;
+    /**
+     * Does fence need to perform a partial refresh because its passed the refresh timer defined in trader.json
+     * @returns true if it needs a partial refresh
+     */
+    needsPartialRefresh(): boolean;
+    /**
+     * Replace a percentage of fence assorts with freshly generated items
+     */
+    performPartialRefresh(): void;
+    /**
+     * Choose an item (not mod) at random and remove from assorts
+     */
+    protected removeRandomItemFromAssorts(): void;
+    /**
+     * Get an integer rounded count of items to replace based on percentrage from traderConfig value
+     * @param totalItemCount total item count
+     * @returns rounded int of items to replace
+     */
+    protected getCountOfItemsToReplace(totalItemCount: number): number;
     /**
      * Get the count of items fence offers
      * @returns number
      */
     getOfferCount(): number;
-    generateFenceAssortCache(pmcData: IPmcData): void;
+    /**
+     * Create a trader assort for fence
+     */
+    generateFenceAssortCache(): void;
+    /**
+     * Create skeleton to hold assort items
+     * @returns ITraderAssort object
+     */
+    protected createBaseTraderAssortItem(): ITraderAssort;
+    /**
+     * Hydrate result parameter object with generated assorts
+     * @param assortCount Number of assorts to generate
+     * @param assorts object to add assorts to
+     */
+    protected createAssorts(assortCount: number, assorts: ITraderAssort): void;
     /**
      * Get the next update timestamp for fence
      * @returns future timestamp
@@ -44,11 +95,14 @@ export declare class FenceService {
      */
     protected getFenceRefreshTime(): number;
     /**
-     * Get the fence level the passed in profile has
+     * Get fence level the passed in profile has
      * @param pmcData Player profile
-     * @returns FenceLevel
+     * @returns FenceLevel object
      */
     getFenceInfo(pmcData: IPmcData): FenceLevel;
+    /**
+     * Remove an assort from fence by id
+     * @param assortIdToRemove assort id to remove from fence assorts
+     */
     removeFenceOffer(assortIdToRemove: string): void;
-    updateFenceOffers(pmcData: IPmcData): void;
 }
diff --git a/TypeScript/7OnLoadHook/types/services/InsuranceService.d.ts b/TypeScript/7OnLoadHook/types/services/InsuranceService.d.ts
index 171bf10..6be8a2f 100644
--- a/TypeScript/7OnLoadHook/types/services/InsuranceService.d.ts
+++ b/TypeScript/7OnLoadHook/types/services/InsuranceService.d.ts
@@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
 import { SecureContainerHelper } from "../helpers/SecureContainerHelper";
 import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
+import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData";
 import { IInsuranceConfig } from "../models/spt/config/IInsuranceConfig";
@@ -44,8 +45,22 @@ export declare class InsuranceService {
      * @param mapId Id of the map player died/exited that caused the insurance to be issued on
      */
     sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void;
+    /**
+     * Store lost gear post-raid inside profile
+     * @param pmcData player profile to store gear in
+     * @param offraidData post-raid request object
+     * @param preRaidGear gear player wore prior to raid
+     * @param sessionID Session id
+     */
     storeLostGear(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
     storeInsuredItemsForReturn(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
-    protected addGearToSend(pmcData: IPmcData, insuredItem: any, actualItem: any, sessionID: string): any;
+    /**
+     * Add gear item to InsuredItems array in player profile
+     * @param pmcData profile to store item in
+     * @param insuredItem Item to store in profile
+     * @param actualItem item to store
+     * @param sessionID Session id
+     */
+    protected addGearToSend(pmcData: IPmcData, insuredItem: InsuredItem, actualItem: Item, sessionID: string): void;
     getPremium(pmcData: IPmcData, inventoryItem: Item, traderId: string): number;
 }
diff --git a/TypeScript/7OnLoadHook/types/services/ItemFilterService.d.ts b/TypeScript/7OnLoadHook/types/services/ItemFilterService.d.ts
new file mode 100644
index 0000000..c9c8ef3
--- /dev/null
+++ b/TypeScript/7OnLoadHook/types/services/ItemFilterService.d.ts
@@ -0,0 +1,24 @@
+import { IItemConfig } from "../models/spt/config/IItemConfig";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+/** Centralise the handling of blacklisting items, uses blacklist found in config/item.json */
+export declare class ItemFilterService {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected configServer: ConfigServer;
+    protected blacklist: string[];
+    protected itemConfig: IItemConfig;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer);
+    /**
+     * Check if the provided template id is blacklisted in config/item.json
+     * @param tpl template id
+     * @returns true if blacklisted
+     */
+    isItemBlacklisted(tpl: string): boolean;
+    /**
+     * Return every template id blacklisted in config/item.json
+     * @returns string array of blacklisted tempalte ids
+     */
+    getBlacklistedItems(): string[];
+}
diff --git a/TypeScript/7OnLoadHook/types/services/ProfileFixerService.d.ts b/TypeScript/7OnLoadHook/types/services/ProfileFixerService.d.ts
index ed1dec7..9cb5a38 100644
--- a/TypeScript/7OnLoadHook/types/services/ProfileFixerService.d.ts
+++ b/TypeScript/7OnLoadHook/types/services/ProfileFixerService.d.ts
@@ -45,6 +45,11 @@ export declare class ProfileFixerService {
      * @param pmcProfile Profile to find and remove slots from
      */
     protected removeResourcesFromSlotsInHideoutWithoutLocationIndexValue(pmcProfile: IPmcData): void;
+    /**
+     * Hideout slots need to be in a specific order, locationIndex in ascending order
+     * @param pmcProfile profile to edit
+     */
+    protected reorderHideoutAreasWithResouceInputs(pmcProfile: IPmcData): void;
     /**
      * add in objects equal to the number of slots
      * @param areaType area to check
diff --git a/TypeScript/7OnLoadHook/types/utils/HashUtil.d.ts b/TypeScript/7OnLoadHook/types/utils/HashUtil.d.ts
index bacbf2a..a8500e1 100644
--- a/TypeScript/7OnLoadHook/types/utils/HashUtil.d.ts
+++ b/TypeScript/7OnLoadHook/types/utils/HashUtil.d.ts
@@ -4,8 +4,18 @@ import { TimeUtil } from "./TimeUtil";
 export declare class HashUtil {
     protected timeUtil: TimeUtil;
     constructor(timeUtil: TimeUtil);
+    /**
+     * Create a 24 character id using the sha256 algorithm + current timestamp
+     * @returns 24 character hash
+     */
     generate(): string;
     generateMd5ForData(data: string): string;
     generateSha1ForData(data: string): string;
+    /**
+     * Create a hash for the data parameter
+     * @param algorithm algorithm to use to hash
+     * @param data data to be hashed
+     * @returns hash value
+     */
     generateHashForData(algorithm: string, data: crypto.BinaryLike): string;
 }
diff --git a/TypeScript/7OnLoadHook/types/utils/RandomUtil.d.ts b/TypeScript/7OnLoadHook/types/utils/RandomUtil.d.ts
index c24dd60..e35d21f 100644
--- a/TypeScript/7OnLoadHook/types/utils/RandomUtil.d.ts
+++ b/TypeScript/7OnLoadHook/types/utils/RandomUtil.d.ts
@@ -150,4 +150,10 @@ export declare class RandomUtil {
      */
     drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[];
     getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number;
+    /**
+     * Fisher-Yates shuffle an array
+     * @param array Array to shuffle
+     * @returns Shuffled array
+     */
+    shuffle<T>(array: Array<T>): Array<T>;
 }
diff --git a/TypeScript/7OnLoadHook/types/utils/TimeUtil.d.ts b/TypeScript/7OnLoadHook/types/utils/TimeUtil.d.ts
index f437f8a..1367e26 100644
--- a/TypeScript/7OnLoadHook/types/utils/TimeUtil.d.ts
+++ b/TypeScript/7OnLoadHook/types/utils/TimeUtil.d.ts
@@ -1,3 +1,6 @@
+/**
+ * Utility class to handle time related problems
+ */
 export declare class TimeUtil {
     static readonly oneHourAsSeconds = 3600;
     formatTime(date: Date): string;
@@ -19,4 +22,10 @@ export declare class TimeUtil {
      * @returns current date in format: 00.00.0000 (dd.mm.yyyy)
      */
     getDateMailFormat(): string;
+    /**
+     * Convert hours into seconds
+     * @param hours hours to convert to seconds
+     * @returns number
+     */
+    getHoursAsSeconds(hours: number): number;
 }
diff --git a/TypeScript/8OnUpdateHook/types/callbacks/LocationCallbacks.d.ts b/TypeScript/8OnUpdateHook/types/callbacks/LocationCallbacks.d.ts
index cc69369..6e0b538 100644
--- a/TypeScript/8OnUpdateHook/types/callbacks/LocationCallbacks.d.ts
+++ b/TypeScript/8OnUpdateHook/types/callbacks/LocationCallbacks.d.ts
@@ -11,4 +11,5 @@ export declare class LocationCallbacks {
     constructor(httpResponse: HttpResponseUtil, locationController: LocationController);
     getLocationData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<ILocationsGenerateAllResponse>;
     getLocation(url: string, info: IGetLocationRequestData, sessionID: string): IGetBodyResponseData<ILocationBase>;
+    getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): string;
 }
diff --git a/TypeScript/8OnUpdateHook/types/callbacks/ProfileCallbacks.d.ts b/TypeScript/8OnUpdateHook/types/callbacks/ProfileCallbacks.d.ts
index 6a86fc0..183bb0a 100644
--- a/TypeScript/8OnUpdateHook/types/callbacks/ProfileCallbacks.d.ts
+++ b/TypeScript/8OnUpdateHook/types/callbacks/ProfileCallbacks.d.ts
@@ -1,5 +1,6 @@
 import { ProfileController } from "../controllers/ProfileController";
 import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData";
+import { IPmcData } from "../models/eft/common/IPmcData";
 import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData";
 import { INullResponseData } from "../models/eft/httpResponse/INullResponseData";
 import { IGetMiniProfileRequestData } from "../models/eft/launcher/IGetMiniProfileRequestData";
@@ -12,20 +13,51 @@ import { ISearchFriendResponse } from "../models/eft/profile/ISearchFriendRespon
 import { IValidateNicknameRequestData } from "../models/eft/profile/IValidateNicknameRequestData";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/** Handle profile related client events */
 export declare class ProfileCallbacks {
     protected httpResponse: HttpResponseUtil;
     protected timeUtil: TimeUtil;
     protected profileController: ProfileController;
     constructor(httpResponse: HttpResponseUtil, timeUtil: TimeUtil, profileController: ProfileController);
     createProfile(url: string, info: IProfileCreateRequestData, sessionID: string): IGetBodyResponseData<any>;
-    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
-    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
+    /**
+     * Get the complete player profile (scav + pmc character)
+     * @param url
+     * @param info Empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle the creation of a scav profile for player
+     * Occurs post-raid and when profile first created immediately after character details are confirmed by player
+     * @param url
+     * @param info empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle client/game/profile/voice/change event
+     * @param url
+     * @param info Change voice request object
+     * @param sessionID Session id
+     * @returns Client response
+     */
     changeVoice(url: string, info: IProfileChangeVoiceRequestData, sessionID: string): INullResponseData;
+    /**
+     * Handle client/game/profile/nickname/change event
+     * Client allows player to adjust their profile name
+     * @param url
+     * @param info Change nickname request object
+     * @param sessionID Session id
+     * @returns client response
+     */
     changeNickname(url: string, info: IProfileChangeNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     validateNickname(url: string, info: IValidateNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     getReservedNickname(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<string>;
     /**
-     * Called when creating a character, when you choose a character face/voice
+     * Called when creating a character when choosing a character face/voice
      * @param url
      * @param info response (empty)
      * @param sessionID
diff --git a/TypeScript/8OnUpdateHook/types/callbacks/RagfairCallbacks.d.ts b/TypeScript/8OnUpdateHook/types/callbacks/RagfairCallbacks.d.ts
index 3a405c9..c609f2f 100644
--- a/TypeScript/8OnUpdateHook/types/callbacks/RagfairCallbacks.d.ts
+++ b/TypeScript/8OnUpdateHook/types/callbacks/RagfairCallbacks.d.ts
@@ -19,6 +19,9 @@ import { ConfigServer } from "../servers/ConfigServer";
 import { RagfairServer } from "../servers/RagfairServer";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+/**
+ * Handle ragfair related callback events
+ */
 export declare class RagfairCallbacks extends OnLoadOnUpdate {
     protected httpResponse: HttpResponseUtil;
     protected logger: ILogger;
diff --git a/TypeScript/8OnUpdateHook/types/controllers/InraidController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/InraidController.d.ts
index 82bb64d..102a2fb 100644
--- a/TypeScript/8OnUpdateHook/types/controllers/InraidController.d.ts
+++ b/TypeScript/8OnUpdateHook/types/controllers/InraidController.d.ts
@@ -35,6 +35,30 @@ export declare class InraidController {
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer);
     addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void;
     saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Handle updating the profile post-pmc raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Reduce body part hp to % of max
+     * @param pmcData profile to edit
+     * @param multipler multipler to apply to max health
+     */
+    protected reducePmcHealthToPercent(pmcData: IPmcData, multipler: number): void;
+    /**
+     * Handle updating the profile post-pscav raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePlayerScavProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Is the player dead after a raid - dead is anything other than "survived" / "runner"
+     * @param statusOnExit exit value from offraidData object
+     * @returns true if dead
+     */
+    protected isPlayerDead(statusOnExit: string): boolean;
     /**
      * Mark inventory items as FiR if player survived raid, otherwise remove FiR from them
      * @param offraidData Save Progress Request
diff --git a/TypeScript/8OnUpdateHook/types/controllers/InventoryController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/InventoryController.d.ts
index f57f731..f564919 100644
--- a/TypeScript/8OnUpdateHook/types/controllers/InventoryController.d.ts
+++ b/TypeScript/8OnUpdateHook/types/controllers/InventoryController.d.ts
@@ -92,7 +92,11 @@ export declare class InventoryController {
      */
     toggleItem(pmcData: IPmcData, body: IInventoryToggleRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Handles Tagging of items (primary Containers).
+     * Add a tag to an inventory item
+     * @param pmcData profile with item to add tag to
+     * @param body tag request data
+     * @param sessionID session id
+     * @returns client response object
      */
     tagItem(pmcData: IPmcData, body: IInventoryTagRequestData, sessionID: string): IItemEventRouterResponse;
     bindItem(pmcData: IPmcData, body: IInventoryBindRequestData, sessionID: string): IItemEventRouterResponse;
diff --git a/TypeScript/8OnUpdateHook/types/controllers/LocationController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/LocationController.d.ts
index 90b6d7a..9db3205 100644
--- a/TypeScript/8OnUpdateHook/types/controllers/LocationController.d.ts
+++ b/TypeScript/8OnUpdateHook/types/controllers/LocationController.d.ts
@@ -1,18 +1,33 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class LocationController {
     protected jsonUtil: JsonUtil;
+    protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/8OnUpdateHook/types/controllers/MatchController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/MatchController.d.ts
index e8585d9..cb40023 100644
--- a/TypeScript/8OnUpdateHook/types/controllers/MatchController.d.ts
+++ b/TypeScript/8OnUpdateHook/types/controllers/MatchController.d.ts
@@ -9,6 +9,7 @@ import { IGetProfileRequestData } from "../models/eft/match/IGetProfileRequestDa
 import { IJoinMatchRequestData } from "../models/eft/match/IJoinMatchRequestData";
 import { IJoinMatchResult } from "../models/eft/match/IJoinMatchResult";
 import { IStartOfflineRaidRequestData } from "../models/eft/match/IStartOffineRaidRequestData";
+import { IBotConfig } from "../models/spt/config/IBotConfig";
 import { IInRaidConfig } from "../models/spt/config/IInRaidConfig";
 import { IMatchConfig } from "../models/spt/config/IMatchConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
@@ -29,6 +30,7 @@ export declare class MatchController {
     protected applicationContext: ApplicationContext;
     protected matchConfig: IMatchConfig;
     protected inraidConfig: IInRaidConfig;
+    protected botConfig: IBotConfig;
     constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, applicationContext: ApplicationContext);
     getEnabled(): boolean;
     getProfile(info: IGetProfileRequestData): IPmcData[];
diff --git a/TypeScript/8OnUpdateHook/types/controllers/QuestController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/QuestController.d.ts
index 2cbccfb..282f50e 100644
--- a/TypeScript/8OnUpdateHook/types/controllers/QuestController.d.ts
+++ b/TypeScript/8OnUpdateHook/types/controllers/QuestController.d.ts
@@ -39,16 +39,31 @@ export declare class QuestController {
      * @returns array of IQuest
      */
     getClientQuests(sessionID: string): IQuest[];
+    /**
+     * Is the quest for the opposite side the player is on
+     * @param side player side (usec/bear)
+     * @param questId questId to check
+     */
+    protected questIsForOtherSide(side: string, questId: string): boolean;
+    /**
+     * Handle the client accepting a quest and starting it
+     * Send starting rewards if any to player and
+     * Send start notification if any to player
+     * @param pmcData Profile to update
+     * @param acceptedQuest Quest accepted
+     * @param sessionID Session id
+     * @returns client response
+     */
     acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Remove completed quest from profile
+     * Update completed quest in profile
      * Add newly unlocked quests to profile
      * Also recalculate thier level due to exp rewards
      * @param pmcData Player profile
-     * @param body completed quest request
-     * @param sessionID session id
-     * @returns ItemEvent response
+     * @param body Completed quest request
+     * @param sessionID Session id
+     * @returns ItemEvent client response
      */
     completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
@@ -67,10 +82,20 @@ export declare class QuestController {
     protected getQuestsFailedByCompletingQuest(completedQuestId: string): IQuest[];
     /**
      * Fail the quests provided
+     * Update quest in profile, otherwise add fresh quest object with failed status
      * @param sessionID session id
      * @param pmcData player profile
      * @param questsToFail quests to fail
      */
     protected failQuests(sessionID: string, pmcData: IPmcData, questsToFail: IQuest[]): void;
     handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment a backend counter stored value by an amount,
+     * Create counter if it does not exist
+     * @param pmcData Profile to find backend counter in
+     * @param conditionId backend counter id to update
+     * @param questId quest id counter is associated with
+     * @param counterValue value to increment the backend counter with
+     */
+    protected updateProfileBackendCounterValue(pmcData: IPmcData, conditionId: string, questId: string, counterValue: number): void;
 }
diff --git a/TypeScript/8OnUpdateHook/types/controllers/RagfairController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/RagfairController.d.ts
index c4ffc15..06af740 100644
--- a/TypeScript/8OnUpdateHook/types/controllers/RagfairController.d.ts
+++ b/TypeScript/8OnUpdateHook/types/controllers/RagfairController.d.ts
@@ -9,6 +9,7 @@ import { RagfairOfferHelper } from "../helpers/RagfairOfferHelper";
 import { RagfairSellHelper } from "../helpers/RagfairSellHelper";
 import { RagfairSortHelper } from "../helpers/RagfairSortHelper";
 import { RagfairTaxHelper } from "../helpers/RagfairTaxHelper";
+import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
@@ -33,6 +34,9 @@ import { RagfairPriceService } from "../services/RagfairPriceService";
 import { RagfairRequiredItemsService } from "../services/RagfairRequiredItemsService";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/**
+ * Handle RagfairCallback events
+ */
 export declare class RagfairController {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
@@ -52,14 +56,20 @@ export declare class RagfairController {
     protected handbookHelper: HandbookHelper;
     protected paymentHelper: PaymentHelper;
     protected inventoryHelper: InventoryHelper;
+    protected traderHelper: TraderHelper;
     protected ragfairHelper: RagfairHelper;
     protected ragfairOfferService: RagfairOfferService;
     protected ragfairRequiredItemsService: RagfairRequiredItemsService;
     protected ragfairOfferGenerator: RagfairOfferGenerator;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
     getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult;
+    /**
+     * Update a trader flea offer with buy restrictions stored in the traders assort
+     * @param offer flea offer to update
+     */
+    protected setTraderOfferPurchaseLimits(offer: IRagfairOffer): void;
     protected isLinkedSearch(info: ISearchRequestData): boolean;
     protected isRequiredSearch(info: ISearchRequestData): boolean;
     update(): void;
diff --git a/TypeScript/8OnUpdateHook/types/controllers/RepeatableQuestController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/RepeatableQuestController.d.ts
index 98d05dd..4c31a3d 100644
--- a/TypeScript/8OnUpdateHook/types/controllers/RepeatableQuestController.d.ts
+++ b/TypeScript/8OnUpdateHook/types/controllers/RepeatableQuestController.d.ts
@@ -7,6 +7,7 @@ import { Exit } from "../models/eft/common/ILocationBase";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { TraderInfo } from "../models/eft/common/tables/IBotBase";
 import { ICompletion, ICompletionAvailableFor, IElimination, IEliminationCondition, IExploration, IExplorationCondition, IPmcDataRepeatableQuest, IRepeatableQuest, IReward, IRewards } from "../models/eft/common/tables/IRepeatableQuests";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
 import { IRepeatableQuestChangeRequest } from "../models/eft/quests/IRepeatableQuestChangeRequest";
 import { ELocationName } from "../models/enums/ELocationName";
@@ -15,6 +16,7 @@ import { ILogger } from "../models/spt/utils/ILogger";
 import { ItemEventRouter } from "../routers/ItemEventRouter";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { PaymentService } from "../services/PaymentService";
 import { ProfileFixerService } from "../services/ProfileFixerService";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -64,9 +66,10 @@ export declare class RepeatableQuestController {
     protected itemEventRouter: ItemEventRouter;
     protected paymentService: PaymentService;
     protected objectId: ObjectId;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
-    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, configServer: ConfigServer);
+    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint
      * Returns an array of objects in the format of repeatable quests to the client.
@@ -217,4 +220,16 @@ export declare class RepeatableQuestController {
     debugLogRepeatableQuestIds(pmcData: IPmcData): void;
     probabilityObjectArray<K, V>(configArrayInput: ProbabilityObject<K, V>[]): ProbabilityObjectArray<K, V>;
     changeRepeatableQuest(pmcDataIn: IPmcData, body: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
+     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
+     */
+    protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig): [string, ITemplateItem][];
+    /**
+     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
+     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
+     * @param {*} tpl template id of item to check
+     * @returns boolean: true if item is valid reward
+     */
+    isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig): boolean;
 }
diff --git a/TypeScript/8OnUpdateHook/types/controllers/TraderController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/TraderController.d.ts
index 0162064..b79f55e 100644
--- a/TypeScript/8OnUpdateHook/types/controllers/TraderController.d.ts
+++ b/TypeScript/8OnUpdateHook/types/controllers/TraderController.d.ts
@@ -4,6 +4,7 @@ import { TraderHelper } from "../helpers/TraderHelper";
 import { IBarterScheme, ITraderAssort, ITraderBase } from "../models/eft/common/tables/ITrader";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { FenceService } from "../services/FenceService";
 import { TraderAssortService } from "../services/TraderAssortService";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
@@ -15,8 +16,9 @@ export declare class TraderController {
     protected traderHelper: TraderHelper;
     protected timeUtil: TimeUtil;
     protected traderAssortService: TraderAssortService;
+    protected fenceService: FenceService;
     protected jsonUtil: JsonUtil;
-    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, jsonUtil: JsonUtil);
+    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, fenceService: FenceService, jsonUtil: JsonUtil);
     /**
      * Runs when onLoad event is fired
      * Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
@@ -26,6 +28,7 @@ export declare class TraderController {
     /**
      * Runs when onUpdate is fired
      * If current time is > nextResupply(expire) time of trader, refresh traders assorts and
+     * Fence is handled slightly differently
      * @returns has run
      */
     update(): boolean;
diff --git a/TypeScript/8OnUpdateHook/types/di/Container.d.ts b/TypeScript/8OnUpdateHook/types/di/Container.d.ts
index 17791b0..98d1fa1 100644
--- a/TypeScript/8OnUpdateHook/types/di/Container.d.ts
+++ b/TypeScript/8OnUpdateHook/types/di/Container.d.ts
@@ -1,4 +1,7 @@
 import { DependencyContainer } from "tsyringe";
+/**
+ * Handle the registration of classes to be used by the Dependency Injection code
+ */
 export declare class Container {
     static registerTypes(depContainer: DependencyContainer): void;
     static registerListTypes(depContainer: DependencyContainer): void;
diff --git a/TypeScript/8OnUpdateHook/types/generators/BotGenerator.d.ts b/TypeScript/8OnUpdateHook/types/generators/BotGenerator.d.ts
index a5fc0ad..7d58f95 100644
--- a/TypeScript/8OnUpdateHook/types/generators/BotGenerator.d.ts
+++ b/TypeScript/8OnUpdateHook/types/generators/BotGenerator.d.ts
@@ -40,7 +40,7 @@ export declare class BotGenerator {
      * @param botTemplate base bot template to use  (e.g. assault/pmcbot)
      * @returns
      */
-    generatePlayerScav(role: string, difficulty: string, botTemplate: IBotType): IBotBase;
+    generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase;
     generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[];
     /**
      * Choose if a bot should become a PMC by checking if bot type is allowed to become a Pmc in botConfig.convertFromChances and doing a random int check
@@ -58,7 +58,7 @@ export declare class BotGenerator {
      * @returns IBotBase object
      */
     protected getCloneOfBotBase(): IBotBase;
-    protected generateBot(bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
+    protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
     /**
      * Log the number of PMCs generated to the debug console
      */
diff --git a/TypeScript/8OnUpdateHook/types/generators/BotInventoryGenerator.d.ts b/TypeScript/8OnUpdateHook/types/generators/BotInventoryGenerator.d.ts
index 35d1ee8..73f8ece 100644
--- a/TypeScript/8OnUpdateHook/types/generators/BotInventoryGenerator.d.ts
+++ b/TypeScript/8OnUpdateHook/types/generators/BotInventoryGenerator.d.ts
@@ -18,7 +18,7 @@ export declare class BotInventoryGenerator {
     protected botGeneratorHelper: BotGeneratorHelper;
     protected weightedRandomHelper: WeightedRandomHelper;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper);
-    generateInventory(templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
+    generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
     protected generateEquipment(equipmentSlot: string, equipmentPool: Record<string, number>, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void;
     protected generateInventoryBase(): PmcInventory;
 }
diff --git a/TypeScript/8OnUpdateHook/types/generators/BotLootGenerator.d.ts b/TypeScript/8OnUpdateHook/types/generators/BotLootGenerator.d.ts
index c6a3f29..5a2d144 100644
--- a/TypeScript/8OnUpdateHook/types/generators/BotLootGenerator.d.ts
+++ b/TypeScript/8OnUpdateHook/types/generators/BotLootGenerator.d.ts
@@ -24,7 +24,7 @@ export declare class BotLootGenerator {
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botLootCacheService: BotLootCacheService, configServer: ConfigServer);
-    generateLoot(templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
+    generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
     protected getRandomisedCount(min: number, max: number, nValue: number): number;
     /**
      * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached
@@ -47,7 +47,7 @@ export declare class BotLootGenerator {
      * @param botRole bots role, .e.g. pmcBot
      * @param isPmc are we generating for a pmc
      */
-    protected addLooseWeaponsToInventorySlot(botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
+    protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
     /**
      * Get a random item from the pool parameter using the biasedRandomNumber system
      * @param pool pool of items to pick an item from
diff --git a/TypeScript/8OnUpdateHook/types/generators/BotWeaponGenerator.d.ts b/TypeScript/8OnUpdateHook/types/generators/BotWeaponGenerator.d.ts
index 9215214..49fa7bf 100644
--- a/TypeScript/8OnUpdateHook/types/generators/BotWeaponGenerator.d.ts
+++ b/TypeScript/8OnUpdateHook/types/generators/BotWeaponGenerator.d.ts
@@ -28,7 +28,18 @@ export declare class BotWeaponGenerator {
     protected botConfig: IBotConfig;
     constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer);
     /**
-     * Get a random weapon from a bots pool of weapons (weighted)
+     * Pick a random weapon based on weightings and generate a functional weapon
+     * @param equipmentSlot Primary/secondary/holster
+     * @param botTemplateInventory e.g. assault.json
+     * @param weaponParentId
+     * @param modChances
+     * @param botRole role of bot, e.g. assault/followerBully
+     * @param isPmc Is weapon generated for a pmc
+     * @returns GenerateWeaponResult object
+     */
+    generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    /**
+     * Get a random weighted weapon from a bots pool of weapons
      * @param equipmentSlot Primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
      * @returns weapon tpl
@@ -39,43 +50,24 @@ export declare class BotWeaponGenerator {
      * @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool())
      * @param equipmentSlot slot to fit into, primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
+     * @param weaponParentId ParentId of the weapon being generated
+     * @param modChances Dictionary of item types and % chance weapon will have that mod
+     * @param botRole e.g. assault/exusec
      * @param isPmc
      * @returns GenerateWeaponResult object
      */
-    generateWeaponByTpl(weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
     /**
-     * Generate an entirely random weapon
-     * @param equipmentSlot Primary/secondary/holster
-     * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
-     * @param isPmc
-     * @returns GenerateWeaponResult object
-     */
-    generateRandomWeapon(equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
-    /**
-     * Create array with weapon base as only element
-     * Add additional properties as required
-     * @param weaponTpl
-     * @param weaponParentId
-     * @param equipmentSlot
-     * @param weaponItemTemplate
+     * Create array with weapon base as only element and
+     * add additional properties based on weapon type
+     * @param weaponTpl Weapon tpl to create item with
+     * @param weaponParentId Weapons parent id
+     * @param equipmentSlot e.g. primary/secondary/holster
+     * @param weaponItemTemplate db template for weapon
      * @param botRole for durability values
-     * @returns
+     * @returns Base weapon item in array
      */
     constructWeaponBaseArray(weaponTpl: string, weaponParentId: string, equipmentSlot: string, weaponItemTemplate: ITemplateItem, botRole: string): Item[];
-    /**
-     * Add compatible magazines to an inventory based on a generated weapon
-     * @param weaponDetails
-     * @param magCounts
-     * @param inventory
-     * @param botRole the bot type we're getting generating extra mags for
-     */
-    addExtraMagazinesToInventory(weaponDetails: GenerateWeaponResult, magCounts: MinMax, inventory: PmcInventory, botRole: string): void;
     /**
      * Get the mods necessary to kit out a weapon to its preset level
      * @param weaponTpl weapon to find preset for
@@ -84,20 +76,32 @@ export declare class BotWeaponGenerator {
      * @returns array of weapon mods
      */
     protected getPresetWeaponMods(weaponTpl: string, equipmentSlot: string, weaponParentId: string, itemTemplate: ITemplateItem, botRole: string): Item[];
-    /** Checks if all required slots are occupied on a weapon and all it's mods */
+    /**
+     * Checks if all required slots are occupied on a weapon and all it's mods
+     * @param weaponItemArray Weapon + mods
+     * @returns true if valid
+     */
     protected isWeaponValid(weaponItemArray: Item[]): boolean;
     /**
      * Generates extra magazines or bullets (if magazine is internal) and adds them to TacticalVest and Pockets.
      * Additionally, adds extra bullets to SecuredContainer
-     * @param weaponMods
-     * @param weaponTemplate
-     * @param magCounts
-     * @param ammoTpl
-     * @param inventory
+     * @param weaponMods mods to attach to weapon
+     * @param weaponTemplate db template for weapon
+     * @param magCounts magazine count to add to inventory
+     * @param ammoTpl ammo templateId to add to magazines
+     * @param inventory inventory to add magazines to
      * @param botRole the bot type we're getting generating extra mags for
      * @returns
      */
-    protected generateExtraMagazines(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    addExtraMagazinesToInventory(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    /**
+     * Create a magazine using the parameters given
+     * @param magazineTpl Tpl of the magazine to create
+     * @param ammoTpl Ammo to add to magazine
+     * @param magTemplate template object of magazine
+     * @returns Item array
+     */
+    protected createMagazine(magazineTpl: string, ammoTpl: string, magTemplate: ITemplateItem): Item[];
     /**
      * Get a randomised number of bullets for a specific magazine
      * @param magCounts min and max count of magazines
@@ -138,10 +142,9 @@ export declare class BotWeaponGenerator {
      * Finds and return a compatible ammo tpl based on the bots ammo weightings (x.json/inventory/equipment/ammo)
      * @param ammo a list of ammo tpls the weapon can use
      * @param weaponTemplate the weapon we want to pick ammo for
-     * @param isPmc is the ammo being gathered for a pmc (runs pmc ammo filtering)
      * @returns an ammo tpl that works with the desired gun
      */
-    protected getCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem, isPmc: boolean): string;
+    protected getWeightedCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem): string;
     /**
      * Get a weapons compatible cartridge caliber
      * @param weaponTemplate Weapon to look up caliber of
diff --git a/TypeScript/8OnUpdateHook/types/generators/LocationGenerator.d.ts b/TypeScript/8OnUpdateHook/types/generators/LocationGenerator.d.ts
index bd368b5..cc61dcf 100644
--- a/TypeScript/8OnUpdateHook/types/generators/LocationGenerator.d.ts
+++ b/TypeScript/8OnUpdateHook/types/generators/LocationGenerator.d.ts
@@ -3,10 +3,9 @@ import { GameEventHelper } from "../helpers/GameEventHelper";
 import { ItemHelper } from "../helpers/ItemHelper";
 import { PresetHelper } from "../helpers/PresetHelper";
 import { RagfairServerHelper } from "../helpers/RagfairServerHelper";
-import { ILooseLoot, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
+import { ILooseLoot, SpawnpointsForced, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IStaticAmmoDetails, IStaticContainerProps, IStaticForcedProps, IStaticLootDetails } from "../models/eft/common/tables/ILootBase";
-import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILocationConfig } from "../models/spt/config/ILocationConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
@@ -36,11 +35,19 @@ export declare class LocationGenerator {
     generateContainerLoot(containerIn: IStaticContainerProps, staticForced: IStaticForcedProps[], staticLootDist: Record<string, IStaticLootDetails>, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): IStaticContainerProps;
     protected getLooseLootMultiplerForLocation(location: string): number;
     protected getStaticLootMultiplerForLocation(location: string): number;
+    /**
+     * Create array of loose + forced loot using probability system
+     * @param dynamicLootDist
+     * @param staticAmmoDist
+     * @param locationName Location to generate loot for
+     * @returns Array of spawn points with loot in them
+     */
     generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): SpawnpointTemplate[];
+    /**
+     * Add forced spawn point loot into loot parameter array
+     * @param loot array to add forced loot to
+     * @param forcedSpawnPoints forced loot to add
+     */
+    protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[]): void;
     protected createItem(tpl: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, parentId?: string): IContainerItem;
-    protected getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
-    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
-    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
-    protected createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
-    protected createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
 }
diff --git a/TypeScript/8OnUpdateHook/types/generators/LootGenerator.d.ts b/TypeScript/8OnUpdateHook/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/8OnUpdateHook/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/8OnUpdateHook/types/generators/PMCLootGenerator.d.ts b/TypeScript/8OnUpdateHook/types/generators/PMCLootGenerator.d.ts
index 64e6f7f..b9f2a83 100644
--- a/TypeScript/8OnUpdateHook/types/generators/PMCLootGenerator.d.ts
+++ b/TypeScript/8OnUpdateHook/types/generators/PMCLootGenerator.d.ts
@@ -1,15 +1,21 @@
 import { ItemHelper } from "../helpers/ItemHelper";
-import { DatabaseServer } from "../servers/DatabaseServer";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+/**
+ * Handle the generation of dynamic PMC loot in pockets and backpacks
+ * and the removal of blacklisted items
+ */
 export declare class PMCLootGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected configServer: ConfigServer;
+    protected itemFilterService: ItemFilterService;
     protected pocketLootPool: string[];
     protected backpackLootPool: string[];
     protected botConfig: IBotConfig;
-    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer);
+    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer, itemFilterService: ItemFilterService);
     generatePMCPocketLootPool(): string[];
     generatePMCBackpackLootPool(): string[];
 }
diff --git a/TypeScript/8OnUpdateHook/types/generators/ScavCaseRewardGenerator.d.ts b/TypeScript/8OnUpdateHook/types/generators/ScavCaseRewardGenerator.d.ts
index c7d6ab7..89cb5c8 100644
--- a/TypeScript/8OnUpdateHook/types/generators/ScavCaseRewardGenerator.d.ts
+++ b/TypeScript/8OnUpdateHook/types/generators/ScavCaseRewardGenerator.d.ts
@@ -8,9 +8,13 @@ import { RewardCountAndPriceDetails, ScavCaseRewardCountsAndPrices } from "../mo
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { RagfairPriceService } from "../services/RagfairPriceService";
 import { HashUtil } from "../utils/HashUtil";
 import { RandomUtil } from "../utils/RandomUtil";
+/**
+ * Handle the creation of randomised scav case rewards
+ */
 export declare class ScavCaseRewardGenerator {
     protected logger: ILogger;
     protected randomUtil: RandomUtil;
@@ -18,9 +22,10 @@ export declare class ScavCaseRewardGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected ragfairPriceService: RagfairPriceService;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected scavCaseConfig: IScavCaseConfig;
-    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, configServer: ConfigServer);
+    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Create an array of rewards that will be given to the player upon completing their scav case build
      * @param body client request
diff --git a/TypeScript/8OnUpdateHook/types/generators/WeatherGenerator.d.ts b/TypeScript/8OnUpdateHook/types/generators/WeatherGenerator.d.ts
index 44cecbb..8ddbe49 100644
--- a/TypeScript/8OnUpdateHook/types/generators/WeatherGenerator.d.ts
+++ b/TypeScript/8OnUpdateHook/types/generators/WeatherGenerator.d.ts
@@ -1,7 +1,7 @@
 import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IWeatherData } from "../models/eft/weather/IWeatherData";
 import { IWeatherConfig } from "../models/spt/config/IWeatherConfig";
+import { ConfigServer } from "../servers/ConfigServer";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class WeatherGenerator {
@@ -21,11 +21,16 @@ export declare class WeatherGenerator {
     protected getAcceleratedTime(computedDate: Date): string;
     /**
      * Get current time formatted to fit BSGs requirement
-     * @param computedDate
+     * @param computedDate date to format into bsg style
      * @returns
      */
     protected getNormalTime(computedDate: Date): string;
-    generateWeather(data: IWeatherData): IWeatherData;
+    /**
+     * Return randomised Weather data
+     * @param weatherData weather input data
+     * @returns Randomised weather data
+     */
+    generateWeather(weatherData: IWeatherData): IWeatherData;
     protected getWeightedFog(): string;
     protected getWeightedRain(): number;
     protected getRandomFloat(node: string): number;
diff --git a/TypeScript/8OnUpdateHook/types/helpers/AssortHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/AssortHelper.d.ts
index 15586b9..bfc157f 100644
--- a/TypeScript/8OnUpdateHook/types/helpers/AssortHelper.d.ts
+++ b/TypeScript/8OnUpdateHook/types/helpers/AssortHelper.d.ts
@@ -17,7 +17,7 @@ export declare class AssortHelper {
      * @param assort assort items from a trader
      * @returns assort items minus locked quest assorts
      */
-    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort): ITraderAssort;
+    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort, flea?: boolean): ITraderAssort;
     /**
      * Remove assorts from a trader that have not been unlocked yet
      * @param pmcProfile player profile
@@ -32,5 +32,5 @@ export declare class AssortHelper {
      * @param itemID item id to remove from asort
      * @returns Modified assort
      */
-    removeItemFromAssort(assort: ITraderAssort, itemID: string): ITraderAssort;
+    removeItemFromAssort(assort: ITraderAssort, itemID: string, flea?: boolean): ITraderAssort;
 }
diff --git a/TypeScript/8OnUpdateHook/types/helpers/BotGeneratorHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/BotGeneratorHelper.d.ts
index 3cd7256..eb0d215 100644
--- a/TypeScript/8OnUpdateHook/types/helpers/BotGeneratorHelper.d.ts
+++ b/TypeScript/8OnUpdateHook/types/helpers/BotGeneratorHelper.d.ts
@@ -3,10 +3,12 @@ import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"
 import { Mods, ModsChances } from "../models/eft/common/tables/IBotType";
 import { Item, Repairable, Upd } from "../models/eft/common/tables/IItem";
 import { Grid, ITemplateItem, Slot } from "../models/eft/common/tables/ITemplateItem";
-import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
@@ -14,6 +16,7 @@ import { ContainerHelper } from "./ContainerHelper";
 import { InventoryHelper } from "./InventoryHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProbabilityHelper } from "./ProbabilityHelper";
+import { ProfileHelper } from "./ProfileHelper";
 export declare class BotGeneratorHelper {
     protected logger: ILogger;
     protected jsonUtil: JsonUtil;
@@ -25,10 +28,76 @@ export declare class BotGeneratorHelper {
     protected itemHelper: ItemHelper;
     protected inventoryHelper: InventoryHelper;
     protected containerHelper: ContainerHelper;
+    protected botEquipmentFilterService: BotEquipmentFilterService;
+    protected itemFilterService: ItemFilterService;
+    protected profileHelper: ProfileHelper;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, configServer: ConfigServer);
-    generateModsForItem(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, configServer: ConfigServer);
+    /**
+     * TODO - very similar to generateModsForWeapon
+     * Check mods are compatible and add to array
+     * @param equipment Equipment item to add mods to
+     * @param modPool Mod list to choose frm
+     * @param parentId parentid of item to add mod to
+     * @param parentTemplate template objet of item to add mods to
+     * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type
+     * @returns Item + compatible mods as an array
+     */
+    generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    /**
+     * TODO - very similar to generateModsForEquipment
+     * @param sessionId session id
+     * @param weapon Weapon to add mods to
+     * @param modPool pool of compatible mods to attach to gun
+     * @param weaponParentId parentId of weapon
+     * @param parentTemplate
+     * @param modSpawnChances
+     * @param ammoTpl ammo tpl to use when generating magazines/cartridges
+     * @param botRole role of bot weapon is generated for
+     * @returns Weapon with mods
+     */
+    generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[];
+    /**
+     * Generate a pool of mods for this bots mod type if bot has values inside `randomisedWeaponModSlots` array found in bot.json/equipment[botrole]
+     * @param allowedMods Mods to be added to mod pool
+     * @param botEquipBlacklist blacklist of items not allowed to be added to mod pool
+     * @param modSlot Slot to generate mods for
+     * @param itemModPool base mod pool to replace values of
+     */
+    protected generateDynamicModPool(allowedMods: string[], botEquipBlacklist: EquipmentFilterDetails, modSlot: string, itemModPool: Record<string, string[]>): void;
+    /**
+     * Check if the specific item type on the weapon has reached the set limit
+     * @param modTpl item to check is limited
+     * @param currentCount current number of this item on gun
+     * @param maxLimit mod limit allowed
+     * @param botRole role of bot we're checking weapon of
+     * @returns true if limit reached
+     */
+    protected weaponModLimitReached(modTpl: string, currentCount: {
+        count: number;
+    }, maxLimit: number, botRole: string): boolean;
+    /**
+     * log errors if mod is not valid for a slot
+     * @param modTpl
+     * @param found
+     * @param itemSlot
+     * @param modTemplate
+     * @param modSlot
+     * @param parentTemplate
+     * @returns true if valid
+     */
+    protected isModValidForSlot(modTpl: string, found: boolean, itemSlot: Slot, modTemplate: ITemplateItem, modSlot: string, parentTemplate: ITemplateItem): boolean;
+    /**
+     * Create a mod item with parameters as properties
+     * @param modId _id
+     * @param modTpl _tpl
+     * @param parentId parentId
+     * @param modSlot slotId
+     * @param modTemplate Used to add additional properites in the upd object
+     * @returns Item object
+     */
+    protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item;
     /**
      * Is this magazine cylinder related (revolvers and grenade launchers)
      * @param magazineParentName the name of the magazines parent
@@ -62,11 +131,11 @@ export declare class BotGeneratorHelper {
      * Those magazines (e.g. 60dc519adf4c47305f6d410d) have a "Cartridges" entry with a _max_count=0.
      * Ammo is not put into the magazine directly but assigned to the magazine's slots: The "camora_xxx" slots.
      * This function is a helper called by generateModsForItem for mods with parent type "CylinderMagazine"
-     *
-     * @param {object}      items               The items where the CylinderMagazine's camora are appended to
-     * @param {object}      modPool             modPool which should include available cartrigdes
-     * @param {string}      parentId            The CylinderMagazine's UID
-     * @param {object}      parentTemplate      The CylinderMagazine's template
+     * @param items The items where the CylinderMagazine's camora are appended to
+     * @param modPool modPool which should include available cartrigdes
+     * @param parentId The CylinderMagazine's UID
+     * @param parentTemplate The CylinderMagazine's template
+     * @returns
      */
     protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void;
     /**
@@ -75,6 +144,13 @@ export declare class BotGeneratorHelper {
      * @returns string array of shells fro luitple camora sources
      */
     protected mergeCamoraPoolsTogether(camorasWithShells: Record<string, string[]>): string[];
+    /**
+     * Adds properties to an item
+     * e.g. Repairable / HasHinge / Foldable / MaxDurability
+     * @param itemTemplate
+     * @param botRole Used by weapons to randomise the durability values
+     * @returns Item Upd object with extra properties
+     */
     generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): {
         upd?: Upd;
     };
@@ -93,12 +169,6 @@ export declare class BotGeneratorHelper {
      */
     protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable;
     protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string;
-    /**
-     * Sort by spawn chance, highest to lowest, higher is more common
-     * @param unsortedModArray String array to sort
-     * @returns Sorted string array
-     */
-    protected sortModArray(unsortedModArray: string[]): string[];
     /**
      * Can an item be added to an item without issue
      * @param items
@@ -117,8 +187,15 @@ export declare class BotGeneratorHelper {
      * @returns a `boolean` indicating item was added
      */
     addItemWithChildrenToEquipmentSlot(equipmentSlots: string[], parentId: string, parentTpl: string, itemWithChildren: Item[], inventory: PmcInventory): boolean;
+    /**
+     * is the provided item allowed inside a container
+     * @param slot location item wants to be placed in
+     * @param itemTpl item being placed
+     * @returns true if allowed
+     */
     protected itemAllowedInContainer(slot: Grid, itemTpl: string): boolean;
 }
+/** TODO - move into own class */
 export declare class ExhaustableArray<T> {
     private itemPool;
     private randomUtil;
diff --git a/TypeScript/8OnUpdateHook/types/helpers/HideoutHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/HideoutHelper.d.ts
index 36e4009..7495a6a 100644
--- a/TypeScript/8OnUpdateHook/types/helpers/HideoutHelper.d.ts
+++ b/TypeScript/8OnUpdateHook/types/helpers/HideoutHelper.d.ts
@@ -44,14 +44,72 @@ export declare class HideoutHelper {
     initProduction(recipeId: string, productionTime: number): Production;
     isProductionType(productive: Productive): productive is Production;
     applyPlayerUpgradesBonuses(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * TODO:
+     * After looking at the skills there doesnt seem to be a configuration per skill to boost
+     * the XP gain PER skill. I THINK you should be able to put the variable "SkillProgress" (just like health has it)
+     * and be able to tune the skill gain PER skill, but I havent tested it and Im not sure!
+     * @param pmcData
+     * @param bonus
+     */
     protected applySkillXPBoost(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * Process a players hideout, update areas that use resources + increment production timers
+     * @param sessionID Session id
+     */
     updatePlayerHideout(sessionID: string): void;
+    /**
+     * Update progress timer for water collector
+     * @param pmcData profile to update
+     * @param productionId id of water collection production to update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateWaterCollectorProductionTimer(pmcData: IPmcData, productionId: string, hideoutProperties: {
+        btcFarmCGs?: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Iterate over productions and update their progress timers
+     * @param pmcData Profile to check for productions and update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Update progress timer for scav case
+     * @param pmcData Profile to update
+     * @param productionId Id of scav case production to update
+     */
+    protected updateScavCaseProductionTimer(pmcData: IPmcData, productionId: string): void;
+    /**
+     * Iterate over hideout areas that use resources (fuel/filters etc) and update associated values
+     * @param sessionID Session id
+     * @param pmcData Profile to update areas of
+     * @param hideoutProperties hideout properties
+     */
+    protected updateAreasWithResources(sessionID: string, pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
     protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
     protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
-    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): HideoutArea;
-    protected updateWaterFilters(waterFilterArea: HideoutArea, pwProd: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
+    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): void;
+    /**
+     * Adjust water filter objects resourceValue or delete when they reach 0 resource
+     * @param waterFilterArea water filter area to update
+     * @param production production object
+     * @param isGeneratorOn is generatory enabled
+     * @param pmcData Player profile
+     * @returns Updated HideoutArea object
+     */
+    protected updateWaterFilters(waterFilterArea: HideoutArea, production: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
     protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
-    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): HideoutArea;
+    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): void;
     protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
     protected getBTCSlots(pmcData: IPmcData): number;
     protected getManagementSkillsSlots(): number;
diff --git a/TypeScript/8OnUpdateHook/types/helpers/InRaidHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/InRaidHelper.d.ts
index b382e30..962df38 100644
--- a/TypeScript/8OnUpdateHook/types/helpers/InRaidHelper.d.ts
+++ b/TypeScript/8OnUpdateHook/types/helpers/InRaidHelper.d.ts
@@ -18,18 +18,6 @@ export declare class InRaidHelper {
     protected paymentHelper: PaymentHelper;
     protected profileFixerService: ProfileFixerService;
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper, profileFixerService: ProfileFixerService);
-    /**
-     * Reset the SPT inraid property stored in a profile to 'none'
-     * @param sessionID Session id
-     */
-    protected removePlayer(sessionID: string): void;
-    /**
-     * Some maps have one-time-use keys (e.g. Labs
-     * Remove the relevant key from an inventory based on the post-raid request data passed in
-     * @param offraidData post-raid data
-     * @param sessionID Session id
-     */
-    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
     /**
      * Check an array of items and add an upd object to money items with a stack count of 1
      * Single stack money items have no upd object and thus no StackObjectsCount, causing issues
@@ -54,6 +42,18 @@ export declare class InRaidHelper {
      * @returns Reset profile object
      */
     updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData;
+    /**
+     * Some maps have one-time-use keys (e.g. Labs
+     * Remove the relevant key from an inventory based on the post-raid request data passed in
+     * @param offraidData post-raid data
+     * @param sessionID Session id
+     */
+    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Set the SPT inraid location Profile property to 'none'
+     * @param sessionID Session id
+     */
+    protected setPlayerInRaidLocationStatusToNone(sessionID: string): void;
     /**
      * Adds SpawnedInSession property to items found in a raid
      * Removes SpawnedInSession for non-scav players if item was taken into raid with SpawnedInSession = true
@@ -95,5 +95,10 @@ export declare class InRaidHelper {
      * @returns true if item is kept after death
      */
     isItemKeptAfterDeath(slotId: string): boolean;
+    /**
+     * Return the equipped items from a players inventory
+     * @param items Players inventory to search through
+     * @returns an array of equipped items
+     */
     getPlayerGear(items: Item[]): Item[];
 }
diff --git a/TypeScript/8OnUpdateHook/types/helpers/ItemHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/ItemHelper.d.ts
index 1701c62..de10892 100644
--- a/TypeScript/8OnUpdateHook/types/helpers/ItemHelper.d.ts
+++ b/TypeScript/8OnUpdateHook/types/helpers/ItemHelper.d.ts
@@ -1,35 +1,30 @@
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item, Repairable } from "../models/eft/common/tables/IItem";
+import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase";
 import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+import { MathUtil } from "../utils/MathUtil";
+import { ObjectId } from "../utils/ObjectId";
+import { RandomUtil } from "../utils/RandomUtil";
 declare class ItemHelper {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
     protected jsonUtil: JsonUtil;
+    protected randomUtil: RandomUtil;
+    protected objectId: ObjectId;
+    protected mathUtil: MathUtil;
     protected databaseServer: DatabaseServer;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer);
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer);
     /**
      * Checks if a id is a valid item. Valid meaning that it's an item that be stored in stash
      * @param       {string}    tpl       the template id / tpl
      * @returns                             boolean; true for items that may be in player posession and not quest items
      */
     isValidItem(tpl: string, invalidBaseTypes?: string[]): boolean;
-    /**
-     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
-     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
-     * @param {*} tpl template id of item to check
-     * @returns boolean: true if item is valid reward
-     */
-    isValidRewardItem(tpl: string): boolean;
-    /**
-     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
-     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
-     */
-    getRewardableItems(): [string, ITemplateItem][];
     /**
      * Check if the tpl / template Id provided is a descendent of the baseclass
      *
@@ -196,6 +191,22 @@ declare class ItemHelper {
      * @returns ItemSize object (width and height)
      */
     getItemSize(items: Item[], rootItemId: string): ItemHelper.ItemSize;
+    /**
+     * Get a random cartridge from an items Filter property
+     * @param item
+     * @returns
+     */
+    getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
+    createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
+    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
+    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
+    createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
+    /**
+     * Get the size of a stack, return 1 if no stack object count property found
+     * @param item Item to get stack size of
+     * @returns size of stack
+     */
+    getItemStackSize(item: Item): number;
 }
 declare namespace ItemHelper {
     interface ItemSize {
diff --git a/TypeScript/8OnUpdateHook/types/helpers/ProfileHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/ProfileHelper.d.ts
index 9d4ff98..9c6560a 100644
--- a/TypeScript/8OnUpdateHook/types/helpers/ProfileHelper.d.ts
+++ b/TypeScript/8OnUpdateHook/types/helpers/ProfileHelper.d.ts
@@ -24,6 +24,19 @@ export declare class ProfileHelper {
     constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, fenceService: FenceService);
     resetProfileQuestCondition(sessionID: string, conditionId: string): void;
     getCompleteProfile(sessionID: string): IPmcData[];
+    /**
+     * Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
+     * Server saves the post-raid changes prior to the xp screen getting the profile, this results in the xp screen using
+     * the now updated profile values as a base, meaning it shows x2 xp gained
+     * Instead, clone the post-raid profile (so we dont alter its values), apply the pre-raid xp values to the cloned objects and return
+     * Delete snapshot of pre-raid profile prior to returning profile data
+     * @param sessionId Session id
+     * @param output pmc and scav profiles array
+     * @param pmcProfile post-raid pmc profile
+     * @param scavProfile post-raid scav profile
+     * @returns updated profile array
+     */
+    protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
     isNicknameTaken(info: IValidateNicknameRequestData, sessionID: string): boolean;
     /**
      * Add experience to a PMC inside the players profile
diff --git a/TypeScript/8OnUpdateHook/types/helpers/QuestHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/QuestHelper.d.ts
index 32e55ec..d66d150 100644
--- a/TypeScript/8OnUpdateHook/types/helpers/QuestHelper.d.ts
+++ b/TypeScript/8OnUpdateHook/types/helpers/QuestHelper.d.ts
@@ -36,11 +36,20 @@ export declare class QuestHelper {
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
     constructor(logger: ILogger, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, itemHelper: ItemHelper, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, localeService: LocaleService, ragfairServerHelper: RagfairServerHelper, dialogueHelper: DialogueHelper, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, traderHelper: TraderHelper, configServer: ConfigServer);
-    questStatus(pmcData: IPmcData, questID: string): QuestStatus;
     /**
-     * returns true is the condition is satisfied
+    * Get status of a quest by quest id
+    * @param pmcData Profile to search
+    * @param questID Quest id to look up
+    * @returns QuestStauts enum
+    */
+    getQuestStatus(pmcData: IPmcData, questID: string): QuestStatus;
+    /**
+     * returns true is the level condition is satisfied
+     * @param playerLevel Players level
+     * @param condition Quest condition
+     * @returns true if player level is greater than or equal to quest
      */
-    evaluateLevel(pmcProfile: IPmcData, cond: AvailableForConditions): boolean;
+    doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean;
     getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[];
     /**
      * Increase skill points of a skill on player profile
diff --git a/TypeScript/8OnUpdateHook/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/RagfairOfferHelper.d.ts
index 8d03bee..e9d72ca 100644
--- a/TypeScript/8OnUpdateHook/types/helpers/RagfairOfferHelper.d.ts
+++ b/TypeScript/8OnUpdateHook/types/helpers/RagfairOfferHelper.d.ts
@@ -22,12 +22,14 @@ import { ProfileHelper } from "./ProfileHelper";
 import { RagfairHelper } from "./RagfairHelper";
 import { RagfairServerHelper } from "./RagfairServerHelper";
 import { RagfairSortHelper } from "./RagfairSortHelper";
+import { TraderHelper } from "./TraderHelper";
 export declare class RagfairOfferHelper {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
     protected hashUtil: HashUtil;
     protected itemEventRouter: ItemEventRouter;
     protected databaseServer: DatabaseServer;
+    protected traderHelper: TraderHelper;
     protected saveServer: SaveServer;
     protected dialogueHelper: DialogueHelper;
     protected itemHelper: ItemHelper;
@@ -43,10 +45,10 @@ export declare class RagfairOfferHelper {
     protected static goodSoldTemplate: string;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, traderHelper: TraderHelper, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
     getValidOffers(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
     getOffersForBuild(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
-    processOffers(sessionID: string): boolean;
+    processOffersOnProfile(sessionID: string): boolean;
     protected getProfileOffers(sessionID: string): IRagfairOffer[];
     protected deleteOfferByOfferId(sessionID: string, offerId: string): void;
     protected completeOffer(sessionID: string, offer: IRagfairOffer, boughtAmount: number): IItemEventRouterResponse;
diff --git a/TypeScript/8OnUpdateHook/types/helpers/RagfairSellHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/RagfairSellHelper.d.ts
index 6ec004a..91b8a20 100644
--- a/TypeScript/8OnUpdateHook/types/helpers/RagfairSellHelper.d.ts
+++ b/TypeScript/8OnUpdateHook/types/helpers/RagfairSellHelper.d.ts
@@ -11,6 +11,12 @@ export declare class RagfairSellHelper {
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     constructor(logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer);
-    calculateSellChance(baseChance: number, offerPrice: number, requirementsPriceInRub: number): number;
-    rollForSale(sellChance: number, count: number): SellResult[];
+    calculateSellChance(baseChancePercent: number, offerPriceRub: number, playerListedPriceRub: number): number;
+    /**
+     * Determine if the offer being listed will be sold
+     * @param sellChancePercent chance item will sell
+     * @param itemSellCount count of items to sell
+     * @returns Array of purchases of item(s) lsited
+     */
+    rollForSale(sellChancePercent: number, itemSellCount: number): SellResult[];
 }
diff --git a/TypeScript/8OnUpdateHook/types/helpers/RagfairServerHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/RagfairServerHelper.d.ts
index e4939d1..a03cdda 100644
--- a/TypeScript/8OnUpdateHook/types/helpers/RagfairServerHelper.d.ts
+++ b/TypeScript/8OnUpdateHook/types/helpers/RagfairServerHelper.d.ts
@@ -6,6 +6,7 @@ import { IRagfairConfig } from "../models/spt/config/IRagfairConfig";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { SaveServer } from "../servers/SaveServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { LocaleService } from "../services/LocaleService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -13,6 +14,9 @@ import { RandomUtil } from "../utils/RandomUtil";
 import { DialogueHelper } from "./DialogueHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProfileHelper } from "./ProfileHelper";
+/**
+ * Helper class for common ragfair server actions
+ */
 export declare class RagfairServerHelper {
     protected randomUtil: RandomUtil;
     protected hashUtil: HashUtil;
@@ -23,11 +27,12 @@ export declare class RagfairServerHelper {
     protected localeService: LocaleService;
     protected dialogueHelper: DialogueHelper;
     protected jsonUtil: JsonUtil;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
     protected static goodsReturnedTemplate: string;
-    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, configServer: ConfigServer);
+    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Is item valid / on blacklist / quest item
      * @param itemDetails
diff --git a/TypeScript/8OnUpdateHook/types/helpers/TradeHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/TradeHelper.d.ts
index 975062b..7ab9768 100644
--- a/TypeScript/8OnUpdateHook/types/helpers/TradeHelper.d.ts
+++ b/TypeScript/8OnUpdateHook/types/helpers/TradeHelper.d.ts
@@ -39,6 +39,12 @@ export declare class TradeHelper {
      * @returns
      */
     sellItem(pmcData: IPmcData, body: IProcessSellTradeRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment the assorts buy count by number of items purchased
+     * Show error on screen if player attepts to buy more than what the buy max allows
+     * @param assortBeingPurchased assort being bought
+     * @param itemsPurchasedCount number of items being bought
+     */
     protected incrementAssortBuyCount(assortBeingPurchased: Item, itemsPurchasedCount: number): void;
     protected checkPurchaseIsWithinTraderItemLimit(assortBeingPurchased: Item, assortId: string, count: number): void;
 }
diff --git a/TypeScript/8OnUpdateHook/types/helpers/TraderAssortHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/TraderAssortHelper.d.ts
index 677dd66..025efd6 100644
--- a/TypeScript/8OnUpdateHook/types/helpers/TraderAssortHelper.d.ts
+++ b/TypeScript/8OnUpdateHook/types/helpers/TraderAssortHelper.d.ts
@@ -1,6 +1,5 @@
 import { RagfairAssortGenerator } from "../generators/RagfairAssortGenerator";
 import { RagfairOfferGenerator } from "../generators/RagfairOfferGenerator";
-import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ITrader, ITraderAssort } from "../models/eft/common/tables/ITrader";
 import { ITraderConfig } from "../models/spt/config/ITraderConfig";
@@ -41,12 +40,7 @@ export declare class TraderAssortHelper {
      * @param traderId traders id
      * @returns a traders' assorts
      */
-    getAssort(sessionId: string, traderId: string): ITraderAssort;
-    /**
-     * if the fence assorts have expired, re-generate them
-     * @param pmcProfile Players profile
-     */
-    refreshFenceAssortIfExpired(pmcProfile: IPmcData): void;
+    getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort;
     /**
      * Reset a traders assorts and move nextResupply value to future
      * Flag trader as needing a flea offer reset to be picked up by flea update() function
diff --git a/TypeScript/8OnUpdateHook/types/helpers/TraderHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/TraderHelper.d.ts
index 6bda5cd..0dc93e8 100644
--- a/TypeScript/8OnUpdateHook/types/helpers/TraderHelper.d.ts
+++ b/TypeScript/8OnUpdateHook/types/helpers/TraderHelper.d.ts
@@ -65,7 +65,7 @@ export declare class TraderHelper {
      * @param item
      * @returns boolean
      */
-    protected isWeaponAndBelowTraderBuyDurability(traderID: string, item: Item): boolean;
+    protected isWeaponBelowTraderBuyDurability(traderID: string, item: Item): boolean;
     /**
      * Get the price of an item and all of its attached children
      * Take into account bonuses/adjsutments e.g. discounts
diff --git a/TypeScript/8OnUpdateHook/types/models/eft/common/tables/ITemplateItem.d.ts b/TypeScript/8OnUpdateHook/types/models/eft/common/tables/ITemplateItem.d.ts
index 23a1a14..6b2fa8f 100644
--- a/TypeScript/8OnUpdateHook/types/models/eft/common/tables/ITemplateItem.d.ts
+++ b/TypeScript/8OnUpdateHook/types/models/eft/common/tables/ITemplateItem.d.ts
@@ -34,6 +34,7 @@ export interface Props {
     LootExperience?: number;
     ExamineExperience?: number;
     HideEntrails?: boolean;
+    InsuranceDisabled?: boolean;
     RepairCost?: number;
     RepairSpeed?: number;
     ExtraSizeLeft?: number;
@@ -206,6 +207,7 @@ export interface Props {
     IsOneoff?: boolean;
     MustBoltBeOpennedForExternalReload?: boolean;
     MustBoltBeOpennedForInternalReload?: boolean;
+    NoFiremodeOnBoltcatch?: boolean;
     BoltAction?: boolean;
     HipAccuracyRestorationDelay?: number;
     HipAccuracyRestorationSpeed?: number;
diff --git a/TypeScript/8OnUpdateHook/types/models/eft/common/tables/ITrader.d.ts b/TypeScript/8OnUpdateHook/types/models/eft/common/tables/ITrader.d.ts
index a84f5af..37b2d61 100644
--- a/TypeScript/8OnUpdateHook/types/models/eft/common/tables/ITrader.d.ts
+++ b/TypeScript/8OnUpdateHook/types/models/eft/common/tables/ITrader.d.ts
@@ -67,6 +67,7 @@ export interface IBarterScheme {
     count: number;
     _tpl: string;
     onlyFunctional?: boolean;
+    sptQuestLocked?: boolean;
 }
 export interface ISuit {
     _id: string;
diff --git a/TypeScript/8OnUpdateHook/types/models/eft/ragfair/IRagfairOffer.d.ts b/TypeScript/8OnUpdateHook/types/models/eft/ragfair/IRagfairOffer.d.ts
index 63f655e..141b605 100644
--- a/TypeScript/8OnUpdateHook/types/models/eft/ragfair/IRagfairOffer.d.ts
+++ b/TypeScript/8OnUpdateHook/types/models/eft/ragfair/IRagfairOffer.d.ts
@@ -15,6 +15,8 @@ export interface IRagfairOffer {
     name?: string;
     shortName?: string;
     loyaltyLevel: number;
+    buyRestrictionMax?: number;
+    buyRestrictionCurrent?: number;
     locked: boolean;
     unlimitedCount: boolean;
     summaryCost: number;
diff --git a/TypeScript/8OnUpdateHook/types/models/enums/AmmoTypes.d.ts b/TypeScript/8OnUpdateHook/types/models/enums/AmmoTypes.d.ts
index b52ddcf..254b410 100644
--- a/TypeScript/8OnUpdateHook/types/models/enums/AmmoTypes.d.ts
+++ b/TypeScript/8OnUpdateHook/types/models/enums/AmmoTypes.d.ts
@@ -23,7 +23,7 @@ export declare enum Ammo762x54 {
     BT_GZH = "5e023d34e8a400319a28ed44",
     BS_GZH = "5e023d48186a883be655e551"
 }
-export declare enum Ammo338Lapua {
+export declare enum Ammo86x70 {
     TAC_X = "5fc382b6d6fa9c00c571bbc3",
     UCW = "5fc382c1016cce60e8341b20",
     AP = "5fc382a9d724d907e2077dab",
@@ -85,13 +85,13 @@ export declare enum Ammo9x21 {
     PE_GZH = "5a26ac06c4a282000c5a90a8",
     BT_GZH = "5a26ac0ec4a28200741e1e18"
 }
-export declare enum Ammo357Mag {
+export declare enum Ammo9x33R {
     FMJ = "62330b3ed4dc74626d570b95",
     HOLLOW_POINT = "62330bfadc5883093563729b",
     SOFT_POINT = "62330c40bdd19b369e1e53d1",
     JACKET_HP = "62330c18744e5e31df12f516"
 }
-export declare enum Ammo45ACP {
+export declare enum Ammo1143x23ACP {
     MATCH_FMJ = "5e81f423763d9f754677bf2e",
     HYDRA_SHOK = "5efb0fc6aeb21837e749c801",
     LASERMATCH_FMJ = "5efb0d4f4bc50b58e81710f3",
@@ -126,7 +126,7 @@ export declare enum Ammo556x45 {
     MK_318_MOD_0_SOST = "60194943740c5d77f6705eea",
     SSA_AP = "601949593ae8f707c4608daa"
 }
-export declare enum Ammo300Blackout {
+export declare enum Ammo762x35 {
     M62_TRACER = "619636be6db0f2477964e710",
     BCP_FMJ = "5fbe3ffdf8b6a877a729ea82",
     AP = "5fd20ff893a8961fc660a954",
diff --git a/TypeScript/8OnUpdateHook/types/models/enums/BaseClasses.d.ts b/TypeScript/8OnUpdateHook/types/models/enums/BaseClasses.d.ts
index e733bca..37c1398 100644
--- a/TypeScript/8OnUpdateHook/types/models/enums/BaseClasses.d.ts
+++ b/TypeScript/8OnUpdateHook/types/models/enums/BaseClasses.d.ts
@@ -68,6 +68,7 @@ export declare enum BaseClasses {
     ASSAULT_SCOPE = "55818add4bdc2d5b648b456f",
     REFLEX_SIGHT = "55818ad54bdc2ddc698b4569",
     TACTICAL_COMBO = "55818b164bdc2ddc698b456c",
+    FLASHLIGHT = "55818b084bdc2d5b648b4571",
     MAGAZINE = "5448bc234bdc2d3c308b4569",
     LIGHT_LASER = "55818b0e4bdc2dde698b456e",
     FLASH_HIDER = "550aa4bf4bdc2dd6348b456b",
diff --git a/TypeScript/8OnUpdateHook/types/models/enums/ConfigTypes.d.ts b/TypeScript/8OnUpdateHook/types/models/enums/ConfigTypes.d.ts
index 61d6f99..468ece5 100644
--- a/TypeScript/8OnUpdateHook/types/models/enums/ConfigTypes.d.ts
+++ b/TypeScript/8OnUpdateHook/types/models/enums/ConfigTypes.d.ts
@@ -8,6 +8,7 @@ export declare enum ConfigTypes {
     IN_RAID = "aki-inraid",
     INSURANCE = "aki-insurance",
     INVENTORY = "aki-inventory",
+    ITEM = "aki-item",
     LOCALE = "aki-locale",
     LOCATION = "aki-location",
     MATCH = "aki-match",
diff --git a/TypeScript/8OnUpdateHook/types/models/enums/ELocationName.d.ts b/TypeScript/8OnUpdateHook/types/models/enums/ELocationName.d.ts
index b56cc08..7ae7caa 100644
--- a/TypeScript/8OnUpdateHook/types/models/enums/ELocationName.d.ts
+++ b/TypeScript/8OnUpdateHook/types/models/enums/ELocationName.d.ts
@@ -1,5 +1,6 @@
 export declare enum ELocationName {
     FACTORY_DAY = "factory4_day",
+    FACTORY_NIGHT = "factory4_night",
     BIGMAP = "bigmap",
     WOODS = "Woods",
     SHORELINE = "Shoreline",
diff --git a/TypeScript/8OnUpdateHook/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/8OnUpdateHook/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/8OnUpdateHook/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/8OnUpdateHook/types/models/spt/config/IBotConfig.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/config/IBotConfig.d.ts
index e171087..f15fa73 100644
--- a/TypeScript/8OnUpdateHook/types/models/spt/config/IBotConfig.d.ts
+++ b/TypeScript/8OnUpdateHook/types/models/spt/config/IBotConfig.d.ts
@@ -1,17 +1,31 @@
 import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
+import { IBotDurability } from "./IBotDurability";
+import { IPmcConfig } from "./IPmcConfig";
 export interface IBotConfig extends IBaseConfig {
     kind: "aki-bot";
+    /** How many variants of each bot should be generated on raid start */
     presetBatch: PresetBatch;
+    /** What bot types should be classified as bosses */
     bosses: string[];
-    durability: Durability;
+    /** Control weapon/armor durability min/max values for each bot type */
+    durability: IBotDurability;
+    /** Control the weighting of how expensive an average loot item is on a PMC or Scav */
     lootNValue: LootNvalue;
+    /** Control what bots are added to a bots revenge list key: bottype, value: bottypes to revenge on seeing their death */
     revenge: Record<string, string[]>;
-    pmc: PmcConfig;
+    /** PMC bot specific config settings */
+    pmc: IPmcConfig;
+    /** Control how many items are allowed to spawn on a bot
+     * key: bottype, value: <key: itemTpl: value: max item count> */
     itemSpawnLimits: Record<string, Record<string, number>>;
-    equipment: Record<string, Equipment>;
+    /** Blacklist/whitelist items on a bot */
+    equipment: Record<string, EquipmentFilters>;
+    /** Show a bots botType value after their name */
     showTypeInNickname: boolean;
+    /** Max number of bots that can be spawned in a raid at any one time */
     maxBotCap: number;
+    /** How many stacks of secret ammo should a bot have in its bot secure container */
     secureContainerAmmoStackCount: number;
 }
 export interface PresetBatch {
@@ -44,79 +58,22 @@ export interface PresetBatch {
     test: number;
     exUsec: number;
 }
-export interface Durability {
-    default: DefaultDurability;
-    pmc: PmcDurability;
-    boss: BotDurability;
-    follower: BotDurability;
-    assault: BotDurability;
-    cursedassault: BotDurability;
-    marksman: BotDurability;
-    pmcbot: BotDurability;
-    exusec: BotDurability;
-    sectantpriest: BotDurability;
-    sectantwarrior: BotDurability;
-}
-export interface DefaultDurability {
-    armor: DefaultArmor;
-    weapon: WeaponDurability;
-}
-export interface DefaultArmor {
-    maxDelta: number;
-    minDelta: number;
-}
-export interface WeaponDurability {
-    lowestMax: number;
-    highestMax: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface PmcDurability {
-    armor: PmcDurabilityArmor;
-    weapon: WeaponDurability;
-}
-export interface PmcDurabilityArmor {
-    lowestMaxPercent: number;
-    highestMaxPercent: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface BotDurability {
-    armor: ArmorDurability;
-    weapon: WeaponDurability;
-}
-export interface ArmorDurability {
-    maxDelta: number;
-    minDelta: number;
-}
 export interface LootNvalue {
     scav: number;
     pmc: number;
 }
-export interface PmcConfig {
-    dynamicLoot: PmcDynamicLoot;
-    difficulty: string;
-    looseWeaponInBackpackChancePercent: number;
-    looseWeaponInBackpackLootMinMax: MinMax;
-    isUsec: number;
-    chanceSameSideIsHostilePercent: number;
-    usecType: string;
-    bearType: string;
-    maxBackpackLootTotalRub: number;
-    maxPocketLootTotalRub: number;
-    maxVestLootTotalRub: number;
-    convertIntoPmcChance: Record<string, MinMax>;
-    enemyTypes: string[];
-}
-export interface PmcDynamicLoot {
-    whitelist: string[];
-    blacklist: string[];
-    moneyStackLimits: Record<string, number>;
-}
-export interface Equipment {
+export interface EquipmentFilters {
+    weaponModLimits: ModLimits;
+    randomisedWeaponModSlots?: string[];
     blacklist: EquipmentFilterDetails[];
     whitelist: EquipmentFilterDetails[];
 }
+export interface ModLimits {
+    /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */
+    scopeLimit?: number;
+    /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */
+    lightLaserLimit?: number;
+}
 export interface EquipmentFilterDetails {
     levelRange: MinMax;
     equipment: Record<string, string[]>;
diff --git a/TypeScript/8OnUpdateHook/types/models/spt/config/IBotDurability.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/config/IBotDurability.d.ts
new file mode 100644
index 0000000..38a47cc
--- /dev/null
+++ b/TypeScript/8OnUpdateHook/types/models/spt/config/IBotDurability.d.ts
@@ -0,0 +1,47 @@
+export interface IBotDurability {
+    default: DefaultDurability;
+    pmc: PmcDurability;
+    boss: BotDurability;
+    follower: BotDurability;
+    assault: BotDurability;
+    cursedassault: BotDurability;
+    marksman: BotDurability;
+    pmcbot: BotDurability;
+    exusec: BotDurability;
+    gifter: BotDurability;
+    sectantpriest: BotDurability;
+    sectantwarrior: BotDurability;
+}
+/** Durability values to be used when a more specific bot type cant be found */
+export interface DefaultDurability {
+    armor: DefaultArmor;
+    weapon: WeaponDurability;
+}
+export interface DefaultArmor {
+    maxDelta: number;
+    minDelta: number;
+}
+export interface WeaponDurability {
+    lowestMax: number;
+    highestMax: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface PmcDurability {
+    armor: PmcDurabilityArmor;
+    weapon: WeaponDurability;
+}
+export interface PmcDurabilityArmor {
+    lowestMaxPercent: number;
+    highestMaxPercent: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface BotDurability {
+    armor: ArmorDurability;
+    weapon: WeaponDurability;
+}
+export interface ArmorDurability {
+    maxDelta: number;
+    minDelta: number;
+}
diff --git a/TypeScript/8OnUpdateHook/types/models/spt/config/IItemConfig.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/config/IItemConfig.d.ts
new file mode 100644
index 0000000..5ecccc2
--- /dev/null
+++ b/TypeScript/8OnUpdateHook/types/models/spt/config/IItemConfig.d.ts
@@ -0,0 +1,5 @@
+import { IBaseConfig } from "./IBaseConfig";
+export interface IItemConfig extends IBaseConfig {
+    kind: "aki-item";
+    blacklist: string[];
+}
diff --git a/TypeScript/8OnUpdateHook/types/models/spt/config/IPmcConfig.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/config/IPmcConfig.d.ts
new file mode 100644
index 0000000..655b58d
--- /dev/null
+++ b/TypeScript/8OnUpdateHook/types/models/spt/config/IPmcConfig.d.ts
@@ -0,0 +1,22 @@
+import { MinMax } from "../../common/MinMax";
+export interface IPmcConfig {
+    dynamicLoot: DynamicLoot;
+    useDifficultyOverride: boolean;
+    difficulty: string;
+    looseWeaponInBackpackChancePercent: number;
+    looseWeaponInBackpackLootMinMax: MinMax;
+    isUsec: number;
+    chanceSameSideIsHostilePercent: number;
+    usecType: string;
+    bearType: string;
+    maxBackpackLootTotalRub: number;
+    maxPocketLootTotalRub: number;
+    maxVestLootTotalRub: number;
+    convertIntoPmcChance: Record<string, MinMax>;
+    enemyTypes: string[];
+}
+export interface DynamicLoot {
+    whitelist: string[];
+    blacklist: string[];
+    moneyStackLimits: Record<string, number>;
+}
diff --git a/TypeScript/8OnUpdateHook/types/models/spt/config/IQuestConfig.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/config/IQuestConfig.d.ts
index be4a97b..45c9aae 100644
--- a/TypeScript/8OnUpdateHook/types/models/spt/config/IQuestConfig.d.ts
+++ b/TypeScript/8OnUpdateHook/types/models/spt/config/IQuestConfig.d.ts
@@ -4,6 +4,8 @@ export interface IQuestConfig extends IBaseConfig {
     kind: "aki-quest";
     redeemTime: number;
     repeatableQuests: IRepeatableQuestConfig[];
+    bearOnlyQuests: string[];
+    usecOnlyQuests: string[];
 }
 export interface IRepeatableQuestConfig {
     name: string;
@@ -15,6 +17,10 @@ export interface IRepeatableQuestConfig {
     locations: Record<ELocationName, string[]>;
     traderWhitelist: ITraderWhitelist[];
     questConfig: IQuestConfig;
+    /** Item base types to block when generating rewards */
+    rewardBaseTypeBlacklist: string[];
+    /** Item tplIds to ignore when generating rewards */
+    rewardBlacklist: string[];
 }
 export interface IRewardScaling {
     levels: number[];
diff --git a/TypeScript/8OnUpdateHook/types/models/spt/config/IRagfairConfig.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/config/IRagfairConfig.d.ts
index 6369eda..3088717 100644
--- a/TypeScript/8OnUpdateHook/types/models/spt/config/IRagfairConfig.d.ts
+++ b/TypeScript/8OnUpdateHook/types/models/spt/config/IRagfairConfig.d.ts
@@ -12,6 +12,7 @@ export interface Sell {
     chance: Chance;
     time: Time;
     reputation: Reputation;
+    simulatedSellHours: number;
 }
 export interface Chance {
     base: number;
diff --git a/TypeScript/8OnUpdateHook/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/config/ITraderConfig.d.ts
index c8e8044..6b1c1e3 100644
--- a/TypeScript/8OnUpdateHook/types/models/spt/config/ITraderConfig.d.ts
+++ b/TypeScript/8OnUpdateHook/types/models/spt/config/ITraderConfig.d.ts
@@ -12,8 +12,10 @@ export interface UpdateTime {
     seconds: number;
 }
 export interface FenceConfig {
+    partialRefreshTimeSeconds: number;
+    partialRefreshChangePercent: number;
     assortSize: number;
-    maxPresetsCount: number;
+    maxPresetsPercent: number;
     presetPriceMult: number;
     blacklist: string[];
 }
diff --git a/TypeScript/8OnUpdateHook/types/models/spt/services/LootItem.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/services/LootItem.d.ts
new file mode 100644
index 0000000..2838472
--- /dev/null
+++ b/TypeScript/8OnUpdateHook/types/models/spt/services/LootItem.d.ts
@@ -0,0 +1,5 @@
+export declare class LootItem {
+    tpl: string;
+    isPreset: boolean;
+    stackCount: number;
+}
diff --git a/TypeScript/8OnUpdateHook/types/models/spt/services/LootRequest.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/8OnUpdateHook/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/8OnUpdateHook/types/services/BotEquipmentFilterService.d.ts b/TypeScript/8OnUpdateHook/types/services/BotEquipmentFilterService.d.ts
index e49645b..632f961 100644
--- a/TypeScript/8OnUpdateHook/types/services/BotEquipmentFilterService.d.ts
+++ b/TypeScript/8OnUpdateHook/types/services/BotEquipmentFilterService.d.ts
@@ -1,12 +1,12 @@
 import { IBotType } from "../models/eft/common/tables/IBotType";
-import { Equipment, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 export declare class BotEquipmentFilterService {
     protected logger: ILogger;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    protected botEquipmentFilterlists: Record<string, Equipment>;
+    protected botEquipmentFilterlists: Record<string, EquipmentFilters>;
     constructor(logger: ILogger, configServer: ConfigServer);
     /**
      * Filter a bots data to exclude equipment and cartridges defines in the botConfig
@@ -22,7 +22,7 @@ export declare class BotEquipmentFilterService {
      * @param playerLevel Level of the player
      * @returns EquipmentBlacklistDetails object
      */
-    protected getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
+    getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
     /**
      * Get the whitelist for a specific bot type that's within the players level
      * @param botRole Bot type
diff --git a/TypeScript/8OnUpdateHook/types/services/FenceService.d.ts b/TypeScript/8OnUpdateHook/types/services/FenceService.d.ts
index c9e325e..c940507 100644
--- a/TypeScript/8OnUpdateHook/types/services/FenceService.d.ts
+++ b/TypeScript/8OnUpdateHook/types/services/FenceService.d.ts
@@ -12,6 +12,11 @@ import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+import { ItemFilterService } from "./ItemFilterService";
+/**
+ * Handle actions surrounding Fence
+ * e.g. generating or refreshing assorts / get next refresh time
+ */
 export declare class FenceService {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
@@ -22,18 +27,64 @@ export declare class FenceService {
     protected handbookHelper: HandbookHelper;
     protected itemHelper: ItemHelper;
     protected presetHelper: PresetHelper;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected fenceAssort: ITraderAssort;
     protected traderConfig: ITraderConfig;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, configServer: ConfigServer);
+    protected nextMiniRefreshTimestamp: number;
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, itemFilterService: ItemFilterService, configServer: ConfigServer);
     protected setFenceAssort(fenceAssort: ITraderAssort): void;
-    getFenceAssorts(): ITraderAssort;
+    /**
+     * Get assorts player can purchase
+     * Adjust prices based on fence level of player
+     * @param pmcProfile Player profile
+     * @returns ITraderAssort
+     */
+    getFenceAssorts(pmcProfile: IPmcData): ITraderAssort;
+    /**
+     * Get fence assorts with no price adjustments based on fence rep
+     * @returns ITraderAssort
+     */
+    getRawFenceAssorts(): ITraderAssort;
+    /**
+     * Does fence need to perform a partial refresh because its passed the refresh timer defined in trader.json
+     * @returns true if it needs a partial refresh
+     */
+    needsPartialRefresh(): boolean;
+    /**
+     * Replace a percentage of fence assorts with freshly generated items
+     */
+    performPartialRefresh(): void;
+    /**
+     * Choose an item (not mod) at random and remove from assorts
+     */
+    protected removeRandomItemFromAssorts(): void;
+    /**
+     * Get an integer rounded count of items to replace based on percentrage from traderConfig value
+     * @param totalItemCount total item count
+     * @returns rounded int of items to replace
+     */
+    protected getCountOfItemsToReplace(totalItemCount: number): number;
     /**
      * Get the count of items fence offers
      * @returns number
      */
     getOfferCount(): number;
-    generateFenceAssortCache(pmcData: IPmcData): void;
+    /**
+     * Create a trader assort for fence
+     */
+    generateFenceAssortCache(): void;
+    /**
+     * Create skeleton to hold assort items
+     * @returns ITraderAssort object
+     */
+    protected createBaseTraderAssortItem(): ITraderAssort;
+    /**
+     * Hydrate result parameter object with generated assorts
+     * @param assortCount Number of assorts to generate
+     * @param assorts object to add assorts to
+     */
+    protected createAssorts(assortCount: number, assorts: ITraderAssort): void;
     /**
      * Get the next update timestamp for fence
      * @returns future timestamp
@@ -44,11 +95,14 @@ export declare class FenceService {
      */
     protected getFenceRefreshTime(): number;
     /**
-     * Get the fence level the passed in profile has
+     * Get fence level the passed in profile has
      * @param pmcData Player profile
-     * @returns FenceLevel
+     * @returns FenceLevel object
      */
     getFenceInfo(pmcData: IPmcData): FenceLevel;
+    /**
+     * Remove an assort from fence by id
+     * @param assortIdToRemove assort id to remove from fence assorts
+     */
     removeFenceOffer(assortIdToRemove: string): void;
-    updateFenceOffers(pmcData: IPmcData): void;
 }
diff --git a/TypeScript/8OnUpdateHook/types/services/InsuranceService.d.ts b/TypeScript/8OnUpdateHook/types/services/InsuranceService.d.ts
index 171bf10..6be8a2f 100644
--- a/TypeScript/8OnUpdateHook/types/services/InsuranceService.d.ts
+++ b/TypeScript/8OnUpdateHook/types/services/InsuranceService.d.ts
@@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
 import { SecureContainerHelper } from "../helpers/SecureContainerHelper";
 import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
+import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData";
 import { IInsuranceConfig } from "../models/spt/config/IInsuranceConfig";
@@ -44,8 +45,22 @@ export declare class InsuranceService {
      * @param mapId Id of the map player died/exited that caused the insurance to be issued on
      */
     sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void;
+    /**
+     * Store lost gear post-raid inside profile
+     * @param pmcData player profile to store gear in
+     * @param offraidData post-raid request object
+     * @param preRaidGear gear player wore prior to raid
+     * @param sessionID Session id
+     */
     storeLostGear(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
     storeInsuredItemsForReturn(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
-    protected addGearToSend(pmcData: IPmcData, insuredItem: any, actualItem: any, sessionID: string): any;
+    /**
+     * Add gear item to InsuredItems array in player profile
+     * @param pmcData profile to store item in
+     * @param insuredItem Item to store in profile
+     * @param actualItem item to store
+     * @param sessionID Session id
+     */
+    protected addGearToSend(pmcData: IPmcData, insuredItem: InsuredItem, actualItem: Item, sessionID: string): void;
     getPremium(pmcData: IPmcData, inventoryItem: Item, traderId: string): number;
 }
diff --git a/TypeScript/8OnUpdateHook/types/services/ItemFilterService.d.ts b/TypeScript/8OnUpdateHook/types/services/ItemFilterService.d.ts
new file mode 100644
index 0000000..c9c8ef3
--- /dev/null
+++ b/TypeScript/8OnUpdateHook/types/services/ItemFilterService.d.ts
@@ -0,0 +1,24 @@
+import { IItemConfig } from "../models/spt/config/IItemConfig";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+/** Centralise the handling of blacklisting items, uses blacklist found in config/item.json */
+export declare class ItemFilterService {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected configServer: ConfigServer;
+    protected blacklist: string[];
+    protected itemConfig: IItemConfig;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer);
+    /**
+     * Check if the provided template id is blacklisted in config/item.json
+     * @param tpl template id
+     * @returns true if blacklisted
+     */
+    isItemBlacklisted(tpl: string): boolean;
+    /**
+     * Return every template id blacklisted in config/item.json
+     * @returns string array of blacklisted tempalte ids
+     */
+    getBlacklistedItems(): string[];
+}
diff --git a/TypeScript/8OnUpdateHook/types/services/ProfileFixerService.d.ts b/TypeScript/8OnUpdateHook/types/services/ProfileFixerService.d.ts
index ed1dec7..9cb5a38 100644
--- a/TypeScript/8OnUpdateHook/types/services/ProfileFixerService.d.ts
+++ b/TypeScript/8OnUpdateHook/types/services/ProfileFixerService.d.ts
@@ -45,6 +45,11 @@ export declare class ProfileFixerService {
      * @param pmcProfile Profile to find and remove slots from
      */
     protected removeResourcesFromSlotsInHideoutWithoutLocationIndexValue(pmcProfile: IPmcData): void;
+    /**
+     * Hideout slots need to be in a specific order, locationIndex in ascending order
+     * @param pmcProfile profile to edit
+     */
+    protected reorderHideoutAreasWithResouceInputs(pmcProfile: IPmcData): void;
     /**
      * add in objects equal to the number of slots
      * @param areaType area to check
diff --git a/TypeScript/8OnUpdateHook/types/utils/HashUtil.d.ts b/TypeScript/8OnUpdateHook/types/utils/HashUtil.d.ts
index bacbf2a..a8500e1 100644
--- a/TypeScript/8OnUpdateHook/types/utils/HashUtil.d.ts
+++ b/TypeScript/8OnUpdateHook/types/utils/HashUtil.d.ts
@@ -4,8 +4,18 @@ import { TimeUtil } from "./TimeUtil";
 export declare class HashUtil {
     protected timeUtil: TimeUtil;
     constructor(timeUtil: TimeUtil);
+    /**
+     * Create a 24 character id using the sha256 algorithm + current timestamp
+     * @returns 24 character hash
+     */
     generate(): string;
     generateMd5ForData(data: string): string;
     generateSha1ForData(data: string): string;
+    /**
+     * Create a hash for the data parameter
+     * @param algorithm algorithm to use to hash
+     * @param data data to be hashed
+     * @returns hash value
+     */
     generateHashForData(algorithm: string, data: crypto.BinaryLike): string;
 }
diff --git a/TypeScript/8OnUpdateHook/types/utils/RandomUtil.d.ts b/TypeScript/8OnUpdateHook/types/utils/RandomUtil.d.ts
index c24dd60..e35d21f 100644
--- a/TypeScript/8OnUpdateHook/types/utils/RandomUtil.d.ts
+++ b/TypeScript/8OnUpdateHook/types/utils/RandomUtil.d.ts
@@ -150,4 +150,10 @@ export declare class RandomUtil {
      */
     drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[];
     getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number;
+    /**
+     * Fisher-Yates shuffle an array
+     * @param array Array to shuffle
+     * @returns Shuffled array
+     */
+    shuffle<T>(array: Array<T>): Array<T>;
 }
diff --git a/TypeScript/8OnUpdateHook/types/utils/TimeUtil.d.ts b/TypeScript/8OnUpdateHook/types/utils/TimeUtil.d.ts
index f437f8a..1367e26 100644
--- a/TypeScript/8OnUpdateHook/types/utils/TimeUtil.d.ts
+++ b/TypeScript/8OnUpdateHook/types/utils/TimeUtil.d.ts
@@ -1,3 +1,6 @@
+/**
+ * Utility class to handle time related problems
+ */
 export declare class TimeUtil {
     static readonly oneHourAsSeconds = 3600;
     formatTime(date: Date): string;
@@ -19,4 +22,10 @@ export declare class TimeUtil {
      * @returns current date in format: 00.00.0000 (dd.mm.yyyy)
      */
     getDateMailFormat(): string;
+    /**
+     * Convert hours into seconds
+     * @param hours hours to convert to seconds
+     * @returns number
+     */
+    getHoursAsSeconds(hours: number): number;
 }
diff --git a/TypeScript/9RouterHooks/types/callbacks/LocationCallbacks.d.ts b/TypeScript/9RouterHooks/types/callbacks/LocationCallbacks.d.ts
index cc69369..6e0b538 100644
--- a/TypeScript/9RouterHooks/types/callbacks/LocationCallbacks.d.ts
+++ b/TypeScript/9RouterHooks/types/callbacks/LocationCallbacks.d.ts
@@ -11,4 +11,5 @@ export declare class LocationCallbacks {
     constructor(httpResponse: HttpResponseUtil, locationController: LocationController);
     getLocationData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<ILocationsGenerateAllResponse>;
     getLocation(url: string, info: IGetLocationRequestData, sessionID: string): IGetBodyResponseData<ILocationBase>;
+    getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): string;
 }
diff --git a/TypeScript/9RouterHooks/types/callbacks/ProfileCallbacks.d.ts b/TypeScript/9RouterHooks/types/callbacks/ProfileCallbacks.d.ts
index 6a86fc0..183bb0a 100644
--- a/TypeScript/9RouterHooks/types/callbacks/ProfileCallbacks.d.ts
+++ b/TypeScript/9RouterHooks/types/callbacks/ProfileCallbacks.d.ts
@@ -1,5 +1,6 @@
 import { ProfileController } from "../controllers/ProfileController";
 import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData";
+import { IPmcData } from "../models/eft/common/IPmcData";
 import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData";
 import { INullResponseData } from "../models/eft/httpResponse/INullResponseData";
 import { IGetMiniProfileRequestData } from "../models/eft/launcher/IGetMiniProfileRequestData";
@@ -12,20 +13,51 @@ import { ISearchFriendResponse } from "../models/eft/profile/ISearchFriendRespon
 import { IValidateNicknameRequestData } from "../models/eft/profile/IValidateNicknameRequestData";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/** Handle profile related client events */
 export declare class ProfileCallbacks {
     protected httpResponse: HttpResponseUtil;
     protected timeUtil: TimeUtil;
     protected profileController: ProfileController;
     constructor(httpResponse: HttpResponseUtil, timeUtil: TimeUtil, profileController: ProfileController);
     createProfile(url: string, info: IProfileCreateRequestData, sessionID: string): IGetBodyResponseData<any>;
-    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
-    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<any>;
+    /**
+     * Get the complete player profile (scav + pmc character)
+     * @param url
+     * @param info Empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    getProfileData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle the creation of a scav profile for player
+     * Occurs post-raid and when profile first created immediately after character details are confirmed by player
+     * @param url
+     * @param info empty
+     * @param sessionID Session id
+     * @returns Profile object
+     */
+    regenerateScav(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
+    /**
+     * Handle client/game/profile/voice/change event
+     * @param url
+     * @param info Change voice request object
+     * @param sessionID Session id
+     * @returns Client response
+     */
     changeVoice(url: string, info: IProfileChangeVoiceRequestData, sessionID: string): INullResponseData;
+    /**
+     * Handle client/game/profile/nickname/change event
+     * Client allows player to adjust their profile name
+     * @param url
+     * @param info Change nickname request object
+     * @param sessionID Session id
+     * @returns client response
+     */
     changeNickname(url: string, info: IProfileChangeNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     validateNickname(url: string, info: IValidateNicknameRequestData, sessionID: string): IGetBodyResponseData<any>;
     getReservedNickname(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<string>;
     /**
-     * Called when creating a character, when you choose a character face/voice
+     * Called when creating a character when choosing a character face/voice
      * @param url
      * @param info response (empty)
      * @param sessionID
diff --git a/TypeScript/9RouterHooks/types/callbacks/RagfairCallbacks.d.ts b/TypeScript/9RouterHooks/types/callbacks/RagfairCallbacks.d.ts
index 3a405c9..c609f2f 100644
--- a/TypeScript/9RouterHooks/types/callbacks/RagfairCallbacks.d.ts
+++ b/TypeScript/9RouterHooks/types/callbacks/RagfairCallbacks.d.ts
@@ -19,6 +19,9 @@ import { ConfigServer } from "../servers/ConfigServer";
 import { RagfairServer } from "../servers/RagfairServer";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+/**
+ * Handle ragfair related callback events
+ */
 export declare class RagfairCallbacks extends OnLoadOnUpdate {
     protected httpResponse: HttpResponseUtil;
     protected logger: ILogger;
diff --git a/TypeScript/9RouterHooks/types/controllers/InraidController.d.ts b/TypeScript/9RouterHooks/types/controllers/InraidController.d.ts
index 82bb64d..102a2fb 100644
--- a/TypeScript/9RouterHooks/types/controllers/InraidController.d.ts
+++ b/TypeScript/9RouterHooks/types/controllers/InraidController.d.ts
@@ -35,6 +35,30 @@ export declare class InraidController {
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer);
     addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void;
     saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Handle updating the profile post-pmc raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Reduce body part hp to % of max
+     * @param pmcData profile to edit
+     * @param multipler multipler to apply to max health
+     */
+    protected reducePmcHealthToPercent(pmcData: IPmcData, multipler: number): void;
+    /**
+     * Handle updating the profile post-pscav raid
+     * @param sessionID session id
+     * @param offraidData post-raid data of raid
+     */
+    protected savePlayerScavProgress(sessionID: string, offraidData: ISaveProgressRequestData): void;
+    /**
+     * Is the player dead after a raid - dead is anything other than "survived" / "runner"
+     * @param statusOnExit exit value from offraidData object
+     * @returns true if dead
+     */
+    protected isPlayerDead(statusOnExit: string): boolean;
     /**
      * Mark inventory items as FiR if player survived raid, otherwise remove FiR from them
      * @param offraidData Save Progress Request
diff --git a/TypeScript/9RouterHooks/types/controllers/InventoryController.d.ts b/TypeScript/9RouterHooks/types/controllers/InventoryController.d.ts
index f57f731..f564919 100644
--- a/TypeScript/9RouterHooks/types/controllers/InventoryController.d.ts
+++ b/TypeScript/9RouterHooks/types/controllers/InventoryController.d.ts
@@ -92,7 +92,11 @@ export declare class InventoryController {
      */
     toggleItem(pmcData: IPmcData, body: IInventoryToggleRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Handles Tagging of items (primary Containers).
+     * Add a tag to an inventory item
+     * @param pmcData profile with item to add tag to
+     * @param body tag request data
+     * @param sessionID session id
+     * @returns client response object
      */
     tagItem(pmcData: IPmcData, body: IInventoryTagRequestData, sessionID: string): IItemEventRouterResponse;
     bindItem(pmcData: IPmcData, body: IInventoryBindRequestData, sessionID: string): IItemEventRouterResponse;
diff --git a/TypeScript/9RouterHooks/types/controllers/LocationController.d.ts b/TypeScript/9RouterHooks/types/controllers/LocationController.d.ts
index 90b6d7a..9db3205 100644
--- a/TypeScript/9RouterHooks/types/controllers/LocationController.d.ts
+++ b/TypeScript/9RouterHooks/types/controllers/LocationController.d.ts
@@ -1,18 +1,33 @@
 import { LocationGenerator } from "../generators/LocationGenerator";
+import { LootGenerator } from "../generators/LootGenerator";
 import { ILocationBase } from "../models/eft/common/ILocationBase";
 import { ILocationsGenerateAllResponse } from "../models/eft/common/ILocationsSourceDestinationBase";
+import { IAirdropConfig } from "../models/spt/config/IAirdropConfig";
+import { LootItem } from "../models/spt/services/LootItem";
 import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class LocationController {
     protected jsonUtil: JsonUtil;
+    protected hashUtil: HashUtil;
     protected logger: ILogger;
     protected locationGenerator: LocationGenerator;
+    protected lootGenerator: LootGenerator;
     protected databaseServer: DatabaseServer;
     protected timeUtil: TimeUtil;
-    constructor(jsonUtil: JsonUtil, logger: ILogger, locationGenerator: LocationGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil);
+    protected configServer: ConfigServer;
+    protected airdropConfig: IAirdropConfig;
+    constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer);
     get(location: string): ILocationBase;
     generate(name: string): ILocationBase;
     generateAll(): ILocationsGenerateAllResponse;
+    /**
+     * Get loot for an airdop container
+     * Generates it randomly based on config/airdrop.json values
+     * @returns Array of LootItem
+     */
+    getAirdropLoot(): LootItem[];
 }
diff --git a/TypeScript/9RouterHooks/types/controllers/MatchController.d.ts b/TypeScript/9RouterHooks/types/controllers/MatchController.d.ts
index e8585d9..cb40023 100644
--- a/TypeScript/9RouterHooks/types/controllers/MatchController.d.ts
+++ b/TypeScript/9RouterHooks/types/controllers/MatchController.d.ts
@@ -9,6 +9,7 @@ import { IGetProfileRequestData } from "../models/eft/match/IGetProfileRequestDa
 import { IJoinMatchRequestData } from "../models/eft/match/IJoinMatchRequestData";
 import { IJoinMatchResult } from "../models/eft/match/IJoinMatchResult";
 import { IStartOfflineRaidRequestData } from "../models/eft/match/IStartOffineRaidRequestData";
+import { IBotConfig } from "../models/spt/config/IBotConfig";
 import { IInRaidConfig } from "../models/spt/config/IInRaidConfig";
 import { IMatchConfig } from "../models/spt/config/IMatchConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
@@ -29,6 +30,7 @@ export declare class MatchController {
     protected applicationContext: ApplicationContext;
     protected matchConfig: IMatchConfig;
     protected inraidConfig: IInRaidConfig;
+    protected botConfig: IBotConfig;
     constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, applicationContext: ApplicationContext);
     getEnabled(): boolean;
     getProfile(info: IGetProfileRequestData): IPmcData[];
diff --git a/TypeScript/9RouterHooks/types/controllers/QuestController.d.ts b/TypeScript/9RouterHooks/types/controllers/QuestController.d.ts
index 2cbccfb..282f50e 100644
--- a/TypeScript/9RouterHooks/types/controllers/QuestController.d.ts
+++ b/TypeScript/9RouterHooks/types/controllers/QuestController.d.ts
@@ -39,16 +39,31 @@ export declare class QuestController {
      * @returns array of IQuest
      */
     getClientQuests(sessionID: string): IQuest[];
+    /**
+     * Is the quest for the opposite side the player is on
+     * @param side player side (usec/bear)
+     * @param questId questId to check
+     */
+    protected questIsForOtherSide(side: string, questId: string): boolean;
+    /**
+     * Handle the client accepting a quest and starting it
+     * Send starting rewards if any to player and
+     * Send start notification if any to player
+     * @param pmcData Profile to update
+     * @param acceptedQuest Quest accepted
+     * @param sessionID Session id
+     * @returns client response
+     */
     acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
-     * Remove completed quest from profile
+     * Update completed quest in profile
      * Add newly unlocked quests to profile
      * Also recalculate thier level due to exp rewards
      * @param pmcData Player profile
-     * @param body completed quest request
-     * @param sessionID session id
-     * @returns ItemEvent response
+     * @param body Completed quest request
+     * @param sessionID Session id
+     * @returns ItemEvent client response
      */
     completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse;
     /**
@@ -67,10 +82,20 @@ export declare class QuestController {
     protected getQuestsFailedByCompletingQuest(completedQuestId: string): IQuest[];
     /**
      * Fail the quests provided
+     * Update quest in profile, otherwise add fresh quest object with failed status
      * @param sessionID session id
      * @param pmcData player profile
      * @param questsToFail quests to fail
      */
     protected failQuests(sessionID: string, pmcData: IPmcData, questsToFail: IQuest[]): void;
     handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment a backend counter stored value by an amount,
+     * Create counter if it does not exist
+     * @param pmcData Profile to find backend counter in
+     * @param conditionId backend counter id to update
+     * @param questId quest id counter is associated with
+     * @param counterValue value to increment the backend counter with
+     */
+    protected updateProfileBackendCounterValue(pmcData: IPmcData, conditionId: string, questId: string, counterValue: number): void;
 }
diff --git a/TypeScript/9RouterHooks/types/controllers/RagfairController.d.ts b/TypeScript/9RouterHooks/types/controllers/RagfairController.d.ts
index c4ffc15..06af740 100644
--- a/TypeScript/9RouterHooks/types/controllers/RagfairController.d.ts
+++ b/TypeScript/9RouterHooks/types/controllers/RagfairController.d.ts
@@ -9,6 +9,7 @@ import { RagfairOfferHelper } from "../helpers/RagfairOfferHelper";
 import { RagfairSellHelper } from "../helpers/RagfairSellHelper";
 import { RagfairSortHelper } from "../helpers/RagfairSortHelper";
 import { RagfairTaxHelper } from "../helpers/RagfairTaxHelper";
+import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
@@ -33,6 +34,9 @@ import { RagfairPriceService } from "../services/RagfairPriceService";
 import { RagfairRequiredItemsService } from "../services/RagfairRequiredItemsService";
 import { HttpResponseUtil } from "../utils/HttpResponseUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+/**
+ * Handle RagfairCallback events
+ */
 export declare class RagfairController {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
@@ -52,14 +56,20 @@ export declare class RagfairController {
     protected handbookHelper: HandbookHelper;
     protected paymentHelper: PaymentHelper;
     protected inventoryHelper: InventoryHelper;
+    protected traderHelper: TraderHelper;
     protected ragfairHelper: RagfairHelper;
     protected ragfairOfferService: RagfairOfferService;
     protected ragfairRequiredItemsService: RagfairRequiredItemsService;
     protected ragfairOfferGenerator: RagfairOfferGenerator;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer);
     getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult;
+    /**
+     * Update a trader flea offer with buy restrictions stored in the traders assort
+     * @param offer flea offer to update
+     */
+    protected setTraderOfferPurchaseLimits(offer: IRagfairOffer): void;
     protected isLinkedSearch(info: ISearchRequestData): boolean;
     protected isRequiredSearch(info: ISearchRequestData): boolean;
     update(): void;
diff --git a/TypeScript/9RouterHooks/types/controllers/RepeatableQuestController.d.ts b/TypeScript/9RouterHooks/types/controllers/RepeatableQuestController.d.ts
index 98d05dd..4c31a3d 100644
--- a/TypeScript/9RouterHooks/types/controllers/RepeatableQuestController.d.ts
+++ b/TypeScript/9RouterHooks/types/controllers/RepeatableQuestController.d.ts
@@ -7,6 +7,7 @@ import { Exit } from "../models/eft/common/ILocationBase";
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { TraderInfo } from "../models/eft/common/tables/IBotBase";
 import { ICompletion, ICompletionAvailableFor, IElimination, IEliminationCondition, IExploration, IExplorationCondition, IPmcDataRepeatableQuest, IRepeatableQuest, IReward, IRewards } from "../models/eft/common/tables/IRepeatableQuests";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse";
 import { IRepeatableQuestChangeRequest } from "../models/eft/quests/IRepeatableQuestChangeRequest";
 import { ELocationName } from "../models/enums/ELocationName";
@@ -15,6 +16,7 @@ import { ILogger } from "../models/spt/utils/ILogger";
 import { ItemEventRouter } from "../routers/ItemEventRouter";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { PaymentService } from "../services/PaymentService";
 import { ProfileFixerService } from "../services/ProfileFixerService";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -64,9 +66,10 @@ export declare class RepeatableQuestController {
     protected itemEventRouter: ItemEventRouter;
     protected paymentService: PaymentService;
     protected objectId: ObjectId;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
-    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, configServer: ConfigServer);
+    constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, itemEventRouter: ItemEventRouter, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint
      * Returns an array of objects in the format of repeatable quests to the client.
@@ -217,4 +220,16 @@ export declare class RepeatableQuestController {
     debugLogRepeatableQuestIds(pmcData: IPmcData): void;
     probabilityObjectArray<K, V>(configArrayInput: ProbabilityObject<K, V>[]): ProbabilityObjectArray<K, V>;
     changeRepeatableQuest(pmcDataIn: IPmcData, body: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
+     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
+     */
+    protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig): [string, ITemplateItem][];
+    /**
+     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
+     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
+     * @param {*} tpl template id of item to check
+     * @returns boolean: true if item is valid reward
+     */
+    isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig): boolean;
 }
diff --git a/TypeScript/9RouterHooks/types/controllers/TraderController.d.ts b/TypeScript/9RouterHooks/types/controllers/TraderController.d.ts
index 0162064..b79f55e 100644
--- a/TypeScript/9RouterHooks/types/controllers/TraderController.d.ts
+++ b/TypeScript/9RouterHooks/types/controllers/TraderController.d.ts
@@ -4,6 +4,7 @@ import { TraderHelper } from "../helpers/TraderHelper";
 import { IBarterScheme, ITraderAssort, ITraderBase } from "../models/eft/common/tables/ITrader";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { FenceService } from "../services/FenceService";
 import { TraderAssortService } from "../services/TraderAssortService";
 import { JsonUtil } from "../utils/JsonUtil";
 import { TimeUtil } from "../utils/TimeUtil";
@@ -15,8 +16,9 @@ export declare class TraderController {
     protected traderHelper: TraderHelper;
     protected timeUtil: TimeUtil;
     protected traderAssortService: TraderAssortService;
+    protected fenceService: FenceService;
     protected jsonUtil: JsonUtil;
-    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, jsonUtil: JsonUtil);
+    constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, timeUtil: TimeUtil, traderAssortService: TraderAssortService, fenceService: FenceService, jsonUtil: JsonUtil);
     /**
      * Runs when onLoad event is fired
      * Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
@@ -26,6 +28,7 @@ export declare class TraderController {
     /**
      * Runs when onUpdate is fired
      * If current time is > nextResupply(expire) time of trader, refresh traders assorts and
+     * Fence is handled slightly differently
      * @returns has run
      */
     update(): boolean;
diff --git a/TypeScript/9RouterHooks/types/di/Container.d.ts b/TypeScript/9RouterHooks/types/di/Container.d.ts
index 17791b0..98d1fa1 100644
--- a/TypeScript/9RouterHooks/types/di/Container.d.ts
+++ b/TypeScript/9RouterHooks/types/di/Container.d.ts
@@ -1,4 +1,7 @@
 import { DependencyContainer } from "tsyringe";
+/**
+ * Handle the registration of classes to be used by the Dependency Injection code
+ */
 export declare class Container {
     static registerTypes(depContainer: DependencyContainer): void;
     static registerListTypes(depContainer: DependencyContainer): void;
diff --git a/TypeScript/9RouterHooks/types/generators/BotGenerator.d.ts b/TypeScript/9RouterHooks/types/generators/BotGenerator.d.ts
index a5fc0ad..7d58f95 100644
--- a/TypeScript/9RouterHooks/types/generators/BotGenerator.d.ts
+++ b/TypeScript/9RouterHooks/types/generators/BotGenerator.d.ts
@@ -40,7 +40,7 @@ export declare class BotGenerator {
      * @param botTemplate base bot template to use  (e.g. assault/pmcbot)
      * @returns
      */
-    generatePlayerScav(role: string, difficulty: string, botTemplate: IBotType): IBotBase;
+    generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase;
     generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[];
     /**
      * Choose if a bot should become a PMC by checking if bot type is allowed to become a Pmc in botConfig.convertFromChances and doing a random int check
@@ -58,7 +58,7 @@ export declare class BotGenerator {
      * @returns IBotBase object
      */
     protected getCloneOfBotBase(): IBotBase;
-    protected generateBot(bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
+    protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase;
     /**
      * Log the number of PMCs generated to the debug console
      */
diff --git a/TypeScript/9RouterHooks/types/generators/BotInventoryGenerator.d.ts b/TypeScript/9RouterHooks/types/generators/BotInventoryGenerator.d.ts
index 35d1ee8..73f8ece 100644
--- a/TypeScript/9RouterHooks/types/generators/BotInventoryGenerator.d.ts
+++ b/TypeScript/9RouterHooks/types/generators/BotInventoryGenerator.d.ts
@@ -18,7 +18,7 @@ export declare class BotInventoryGenerator {
     protected botGeneratorHelper: BotGeneratorHelper;
     protected weightedRandomHelper: WeightedRandomHelper;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper);
-    generateInventory(templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
+    generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory;
     protected generateEquipment(equipmentSlot: string, equipmentPool: Record<string, number>, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void;
     protected generateInventoryBase(): PmcInventory;
 }
diff --git a/TypeScript/9RouterHooks/types/generators/BotLootGenerator.d.ts b/TypeScript/9RouterHooks/types/generators/BotLootGenerator.d.ts
index c6a3f29..5a2d144 100644
--- a/TypeScript/9RouterHooks/types/generators/BotLootGenerator.d.ts
+++ b/TypeScript/9RouterHooks/types/generators/BotLootGenerator.d.ts
@@ -24,7 +24,7 @@ export declare class BotLootGenerator {
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
     constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botLootCacheService: BotLootCacheService, configServer: ConfigServer);
-    generateLoot(templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
+    generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void;
     protected getRandomisedCount(min: number, max: number, nValue: number): number;
     /**
      * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached
@@ -47,7 +47,7 @@ export declare class BotLootGenerator {
      * @param botRole bots role, .e.g. pmcBot
      * @param isPmc are we generating for a pmc
      */
-    protected addLooseWeaponsToInventorySlot(botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
+    protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void;
     /**
      * Get a random item from the pool parameter using the biasedRandomNumber system
      * @param pool pool of items to pick an item from
diff --git a/TypeScript/9RouterHooks/types/generators/BotWeaponGenerator.d.ts b/TypeScript/9RouterHooks/types/generators/BotWeaponGenerator.d.ts
index 9215214..49fa7bf 100644
--- a/TypeScript/9RouterHooks/types/generators/BotWeaponGenerator.d.ts
+++ b/TypeScript/9RouterHooks/types/generators/BotWeaponGenerator.d.ts
@@ -28,7 +28,18 @@ export declare class BotWeaponGenerator {
     protected botConfig: IBotConfig;
     constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer);
     /**
-     * Get a random weapon from a bots pool of weapons (weighted)
+     * Pick a random weapon based on weightings and generate a functional weapon
+     * @param equipmentSlot Primary/secondary/holster
+     * @param botTemplateInventory e.g. assault.json
+     * @param weaponParentId
+     * @param modChances
+     * @param botRole role of bot, e.g. assault/followerBully
+     * @param isPmc Is weapon generated for a pmc
+     * @returns GenerateWeaponResult object
+     */
+    generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    /**
+     * Get a random weighted weapon from a bots pool of weapons
      * @param equipmentSlot Primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
      * @returns weapon tpl
@@ -39,43 +50,24 @@ export declare class BotWeaponGenerator {
      * @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool())
      * @param equipmentSlot slot to fit into, primary/secondary/holster
      * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
+     * @param weaponParentId ParentId of the weapon being generated
+     * @param modChances Dictionary of item types and % chance weapon will have that mod
+     * @param botRole e.g. assault/exusec
      * @param isPmc
      * @returns GenerateWeaponResult object
      */
-    generateWeaponByTpl(weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
+    generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
     /**
-     * Generate an entirely random weapon
-     * @param equipmentSlot Primary/secondary/holster
-     * @param botTemplateInventory e.g. assault.json
-     * @param weaponParentId
-     * @param modChances
-     * @param botRole
-     * @param isPmc
-     * @returns GenerateWeaponResult object
-     */
-    generateRandomWeapon(equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult;
-    /**
-     * Create array with weapon base as only element
-     * Add additional properties as required
-     * @param weaponTpl
-     * @param weaponParentId
-     * @param equipmentSlot
-     * @param weaponItemTemplate
+     * Create array with weapon base as only element and
+     * add additional properties based on weapon type
+     * @param weaponTpl Weapon tpl to create item with
+     * @param weaponParentId Weapons parent id
+     * @param equipmentSlot e.g. primary/secondary/holster
+     * @param weaponItemTemplate db template for weapon
      * @param botRole for durability values
-     * @returns
+     * @returns Base weapon item in array
      */
     constructWeaponBaseArray(weaponTpl: string, weaponParentId: string, equipmentSlot: string, weaponItemTemplate: ITemplateItem, botRole: string): Item[];
-    /**
-     * Add compatible magazines to an inventory based on a generated weapon
-     * @param weaponDetails
-     * @param magCounts
-     * @param inventory
-     * @param botRole the bot type we're getting generating extra mags for
-     */
-    addExtraMagazinesToInventory(weaponDetails: GenerateWeaponResult, magCounts: MinMax, inventory: PmcInventory, botRole: string): void;
     /**
      * Get the mods necessary to kit out a weapon to its preset level
      * @param weaponTpl weapon to find preset for
@@ -84,20 +76,32 @@ export declare class BotWeaponGenerator {
      * @returns array of weapon mods
      */
     protected getPresetWeaponMods(weaponTpl: string, equipmentSlot: string, weaponParentId: string, itemTemplate: ITemplateItem, botRole: string): Item[];
-    /** Checks if all required slots are occupied on a weapon and all it's mods */
+    /**
+     * Checks if all required slots are occupied on a weapon and all it's mods
+     * @param weaponItemArray Weapon + mods
+     * @returns true if valid
+     */
     protected isWeaponValid(weaponItemArray: Item[]): boolean;
     /**
      * Generates extra magazines or bullets (if magazine is internal) and adds them to TacticalVest and Pockets.
      * Additionally, adds extra bullets to SecuredContainer
-     * @param weaponMods
-     * @param weaponTemplate
-     * @param magCounts
-     * @param ammoTpl
-     * @param inventory
+     * @param weaponMods mods to attach to weapon
+     * @param weaponTemplate db template for weapon
+     * @param magCounts magazine count to add to inventory
+     * @param ammoTpl ammo templateId to add to magazines
+     * @param inventory inventory to add magazines to
      * @param botRole the bot type we're getting generating extra mags for
      * @returns
      */
-    protected generateExtraMagazines(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    addExtraMagazinesToInventory(weaponMods: Item[], weaponTemplate: ITemplateItem, magCounts: MinMax, ammoTpl: string, inventory: PmcInventory, botRole: string): void;
+    /**
+     * Create a magazine using the parameters given
+     * @param magazineTpl Tpl of the magazine to create
+     * @param ammoTpl Ammo to add to magazine
+     * @param magTemplate template object of magazine
+     * @returns Item array
+     */
+    protected createMagazine(magazineTpl: string, ammoTpl: string, magTemplate: ITemplateItem): Item[];
     /**
      * Get a randomised number of bullets for a specific magazine
      * @param magCounts min and max count of magazines
@@ -138,10 +142,9 @@ export declare class BotWeaponGenerator {
      * Finds and return a compatible ammo tpl based on the bots ammo weightings (x.json/inventory/equipment/ammo)
      * @param ammo a list of ammo tpls the weapon can use
      * @param weaponTemplate the weapon we want to pick ammo for
-     * @param isPmc is the ammo being gathered for a pmc (runs pmc ammo filtering)
      * @returns an ammo tpl that works with the desired gun
      */
-    protected getCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem, isPmc: boolean): string;
+    protected getWeightedCompatibleAmmo(ammo: Record<string, Record<string, number>>, weaponTemplate: ITemplateItem): string;
     /**
      * Get a weapons compatible cartridge caliber
      * @param weaponTemplate Weapon to look up caliber of
diff --git a/TypeScript/9RouterHooks/types/generators/LocationGenerator.d.ts b/TypeScript/9RouterHooks/types/generators/LocationGenerator.d.ts
index bd368b5..cc61dcf 100644
--- a/TypeScript/9RouterHooks/types/generators/LocationGenerator.d.ts
+++ b/TypeScript/9RouterHooks/types/generators/LocationGenerator.d.ts
@@ -3,10 +3,9 @@ import { GameEventHelper } from "../helpers/GameEventHelper";
 import { ItemHelper } from "../helpers/ItemHelper";
 import { PresetHelper } from "../helpers/PresetHelper";
 import { RagfairServerHelper } from "../helpers/RagfairServerHelper";
-import { ILooseLoot, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
+import { ILooseLoot, SpawnpointsForced, SpawnpointTemplate } from "../models/eft/common/ILooseLoot";
 import { Item } from "../models/eft/common/tables/IItem";
 import { IStaticAmmoDetails, IStaticContainerProps, IStaticForcedProps, IStaticLootDetails } from "../models/eft/common/tables/ILootBase";
-import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILocationConfig } from "../models/spt/config/ILocationConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
@@ -36,11 +35,19 @@ export declare class LocationGenerator {
     generateContainerLoot(containerIn: IStaticContainerProps, staticForced: IStaticForcedProps[], staticLootDist: Record<string, IStaticLootDetails>, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): IStaticContainerProps;
     protected getLooseLootMultiplerForLocation(location: string): number;
     protected getStaticLootMultiplerForLocation(location: string): number;
+    /**
+     * Create array of loose + forced loot using probability system
+     * @param dynamicLootDist
+     * @param staticAmmoDist
+     * @param locationName Location to generate loot for
+     * @returns Array of spawn points with loot in them
+     */
     generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, locationName: string): SpawnpointTemplate[];
+    /**
+     * Add forced spawn point loot into loot parameter array
+     * @param loot array to add forced loot to
+     * @param forcedSpawnPoints forced loot to add
+     */
+    protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[]): void;
     protected createItem(tpl: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, parentId?: string): IContainerItem;
-    protected getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
-    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
-    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
-    protected createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
-    protected createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
 }
diff --git a/TypeScript/9RouterHooks/types/generators/LootGenerator.d.ts b/TypeScript/9RouterHooks/types/generators/LootGenerator.d.ts
new file mode 100644
index 0000000..fdefa6d
--- /dev/null
+++ b/TypeScript/9RouterHooks/types/generators/LootGenerator.d.ts
@@ -0,0 +1,55 @@
+import { ItemHelper } from "../helpers/ItemHelper";
+import { Preset } from "../models/eft/common/IGlobals";
+import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
+import { LootItem } from "../models/spt/services/LootItem";
+import { LootRequest } from "../models/spt/services/LootRequest";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+import { RandomUtil } from "../utils/RandomUtil";
+export declare class LootGenerator {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected randomUtil: RandomUtil;
+    protected itemHelper: ItemHelper;
+    protected itemFilterService: ItemFilterService;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, itemHelper: ItemHelper, itemFilterService: ItemFilterService);
+    /**
+     * Generate a list of items based on options passed in
+     * @param options parameters to adjust what loot is generated
+     * @returns An array of loot items
+     */
+    createRandomloot(options: LootRequest): LootItem[];
+    /**
+     * Construct item limit record to hold max and current item count
+     * @param limits limits as defined in config
+     * @returns record, key: item tplId, value: current/max item count allowed
+     */
+    protected initItemLimitCounter(limits: Record<string, number>): Record<string, {
+        current: number;
+        max: number;
+    }>;
+    /**
+     * Find a random item in items.json and add to result array
+     * @param items items to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found item to
+     * @returns true if item was valid and added to pool
+     */
+    protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+    /**
+     *
+     * Find a random item in items.json and add to result array
+     * @param globalDefaultPresets presets to choose from
+     * @param itemTypeCounts item limit counts
+     * @param result array to add found preset to
+     * @returns true if preset was valid and added to pool
+     */
+    protected findAndAddRandomPresetToLoot(globalDefaultPresets: [string, Preset][], itemTypeCounts: Record<string, {
+        current: number;
+        max: number;
+    }>, result: LootItem[]): boolean;
+}
diff --git a/TypeScript/9RouterHooks/types/generators/PMCLootGenerator.d.ts b/TypeScript/9RouterHooks/types/generators/PMCLootGenerator.d.ts
index 64e6f7f..b9f2a83 100644
--- a/TypeScript/9RouterHooks/types/generators/PMCLootGenerator.d.ts
+++ b/TypeScript/9RouterHooks/types/generators/PMCLootGenerator.d.ts
@@ -1,15 +1,21 @@
 import { ItemHelper } from "../helpers/ItemHelper";
-import { DatabaseServer } from "../servers/DatabaseServer";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
+/**
+ * Handle the generation of dynamic PMC loot in pockets and backpacks
+ * and the removal of blacklisted items
+ */
 export declare class PMCLootGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected configServer: ConfigServer;
+    protected itemFilterService: ItemFilterService;
     protected pocketLootPool: string[];
     protected backpackLootPool: string[];
     protected botConfig: IBotConfig;
-    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer);
+    constructor(itemHelper: ItemHelper, databaseServer: DatabaseServer, configServer: ConfigServer, itemFilterService: ItemFilterService);
     generatePMCPocketLootPool(): string[];
     generatePMCBackpackLootPool(): string[];
 }
diff --git a/TypeScript/9RouterHooks/types/generators/ScavCaseRewardGenerator.d.ts b/TypeScript/9RouterHooks/types/generators/ScavCaseRewardGenerator.d.ts
index c7d6ab7..89cb5c8 100644
--- a/TypeScript/9RouterHooks/types/generators/ScavCaseRewardGenerator.d.ts
+++ b/TypeScript/9RouterHooks/types/generators/ScavCaseRewardGenerator.d.ts
@@ -8,9 +8,13 @@ import { RewardCountAndPriceDetails, ScavCaseRewardCountsAndPrices } from "../mo
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { RagfairPriceService } from "../services/RagfairPriceService";
 import { HashUtil } from "../utils/HashUtil";
 import { RandomUtil } from "../utils/RandomUtil";
+/**
+ * Handle the creation of randomised scav case rewards
+ */
 export declare class ScavCaseRewardGenerator {
     protected logger: ILogger;
     protected randomUtil: RandomUtil;
@@ -18,9 +22,10 @@ export declare class ScavCaseRewardGenerator {
     protected itemHelper: ItemHelper;
     protected databaseServer: DatabaseServer;
     protected ragfairPriceService: RagfairPriceService;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected scavCaseConfig: IScavCaseConfig;
-    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, configServer: ConfigServer);
+    constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Create an array of rewards that will be given to the player upon completing their scav case build
      * @param body client request
diff --git a/TypeScript/9RouterHooks/types/generators/WeatherGenerator.d.ts b/TypeScript/9RouterHooks/types/generators/WeatherGenerator.d.ts
index 44cecbb..8ddbe49 100644
--- a/TypeScript/9RouterHooks/types/generators/WeatherGenerator.d.ts
+++ b/TypeScript/9RouterHooks/types/generators/WeatherGenerator.d.ts
@@ -1,7 +1,7 @@
 import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper";
-import { ConfigServer } from "../servers/ConfigServer";
 import { IWeatherData } from "../models/eft/weather/IWeatherData";
 import { IWeatherConfig } from "../models/spt/config/IWeatherConfig";
+import { ConfigServer } from "../servers/ConfigServer";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
 export declare class WeatherGenerator {
@@ -21,11 +21,16 @@ export declare class WeatherGenerator {
     protected getAcceleratedTime(computedDate: Date): string;
     /**
      * Get current time formatted to fit BSGs requirement
-     * @param computedDate
+     * @param computedDate date to format into bsg style
      * @returns
      */
     protected getNormalTime(computedDate: Date): string;
-    generateWeather(data: IWeatherData): IWeatherData;
+    /**
+     * Return randomised Weather data
+     * @param weatherData weather input data
+     * @returns Randomised weather data
+     */
+    generateWeather(weatherData: IWeatherData): IWeatherData;
     protected getWeightedFog(): string;
     protected getWeightedRain(): number;
     protected getRandomFloat(node: string): number;
diff --git a/TypeScript/9RouterHooks/types/helpers/AssortHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/AssortHelper.d.ts
index 15586b9..bfc157f 100644
--- a/TypeScript/9RouterHooks/types/helpers/AssortHelper.d.ts
+++ b/TypeScript/9RouterHooks/types/helpers/AssortHelper.d.ts
@@ -17,7 +17,7 @@ export declare class AssortHelper {
      * @param assort assort items from a trader
      * @returns assort items minus locked quest assorts
      */
-    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort): ITraderAssort;
+    stripLockedQuestAssort(pmcProfile: IPmcData, traderId: string, assort: ITraderAssort, flea?: boolean): ITraderAssort;
     /**
      * Remove assorts from a trader that have not been unlocked yet
      * @param pmcProfile player profile
@@ -32,5 +32,5 @@ export declare class AssortHelper {
      * @param itemID item id to remove from asort
      * @returns Modified assort
      */
-    removeItemFromAssort(assort: ITraderAssort, itemID: string): ITraderAssort;
+    removeItemFromAssort(assort: ITraderAssort, itemID: string, flea?: boolean): ITraderAssort;
 }
diff --git a/TypeScript/9RouterHooks/types/helpers/BotGeneratorHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/BotGeneratorHelper.d.ts
index 3cd7256..eb0d215 100644
--- a/TypeScript/9RouterHooks/types/helpers/BotGeneratorHelper.d.ts
+++ b/TypeScript/9RouterHooks/types/helpers/BotGeneratorHelper.d.ts
@@ -3,10 +3,12 @@ import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"
 import { Mods, ModsChances } from "../models/eft/common/tables/IBotType";
 import { Item, Repairable, Upd } from "../models/eft/common/tables/IItem";
 import { Grid, ITemplateItem, Slot } from "../models/eft/common/tables/ITemplateItem";
-import { IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
+import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
@@ -14,6 +16,7 @@ import { ContainerHelper } from "./ContainerHelper";
 import { InventoryHelper } from "./InventoryHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProbabilityHelper } from "./ProbabilityHelper";
+import { ProfileHelper } from "./ProfileHelper";
 export declare class BotGeneratorHelper {
     protected logger: ILogger;
     protected jsonUtil: JsonUtil;
@@ -25,10 +28,76 @@ export declare class BotGeneratorHelper {
     protected itemHelper: ItemHelper;
     protected inventoryHelper: InventoryHelper;
     protected containerHelper: ContainerHelper;
+    protected botEquipmentFilterService: BotEquipmentFilterService;
+    protected itemFilterService: ItemFilterService;
+    protected profileHelper: ProfileHelper;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, configServer: ConfigServer);
-    generateModsForItem(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, configServer: ConfigServer);
+    /**
+     * TODO - very similar to generateModsForWeapon
+     * Check mods are compatible and add to array
+     * @param equipment Equipment item to add mods to
+     * @param modPool Mod list to choose frm
+     * @param parentId parentid of item to add mod to
+     * @param parentTemplate template objet of item to add mods to
+     * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type
+     * @returns Item + compatible mods as an array
+     */
+    generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[];
+    /**
+     * TODO - very similar to generateModsForEquipment
+     * @param sessionId session id
+     * @param weapon Weapon to add mods to
+     * @param modPool pool of compatible mods to attach to gun
+     * @param weaponParentId parentId of weapon
+     * @param parentTemplate
+     * @param modSpawnChances
+     * @param ammoTpl ammo tpl to use when generating magazines/cartridges
+     * @param botRole role of bot weapon is generated for
+     * @returns Weapon with mods
+     */
+    generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[];
+    /**
+     * Generate a pool of mods for this bots mod type if bot has values inside `randomisedWeaponModSlots` array found in bot.json/equipment[botrole]
+     * @param allowedMods Mods to be added to mod pool
+     * @param botEquipBlacklist blacklist of items not allowed to be added to mod pool
+     * @param modSlot Slot to generate mods for
+     * @param itemModPool base mod pool to replace values of
+     */
+    protected generateDynamicModPool(allowedMods: string[], botEquipBlacklist: EquipmentFilterDetails, modSlot: string, itemModPool: Record<string, string[]>): void;
+    /**
+     * Check if the specific item type on the weapon has reached the set limit
+     * @param modTpl item to check is limited
+     * @param currentCount current number of this item on gun
+     * @param maxLimit mod limit allowed
+     * @param botRole role of bot we're checking weapon of
+     * @returns true if limit reached
+     */
+    protected weaponModLimitReached(modTpl: string, currentCount: {
+        count: number;
+    }, maxLimit: number, botRole: string): boolean;
+    /**
+     * log errors if mod is not valid for a slot
+     * @param modTpl
+     * @param found
+     * @param itemSlot
+     * @param modTemplate
+     * @param modSlot
+     * @param parentTemplate
+     * @returns true if valid
+     */
+    protected isModValidForSlot(modTpl: string, found: boolean, itemSlot: Slot, modTemplate: ITemplateItem, modSlot: string, parentTemplate: ITemplateItem): boolean;
+    /**
+     * Create a mod item with parameters as properties
+     * @param modId _id
+     * @param modTpl _tpl
+     * @param parentId parentId
+     * @param modSlot slotId
+     * @param modTemplate Used to add additional properites in the upd object
+     * @returns Item object
+     */
+    protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item;
     /**
      * Is this magazine cylinder related (revolvers and grenade launchers)
      * @param magazineParentName the name of the magazines parent
@@ -62,11 +131,11 @@ export declare class BotGeneratorHelper {
      * Those magazines (e.g. 60dc519adf4c47305f6d410d) have a "Cartridges" entry with a _max_count=0.
      * Ammo is not put into the magazine directly but assigned to the magazine's slots: The "camora_xxx" slots.
      * This function is a helper called by generateModsForItem for mods with parent type "CylinderMagazine"
-     *
-     * @param {object}      items               The items where the CylinderMagazine's camora are appended to
-     * @param {object}      modPool             modPool which should include available cartrigdes
-     * @param {string}      parentId            The CylinderMagazine's UID
-     * @param {object}      parentTemplate      The CylinderMagazine's template
+     * @param items The items where the CylinderMagazine's camora are appended to
+     * @param modPool modPool which should include available cartrigdes
+     * @param parentId The CylinderMagazine's UID
+     * @param parentTemplate The CylinderMagazine's template
+     * @returns
      */
     protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void;
     /**
@@ -75,6 +144,13 @@ export declare class BotGeneratorHelper {
      * @returns string array of shells fro luitple camora sources
      */
     protected mergeCamoraPoolsTogether(camorasWithShells: Record<string, string[]>): string[];
+    /**
+     * Adds properties to an item
+     * e.g. Repairable / HasHinge / Foldable / MaxDurability
+     * @param itemTemplate
+     * @param botRole Used by weapons to randomise the durability values
+     * @returns Item Upd object with extra properties
+     */
     generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): {
         upd?: Upd;
     };
@@ -93,12 +169,6 @@ export declare class BotGeneratorHelper {
      */
     protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable;
     protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string;
-    /**
-     * Sort by spawn chance, highest to lowest, higher is more common
-     * @param unsortedModArray String array to sort
-     * @returns Sorted string array
-     */
-    protected sortModArray(unsortedModArray: string[]): string[];
     /**
      * Can an item be added to an item without issue
      * @param items
@@ -117,8 +187,15 @@ export declare class BotGeneratorHelper {
      * @returns a `boolean` indicating item was added
      */
     addItemWithChildrenToEquipmentSlot(equipmentSlots: string[], parentId: string, parentTpl: string, itemWithChildren: Item[], inventory: PmcInventory): boolean;
+    /**
+     * is the provided item allowed inside a container
+     * @param slot location item wants to be placed in
+     * @param itemTpl item being placed
+     * @returns true if allowed
+     */
     protected itemAllowedInContainer(slot: Grid, itemTpl: string): boolean;
 }
+/** TODO - move into own class */
 export declare class ExhaustableArray<T> {
     private itemPool;
     private randomUtil;
diff --git a/TypeScript/9RouterHooks/types/helpers/HideoutHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/HideoutHelper.d.ts
index 36e4009..7495a6a 100644
--- a/TypeScript/9RouterHooks/types/helpers/HideoutHelper.d.ts
+++ b/TypeScript/9RouterHooks/types/helpers/HideoutHelper.d.ts
@@ -44,14 +44,72 @@ export declare class HideoutHelper {
     initProduction(recipeId: string, productionTime: number): Production;
     isProductionType(productive: Productive): productive is Production;
     applyPlayerUpgradesBonuses(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * TODO:
+     * After looking at the skills there doesnt seem to be a configuration per skill to boost
+     * the XP gain PER skill. I THINK you should be able to put the variable "SkillProgress" (just like health has it)
+     * and be able to tune the skill gain PER skill, but I havent tested it and Im not sure!
+     * @param pmcData
+     * @param bonus
+     */
     protected applySkillXPBoost(pmcData: IPmcData, bonus: StageBonus): void;
+    /**
+     * Process a players hideout, update areas that use resources + increment production timers
+     * @param sessionID Session id
+     */
     updatePlayerHideout(sessionID: string): void;
+    /**
+     * Update progress timer for water collector
+     * @param pmcData profile to update
+     * @param productionId id of water collection production to update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateWaterCollectorProductionTimer(pmcData: IPmcData, productionId: string, hideoutProperties: {
+        btcFarmCGs?: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Iterate over productions and update their progress timers
+     * @param pmcData Profile to check for productions and update
+     * @param hideoutProperties Hideout properties
+     */
+    protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
+    /**
+     * Update progress timer for scav case
+     * @param pmcData Profile to update
+     * @param productionId Id of scav case production to update
+     */
+    protected updateScavCaseProductionTimer(pmcData: IPmcData, productionId: string): void;
+    /**
+     * Iterate over hideout areas that use resources (fuel/filters etc) and update associated values
+     * @param sessionID Session id
+     * @param pmcData Profile to update areas of
+     * @param hideoutProperties hideout properties
+     */
+    protected updateAreasWithResources(sessionID: string, pmcData: IPmcData, hideoutProperties: {
+        btcFarmCGs: number;
+        isGeneratorOn: boolean;
+        waterCollectorHasFilter: boolean;
+    }): void;
     protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
     protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
-    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): HideoutArea;
-    protected updateWaterFilters(waterFilterArea: HideoutArea, pwProd: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
+    protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData): void;
+    /**
+     * Adjust water filter objects resourceValue or delete when they reach 0 resource
+     * @param waterFilterArea water filter area to update
+     * @param production production object
+     * @param isGeneratorOn is generatory enabled
+     * @param pmcData Player profile
+     * @returns Updated HideoutArea object
+     */
+    protected updateWaterFilters(waterFilterArea: HideoutArea, production: Production, isGeneratorOn: boolean, pmcData: IPmcData): HideoutArea;
     protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
-    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): HideoutArea;
+    protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData): void;
     protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
     protected getBTCSlots(pmcData: IPmcData): number;
     protected getManagementSkillsSlots(): number;
diff --git a/TypeScript/9RouterHooks/types/helpers/InRaidHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/InRaidHelper.d.ts
index b382e30..962df38 100644
--- a/TypeScript/9RouterHooks/types/helpers/InRaidHelper.d.ts
+++ b/TypeScript/9RouterHooks/types/helpers/InRaidHelper.d.ts
@@ -18,18 +18,6 @@ export declare class InRaidHelper {
     protected paymentHelper: PaymentHelper;
     protected profileFixerService: ProfileFixerService;
     constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper, profileFixerService: ProfileFixerService);
-    /**
-     * Reset the SPT inraid property stored in a profile to 'none'
-     * @param sessionID Session id
-     */
-    protected removePlayer(sessionID: string): void;
-    /**
-     * Some maps have one-time-use keys (e.g. Labs
-     * Remove the relevant key from an inventory based on the post-raid request data passed in
-     * @param offraidData post-raid data
-     * @param sessionID Session id
-     */
-    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
     /**
      * Check an array of items and add an upd object to money items with a stack count of 1
      * Single stack money items have no upd object and thus no StackObjectsCount, causing issues
@@ -54,6 +42,18 @@ export declare class InRaidHelper {
      * @returns Reset profile object
      */
     updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData;
+    /**
+     * Some maps have one-time-use keys (e.g. Labs
+     * Remove the relevant key from an inventory based on the post-raid request data passed in
+     * @param offraidData post-raid data
+     * @param sessionID Session id
+     */
+    protected removeMapAccessKey(offraidData: ISaveProgressRequestData, sessionID: string): void;
+    /**
+     * Set the SPT inraid location Profile property to 'none'
+     * @param sessionID Session id
+     */
+    protected setPlayerInRaidLocationStatusToNone(sessionID: string): void;
     /**
      * Adds SpawnedInSession property to items found in a raid
      * Removes SpawnedInSession for non-scav players if item was taken into raid with SpawnedInSession = true
@@ -95,5 +95,10 @@ export declare class InRaidHelper {
      * @returns true if item is kept after death
      */
     isItemKeptAfterDeath(slotId: string): boolean;
+    /**
+     * Return the equipped items from a players inventory
+     * @param items Players inventory to search through
+     * @returns an array of equipped items
+     */
     getPlayerGear(items: Item[]): Item[];
 }
diff --git a/TypeScript/9RouterHooks/types/helpers/ItemHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/ItemHelper.d.ts
index 1701c62..de10892 100644
--- a/TypeScript/9RouterHooks/types/helpers/ItemHelper.d.ts
+++ b/TypeScript/9RouterHooks/types/helpers/ItemHelper.d.ts
@@ -1,35 +1,30 @@
 import { IPmcData } from "../models/eft/common/IPmcData";
 import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item, Repairable } from "../models/eft/common/tables/IItem";
+import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase";
 import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
+import { MathUtil } from "../utils/MathUtil";
+import { ObjectId } from "../utils/ObjectId";
+import { RandomUtil } from "../utils/RandomUtil";
 declare class ItemHelper {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
     protected jsonUtil: JsonUtil;
+    protected randomUtil: RandomUtil;
+    protected objectId: ObjectId;
+    protected mathUtil: MathUtil;
     protected databaseServer: DatabaseServer;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer);
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer);
     /**
      * Checks if a id is a valid item. Valid meaning that it's an item that be stored in stash
      * @param       {string}    tpl       the template id / tpl
      * @returns                             boolean; true for items that may be in player posession and not quest items
      */
     isValidItem(tpl: string, invalidBaseTypes?: string[]): boolean;
-    /**
-     * Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
-     * or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
-     * @param {*} tpl template id of item to check
-     * @returns boolean: true if item is valid reward
-     */
-    isValidRewardItem(tpl: string): boolean;
-    /**
-     * Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
-     * @returns     a list of rewardable items [[_tpl, itemTemplate],...]
-     */
-    getRewardableItems(): [string, ITemplateItem][];
     /**
      * Check if the tpl / template Id provided is a descendent of the baseclass
      *
@@ -196,6 +191,22 @@ declare class ItemHelper {
      * @returns ItemSize object (width and height)
      */
     getItemSize(items: Item[], rootItemId: string): ItemHelper.ItemSize;
+    /**
+     * Get a random cartridge from an items Filter property
+     * @param item
+     * @returns
+     */
+    getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string;
+    createRandomMagCartridges(magTemplate: ITemplateItem, parentId: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>, caliber?: string): Item;
+    protected getRandomValidCaliber(magTemplate: ITemplateItem): string;
+    protected drawAmmoTpl(caliber: string, staticAmmoDist: Record<string, IStaticAmmoDetails[]>): string;
+    createCartidges(parentId: string, ammoTpl: string, stackCount: number): Item;
+    /**
+     * Get the size of a stack, return 1 if no stack object count property found
+     * @param item Item to get stack size of
+     * @returns size of stack
+     */
+    getItemStackSize(item: Item): number;
 }
 declare namespace ItemHelper {
     interface ItemSize {
diff --git a/TypeScript/9RouterHooks/types/helpers/ProfileHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/ProfileHelper.d.ts
index 9d4ff98..9c6560a 100644
--- a/TypeScript/9RouterHooks/types/helpers/ProfileHelper.d.ts
+++ b/TypeScript/9RouterHooks/types/helpers/ProfileHelper.d.ts
@@ -24,6 +24,19 @@ export declare class ProfileHelper {
     constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, fenceService: FenceService);
     resetProfileQuestCondition(sessionID: string, conditionId: string): void;
     getCompleteProfile(sessionID: string): IPmcData[];
+    /**
+     * Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
+     * Server saves the post-raid changes prior to the xp screen getting the profile, this results in the xp screen using
+     * the now updated profile values as a base, meaning it shows x2 xp gained
+     * Instead, clone the post-raid profile (so we dont alter its values), apply the pre-raid xp values to the cloned objects and return
+     * Delete snapshot of pre-raid profile prior to returning profile data
+     * @param sessionId Session id
+     * @param output pmc and scav profiles array
+     * @param pmcProfile post-raid pmc profile
+     * @param scavProfile post-raid scav profile
+     * @returns updated profile array
+     */
+    protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
     isNicknameTaken(info: IValidateNicknameRequestData, sessionID: string): boolean;
     /**
      * Add experience to a PMC inside the players profile
diff --git a/TypeScript/9RouterHooks/types/helpers/QuestHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/QuestHelper.d.ts
index 32e55ec..d66d150 100644
--- a/TypeScript/9RouterHooks/types/helpers/QuestHelper.d.ts
+++ b/TypeScript/9RouterHooks/types/helpers/QuestHelper.d.ts
@@ -36,11 +36,20 @@ export declare class QuestHelper {
     protected configServer: ConfigServer;
     protected questConfig: IQuestConfig;
     constructor(logger: ILogger, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, itemHelper: ItemHelper, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, localeService: LocaleService, ragfairServerHelper: RagfairServerHelper, dialogueHelper: DialogueHelper, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, traderHelper: TraderHelper, configServer: ConfigServer);
-    questStatus(pmcData: IPmcData, questID: string): QuestStatus;
     /**
-     * returns true is the condition is satisfied
+    * Get status of a quest by quest id
+    * @param pmcData Profile to search
+    * @param questID Quest id to look up
+    * @returns QuestStauts enum
+    */
+    getQuestStatus(pmcData: IPmcData, questID: string): QuestStatus;
+    /**
+     * returns true is the level condition is satisfied
+     * @param playerLevel Players level
+     * @param condition Quest condition
+     * @returns true if player level is greater than or equal to quest
      */
-    evaluateLevel(pmcProfile: IPmcData, cond: AvailableForConditions): boolean;
+    doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean;
     getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[];
     /**
      * Increase skill points of a skill on player profile
diff --git a/TypeScript/9RouterHooks/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/RagfairOfferHelper.d.ts
index 8d03bee..e9d72ca 100644
--- a/TypeScript/9RouterHooks/types/helpers/RagfairOfferHelper.d.ts
+++ b/TypeScript/9RouterHooks/types/helpers/RagfairOfferHelper.d.ts
@@ -22,12 +22,14 @@ import { ProfileHelper } from "./ProfileHelper";
 import { RagfairHelper } from "./RagfairHelper";
 import { RagfairServerHelper } from "./RagfairServerHelper";
 import { RagfairSortHelper } from "./RagfairSortHelper";
+import { TraderHelper } from "./TraderHelper";
 export declare class RagfairOfferHelper {
     protected logger: ILogger;
     protected timeUtil: TimeUtil;
     protected hashUtil: HashUtil;
     protected itemEventRouter: ItemEventRouter;
     protected databaseServer: DatabaseServer;
+    protected traderHelper: TraderHelper;
     protected saveServer: SaveServer;
     protected dialogueHelper: DialogueHelper;
     protected itemHelper: ItemHelper;
@@ -43,10 +45,10 @@ export declare class RagfairOfferHelper {
     protected static goodSoldTemplate: string;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
-    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
+    constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemEventRouter: ItemEventRouter, databaseServer: DatabaseServer, traderHelper: TraderHelper, saveServer: SaveServer, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, localeService: LocaleService, configServer: ConfigServer);
     getValidOffers(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
     getOffersForBuild(info: ISearchRequestData, itemsToAdd: string[], assorts: Record<string, ITraderAssort>, pmcProfile: IPmcData): IRagfairOffer[];
-    processOffers(sessionID: string): boolean;
+    processOffersOnProfile(sessionID: string): boolean;
     protected getProfileOffers(sessionID: string): IRagfairOffer[];
     protected deleteOfferByOfferId(sessionID: string, offerId: string): void;
     protected completeOffer(sessionID: string, offer: IRagfairOffer, boughtAmount: number): IItemEventRouterResponse;
diff --git a/TypeScript/9RouterHooks/types/helpers/RagfairSellHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/RagfairSellHelper.d.ts
index 6ec004a..91b8a20 100644
--- a/TypeScript/9RouterHooks/types/helpers/RagfairSellHelper.d.ts
+++ b/TypeScript/9RouterHooks/types/helpers/RagfairSellHelper.d.ts
@@ -11,6 +11,12 @@ export declare class RagfairSellHelper {
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     constructor(logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer);
-    calculateSellChance(baseChance: number, offerPrice: number, requirementsPriceInRub: number): number;
-    rollForSale(sellChance: number, count: number): SellResult[];
+    calculateSellChance(baseChancePercent: number, offerPriceRub: number, playerListedPriceRub: number): number;
+    /**
+     * Determine if the offer being listed will be sold
+     * @param sellChancePercent chance item will sell
+     * @param itemSellCount count of items to sell
+     * @returns Array of purchases of item(s) lsited
+     */
+    rollForSale(sellChancePercent: number, itemSellCount: number): SellResult[];
 }
diff --git a/TypeScript/9RouterHooks/types/helpers/RagfairServerHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/RagfairServerHelper.d.ts
index e4939d1..a03cdda 100644
--- a/TypeScript/9RouterHooks/types/helpers/RagfairServerHelper.d.ts
+++ b/TypeScript/9RouterHooks/types/helpers/RagfairServerHelper.d.ts
@@ -6,6 +6,7 @@ import { IRagfairConfig } from "../models/spt/config/IRagfairConfig";
 import { ConfigServer } from "../servers/ConfigServer";
 import { DatabaseServer } from "../servers/DatabaseServer";
 import { SaveServer } from "../servers/SaveServer";
+import { ItemFilterService } from "../services/ItemFilterService";
 import { LocaleService } from "../services/LocaleService";
 import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
@@ -13,6 +14,9 @@ import { RandomUtil } from "../utils/RandomUtil";
 import { DialogueHelper } from "./DialogueHelper";
 import { ItemHelper } from "./ItemHelper";
 import { ProfileHelper } from "./ProfileHelper";
+/**
+ * Helper class for common ragfair server actions
+ */
 export declare class RagfairServerHelper {
     protected randomUtil: RandomUtil;
     protected hashUtil: HashUtil;
@@ -23,11 +27,12 @@ export declare class RagfairServerHelper {
     protected localeService: LocaleService;
     protected dialogueHelper: DialogueHelper;
     protected jsonUtil: JsonUtil;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected ragfairConfig: IRagfairConfig;
     protected questConfig: IQuestConfig;
     protected static goodsReturnedTemplate: string;
-    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, configServer: ConfigServer);
+    constructor(randomUtil: RandomUtil, hashUtil: HashUtil, saveServer: SaveServer, databaseServer: DatabaseServer, profileHelper: ProfileHelper, itemHelper: ItemHelper, localeService: LocaleService, dialogueHelper: DialogueHelper, jsonUtil: JsonUtil, itemFilterService: ItemFilterService, configServer: ConfigServer);
     /**
      * Is item valid / on blacklist / quest item
      * @param itemDetails
diff --git a/TypeScript/9RouterHooks/types/helpers/TradeHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/TradeHelper.d.ts
index 975062b..7ab9768 100644
--- a/TypeScript/9RouterHooks/types/helpers/TradeHelper.d.ts
+++ b/TypeScript/9RouterHooks/types/helpers/TradeHelper.d.ts
@@ -39,6 +39,12 @@ export declare class TradeHelper {
      * @returns
      */
     sellItem(pmcData: IPmcData, body: IProcessSellTradeRequestData, sessionID: string): IItemEventRouterResponse;
+    /**
+     * Increment the assorts buy count by number of items purchased
+     * Show error on screen if player attepts to buy more than what the buy max allows
+     * @param assortBeingPurchased assort being bought
+     * @param itemsPurchasedCount number of items being bought
+     */
     protected incrementAssortBuyCount(assortBeingPurchased: Item, itemsPurchasedCount: number): void;
     protected checkPurchaseIsWithinTraderItemLimit(assortBeingPurchased: Item, assortId: string, count: number): void;
 }
diff --git a/TypeScript/9RouterHooks/types/helpers/TraderAssortHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/TraderAssortHelper.d.ts
index 677dd66..025efd6 100644
--- a/TypeScript/9RouterHooks/types/helpers/TraderAssortHelper.d.ts
+++ b/TypeScript/9RouterHooks/types/helpers/TraderAssortHelper.d.ts
@@ -1,6 +1,5 @@
 import { RagfairAssortGenerator } from "../generators/RagfairAssortGenerator";
 import { RagfairOfferGenerator } from "../generators/RagfairOfferGenerator";
-import { IPmcData } from "../models/eft/common/IPmcData";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ITrader, ITraderAssort } from "../models/eft/common/tables/ITrader";
 import { ITraderConfig } from "../models/spt/config/ITraderConfig";
@@ -41,12 +40,7 @@ export declare class TraderAssortHelper {
      * @param traderId traders id
      * @returns a traders' assorts
      */
-    getAssort(sessionId: string, traderId: string): ITraderAssort;
-    /**
-     * if the fence assorts have expired, re-generate them
-     * @param pmcProfile Players profile
-     */
-    refreshFenceAssortIfExpired(pmcProfile: IPmcData): void;
+    getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort;
     /**
      * Reset a traders assorts and move nextResupply value to future
      * Flag trader as needing a flea offer reset to be picked up by flea update() function
diff --git a/TypeScript/9RouterHooks/types/helpers/TraderHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/TraderHelper.d.ts
index 6bda5cd..0dc93e8 100644
--- a/TypeScript/9RouterHooks/types/helpers/TraderHelper.d.ts
+++ b/TypeScript/9RouterHooks/types/helpers/TraderHelper.d.ts
@@ -65,7 +65,7 @@ export declare class TraderHelper {
      * @param item
      * @returns boolean
      */
-    protected isWeaponAndBelowTraderBuyDurability(traderID: string, item: Item): boolean;
+    protected isWeaponBelowTraderBuyDurability(traderID: string, item: Item): boolean;
     /**
      * Get the price of an item and all of its attached children
      * Take into account bonuses/adjsutments e.g. discounts
diff --git a/TypeScript/9RouterHooks/types/models/eft/common/tables/ITemplateItem.d.ts b/TypeScript/9RouterHooks/types/models/eft/common/tables/ITemplateItem.d.ts
index 23a1a14..6b2fa8f 100644
--- a/TypeScript/9RouterHooks/types/models/eft/common/tables/ITemplateItem.d.ts
+++ b/TypeScript/9RouterHooks/types/models/eft/common/tables/ITemplateItem.d.ts
@@ -34,6 +34,7 @@ export interface Props {
     LootExperience?: number;
     ExamineExperience?: number;
     HideEntrails?: boolean;
+    InsuranceDisabled?: boolean;
     RepairCost?: number;
     RepairSpeed?: number;
     ExtraSizeLeft?: number;
@@ -206,6 +207,7 @@ export interface Props {
     IsOneoff?: boolean;
     MustBoltBeOpennedForExternalReload?: boolean;
     MustBoltBeOpennedForInternalReload?: boolean;
+    NoFiremodeOnBoltcatch?: boolean;
     BoltAction?: boolean;
     HipAccuracyRestorationDelay?: number;
     HipAccuracyRestorationSpeed?: number;
diff --git a/TypeScript/9RouterHooks/types/models/eft/common/tables/ITrader.d.ts b/TypeScript/9RouterHooks/types/models/eft/common/tables/ITrader.d.ts
index a84f5af..37b2d61 100644
--- a/TypeScript/9RouterHooks/types/models/eft/common/tables/ITrader.d.ts
+++ b/TypeScript/9RouterHooks/types/models/eft/common/tables/ITrader.d.ts
@@ -67,6 +67,7 @@ export interface IBarterScheme {
     count: number;
     _tpl: string;
     onlyFunctional?: boolean;
+    sptQuestLocked?: boolean;
 }
 export interface ISuit {
     _id: string;
diff --git a/TypeScript/9RouterHooks/types/models/eft/ragfair/IRagfairOffer.d.ts b/TypeScript/9RouterHooks/types/models/eft/ragfair/IRagfairOffer.d.ts
index 63f655e..141b605 100644
--- a/TypeScript/9RouterHooks/types/models/eft/ragfair/IRagfairOffer.d.ts
+++ b/TypeScript/9RouterHooks/types/models/eft/ragfair/IRagfairOffer.d.ts
@@ -15,6 +15,8 @@ export interface IRagfairOffer {
     name?: string;
     shortName?: string;
     loyaltyLevel: number;
+    buyRestrictionMax?: number;
+    buyRestrictionCurrent?: number;
     locked: boolean;
     unlimitedCount: boolean;
     summaryCost: number;
diff --git a/TypeScript/9RouterHooks/types/models/enums/AmmoTypes.d.ts b/TypeScript/9RouterHooks/types/models/enums/AmmoTypes.d.ts
index b52ddcf..254b410 100644
--- a/TypeScript/9RouterHooks/types/models/enums/AmmoTypes.d.ts
+++ b/TypeScript/9RouterHooks/types/models/enums/AmmoTypes.d.ts
@@ -23,7 +23,7 @@ export declare enum Ammo762x54 {
     BT_GZH = "5e023d34e8a400319a28ed44",
     BS_GZH = "5e023d48186a883be655e551"
 }
-export declare enum Ammo338Lapua {
+export declare enum Ammo86x70 {
     TAC_X = "5fc382b6d6fa9c00c571bbc3",
     UCW = "5fc382c1016cce60e8341b20",
     AP = "5fc382a9d724d907e2077dab",
@@ -85,13 +85,13 @@ export declare enum Ammo9x21 {
     PE_GZH = "5a26ac06c4a282000c5a90a8",
     BT_GZH = "5a26ac0ec4a28200741e1e18"
 }
-export declare enum Ammo357Mag {
+export declare enum Ammo9x33R {
     FMJ = "62330b3ed4dc74626d570b95",
     HOLLOW_POINT = "62330bfadc5883093563729b",
     SOFT_POINT = "62330c40bdd19b369e1e53d1",
     JACKET_HP = "62330c18744e5e31df12f516"
 }
-export declare enum Ammo45ACP {
+export declare enum Ammo1143x23ACP {
     MATCH_FMJ = "5e81f423763d9f754677bf2e",
     HYDRA_SHOK = "5efb0fc6aeb21837e749c801",
     LASERMATCH_FMJ = "5efb0d4f4bc50b58e81710f3",
@@ -126,7 +126,7 @@ export declare enum Ammo556x45 {
     MK_318_MOD_0_SOST = "60194943740c5d77f6705eea",
     SSA_AP = "601949593ae8f707c4608daa"
 }
-export declare enum Ammo300Blackout {
+export declare enum Ammo762x35 {
     M62_TRACER = "619636be6db0f2477964e710",
     BCP_FMJ = "5fbe3ffdf8b6a877a729ea82",
     AP = "5fd20ff893a8961fc660a954",
diff --git a/TypeScript/9RouterHooks/types/models/enums/BaseClasses.d.ts b/TypeScript/9RouterHooks/types/models/enums/BaseClasses.d.ts
index e733bca..37c1398 100644
--- a/TypeScript/9RouterHooks/types/models/enums/BaseClasses.d.ts
+++ b/TypeScript/9RouterHooks/types/models/enums/BaseClasses.d.ts
@@ -68,6 +68,7 @@ export declare enum BaseClasses {
     ASSAULT_SCOPE = "55818add4bdc2d5b648b456f",
     REFLEX_SIGHT = "55818ad54bdc2ddc698b4569",
     TACTICAL_COMBO = "55818b164bdc2ddc698b456c",
+    FLASHLIGHT = "55818b084bdc2d5b648b4571",
     MAGAZINE = "5448bc234bdc2d3c308b4569",
     LIGHT_LASER = "55818b0e4bdc2dde698b456e",
     FLASH_HIDER = "550aa4bf4bdc2dd6348b456b",
diff --git a/TypeScript/9RouterHooks/types/models/enums/ConfigTypes.d.ts b/TypeScript/9RouterHooks/types/models/enums/ConfigTypes.d.ts
index 61d6f99..468ece5 100644
--- a/TypeScript/9RouterHooks/types/models/enums/ConfigTypes.d.ts
+++ b/TypeScript/9RouterHooks/types/models/enums/ConfigTypes.d.ts
@@ -8,6 +8,7 @@ export declare enum ConfigTypes {
     IN_RAID = "aki-inraid",
     INSURANCE = "aki-insurance",
     INVENTORY = "aki-inventory",
+    ITEM = "aki-item",
     LOCALE = "aki-locale",
     LOCATION = "aki-location",
     MATCH = "aki-match",
diff --git a/TypeScript/9RouterHooks/types/models/enums/ELocationName.d.ts b/TypeScript/9RouterHooks/types/models/enums/ELocationName.d.ts
index b56cc08..7ae7caa 100644
--- a/TypeScript/9RouterHooks/types/models/enums/ELocationName.d.ts
+++ b/TypeScript/9RouterHooks/types/models/enums/ELocationName.d.ts
@@ -1,5 +1,6 @@
 export declare enum ELocationName {
     FACTORY_DAY = "factory4_day",
+    FACTORY_NIGHT = "factory4_night",
     BIGMAP = "bigmap",
     WOODS = "Woods",
     SHORELINE = "Shoreline",
diff --git a/TypeScript/9RouterHooks/types/models/spt/config/IAirdropConfig.d.ts b/TypeScript/9RouterHooks/types/models/spt/config/IAirdropConfig.d.ts
index f4aee89..8b7fffc 100644
--- a/TypeScript/9RouterHooks/types/models/spt/config/IAirdropConfig.d.ts
+++ b/TypeScript/9RouterHooks/types/models/spt/config/IAirdropConfig.d.ts
@@ -1,14 +1,14 @@
+import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
 export interface IAirdropConfig extends IBaseConfig {
     kind: "aki-airdrop";
     airdropChancePercent: AirdropChancePercent;
-    airdropMinOpenHeight: number;
-    airdropMaxOpenHeight: number;
     planeMinFlyHeight: number;
     planeMaxFlyHeight: number;
     planeVolume: number;
     airdropMinStartTimeSeconds: number;
     airdropMaxStartTimeSeconds: number;
+    loot: AirdropLoot;
 }
 export interface AirdropChancePercent {
     bigmap: number;
@@ -18,3 +18,11 @@ export interface AirdropChancePercent {
     interchange: number;
     reserve: number;
 }
+export interface AirdropLoot {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/9RouterHooks/types/models/spt/config/IBotConfig.d.ts b/TypeScript/9RouterHooks/types/models/spt/config/IBotConfig.d.ts
index e171087..f15fa73 100644
--- a/TypeScript/9RouterHooks/types/models/spt/config/IBotConfig.d.ts
+++ b/TypeScript/9RouterHooks/types/models/spt/config/IBotConfig.d.ts
@@ -1,17 +1,31 @@
 import { MinMax } from "../../common/MinMax";
 import { IBaseConfig } from "./IBaseConfig";
+import { IBotDurability } from "./IBotDurability";
+import { IPmcConfig } from "./IPmcConfig";
 export interface IBotConfig extends IBaseConfig {
     kind: "aki-bot";
+    /** How many variants of each bot should be generated on raid start */
     presetBatch: PresetBatch;
+    /** What bot types should be classified as bosses */
     bosses: string[];
-    durability: Durability;
+    /** Control weapon/armor durability min/max values for each bot type */
+    durability: IBotDurability;
+    /** Control the weighting of how expensive an average loot item is on a PMC or Scav */
     lootNValue: LootNvalue;
+    /** Control what bots are added to a bots revenge list key: bottype, value: bottypes to revenge on seeing their death */
     revenge: Record<string, string[]>;
-    pmc: PmcConfig;
+    /** PMC bot specific config settings */
+    pmc: IPmcConfig;
+    /** Control how many items are allowed to spawn on a bot
+     * key: bottype, value: <key: itemTpl: value: max item count> */
     itemSpawnLimits: Record<string, Record<string, number>>;
-    equipment: Record<string, Equipment>;
+    /** Blacklist/whitelist items on a bot */
+    equipment: Record<string, EquipmentFilters>;
+    /** Show a bots botType value after their name */
     showTypeInNickname: boolean;
+    /** Max number of bots that can be spawned in a raid at any one time */
     maxBotCap: number;
+    /** How many stacks of secret ammo should a bot have in its bot secure container */
     secureContainerAmmoStackCount: number;
 }
 export interface PresetBatch {
@@ -44,79 +58,22 @@ export interface PresetBatch {
     test: number;
     exUsec: number;
 }
-export interface Durability {
-    default: DefaultDurability;
-    pmc: PmcDurability;
-    boss: BotDurability;
-    follower: BotDurability;
-    assault: BotDurability;
-    cursedassault: BotDurability;
-    marksman: BotDurability;
-    pmcbot: BotDurability;
-    exusec: BotDurability;
-    sectantpriest: BotDurability;
-    sectantwarrior: BotDurability;
-}
-export interface DefaultDurability {
-    armor: DefaultArmor;
-    weapon: WeaponDurability;
-}
-export interface DefaultArmor {
-    maxDelta: number;
-    minDelta: number;
-}
-export interface WeaponDurability {
-    lowestMax: number;
-    highestMax: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface PmcDurability {
-    armor: PmcDurabilityArmor;
-    weapon: WeaponDurability;
-}
-export interface PmcDurabilityArmor {
-    lowestMaxPercent: number;
-    highestMaxPercent: number;
-    maxDelta: number;
-    minDelta: number;
-}
-export interface BotDurability {
-    armor: ArmorDurability;
-    weapon: WeaponDurability;
-}
-export interface ArmorDurability {
-    maxDelta: number;
-    minDelta: number;
-}
 export interface LootNvalue {
     scav: number;
     pmc: number;
 }
-export interface PmcConfig {
-    dynamicLoot: PmcDynamicLoot;
-    difficulty: string;
-    looseWeaponInBackpackChancePercent: number;
-    looseWeaponInBackpackLootMinMax: MinMax;
-    isUsec: number;
-    chanceSameSideIsHostilePercent: number;
-    usecType: string;
-    bearType: string;
-    maxBackpackLootTotalRub: number;
-    maxPocketLootTotalRub: number;
-    maxVestLootTotalRub: number;
-    convertIntoPmcChance: Record<string, MinMax>;
-    enemyTypes: string[];
-}
-export interface PmcDynamicLoot {
-    whitelist: string[];
-    blacklist: string[];
-    moneyStackLimits: Record<string, number>;
-}
-export interface Equipment {
+export interface EquipmentFilters {
+    weaponModLimits: ModLimits;
+    randomisedWeaponModSlots?: string[];
     blacklist: EquipmentFilterDetails[];
     whitelist: EquipmentFilterDetails[];
 }
+export interface ModLimits {
+    /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */
+    scopeLimit?: number;
+    /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */
+    lightLaserLimit?: number;
+}
 export interface EquipmentFilterDetails {
     levelRange: MinMax;
     equipment: Record<string, string[]>;
diff --git a/TypeScript/9RouterHooks/types/models/spt/config/IBotDurability.d.ts b/TypeScript/9RouterHooks/types/models/spt/config/IBotDurability.d.ts
new file mode 100644
index 0000000..38a47cc
--- /dev/null
+++ b/TypeScript/9RouterHooks/types/models/spt/config/IBotDurability.d.ts
@@ -0,0 +1,47 @@
+export interface IBotDurability {
+    default: DefaultDurability;
+    pmc: PmcDurability;
+    boss: BotDurability;
+    follower: BotDurability;
+    assault: BotDurability;
+    cursedassault: BotDurability;
+    marksman: BotDurability;
+    pmcbot: BotDurability;
+    exusec: BotDurability;
+    gifter: BotDurability;
+    sectantpriest: BotDurability;
+    sectantwarrior: BotDurability;
+}
+/** Durability values to be used when a more specific bot type cant be found */
+export interface DefaultDurability {
+    armor: DefaultArmor;
+    weapon: WeaponDurability;
+}
+export interface DefaultArmor {
+    maxDelta: number;
+    minDelta: number;
+}
+export interface WeaponDurability {
+    lowestMax: number;
+    highestMax: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface PmcDurability {
+    armor: PmcDurabilityArmor;
+    weapon: WeaponDurability;
+}
+export interface PmcDurabilityArmor {
+    lowestMaxPercent: number;
+    highestMaxPercent: number;
+    maxDelta: number;
+    minDelta: number;
+}
+export interface BotDurability {
+    armor: ArmorDurability;
+    weapon: WeaponDurability;
+}
+export interface ArmorDurability {
+    maxDelta: number;
+    minDelta: number;
+}
diff --git a/TypeScript/9RouterHooks/types/models/spt/config/IItemConfig.d.ts b/TypeScript/9RouterHooks/types/models/spt/config/IItemConfig.d.ts
new file mode 100644
index 0000000..5ecccc2
--- /dev/null
+++ b/TypeScript/9RouterHooks/types/models/spt/config/IItemConfig.d.ts
@@ -0,0 +1,5 @@
+import { IBaseConfig } from "./IBaseConfig";
+export interface IItemConfig extends IBaseConfig {
+    kind: "aki-item";
+    blacklist: string[];
+}
diff --git a/TypeScript/9RouterHooks/types/models/spt/config/IPmcConfig.d.ts b/TypeScript/9RouterHooks/types/models/spt/config/IPmcConfig.d.ts
new file mode 100644
index 0000000..655b58d
--- /dev/null
+++ b/TypeScript/9RouterHooks/types/models/spt/config/IPmcConfig.d.ts
@@ -0,0 +1,22 @@
+import { MinMax } from "../../common/MinMax";
+export interface IPmcConfig {
+    dynamicLoot: DynamicLoot;
+    useDifficultyOverride: boolean;
+    difficulty: string;
+    looseWeaponInBackpackChancePercent: number;
+    looseWeaponInBackpackLootMinMax: MinMax;
+    isUsec: number;
+    chanceSameSideIsHostilePercent: number;
+    usecType: string;
+    bearType: string;
+    maxBackpackLootTotalRub: number;
+    maxPocketLootTotalRub: number;
+    maxVestLootTotalRub: number;
+    convertIntoPmcChance: Record<string, MinMax>;
+    enemyTypes: string[];
+}
+export interface DynamicLoot {
+    whitelist: string[];
+    blacklist: string[];
+    moneyStackLimits: Record<string, number>;
+}
diff --git a/TypeScript/9RouterHooks/types/models/spt/config/IQuestConfig.d.ts b/TypeScript/9RouterHooks/types/models/spt/config/IQuestConfig.d.ts
index be4a97b..45c9aae 100644
--- a/TypeScript/9RouterHooks/types/models/spt/config/IQuestConfig.d.ts
+++ b/TypeScript/9RouterHooks/types/models/spt/config/IQuestConfig.d.ts
@@ -4,6 +4,8 @@ export interface IQuestConfig extends IBaseConfig {
     kind: "aki-quest";
     redeemTime: number;
     repeatableQuests: IRepeatableQuestConfig[];
+    bearOnlyQuests: string[];
+    usecOnlyQuests: string[];
 }
 export interface IRepeatableQuestConfig {
     name: string;
@@ -15,6 +17,10 @@ export interface IRepeatableQuestConfig {
     locations: Record<ELocationName, string[]>;
     traderWhitelist: ITraderWhitelist[];
     questConfig: IQuestConfig;
+    /** Item base types to block when generating rewards */
+    rewardBaseTypeBlacklist: string[];
+    /** Item tplIds to ignore when generating rewards */
+    rewardBlacklist: string[];
 }
 export interface IRewardScaling {
     levels: number[];
diff --git a/TypeScript/9RouterHooks/types/models/spt/config/IRagfairConfig.d.ts b/TypeScript/9RouterHooks/types/models/spt/config/IRagfairConfig.d.ts
index 6369eda..3088717 100644
--- a/TypeScript/9RouterHooks/types/models/spt/config/IRagfairConfig.d.ts
+++ b/TypeScript/9RouterHooks/types/models/spt/config/IRagfairConfig.d.ts
@@ -12,6 +12,7 @@ export interface Sell {
     chance: Chance;
     time: Time;
     reputation: Reputation;
+    simulatedSellHours: number;
 }
 export interface Chance {
     base: number;
diff --git a/TypeScript/9RouterHooks/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/9RouterHooks/types/models/spt/config/ITraderConfig.d.ts
index c8e8044..6b1c1e3 100644
--- a/TypeScript/9RouterHooks/types/models/spt/config/ITraderConfig.d.ts
+++ b/TypeScript/9RouterHooks/types/models/spt/config/ITraderConfig.d.ts
@@ -12,8 +12,10 @@ export interface UpdateTime {
     seconds: number;
 }
 export interface FenceConfig {
+    partialRefreshTimeSeconds: number;
+    partialRefreshChangePercent: number;
     assortSize: number;
-    maxPresetsCount: number;
+    maxPresetsPercent: number;
     presetPriceMult: number;
     blacklist: string[];
 }
diff --git a/TypeScript/9RouterHooks/types/models/spt/services/LootItem.d.ts b/TypeScript/9RouterHooks/types/models/spt/services/LootItem.d.ts
new file mode 100644
index 0000000..2838472
--- /dev/null
+++ b/TypeScript/9RouterHooks/types/models/spt/services/LootItem.d.ts
@@ -0,0 +1,5 @@
+export declare class LootItem {
+    tpl: string;
+    isPreset: boolean;
+    stackCount: number;
+}
diff --git a/TypeScript/9RouterHooks/types/models/spt/services/LootRequest.d.ts b/TypeScript/9RouterHooks/types/models/spt/services/LootRequest.d.ts
new file mode 100644
index 0000000..64b4e5c
--- /dev/null
+++ b/TypeScript/9RouterHooks/types/models/spt/services/LootRequest.d.ts
@@ -0,0 +1,9 @@
+import { MinMax } from "../../common/MinMax";
+export declare class LootRequest {
+    presetCount: MinMax;
+    itemCount: MinMax;
+    itemBlacklist: string[];
+    itemTypeWhitelist: string[];
+    /** key: item base type: value: max count */
+    itemLimits: Record<string, number>;
+}
diff --git a/TypeScript/9RouterHooks/types/services/BotEquipmentFilterService.d.ts b/TypeScript/9RouterHooks/types/services/BotEquipmentFilterService.d.ts
index e49645b..632f961 100644
--- a/TypeScript/9RouterHooks/types/services/BotEquipmentFilterService.d.ts
+++ b/TypeScript/9RouterHooks/types/services/BotEquipmentFilterService.d.ts
@@ -1,12 +1,12 @@
 import { IBotType } from "../models/eft/common/tables/IBotType";
-import { Equipment, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
+import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig";
 import { ILogger } from "../models/spt/utils/ILogger";
 import { ConfigServer } from "../servers/ConfigServer";
 export declare class BotEquipmentFilterService {
     protected logger: ILogger;
     protected configServer: ConfigServer;
     protected botConfig: IBotConfig;
-    protected botEquipmentFilterlists: Record<string, Equipment>;
+    protected botEquipmentFilterlists: Record<string, EquipmentFilters>;
     constructor(logger: ILogger, configServer: ConfigServer);
     /**
      * Filter a bots data to exclude equipment and cartridges defines in the botConfig
@@ -22,7 +22,7 @@ export declare class BotEquipmentFilterService {
      * @param playerLevel Level of the player
      * @returns EquipmentBlacklistDetails object
      */
-    protected getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
+    getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails;
     /**
      * Get the whitelist for a specific bot type that's within the players level
      * @param botRole Bot type
diff --git a/TypeScript/9RouterHooks/types/services/FenceService.d.ts b/TypeScript/9RouterHooks/types/services/FenceService.d.ts
index c9e325e..c940507 100644
--- a/TypeScript/9RouterHooks/types/services/FenceService.d.ts
+++ b/TypeScript/9RouterHooks/types/services/FenceService.d.ts
@@ -12,6 +12,11 @@ import { HashUtil } from "../utils/HashUtil";
 import { JsonUtil } from "../utils/JsonUtil";
 import { RandomUtil } from "../utils/RandomUtil";
 import { TimeUtil } from "../utils/TimeUtil";
+import { ItemFilterService } from "./ItemFilterService";
+/**
+ * Handle actions surrounding Fence
+ * e.g. generating or refreshing assorts / get next refresh time
+ */
 export declare class FenceService {
     protected logger: ILogger;
     protected hashUtil: HashUtil;
@@ -22,18 +27,64 @@ export declare class FenceService {
     protected handbookHelper: HandbookHelper;
     protected itemHelper: ItemHelper;
     protected presetHelper: PresetHelper;
+    protected itemFilterService: ItemFilterService;
     protected configServer: ConfigServer;
     protected fenceAssort: ITraderAssort;
     protected traderConfig: ITraderConfig;
-    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, configServer: ConfigServer);
+    protected nextMiniRefreshTimestamp: number;
+    constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, itemFilterService: ItemFilterService, configServer: ConfigServer);
     protected setFenceAssort(fenceAssort: ITraderAssort): void;
-    getFenceAssorts(): ITraderAssort;
+    /**
+     * Get assorts player can purchase
+     * Adjust prices based on fence level of player
+     * @param pmcProfile Player profile
+     * @returns ITraderAssort
+     */
+    getFenceAssorts(pmcProfile: IPmcData): ITraderAssort;
+    /**
+     * Get fence assorts with no price adjustments based on fence rep
+     * @returns ITraderAssort
+     */
+    getRawFenceAssorts(): ITraderAssort;
+    /**
+     * Does fence need to perform a partial refresh because its passed the refresh timer defined in trader.json
+     * @returns true if it needs a partial refresh
+     */
+    needsPartialRefresh(): boolean;
+    /**
+     * Replace a percentage of fence assorts with freshly generated items
+     */
+    performPartialRefresh(): void;
+    /**
+     * Choose an item (not mod) at random and remove from assorts
+     */
+    protected removeRandomItemFromAssorts(): void;
+    /**
+     * Get an integer rounded count of items to replace based on percentrage from traderConfig value
+     * @param totalItemCount total item count
+     * @returns rounded int of items to replace
+     */
+    protected getCountOfItemsToReplace(totalItemCount: number): number;
     /**
      * Get the count of items fence offers
      * @returns number
      */
     getOfferCount(): number;
-    generateFenceAssortCache(pmcData: IPmcData): void;
+    /**
+     * Create a trader assort for fence
+     */
+    generateFenceAssortCache(): void;
+    /**
+     * Create skeleton to hold assort items
+     * @returns ITraderAssort object
+     */
+    protected createBaseTraderAssortItem(): ITraderAssort;
+    /**
+     * Hydrate result parameter object with generated assorts
+     * @param assortCount Number of assorts to generate
+     * @param assorts object to add assorts to
+     */
+    protected createAssorts(assortCount: number, assorts: ITraderAssort): void;
     /**
      * Get the next update timestamp for fence
      * @returns future timestamp
@@ -44,11 +95,14 @@ export declare class FenceService {
      */
     protected getFenceRefreshTime(): number;
     /**
-     * Get the fence level the passed in profile has
+     * Get fence level the passed in profile has
      * @param pmcData Player profile
-     * @returns FenceLevel
+     * @returns FenceLevel object
      */
     getFenceInfo(pmcData: IPmcData): FenceLevel;
+    /**
+     * Remove an assort from fence by id
+     * @param assortIdToRemove assort id to remove from fence assorts
+     */
     removeFenceOffer(assortIdToRemove: string): void;
-    updateFenceOffers(pmcData: IPmcData): void;
 }
diff --git a/TypeScript/9RouterHooks/types/services/InsuranceService.d.ts b/TypeScript/9RouterHooks/types/services/InsuranceService.d.ts
index 171bf10..6be8a2f 100644
--- a/TypeScript/9RouterHooks/types/services/InsuranceService.d.ts
+++ b/TypeScript/9RouterHooks/types/services/InsuranceService.d.ts
@@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
 import { SecureContainerHelper } from "../helpers/SecureContainerHelper";
 import { TraderHelper } from "../helpers/TraderHelper";
 import { IPmcData } from "../models/eft/common/IPmcData";
+import { InsuredItem } from "../models/eft/common/tables/IBotBase";
 import { Item } from "../models/eft/common/tables/IItem";
 import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData";
 import { IInsuranceConfig } from "../models/spt/config/IInsuranceConfig";
@@ -44,8 +45,22 @@ export declare class InsuranceService {
      * @param mapId Id of the map player died/exited that caused the insurance to be issued on
      */
     sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void;
+    /**
+     * Store lost gear post-raid inside profile
+     * @param pmcData player profile to store gear in
+     * @param offraidData post-raid request object
+     * @param preRaidGear gear player wore prior to raid
+     * @param sessionID Session id
+     */
     storeLostGear(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
     storeInsuredItemsForReturn(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string): void;
-    protected addGearToSend(pmcData: IPmcData, insuredItem: any, actualItem: any, sessionID: string): any;
+    /**
+     * Add gear item to InsuredItems array in player profile
+     * @param pmcData profile to store item in
+     * @param insuredItem Item to store in profile
+     * @param actualItem item to store
+     * @param sessionID Session id
+     */
+    protected addGearToSend(pmcData: IPmcData, insuredItem: InsuredItem, actualItem: Item, sessionID: string): void;
     getPremium(pmcData: IPmcData, inventoryItem: Item, traderId: string): number;
 }
diff --git a/TypeScript/9RouterHooks/types/services/ItemFilterService.d.ts b/TypeScript/9RouterHooks/types/services/ItemFilterService.d.ts
new file mode 100644
index 0000000..c9c8ef3
--- /dev/null
+++ b/TypeScript/9RouterHooks/types/services/ItemFilterService.d.ts
@@ -0,0 +1,24 @@
+import { IItemConfig } from "../models/spt/config/IItemConfig";
+import { ILogger } from "../models/spt/utils/ILogger";
+import { ConfigServer } from "../servers/ConfigServer";
+import { DatabaseServer } from "../servers/DatabaseServer";
+/** Centralise the handling of blacklisting items, uses blacklist found in config/item.json */
+export declare class ItemFilterService {
+    protected logger: ILogger;
+    protected databaseServer: DatabaseServer;
+    protected configServer: ConfigServer;
+    protected blacklist: string[];
+    protected itemConfig: IItemConfig;
+    constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer);
+    /**
+     * Check if the provided template id is blacklisted in config/item.json
+     * @param tpl template id
+     * @returns true if blacklisted
+     */
+    isItemBlacklisted(tpl: string): boolean;
+    /**
+     * Return every template id blacklisted in config/item.json
+     * @returns string array of blacklisted tempalte ids
+     */
+    getBlacklistedItems(): string[];
+}
diff --git a/TypeScript/9RouterHooks/types/services/ProfileFixerService.d.ts b/TypeScript/9RouterHooks/types/services/ProfileFixerService.d.ts
index ed1dec7..9cb5a38 100644
--- a/TypeScript/9RouterHooks/types/services/ProfileFixerService.d.ts
+++ b/TypeScript/9RouterHooks/types/services/ProfileFixerService.d.ts
@@ -45,6 +45,11 @@ export declare class ProfileFixerService {
      * @param pmcProfile Profile to find and remove slots from
      */
     protected removeResourcesFromSlotsInHideoutWithoutLocationIndexValue(pmcProfile: IPmcData): void;
+    /**
+     * Hideout slots need to be in a specific order, locationIndex in ascending order
+     * @param pmcProfile profile to edit
+     */
+    protected reorderHideoutAreasWithResouceInputs(pmcProfile: IPmcData): void;
     /**
      * add in objects equal to the number of slots
      * @param areaType area to check
diff --git a/TypeScript/9RouterHooks/types/utils/HashUtil.d.ts b/TypeScript/9RouterHooks/types/utils/HashUtil.d.ts
index bacbf2a..a8500e1 100644
--- a/TypeScript/9RouterHooks/types/utils/HashUtil.d.ts
+++ b/TypeScript/9RouterHooks/types/utils/HashUtil.d.ts
@@ -4,8 +4,18 @@ import { TimeUtil } from "./TimeUtil";
 export declare class HashUtil {
     protected timeUtil: TimeUtil;
     constructor(timeUtil: TimeUtil);
+    /**
+     * Create a 24 character id using the sha256 algorithm + current timestamp
+     * @returns 24 character hash
+     */
     generate(): string;
     generateMd5ForData(data: string): string;
     generateSha1ForData(data: string): string;
+    /**
+     * Create a hash for the data parameter
+     * @param algorithm algorithm to use to hash
+     * @param data data to be hashed
+     * @returns hash value
+     */
     generateHashForData(algorithm: string, data: crypto.BinaryLike): string;
 }
diff --git a/TypeScript/9RouterHooks/types/utils/RandomUtil.d.ts b/TypeScript/9RouterHooks/types/utils/RandomUtil.d.ts
index c24dd60..e35d21f 100644
--- a/TypeScript/9RouterHooks/types/utils/RandomUtil.d.ts
+++ b/TypeScript/9RouterHooks/types/utils/RandomUtil.d.ts
@@ -150,4 +150,10 @@ export declare class RandomUtil {
      */
     drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[];
     getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number;
+    /**
+     * Fisher-Yates shuffle an array
+     * @param array Array to shuffle
+     * @returns Shuffled array
+     */
+    shuffle<T>(array: Array<T>): Array<T>;
 }
diff --git a/TypeScript/9RouterHooks/types/utils/TimeUtil.d.ts b/TypeScript/9RouterHooks/types/utils/TimeUtil.d.ts
index f437f8a..1367e26 100644
--- a/TypeScript/9RouterHooks/types/utils/TimeUtil.d.ts
+++ b/TypeScript/9RouterHooks/types/utils/TimeUtil.d.ts
@@ -1,3 +1,6 @@
+/**
+ * Utility class to handle time related problems
+ */
 export declare class TimeUtil {
     static readonly oneHourAsSeconds = 3600;
     formatTime(date: Date): string;
@@ -19,4 +22,10 @@ export declare class TimeUtil {
      * @returns current date in format: 00.00.0000 (dd.mm.yyyy)
      */
     getDateMailFormat(): string;
+    /**
+     * Convert hours into seconds
+     * @param hours hours to convert to seconds
+     * @returns number
+     */
+    getHoursAsSeconds(hours: number): number;
 }