def Attachments(self: Any, weapons: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the loot/iw8_*_*_attachment_ids.csv XAssets.""" files: List[str] = Utility.GetMatchingFiles(self, f"{self.iXAssets}/loot/", "csv", None, "_attachment_ids") for weapon in weapons: if (wAltId := weapon.get("altId")) is None: continue for file in files: filePartial: str = file.split("\\")[-1].split(".")[0] if filePartial.startswith(wAltId + "_") is False: continue table: List[Dict[str, Any]] = Utility.ReadCSV( self, file, AttachmentIDs) if table is None: continue for attachment in weapon.get("attachments"): for entry in table: if entry.get("ref") is None: continue elif attachment.get("id") != entry.get("index"): continue attachment["altId"] = entry.get("ref")
def Table(self: Any, maps: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the mp/mapinfo.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/mp/mapinfo.csv", MapInfo) if table is None: return maps for entry in table: maps.append({ "altId": entry.get("ref"), "name": self.localize.get(entry.get("name")), "night": bool(entry.get("isNightMap")), "raytracing": True if entry.get("dxr") == "DXR_ON" else False, "image": entry.get("loadingImage"), "hidden": bool(entry.get("hideInMapSelect")), }) return maps
def IDs(self: Any, features: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the loot/feature_ids.csv XAsset.""" ids: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/loot/feature_ids.csv", FeatureIDs) if ids is None: return features for entry in ids: features.append({ "id": entry.get("index"), "altId": entry.get("ref"), "name": None if (n := self.localize.get(entry.get("name"))) is None else n.replace("&&1 ", ""), "description": self.localize.get(entry.get("desc")), "type": self.ModernWarfare.GetLootType(entry.get("index")), "rarity": self.ModernWarfare.GetLootRarity(entry.get("quality")), "image": None if (i := entry.get("hudImage")) == "white" else i, "background": "ui_loot_bg_generic", })
def Table(self: Any, streaks: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the mp/killstreaktable.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/mp/killstreaktable.csv", KillstreakTable) if table is None: return streaks for streak in streaks: for entry in table: if streak.get("altId") != entry.get("ref"): continue streak["name"] = self.localize.get(entry.get("name")) streak["description"] = self.localize.get(entry.get("desc")) streak["category"] = (None if (c := entry.get("streakType")) is None else c.title()) streak["costKills"] = entry.get("kills") streak["costScore"] = entry.get("scoreCost") streak["hidden"] = not bool(entry.get("showInMenus")) streak["image"] = (None if (img := entry.get("progressionImage")) == "placeholder_x" else img) streak["icon"] = entry.get("tabletImage") streak["video"] = entry.get("tutorialVideo")
def IDs(self: Any, items: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the loot/special_ids.csv XAsset.""" ids: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/loot/special_ids.csv", SpecialIDs ) if ids is None: return items for entry in ids: items.append( { "id": entry.get("id"), "altId": entry.get("ref"), "name": self.localize.get(entry.get("name")), "type": self.ModernWarfare.GetLootType(entry.get("id")), "rarity": self.ModernWarfare.GetLootRarity(entry.get("rarity")), "season": self.ModernWarfare.GetLootSeason(entry.get("license")), "image": entry.get("image"), "background": "ui_loot_bg_generic", } ) return items
def IDs(self: Any, tracks: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the loot/vehicle_track_ids.csv XAsset.""" ids: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/loot/vehicle_track_ids.csv", VehicleTrackIDs ) if ids is None: return tracks for entry in ids: tracks.append( { "id": entry.get("id"), "altId": entry.get("ref"), "name": None, "type": self.ModernWarfare.GetLootType(entry.get("id")), "rarity": self.ModernWarfare.GetLootRarity(entry.get("rarity")), "season": self.ModernWarfare.GetLootSeason(entry.get("license")), "unlock": None, "hidden": None, "image": "ui_vehicle_battle_track", "background": "ui_loot_bg_vehicle_horn", } ) return tracks
def IDs(self: Any, consumables: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the loot/consumable_ids.csv XAsset.""" ids: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/loot/consumable_ids.csv", ConsumableIDs) if ids is None: return consumables for entry in ids: consumables.append({ "id": entry.get("id"), "altId": entry.get("ref"), "name": self.localize.get(entry.get("name")), "description": self.localize.get(entry.get("duration")), "type": self.ModernWarfare.GetLootType(entry.get("id")), "rarity": self.ModernWarfare.GetLootRarity(entry.get("quality")), "image": None if ((i := entry.get("image")) == "placeholder_x") or (i == "white") else i, "background": "ui_loot_bg_generic", })
def IDs(self: Any, charms: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the loot/weapon_charm_ids.csv XAsset.""" ids: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/loot/weapon_charm_ids.csv", WeaponCharmIDs) if ids is None: return charms for entry in ids: charms.append({ "id": entry.get("id"), "altId": entry.get("ref"), "name": None, "flavor": self.localize.get("STORE_FLAVOR/" + entry.get("ref").upper() + "_FLAVOR"), "type": self.ModernWarfare.GetLootType(entry.get("id")), "rarity": self.ModernWarfare.GetLootRarity(entry.get("rarity")), "season": self.ModernWarfare.GetLootSeason(entry.get("license")), "hidden": None, "image": None, "background": "ui_loot_bg_charm", }) return charms
def IDs(self: Any, camos: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the loot/camo_ids.csv XAsset.""" ids: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/loot/camo_ids.csv", CamoIDs) if ids is None: return camos for entry in ids: camos.append({ "id": entry.get("id"), "altId": entry.get("ref"), "name": None, "category": None, "type": self.ModernWarfare.GetLootType(entry.get("id")), "rarity": self.ModernWarfare.GetLootRarity(entry.get("rarity")), "season": self.ModernWarfare.GetLootSeason(entry.get("license")), "hidden": None, "image": None, }) return camos
def Table(self: Any, challenges: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the mp/petwatchturbotable.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/mp/petwatchturbotable.csv", PetWatchTurboTable) if table is None: return challenges for entry in table: challenges.append({ "altId": entry.get("ref"), "phase": entry.get("phaseNum"), "description": self.localize.get(entry.get("challengeDesc")), "phaseTime": entry.get("phaseTime"), "maxBonusTime": entry.get("bonusTimeMax"), "charmAltId": None if (cid := entry.get("charmID")) is None else f"cos_{cid}", })
def IDs(self: Any, equipment: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the loot/equipment_ids.csv XAsset.""" ids: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/loot/equipment_ids.csv", EquipmentIDs ) if ids is None: return equipment for entry in ids: equipment.append( { "id": entry.get("id"), "altId": entry.get("ref"), "name": None, "description": None, "type": self.ModernWarfare.GetLootType(entry.get("id")), "rarity": self.ModernWarfare.GetLootRarity(entry.get("rarity")), "image": None, "icon": None, "video": None, } ) return equipment
def IDs(self: Any, stickers: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the loot/sticker_ids.csv XAsset.""" ids: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/loot/sticker_ids.csv", StickerIDs) if ids is None: return stickers for entry in ids: stickers.append({ "id": entry.get("id"), "altId": entry.get("ref"), "name": None, "type": self.ModernWarfare.GetLootType(entry.get("id")), "rarity": self.ModernWarfare.GetLootRarity(entry.get("rarity")), "season": self.ModernWarfare.GetLootSeason(entry.get("license")), "hidden": None, "image": None, "background": "ui_loot_bg_sticker", }) return stickers
def Table(self: Any, skins: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the operatorskins.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/operatorskins.csv", OperatorSkins) if table is None: return skins for skin in skins: for entry in table: if skin.get("altId") != entry.get("ref"): continue skin["name"] = self.localize.get(entry.get("name")) skin["description"] = self.localize.get(entry.get("desc")) skin["image"] = entry.get("lootImage") if bool(entry.get("isGlobal")) is True: skin["operatorId"] = self.ModernWarfare.GetOperatorID( "universal_base_ref") skin["operatorAltId"] = "universal_base_ref" else: ref: str = entry.get("operatorRef") skin["operatorId"] = self.ModernWarfare.GetOperatorID(ref) skin["operatorAltId"] = ref return skins
def Table(self: Any, challenges: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the gun_unlock_challenges.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/gun_unlock_challenges.csv", GunUnlockChallenges) if table is None: return challenges for entry in table: if (amount := entry.get("amount")) is not None: amount: Optional[Union[str, int]] = f"{amount:,}" challenges.append({ "id": entry.get("id"), "altId": entry.get("ref"), "name": self.localize.get(entry.get("name")), "description": self.localize.get(entry.get("desc")).replace("&&1", amount), "weaponId": entry.get("loot"), })
def FactionTable(self: Any, operators: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the mp/factiontable.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/mp/factiontable.csv", FactionTable) if table is None: return operators for operator in operators: for entry in table: if operator.get("branch") != entry.get("ref"): continue operator["branch"] = self.localize.get(entry.get("name")) if operator.get("altId").startswith("default_"): # This is a (temporary?) workaround as Infinity Ward does # not distinguish the two Mil-Sim branches in the factiontable, # thus resulting in each incorrectly belonging to Coalition. if (faction := operator.get("faction")) == 0: operator["faction"] = self.localize.get( "LUA_MENU/THE_WEST") elif faction == 1: operator["faction"] = self.localize.get( "LUA_MENU/THE_EAST") else: operator["faction"] = None else: operator["faction"] = self.localize.get( entry.get("superFactionName"))
def Table(self: Any, sources: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the mp/itemsourcetable.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/mp/itemsourcetable.csv", ItemSourceTable) if table is None: return sources for entry in table: sources.append({ "id": entry.get("marketPlaceID"), "altId": entry.get("refName"), "type": self.ModernWarfare.GetLootType(entry.get("marketPlaceID")), "source": entry.get("gameSourceID"), "iw8mp": bool(entry.get("equippableIW8MP")), "wz": bool(entry.get("equippableWZ")), "t9": bool(entry.get("equippableT9")), "s4": bool(entry.get("equippableS4")), }) return sources
def Table(self: Any, types: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the mp/gametypestable.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/mp/gametypestable.csv", GameTypesTable) if table is None: return types for entry in table: types.append({ "altId": entry.get("ref"), "name": self.localize.get(entry.get("name")), "description": self.localize.get(entry.get("desc")), "hints": { "global": None if (val := entry.get("objectiveHintAttackers")) != entry.get("objectiveHintDefenders") else self.localize.get(val), "offense": None if (val := entry.get("objectiveHintAttackers")) == entry.get("objectiveHintDefenders") else self.localize.get(val), "defense": None if entry.get("objectiveHintAttackers") == (val := entry.get("objectiveHintDefenders")) else self.localize.get(val), }, "category": self.ModernWarfare.GetGameTypeCategory(entry.get("category")), "teamBased": bool(entry.get("teamBased")), "roundBased": bool(entry.get("isRoundBased")), "teamChoice": bool(entry.get("teamChoice")), "classChoice": bool(entry.get("classChoice")), "scaleXP": entry.get("xpScalar"), "scaleWeaponXP": entry.get("weaponXPScalar"), "icons": { "core": entry.get("image"), "hardcore": entry.get("hardcoreImage"), "realism": entry.get("realismImage"), "cdl": entry.get("CDLImage"), }, "hidden": bool(entry.get("hideInUI")), })
def Table(self: Any, challenges: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the misc_challenges.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/misc_challenges.csv", MiscChallenges) if table is None: return challenges for entry in table: if (d := self.localize.get(entry.get("desc"))) is not None: desc: Optional[str] = d elif (d := self.localize.get(entry.get("detailDesc"))) is not None: desc = d
def Table(self: Any, challenges: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the br_weekly_challenges.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/br_weekly_challenges.csv", BRWeeklyChallenges) if table is None: return challenges for entry in table: altId: str = entry.get("ref") season: int = int(altId.split("season_")[1].split("_")[0]) week: int = int(altId.split("week_")[1].split("_")[0]) if (amount := entry.get("amount")) is not None: amount: Optional[Union[str, int]] = f"{amount:,}" challenges.append({ "id": entry.get("id"), "altId": altId, "name": self.localize.get(entry.get("name")), "description": self.localize.get(entry.get("desc")).replace("&&1", amount), "start": Utility.PrettyTime(self, entry.get("start")), "season": season, "week": week, "xp": entry.get("xp"), "rewards": [], }) if (l := entry.get("loot")) is not None: challenges[-1]["rewards"].append({ "id": l, "type": self.ModernWarfare.GetLootType(l) })
def IDs(self: Any, weapons: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the loot/weapon_ids.csv XAsset.""" ids: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/loot/weapon_ids.csv", WeaponIDs) if ids is None: return weapons for weapon in weapons: for entry in ids: if weapon.get("altId") != entry.get("baseRef"): continue if entry.get("quality") == 0: weapon["id"] = entry.get("index") weapon["type"] = self.ModernWarfare.GetLootType( entry.get("index")) weapon["rarity"] = self.ModernWarfare.GetLootRarity( entry.get("quality")) weapon["season"] = self.ModernWarfare.GetLootSeason( entry.get("license")) else: weapon["variants"].append({ "id": entry.get("index"), "altId": entry.get("variantRef"), "name": None, "flavor": None, "type": self.ModernWarfare.GetLootType(entry.get("index")), "rarity": self.ModernWarfare.GetLootRarity(entry.get("quality")), "season": self.ModernWarfare.GetLootSeason(entry.get("license")), "tracers": None, "dismemberment": None, "image": None, }) return weapons
def Table(self: Any, challenges: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the sticker_book_challenges.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/sticker_book_challenges.csv", StickerBookChallenges) if table is None: return challenges for entry in table: challenges.append({ "altId": entry.get("ref"), "name": self.localize.get(entry.get("name")), "description": self.localize.get(entry.get("desc")), "category": entry.get("categoryType"), "rewards": [], }) amounts: List[int] = Utility.GetCSVArray(self, entry.get("amount"), int) loot: List[int] = Utility.GetCSVArray(self, entry.get("loot"), int) xp: List[int] = Utility.GetCSVArray(self, entry.get("XPReward"), int) for a, l, x in zip(amounts, loot, xp): challenges[-1]["rewards"].append({ "amount": a, "xp": x, "id": l, "type": self.ModernWarfare.GetLootType(l), }) if (desc := challenges[-1].get("description")) is not None: challenges[-1]["description"] = desc.replace( "&&1", str(amounts[-1]))
def Variants(self: Any, weapons: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the mp/gunsmith/*_*_variants.csv XAssets.""" files: List[str] = Utility.GetMatchingFiles( self, f"{self.iXAssets}/mp/gunsmith/", "csv", None, "_variants") for weapon in weapons: if (altId := weapon.get("altId")) is None: continue for file in files: refPartial: str = altId.replace("iw8_", "") + "_" filePartial: str = file.split("\\")[-1].split(".")[0] if filePartial.startswith(refPartial) is False: continue table: List[Dict[str, Any]] = Utility.ReadCSV( self, file, WeaponVariants) if table is None: continue for entry in table: if entry.get("variantID") == 0: weapon["image"] = entry.get("image") for variant in weapon.get("variants", []): if variant.get("altId") != entry.get("ref"): continue flavor: str = variant.get("altId").replace( "iw8_", "").replace("variant_", "") variant["name"] = self.localize.get(entry.get("name")) variant["flavor"] = self.localize.get( f"WEAPON_FLAVOR/{flavor.upper()}_FLAVOR") variant["tracers"] = self.ModernWarfare.GetAttribute( entry.get("tracerColor")) variant[ "dismemberment"] = self.ModernWarfare.GetAttribute( entry.get("dismembermentEnabled")) variant["image"] = entry.get("image")
def Table(self: Any, operators: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the operators.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/operators.csv", OperatorsTable) if table is None: return operators for operator in operators: for entry in table: if operator.get("altId") != entry.get("ref"): continue operator["name"] = self.localize.get(entry.get("name")).title() operator["description"] = self.localize.get( entry.get("background")) operator["faction"] = entry.get("superFaction") operator["branch"] = entry.get("factionRef") operator["branchIcon"] = entry.get("factionIcon") operator["thumbprint"] = entry.get("thumbprint") operator["launchOperator"] = bool( entry.get("isLaunchOperator")) operator["image"] = entry.get("icon") operator["video"] = (None if ((v := entry.get("introVideo")) is None) or (v.endswith("_placeholder")) else v) operator["hidden"] = bool(entry.get("hiddenWhenLocked")) operator["billets"] = [ { "label": self.localize.get("LUA_MENU/CITIZENSHIP"), "value": self.localize.get(entry.get("citizenship")), }, { "label": self.localize.get("LUA_MENU/FIRST_LANGUAGE"), "value": self.localize.get(entry.get("firstLanguage")), }, { "label": self.localize.get("LUA_MENU/STATUS"), "value": self.localize.get(entry.get("status")), }, ]
def Table(self: Any, charms: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the mp/weaponcharmtable.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/mp/weaponcharmtable.csv", WeaponCharmTable) if table is None: return charms for charm in charms: for entry in table: if charm.get("altId") != entry.get("ref"): continue charm["name"] = self.localize.get(entry.get("name")) charm["hidden"] = bool(entry.get("hideInUI")) charm["image"] = entry.get("image") return charms
def IntelTable(self: Any, missions: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the mp/intel_challenges.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/mp/intel_challenges.csv", IntelChallenges) if table is None: return missions for mission in missions: for objective in mission.get("objectives", []): for entry in table: if objective.get("altId") != entry.get("ref"): continue objective["image"] = entry.get("image") return missions
def Table(self: Any, cards: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the mp/callingcards.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/mp/callingcards.csv", CallingCardsTable) if table is None: return cards for card in cards: for entry in table: if card.get("altId") != entry.get("ref"): continue card["name"] = self.localize.get(entry.get("name")) card["hidden"] = bool(entry.get("hideInUI")) card["image"] = entry.get("image") return cards
def Table(self: Any, sprays: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the mp/spraytable.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/mp/spraytable.csv", SprayTable) if table is None: return sprays for spray in sprays: for entry in table: if spray.get("altId") != entry.get("ref"): continue spray["name"] = self.localize.get(entry.get("name")) spray["hidden"] = bool(entry.get("hideInUI")) spray["image"] = entry.get("image") return sprays
def Table(self: Any, challenges: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the elder_challenges.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/elder_challenges.csv", ElderChallenges) if table is None: return challenges for entry in table: if (ref := entry.get("ref")).startswith("ch_elder_s"): season: Optional[int] = int( ref.split("ch_elder_s")[1].split("_")[0]) else: season: Optional[int] = None if (amount := entry.get("amount")) is not None: amount: Optional[Union[str, int]] = f"{amount:,}"
def Progression(self, weapons: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the mp/gunsmith/*_*_progression.csv XAssets.""" files: List[str] = Utility.GetMatchingFiles( self, f"{self.iXAssets}/mp/gunsmith/", "csv", None, "_progression") for weapon in weapons: if (wAltId := weapon.get("altId")) is None: continue for file in files: refPartial: str = wAltId.replace("iw8_", "") + "_" filePartial: str = file.split("\\")[-1].split(".")[0] if filePartial.startswith(refPartial) is False: continue table: List[Dict[str, Any]] = Utility.ReadCSV( self, file, WeaponProgression) if table is None: continue for entry in table: if entry.get("lootID") is None: continue elif entry.get("level") < 0: continue weapon["attachments"].append({ "id": entry.get("lootID"), "altId": None, "name": None, "description": None, "type": None, "unlock": entry.get("level"), "image": None, "background": "ui_loot_bg_generic", "attributes": [], "statBars": [], })
def Table(self: Any, emblems: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Compile the mp/emblemtable.csv XAsset.""" table: List[Dict[str, Any]] = Utility.ReadCSV( self, f"{self.iXAssets}/mp/emblemtable.csv", EmblemTable ) if table is None: return emblems for emblem in emblems: for entry in table: if emblem.get("altId") != entry.get("ref"): continue emblem["name"] = self.localize.get(entry.get("name")) emblem["hidden"] = bool(entry.get("hideInUI")) emblem["image"] = entry.get("image") return emblems