diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 0c7c41dcbc6c441c76efaf5427577f445a1366df..b2bc9d410464f581372e191dfff66f05f1a58198 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -244,3 +244,15 @@ bool LLAssetType::lookupIsAssetIDKnowable(EType asset_type)
 	}
 	return false;
 }
+
+std::vector<std::string> LLAssetType::getAssetTypeNames()
+{
+    std::vector<std::string> names;
+    const LLAssetDictionary& dict = LLAssetDictionary::instanceFast();
+    for (const auto& dict_pair : dict)
+    {
+        const AssetEntry* entry = dict_pair.second;
+        names.push_back(entry->mTypeName);
+    }
+    return names;
+}
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index 13a454a9eb3ac91faf49e8c3c7ede3a0662524ca..7c8ce9db68f01e163429abece5176cd1a2ec5a58 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -28,6 +28,7 @@
 #define LL_LLASSETTYPE_H
 
 #include <string>
+#include <vector>
 
 class LL_COMMON_API LLAssetType
 {
@@ -162,6 +163,8 @@ class LL_COMMON_API LLAssetType
 	static bool 				lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download
 	static bool 				lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer
 
+	static std::vector<std::string> getAssetTypeNames();
+
     static const std::string    BADLOOKUP;
 
 	LLAssetType() = delete;
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index dfcfd4a1efd05268657dc2b28d6cad425af6b1f0..00844507f4c0b975e4942db9f93e08949178c107 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -326,6 +326,7 @@ set(viewer_SOURCE_FILES
     llfloatermyscripts.cpp
     llfloatermyenvironment.cpp
     llfloaternamedesc.cpp
+    llfloaternewlocalinventory.cpp
     llfloaternotificationsconsole.cpp
     llfloaternotificationstabbed.cpp
     llfloateroutfitphotopreview.cpp
@@ -1027,6 +1028,7 @@ set(viewer_HEADER_FILES
     llfloatermyscripts.h
     llfloatermyenvironment.h
     llfloaternamedesc.h
+    llfloaternewlocalinventory.h
     llfloaternotificationsconsole.h
     llfloaternotificationstabbed.h
     llfloateroutfitphotopreview.h
diff --git a/indra/newview/alviewermenu.cpp b/indra/newview/alviewermenu.cpp
index 35cb04bf52447d23b2fca11effa1f353d4ba9bb9..005fd7ed45319db5322a2065b83df563130d75d3 100644
--- a/indra/newview/alviewermenu.cpp
+++ b/indra/newview/alviewermenu.cpp
@@ -230,8 +230,9 @@ namespace
 		return true;
 	}
 
-    bool is_powerful_wizard() {
-	    return gSavedSettings.getBOOL("AlchemyPowerfulWizard");
+    bool get_saved_setting(const LLSD& userdata)
+    {
+	    return gSavedSettings.getBOOL(userdata.asString());
     }
 
 	bool is_powerful_wizard_object()
@@ -414,11 +415,11 @@ namespace
 void ALViewerMenu::initialize_menus()
 {
 	LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar();
-    enable.add("Alchemy.PowerfulWizard", [](LLUICtrl* ctrl, const LLSD& param) { return is_powerful_wizard(); });
 	enable.add("Alchemy.PowerfulWizardObject", [](LLUICtrl* ctrl, const LLSD& param) { return is_powerful_wizard_object(); });
 	enable.add("Avatar.EnableManageEstate", [](LLUICtrl* ctrl, const LLSD& param) { return can_manage_avatar_estate(); });
 	enable.add("Avatar.EnableTeleportTo", [](LLUICtrl* ctrl, const LLSD& param) { return can_teleport_to(); });
 	enable.add("Object.EnableEditParticles", [](LLUICtrl* ctrl, const LLSD& param) { return enable_edit_particle_source(); });
+    enable.add("SavedSetting", [](LLUICtrl* ctrl, const LLSD& param) { return get_saved_setting(param); });
 
 	LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
 	commit.add("Avatar.CopyData",		[](LLUICtrl* ctrl, const LLSD& param) { avatar_copy_data(param); });
diff --git a/indra/newview/llfloaternewlocalinventory.cpp b/indra/newview/llfloaternewlocalinventory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c0386fe637b204c2c90424d14d778c6ef872ec25
--- /dev/null
+++ b/indra/newview/llfloaternewlocalinventory.cpp
@@ -0,0 +1,210 @@
+/**
+ * @file llfloaternewlocalinventory.cpp
+ * @brief Create local inventory item
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Cinder Roxley
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaternewlocalinventory.h"
+
+#include "llagent.h"
+#include "llbutton.h"
+#include "llcombobox.h"
+#include "llinventorymodel.h"
+#include "lllineeditor.h"
+#include "lluuid.h"
+#include "llviewerinventory.h"
+#include "llfloaterreg.h"
+#include "llpreviewgesture.h"
+
+LLUUID LLFloaterNewLocalInventory::sLastCreatorId(LLUUID::null);
+
+static void add_item(LLViewerInventoryItem* item);
+static void open_asset(LLUUID const& item_id);
+
+LLFloaterNewLocalInventory::LLFloaterNewLocalInventory(const LLSD& key)
+:   LLFloater(key)
+{ }
+
+BOOL LLFloaterNewLocalInventory::postBuild()
+{
+    getChild<LLLineEditor>("creator_id_line")->setText(LLUUID::null.asString());
+    getChild<LLLineEditor>("owner_id_line")->setText(gAgent.getID().asString());
+    getChild<LLLineEditor>("asset_id_line")->setText(LLUUID::null.asString());
+    getChild<LLLineEditor>("name_line")->setText(std::string(""));
+    getChild<LLLineEditor>("desc_line")->setText(std::string(""));
+    getChild<LLButton>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNewLocalInventory::onClickOK, this));
+
+    LLComboBox* combo = getChild<LLComboBox>("type_combo");
+    std::vector<std::string> type_names = LLAssetType::getAssetTypeNames();
+    for (auto const& name : type_names)
+    {
+        combo->add(name);
+    }
+
+    return TRUE;
+}
+
+void LLFloaterNewLocalInventory::onClickOK()
+{
+    LLUUID item_id;
+    item_id.generate();
+
+    std::string name       = getChild<LLLineEditor>("name_line")->getText();
+    std::string desc       = getChild<LLLineEditor>("desc_line")->getText();
+    LLUUID      asset_id   = LLUUID(getChild<LLLineEditor>("asset_id_line")->getText());
+    LLUUID      creator_id = LLUUID(getChild<LLLineEditor>("creator_id_line")->getText());
+    LLUUID      owner_id   = LLUUID(getChild<LLLineEditor>("owner_id_line")->getText());
+
+    LLAssetType::EType     type     = LLAssetType::lookup(getChild<LLUICtrl>("type_combo")->getValue().asString());
+    LLInventoryType::EType inv_type = LLInventoryType::IT_UNKNOWN;
+    switch (type)
+    {
+        case LLAssetType::AT_TEXTURE:
+        case LLAssetType::AT_TEXTURE_TGA:
+        case LLAssetType::AT_IMAGE_TGA:
+        case LLAssetType::AT_IMAGE_JPEG:
+            inv_type = LLInventoryType::IT_TEXTURE;
+            break;
+        case LLAssetType::AT_SOUND:
+        case LLAssetType::AT_SOUND_WAV:
+            inv_type = LLInventoryType::IT_SOUND;
+            break;
+        case LLAssetType::AT_CALLINGCARD:
+            inv_type = LLInventoryType::IT_CALLINGCARD;
+            break;
+        case LLAssetType::AT_LANDMARK:
+            inv_type = LLInventoryType::IT_LANDMARK;
+            break;
+        case LLAssetType::AT_SCRIPT:
+            inv_type = LLInventoryType::IT_LSL;
+            break;
+        case LLAssetType::AT_CLOTHING:
+            inv_type = LLInventoryType::IT_WEARABLE;
+            break;
+        case LLAssetType::AT_OBJECT:
+            inv_type = LLInventoryType::IT_OBJECT;
+            break;
+        case LLAssetType::AT_NOTECARD:
+            inv_type = LLInventoryType::IT_NOTECARD;
+            break;
+        case LLAssetType::AT_CATEGORY:
+            inv_type = LLInventoryType::IT_CATEGORY;
+            break;
+        case LLAssetType::AT_LSL_TEXT:
+        case LLAssetType::AT_LSL_BYTECODE:
+            inv_type = LLInventoryType::IT_LSL;
+            break;
+        case LLAssetType::AT_BODYPART:
+            inv_type = LLInventoryType::IT_WEARABLE;
+            break;
+        case LLAssetType::AT_ANIMATION:
+            inv_type = LLInventoryType::IT_ANIMATION;
+            break;
+        case LLAssetType::AT_GESTURE:
+            inv_type = LLInventoryType::IT_GESTURE;
+            break;
+        case LLAssetType::AT_SETTINGS:
+            inv_type = LLInventoryType::IT_SETTINGS;
+            break;
+        case LLAssetType::AT_MESH:
+            inv_type = LLInventoryType::IT_MESH;
+            break;
+        case LLAssetType::AT_SIMSTATE:
+            // *TODO: maybe I missed something? IDK. IDGAF.
+        default:
+            LL_WARNS("LocalInventory") << "Could not determine LLInventoryType for " << type << "." << LL_ENDL;
+            inv_type = LLInventoryType::IT_UNKNOWN;
+            break;
+    }
+
+    auto* perms = new LLPermissions();
+    perms->init(creator_id, owner_id, LLUUID::null, LLUUID::null);
+
+    auto* item =
+        new LLViewerInventoryItem(item_id, gLocalInventory, 
+            *perms, asset_id, type, inv_type, name, desc, LLSaleInfo::DEFAULT, 
+            0, 0);
+
+    add_item(item);
+    if (getChild<LLUICtrl>("chk_open")->getValue().asBoolean())
+    {
+       open_asset(item_id);
+    }
+
+    sLastCreatorId = creator_id;
+    closeFloater();
+}
+
+void add_item(LLViewerInventoryItem* item)
+{
+    LLInventoryModel::update_map_t update;
+    ++update[item->getParentUUID()];
+    gInventory.accountForUpdate(update);
+    gInventory.updateItem(item);
+    gInventory.notifyObservers();
+}
+
+void open_asset(LLUUID const& item_id)
+{
+    LLViewerInventoryItem* item    = gInventory.getItem(item_id);
+    LLUUID                 assetid = gInventory.getObject(item_id)->getUUID();
+    if (!item)
+    {
+        LL_WARNS("Local Inv") << "Trying to open non-existent item" << LL_ENDL;
+        return;
+    }
+
+    LLAssetType::EType type = item->getType();
+    switch (type)
+    {
+        case LLAssetType::AT_SOUND:
+        case LLAssetType::AT_SOUND_WAV:
+        {
+            LLFloaterReg::showInstance("preview_sound", LLSD(assetid), TAKE_FOCUS_NO);
+            break;
+        }
+        case LLAssetType::AT_ANIMATION:
+        {
+            LLFloaterReg::showInstance("preview_anim", LLSD(assetid), TAKE_FOCUS_NO);
+            break;
+        }
+        case LLAssetType::AT_TEXTURE:
+        {
+            LLFloaterReg::showInstance("preview_texture", LLSD(assetid), TAKE_FOCUS_NO);
+            break;
+        }
+        case LLAssetType::AT_GESTURE:
+        {
+            LLPreviewGesture* preview = LLPreviewGesture::show(assetid, LLUUID::null);
+            preview->setFocus(TRUE);
+            break;
+        }
+        // *TODO: Handle lsl, notecards, AT_SETTINGS, etc.
+        default:
+        {
+            LL_WARNS("LocalInventory") << "Cannot open type " << type << "." << LL_ENDL;
+            break;
+        }
+    }
+}
diff --git a/indra/newview/llfloaternewlocalinventory.h b/indra/newview/llfloaternewlocalinventory.h
new file mode 100644
index 0000000000000000000000000000000000000000..619a84535f4bcc67a3f591dc7a85ac597ca3c8e1
--- /dev/null
+++ b/indra/newview/llfloaternewlocalinventory.h
@@ -0,0 +1,43 @@
+/**
+ * @file llfloaternewlocalinventory.h
+ * @brief Create fake local inventory item
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Cinder Roxley
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llfloater.h"
+
+class LLLineEditor;
+
+class LLFloaterNewLocalInventory
+:	public LLFloater
+{
+public:
+	LLFloaterNewLocalInventory(const LLSD& key);
+	BOOL postBuild();
+
+	void onClickOK();
+	static LLUUID sLastCreatorId;
+
+private:
+    ~LLFloaterNewLocalInventory() override = default;
+};
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 5a013f3212ab40b69bd6b28af91a612d89b31fe5..1e669af88ccc6ad75cc64ee888faffc8ebe681ba 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -114,6 +114,7 @@
 #include "llfloatermyscripts.h"
 #include "llfloatermyenvironment.h"
 #include "llfloaternamedesc.h"
+#include "llfloaternewlocalinventory.h"
 #include "llfloaternotificationsconsole.h"
 #include "llfloaternotificationstabbed.h"
 #include "llfloaterobjectweights.h"
@@ -430,6 +431,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("message_log", "floater_message_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMessageLog>);
 	LLFloaterReg::add("message_rewriter", "floater_message_rewriter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMessageRewriter>);
 	LLFloaterReg::add("music_ticker", "floater_music_ticker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);
+    LLFloaterReg::add("new_local_inventory", "floater_new_local_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNewLocalInventory>);
 	LLFloaterReg::add("particle_editor", "floater_particle_editor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ALFloaterParticleEditor>);
 	LLFloaterReg::add("progress_view", "floater_progress_view.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProgressView>);
 	LLFloaterReg::add("quick_settings", "floater_quick_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);
diff --git a/indra/newview/skins/default/xui/en/floater_new_local_inventory.xml b/indra/newview/skins/default/xui/en/floater_new_local_inventory.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dfc9c306611c98c4d1b5293a75c81d22851cae24
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_new_local_inventory.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater 
+	layout="topleft"
+	can_close="true"
+	can_drag_on_left="false"
+	can_minimize="true"
+    can_resize="false" 
+	height="130" 
+	width="350"
+    name="new_inventory_item"
+    title="Create Local Inventory Asset">
+	<text
+		top="5" 
+		follows="left|top"
+	    h_pad="0" 
+		halign="left"
+		height="10" 
+		left="10"
+	    name="LabelItemNameTitle" 
+		v_pad="0" 
+		width="78" value="Name:" />
+	<line_editor
+		top_delta="0"
+		enabled="true" 
+		follows="left|top|right" 
+		font="SansSerifSmall"
+		height="16"
+		is_unicode="false"
+		left="88" 
+		max_length="63"
+		mouse_opaque="true"
+		name="name_line" 
+		width="252" />
+	<text 
+		top_delta="20" 
+		follows="left|top"
+	    h_pad="0" 
+		halign="left" 
+		height="10" 
+		left="10"
+		name="LabelItemDescTitle" 
+		v_pad="0"
+		width="78"
+		value="Description:" />
+	<line_editor
+		top_delta="0"
+		enabled="true" 
+		follows="left|top|right" 
+		height="16"
+	    is_unicode="false" 
+		left="88" 
+		max_length="127" 
+		mouse_opaque="true"
+	    name="desc_line"
+		width="252" />
+	<text
+		top_delta="20"
+		follows="left|top"
+		h_pad="0" 
+		halign="left" 
+		height="16" 
+		left="10"
+		name="LabelAssetTitle"
+		v_pad="0"
+		width="78"
+		value="Asset:" />
+	<line_editor
+		top_delta="0"
+	    enabled="true"
+		follows="left|top|right"
+		height="16"
+		is_unicode="false"
+		left="88" 
+		max_length="127"
+		mouse_opaque="true"
+		name="asset_id_line" 
+		width="252" />
+	<text
+		top_delta="20"
+		follows="left|top"
+	    h_pad="0" 
+		halign="left" 
+		height="16" 
+		left="10"
+		name="LabelCreatorTitle" 
+		v_pad="0" 
+		width="78"
+		value="Creator:" />
+	<line_editor
+		top_delta="0"
+		enabled="true" 
+		follows="left|top|right" 
+		height="16"
+		is_unicode="false"
+		left="88" 
+		max_length="127"
+		name="creator_id_line"
+		width="252" />
+	<text
+		top_delta="20"
+		follows="left|top"
+	    h_pad="0" 
+		halign="left" 
+		height="16" 
+		left="10"
+	    name="LabelOwnerTitle" 
+		v_pad="0" 
+		width="78"
+		value="Owner" />
+	<line_editor
+		top_delta="0"
+		enabled="true" 
+		follows="left|top|right"
+		height="16"
+	     is_unicode="false" 
+		left="88"
+		max_length="127"
+		name="owner_id_line"
+		width="252" />
+	<combo_box 
+		top_delta="20"
+		allow_text_entry="false" 
+		follows="left|top"
+		height="18"
+	    left="8"
+		max_chars="20"
+		name="type_combo"
+		width="100">
+	</combo_box>
+	<check_box
+		top_delta="0"
+		height="16"
+		initial_value="true"
+		label="Open immediately"
+		left="113"
+		name="chk_open"
+		width="120" />
+	<button 
+		top_delta="0"
+		height="20" 
+		label="OK" 
+		left="240"
+		name="ok_btn" 
+		width="100" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 120ed7615564fd41037cb83a8ac604914e46143e..cf57268f72f93152a6933554c09ad27877407c90 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -674,7 +674,8 @@
      function="Inventory.DoToSelected"
      parameter="restoreToWorld" />
     <menu_item_call.on_enable
-     function="Alchemy.PowerfulWizard" />
+     function="SavedSetting"
+     parameter="AlchemyPowerfulWizard" />
 	</menu_item_call>
     <menu_item_call
      label="Delete"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
index 3385a29a6c6260cfee22bf08f869c29c4a78e9c6..e22753d7871051358a1dd4c2df4331e50b1538a4 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -253,7 +253,7 @@
                      parameter="eyes" />
                 </menu_item_call>
             </menu>
-    <menu
+		<menu
             label="New Settings"
             layout="topleft"
             name="New Settings">
@@ -290,4 +290,19 @@
                     function="Inventory.EnvironmentEnabled" />
         </menu_item_call>
     </menu>
+	<menu_item_separator>
+        <menu_item_seperator.on_visible
+			function="SavedSetting"
+			parameter="LocalInventoryEnabled"/>
+	</menu_item_separator>
+	<menu_item_call
+			label="New Local Asset"
+			name="New Local Item">
+		<menu_item_call.on_visible
+			function="SavedSetting"
+			parameter="LocalInventoryEnabled" />
+		<menu_item_call.on_click
+			function="Floater.Show"
+			parameter="new_local_inventory"/>
+	</menu_item_call>
 </menu>
\ No newline at end of file