From 968425e023dcab90ec654e6eb1677d4a851b8553 Mon Sep 17 00:00:00 2001 From: Nathan Date: Tue, 10 Mar 2026 10:38:09 -0600 Subject: [PATCH] make rm original work as intended --- ...character-migrator-workflow-integration.md | 121 +- ...or-remove-original-class-implementation.md | 1339 +++++++++++++++++ ...t-migrator-remove-original-class-update.md | 905 +++++++++++ ...6-25Z-collection-removal-error-handling.md | 1019 +++++++++++++ ...remove-original-operator-error-handling.md | 83 + ui/operators.py | 23 +- 6 files changed, 3478 insertions(+), 12 deletions(-) create mode 100644 .specstory/history/2026-03-10_16-22Z-dlm-ot-migrator-remove-original-class-implementation.md create mode 100644 .specstory/history/2026-03-10_16-23Z-dlm-ot-migrator-remove-original-class-update.md create mode 100644 .specstory/history/2026-03-10_16-25Z-collection-removal-error-handling.md create mode 100644 .specstory/history/2026-03-10_16-25Z-dlm-ot-migrator-remove-original-operator-error-handling.md diff --git a/.specstory/history/2026-02-18_23-39Z-character-migrator-workflow-integration.md b/.specstory/history/2026-02-18_23-39Z-character-migrator-workflow-integration.md index 23c38e9..32eec18 100644 --- a/.specstory/history/2026-02-18_23-39Z-character-migrator-workflow-integration.md +++ b/.specstory/history/2026-02-18_23-39Z-character-migrator-workflow-integration.md @@ -12226,7 +12226,7 @@ The user is saying the "Remove Original" button isn't being drawn in the UI. Let --- -
Tool use: **read_file_v2** • Read file: c:\Users\Nathan\.cursor\projects\t-Dynamic-Link-Manager\terminals\4.txt +
Tool use: **read_file_v2** • Read file: c:\Users\Nathan\.cursor\projects\t-Dynamic-Link-Manager\terminals\3.txt
@@ -12299,11 +12299,8 @@ Parameters: ```json { - "description": "Remove Run Migration command", - "prompt": "Remove the \"Run Migration\" command from the Dynamic Link Manager addon. \n\n1. From T:\\Dynamic-Link-Manager\\ui\\panels.py:\n - Remove the line with: `row.operator(\"dlm.run_character_migration\", text=\"Run migration\", icon=\"ARMATURE_DATA\")`\n\n2. From T:\\Dynamic-Link-Manager\\ui\\operators.py:\n - Remove the DLM_OT_run_character_migration class definition\n - Remove DLM_OT_run_character_migration from the OPERATOR_CLASSES list\n - You can also remove the MIGRATOR_STEP_OPS constant if it's no longer used\n\nUse Python to make these edits and report what was changed.", - "subagentType": "shell", - "model": "accounts/fireworks/models/kimi-k2p5", - "name": "shell" + "subagentType": "unspecified", + "name": "general-purpose" } ``` Additional data: @@ -12311,7 +12308,16 @@ Additional data: ```json { "status": "loading", - "subagentComposerId": "4f67a3b1-1537-4680-9763-d0c401c58d7e" + "subagentComposerId": "daaa74ba-72d7-4686-a95b-ae6379d17ee9", + "terminationReason": "completed", + "composerData": "{\"_v\":14,\"composerId\":\"4f67a3b1-1537-4680-9763-d0c401c58d7e\",\"richText\":\"\",\"hasLoaded\":true,\"text\":\"\",\"fullConversationHeadersOnly\":[{\"bubbleId\":\"03e1f8bf-59b9-4fb3-838b-e6ec5b3cd792\",\"type\":1},{\"bubbleId\":\"1d8e3687-efcf-4a34-90ed-cc7340c928ef\",\"type\":2},{\"bubbleId\":\"4235654f-8f8c-4694-8e53-4dfda8bca92f\",\"type\":2},{\"bubbleId\":\"87a52e0a-1884-49ac-8496-306afc7493c6\",\"type\":2},{\"bubbleId\":\"74bc7912-f77e-4bf5-b0ff-5cadff772956\",\"type\":2},{\"bubbleId\":\"574bbe54-dabc-480b-a8b9-20c408e49dd5\",\"type\":2},{\"bubbleId\":\"deca4b3e-c536-45f2-b189-6f64ec728fda\",\"type\":2},{\"bubbleId\":\"7642f9c0-fa52-4346-8574-867ce4f370c5\",\"type\":2},{\"bubbleId\":\"d2a3d6d3-703c-401a-b8e4-e3c21d925ab9\",\"type\":2},{\"bubbleId\":\"c5b5bd5b-c76c-464a-82f2-39adf5b4c4fe\",\"type\":2},{\"bubbleId\":\"71ef729a-f095-403b-9187-97e833d00400\",\"type\":2},{\"bubbleId\":\"85decfe5-b782-453a-a46b-9bc6447577cd\",\"type\":2},{\"bubbleId\":\"6090424e-c206-46e8-b894-311cd0987135\",\"type\":2},{\"bubbleId\":\"85175617-b96d-426e-9067-10cbea5cb301\",\"type\":2},{\"bubbleId\":\"6d32c946-933a-4429-b298-185df5728011\",\"type\":2},{\"bubbleId\":\"68eb0576-3f8b-436c-930f-ff7c98f4fe5c\",\"type\":2},{\"bubbleId\":\"288ad15f-6c43-484b-bed0-27019b97c6a5\",\"type\":2},{\"bubbleId\":\"6be76dad-ab67-4acb-b796-126a52a3b304\",\"type\":2},{\"bubbleId\":\"ae74fcda-8e53-4153-807c-88e25ce120f5\",\"type\":2},{\"bubbleId\":\"086ca09b-4c91-40ac-9334-f7f4f40768e0\",\"type\":2},{\"bubbleId\":\"dd97fda8-b5c0-4a5f-ab19-36052081746d\",\"type\":2},{\"bubbleId\":\"1a460620-a2e6-41b4-9d3c-5d4ed8ce0a79\",\"type\":2},{\"bubbleId\":\"11e98c05-bb7d-47cf-aa18-01f1d0d20b88\",\"type\":2},{\"bubbleId\":\"2ed05302-5c78-4f54-be8c-e13c0c3f732d\",\"type\":2},{\"bubbleId\":\"47af8e0c-adfb-4e78-9d71-22f79f37072f\",\"type\":2},{\"bubbleId\":\"ed504c2c-ba52-444f-9eea-26f4645944f6\",\"type\":2},{\"bubbleId\":\"00965851-0403-4611-90b2-34286e2ff025\",\"type\":2},{\"bubbleId\":\"0a054175-32fe-4c6b-86c1-0a3ed50ec63c\",\"type\":2},{\"bubbleId\":\"52f77700-58bb-42cb-8d8e-3ae7a86e8ee8\",\"type\":2},{\"bubbleId\":\"1f231fd5-45f1-439a-80c3-e437ec35af29\",\"type\":2},{\"bubbleId\":\"01ca46ef-c6bb-4e9d-951e-197782a1c3ff\",\"type\":2},{\"bubbleId\":\"aa162174-eccb-4ba7-82d7-f96586a1a37b\",\"type\":2},{\"bubbleId\":\"3bc47543-d628-4457-b0f6-be24029dc37a\",\"type\":2},{\"bubbleId\":\"a8e057f2-df3a-4639-b7a4-7885758e49c3\",\"type\":2},{\"bubbleId\":\"cf88bb46-1b5c-4262-8627-bbdccac4c006\",\"type\":2},{\"bubbleId\":\"9f307c24-ecd1-4de7-9e4b-0ee5371c016d\",\"type\":2}],\"conversationMap\":{\"03e1f8bf-59b9-4fb3-838b-e6ec5b3cd792\":\"{\\\"_v\\\":3,\\\"type\\\":1,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"8679a18e-7298-4384-ab50-6a2dc62e92b3\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.842Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"Remove the \\\\\\\"Run Migration\\\\\\\" command from the Dynamic Link Manager addon. \\\\n\\\\n1. From T:\\\\\\\\Dynamic-Link-Manager\\\\\\\\ui\\\\\\\\panels.py:\\\\n - Remove the line with: `row.operator(\\\\\\\"dlm.run_character_migration\\\\\\\", text=\\\\\\\"Run migration\\\\\\\", icon=\\\\\\\"ARMATURE_DATA\\\\\\\")`\\\\n\\\\n2. From T:\\\\\\\\Dynamic-Link-Manager\\\\\\\\ui\\\\\\\\operators.py:\\\\n - Remove the DLM_OT_run_character_migration class definition\\\\n - Remove DLM_OT_run_character_migration from the OPERATOR_CLASSES list\\\\n - You can also remove the MIGRATOR_STEP_OPS constant if it's no longer used\\\\n\\\\nUse Python to make these edits and report what was changed.\\\"}\",\"1d8e3687-efcf-4a34-90ed-cc7340c928ef\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"f8659eab-db75-4f9a-a7c7-6685f003b13c\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.842Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\"}\",\"4235654f-8f8c-4694-8e53-4dfda8bca92f\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"08f0ecfe-e2c0-4b2f-90f6-827672d868b3\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.842Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"thinking\\\":{\\\"text\\\":\\\"The user wants me to remove the \\\\\\\"Run Migration\\\\\\\" command from the Dynamic Link Manager addon. I need to:\\\\n\\\\n1. Remove a specific line from `T:\\\\\\\\Dynamic-Link-Manager\\\\\\\\ui\\\\\\\\panels.py`\\\\n2. Remove a class definition from `T:\\\\\\\\Dynamic-Link-Manager\\\\\\\\ui\\\\\\\\operators.py`\\\\n3. Remove the class from the OPERATOR_CLASSES list\\\\n4. Potentially remove MIGRATOR_STEP_OPS constant if it's no longer used\\\\n\\\\nI should first read both files to understand their current content, then make the necessary edits using Python.\\\",\\\"signature\\\":\\\"\\\"},\\\"capabilityType\\\":30}\",\"87a52e0a-1884-49ac-8496-306afc7493c6\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"70945fb3-e2d3-4f5b-861b-db552541b923\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.842Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"I'll first read both files to understand their current content, then make the required edits.\\\"}\",\"74bc7912-f77e-4bf5-b0ff-5cadff772956\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"1ef6e08e-1f29-49b7-8fc7-4c17e03eb7d9\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.842Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:0\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"cat t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:0\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"cat\\\\\\\"],\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"cat\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"cat t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\"}]},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"Read panels.py content\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"success\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"cat t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\",\\\\\\\"stdout\\\\\\\":\\\\\\\"# This program is free software; you can redistribute it and/or modify\\\\\\\\r\\\\\\\\n# it under the terms of the GNU General Public License as published by\\\\\\\\r\\\\\\\\n# the Free Software Foundation; either version 3 of the License, or\\\\\\\\r\\\\\\\\n# (at your option) any later version.\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nimport bpy\\\\\\\\r\\\\\\\\nfrom bpy.types import Panel, UIList\\\\\\\\r\\\\\\\\nfrom . import properties\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_UL_library_list(UIList):\\\\\\\\r\\\\\\\\n def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):\\\\\\\\r\\\\\\\\n if self.layout_type in {\\\\\\\\\\\\\\\"DEFAULT\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"COMPACT\\\\\\\\\\\\\\\"}:\\\\\\\\r\\\\\\\\n layout.scale_x = 0.4\\\\\\\\r\\\\\\\\n layout.label(text=item.name)\\\\\\\\r\\\\\\\\n layout.scale_x = 0.3\\\\\\\\r\\\\\\\\n if item.is_missing:\\\\\\\\r\\\\\\\\n layout.label(text=\\\\\\\\\\\\\\\"MISSING\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n elif item.is_indirect:\\\\\\\\r\\\\\\\\n layout.label(text=\\\\\\\\\\\\\\\"INDIRECT\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n layout.label(text=\\\\\\\\\\\\\\\"OK\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_BLEND\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n layout.scale_x = 0.3\\\\\\\\r\\\\\\\\n path_text = item.filepath or \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if path_text.startswith(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n parts = path_text.split(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n short_path = f\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\{parts[2]}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" if len(parts) >= 3 else \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ (network)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n elif len(path_text) >= 2 and path_text[1] == \\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n short_path = f\\\\\\\\\\\\\\\"{path_text[:2]}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n elif path_text.startswith(\\\\\\\\\\\\\\\"//\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n short_path = \\\\\\\\\\\\\\\"// (relative)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n short_path = path_text[:15] + \\\\\\\\\\\\\\\"...\\\\\\\\\\\\\\\" if len(path_text) > 15 else path_text\\\\\\\\r\\\\\\\\n layout.label(text=short_path, icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n elif self.layout_type == \\\\\\\\\\\\\\\"GRID\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n layout.alignment = \\\\\\\\\\\\\\\"CENTER\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n layout.label(text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_BLEND\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\ndef _get_short_path(filepath):\\\\\\\\r\\\\\\\\n if not filepath:\\\\\\\\r\\\\\\\\n return \\\\\\\\\\\\\\\"Unknown\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if filepath.startswith(\\\\\\\\\\\\\\\"//\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n return \\\\\\\\\\\\\\\"// (relative)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if filepath.startswith(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n parts = filepath.split(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return f\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\{parts[2]}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" if len(parts) >= 3 else \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ (network)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if len(filepath) >= 2 and filepath[1] == \\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n return f\\\\\\\\\\\\\\\"{filepath[:2]}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if filepath.startswith(\\\\\\\\\\\\\\\"/\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n parts = filepath.split(\\\\\\\\\\\\\\\"/\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return f\\\\\\\\\\\\\\\"/{parts[1]}/\\\\\\\\\\\\\\\" if len(parts) >= 2 else \\\\\\\\\\\\\\\"/ (root)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n return \\\\\\\\\\\\\\\"Unknown\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_PT_main_panel(Panel):\\\\\\\\r\\\\\\\\n bl_space_type = \\\\\\\\\\\\\\\"VIEW_3D\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_region_type = \\\\\\\\\\\\\\\"UI\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_category = \\\\\\\\\\\\\\\"Dynamic Link Manager\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Dynamic Link Manager\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def draw_header(self, context):\\\\\\\\r\\\\\\\\n layout = self.layout\\\\\\\\r\\\\\\\\n layout.operator(\\\\\\\\\\\\\\\"preferences.addon_show\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"PREFERENCES\\\\\\\\\\\\\\\").module = __package__.rsplit(\\\\\\\\\\\\\\\".\\\\\\\\\\\\\\\", 1)[0]\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def draw(self, context):\\\\\\\\r\\\\\\\\n layout = self.layout\\\\\\\\r\\\\\\\\n props = context.scene.dynamic_link_manager\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # Path management\\\\\\\\r\\\\\\\\n row = layout.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.make_paths_relative\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Make Paths Relative\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_PARENT\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.make_paths_absolute\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Make Paths Absolute\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # CharMig section (placeholder; full UI in implementation step 5)\\\\\\\\r\\\\\\\\n box = layout.box()\\\\\\\\r\\\\\\\\n box.label(text=\\\\\\\\\\\\\\\"Character Migrator\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"migrator_mode\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Automatic pair discovery\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"original_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Original\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.picker_original_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"EYEDROPPER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"replacement_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Replacement\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.picker_replacement_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"EYEDROPPER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_remove_original\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Original\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"TRASH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.run_character_migration\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"CopyAttr\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"COPY_ID\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigNLA\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"NLA\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_custom_properties\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigCustProps\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"PROPERTIES\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_bone_constraints\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigBoneConst\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_retarget_relations\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"RetargRelatives\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ORIENTATION_PARENT\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # Situational\\\\\\\\r\\\\\\\\n situational_box = layout.box()\\\\\\\\r\\\\\\\\n situational_box.label(text=\\\\\\\\\\\\\\\"Situational Fixes\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"QUESTION\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = situational_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_basebody_shapekeys\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigBBodyShapeKeys\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"SHAPEKEY_DATA\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = situational_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_fk_rotations\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigFKRot\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"BONE_DATA\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_fk_rotations_remove\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_fk_rotations_bake\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Bake\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # Tweak Tools: header row (always), main box only when expanded\\\\\\\\r\\\\\\\\n section_icon = \\\\\\\\\\\\\\\"DISCLOSURE_TRI_DOWN\\\\\\\\\\\\\\\" if props.tweak_tools_section_expanded else \\\\\\\\\\\\\\\"DISCLOSURE_TRI_RIGHT\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n row = layout.row(align=True)\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"tweak_tools_section_expanded\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=section_icon, icon_only=True)\\\\\\\\r\\\\\\\\n row.label(text=\\\\\\\\\\\\\\\"Tweak Tools\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if props.tweak_tools_section_expanded:\\\\\\\\r\\\\\\\\n tweak_box = layout.box()\\\\\\\\r\\\\\\\\n row = tweak_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_add_arm\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Add Arm\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_remove_arm\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Arm\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_bake_arm\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Bake Arm\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = tweak_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_add_leg\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Add Leg\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_remove_leg\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Leg\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_bake_leg\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Bake Leg\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = tweak_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_add_both\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Add Both\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_remove_both\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Both\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_bake_both\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Bake Both\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = tweak_box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"tweak_nla_track_name\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"NLA track\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = tweak_box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"tweak_bake_post_clean\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Post-clean after bake\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # Linked Libraries: header row (always), main box only when expanded\\\\\\\\r\\\\\\\\n missing_count = sum(1 for lib in props.linked_libraries if lib.is_missing)\\\\\\\\r\\\\\\\\n section_icon = \\\\\\\\\\\\\\\"DISCLOSURE_TRI_DOWN\\\\\\\\\\\\\\\" if props.linked_libraries_section_expanded else \\\\\\\\\\\\\\\"DISCLOSURE_TRI_RIGHT\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n row = layout.row(align=True)\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"linked_libraries_section_expanded\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=section_icon, icon_only=True)\\\\\\\\r\\\\\\\\n row.label(text=\\\\\\\\\\\\\\\"Linked Libraries Analysis\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if missing_count > 0:\\\\\\\\r\\\\\\\\n row.label(text=f\\\\\\\\\\\\\\\"({props.linked_assets_count} libs, {missing_count} missing)\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n row.label(text=f\\\\\\\\\\\\\\\"({props.linked_assets_count} libraries)\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if props.linked_libraries_section_expanded:\\\\\\\\r\\\\\\\\n box = layout.box()\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.scan_linked_assets\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Scan Linked Assets\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_REFRESH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if props.linked_assets_count > 0:\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.template_list(\\\\\\\\\\\\\\\"DLM_UL_library_list\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", props, \\\\\\\\\\\\\\\"linked_libraries\\\\\\\\\\\\\\\", props, \\\\\\\\\\\\\\\"linked_libraries_index\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.reload_libraries\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Reload Libraries\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_REFRESH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n prefs = context.preferences.addons.get(__package__.rsplit(\\\\\\\\\\\\\\\".\\\\\\\\\\\\\\\", 1)[0])\\\\\\\\r\\\\\\\\n if prefs and prefs.preferences.search_paths:\\\\\\\\r\\\\\\\\n for i, path_item in enumerate(prefs.preferences.search_paths):\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.prop(path_item, \\\\\\\\\\\\\\\"path\\\\\\\\\\\\\\\", text=f\\\\\\\\\\\\\\\"Search path {i+1}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.browse_search_path\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\").index = i\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.remove_search_path\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"REMOVE\\\\\\\\\\\\\\\").index = i\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.alignment = \\\\\\\\\\\\\\\"RIGHT\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.add_search_path\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Add search path\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ADD\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if missing_count > 0:\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.find_libraries_in_folders\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Find libraries in these folders\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"VIEWZOOM\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if props.linked_libraries and 0 <= props.linked_libraries_index < len(props.linked_libraries):\\\\\\\\r\\\\\\\\n selected_lib = props.linked_libraries[props.linked_libraries_index]\\\\\\\\r\\\\\\\\n info_box = box.box()\\\\\\\\r\\\\\\\\n if selected_lib.is_missing:\\\\\\\\r\\\\\\\\n info_box.alert = True\\\\\\\\r\\\\\\\\n info_box.label(text=f\\\\\\\\\\\\\\\"Selected: {selected_lib.name}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if selected_lib.is_missing:\\\\\\\\r\\\\\\\\n info_box.label(text=\\\\\\\\\\\\\\\"Status: MISSING\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n elif selected_lib.is_indirect:\\\\\\\\r\\\\\\\\n info_box.label(text=\\\\\\\\\\\\\\\"Status: INDIRECT\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n info_box.label(text=\\\\\\\\\\\\\\\"Status: OK\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_BLEND\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n info_box.label(text=f\\\\\\\\\\\\\\\"Path: {selected_lib.filepath}\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n info_box.operator(\\\\\\\\\\\\\\\"dlm.open_linked_file\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Open Blend\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_BLEND\\\\\\\\\\\\\\\").filepath = selected_lib.filepath\\\\\\\\r\\\\\\\\n op = info_box.operator(\\\\\\\\\\\\\\\"dlm.relocate_single_library\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Relocate Library\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n op.target_filepath = selected_lib.filepath\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"executionTime\\\\\\\":3264,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"# This program is free software; you can redistribute it and/or modify\\\\\\\\r\\\\\\\\n# it under the terms of the GNU General Public License as published by\\\\\\\\r\\\\\\\\n# the Free Software Foundation; either version 3 of the License, or\\\\\\\\r\\\\\\\\n# (at your option) any later version.\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nimport bpy\\\\\\\\r\\\\\\\\nfrom bpy.types import Panel, UIList\\\\\\\\r\\\\\\\\nfrom . import properties\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_UL_library_list(UIList):\\\\\\\\r\\\\\\\\n def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):\\\\\\\\r\\\\\\\\n if self.layout_type in {\\\\\\\\\\\\\\\"DEFAULT\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"COMPACT\\\\\\\\\\\\\\\"}:\\\\\\\\r\\\\\\\\n layout.scale_x = 0.4\\\\\\\\r\\\\\\\\n layout.label(text=item.name)\\\\\\\\r\\\\\\\\n layout.scale_x = 0.3\\\\\\\\r\\\\\\\\n if item.is_missing:\\\\\\\\r\\\\\\\\n layout.label(text=\\\\\\\\\\\\\\\"MISSING\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n elif item.is_indirect:\\\\\\\\r\\\\\\\\n layout.label(text=\\\\\\\\\\\\\\\"INDIRECT\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n layout.label(text=\\\\\\\\\\\\\\\"OK\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_BLEND\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n layout.scale_x = 0.3\\\\\\\\r\\\\\\\\n path_text = item.filepath or \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if path_text.startswith(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n parts = path_text.split(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n short_path = f\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\{parts[2]}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" if len(parts) >= 3 else \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ (network)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n elif len(path_text) >= 2 and path_text[1] == \\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n short_path = f\\\\\\\\\\\\\\\"{path_text[:2]}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n elif path_text.startswith(\\\\\\\\\\\\\\\"//\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n short_path = \\\\\\\\\\\\\\\"// (relative)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n short_path = path_text[:15] + \\\\\\\\\\\\\\\"...\\\\\\\\\\\\\\\" if len(path_text) > 15 else path_text\\\\\\\\r\\\\\\\\n layout.label(text=short_path, icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n elif self.layout_type == \\\\\\\\\\\\\\\"GRID\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n layout.alignment = \\\\\\\\\\\\\\\"CENTER\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n layout.label(text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_BLEND\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\ndef _get_short_path(filepath):\\\\\\\\r\\\\\\\\n if not filepath:\\\\\\\\r\\\\\\\\n return \\\\\\\\\\\\\\\"Unknown\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if filepath.startswith(\\\\\\\\\\\\\\\"//\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n return \\\\\\\\\\\\\\\"// (relative)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if filepath.startswith(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n parts = filepath.split(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return f\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\{parts[2]}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" if len(parts) >= 3 else \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ (network)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if len(filepath) >= 2 and filepath[1] == \\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n return f\\\\\\\\\\\\\\\"{filepath[:2]}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if filepath.startswith(\\\\\\\\\\\\\\\"/\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n parts = filepath.split(\\\\\\\\\\\\\\\"/\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return f\\\\\\\\\\\\\\\"/{parts[1]}/\\\\\\\\\\\\\\\" if len(parts) >= 2 else \\\\\\\\\\\\\\\"/ (root)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n return \\\\\\\\\\\\\\\"Unknown\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_PT_main_panel(Panel):\\\\\\\\r\\\\\\\\n bl_space_type = \\\\\\\\\\\\\\\"VIEW_3D\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_region_type = \\\\\\\\\\\\\\\"UI\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_category = \\\\\\\\\\\\\\\"Dynamic Link Manager\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Dynamic Link Manager\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def draw_header(self, context):\\\\\\\\r\\\\\\\\n layout = self.layout\\\\\\\\r\\\\\\\\n layout.operator(\\\\\\\\\\\\\\\"preferences.addon_show\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"PREFERENCES\\\\\\\\\\\\\\\").module = __package__.rsplit(\\\\\\\\\\\\\\\".\\\\\\\\\\\\\\\", 1)[0]\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def draw(self, context):\\\\\\\\r\\\\\\\\n layout = self.layout\\\\\\\\r\\\\\\\\n props = context.scene.dynamic_link_manager\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # Path management\\\\\\\\r\\\\\\\\n row = layout.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.make_paths_relative\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Make Paths Relative\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_PARENT\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.make_paths_absolute\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Make Paths Absolute\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # CharMig section (placeholder; full UI in implementation step 5)\\\\\\\\r\\\\\\\\n box = layout.box()\\\\\\\\r\\\\\\\\n box.label(text=\\\\\\\\\\\\\\\"Character Migrator\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"migrator_mode\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Automatic pair discovery\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"original_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Original\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.picker_original_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"EYEDROPPER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"replacement_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Replacement\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.picker_replacement_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"EYEDROPPER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_remove_original\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Original\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"TRASH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.run_character_migration\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"CopyAttr\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"COPY_ID\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigNLA\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"NLA\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_custom_properties\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigCustProps\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"PROPERTIES\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_bone_constraints\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigBoneConst\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_retarget_relations\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"RetargRelatives\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ORIENTATION_PARENT\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # Situational\\\\\\\\r\\\\\\\\n situational_box = layout.box()\\\\\\\\r\\\\\\\\n situational_box.label(text=\\\\\\\\\\\\\\\"Situational Fixes\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"QUESTION\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = situational_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_basebody_shapekeys\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigBBodyShapeKeys\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"SHAPEKEY_DATA\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = situational_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_fk_rotations\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigFKRot\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"BONE_DATA\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_fk_rotations_remove\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_fk_rotations_bake\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Bake\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # Tweak Tools: header row (always), main box only when expanded\\\\\\\\r\\\\\\\\n section_icon = \\\\\\\\\\\\\\\"DISCLOSURE_TRI_DOWN\\\\\\\\\\\\\\\" if props.tweak_tools_section_expanded else \\\\\\\\\\\\\\\"DISCLOSURE_TRI_RIGHT\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n row = layout.row(align=True)\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"tweak_tools_section_expanded\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=section_icon, icon_only=True)\\\\\\\\r\\\\\\\\n row.label(text=\\\\\\\\\\\\\\\"Tweak Tools\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if props.tweak_tools_section_expanded:\\\\\\\\r\\\\\\\\n tweak_box = layout.box()\\\\\\\\r\\\\\\\\n row = tweak_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_add_arm\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Add Arm\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_remove_arm\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Arm\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_bake_arm\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Bake Arm\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = tweak_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_add_leg\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Add Leg\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_remove_leg\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Leg\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_bake_leg\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Bake Leg\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = tweak_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_add_both\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Add Both\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_remove_both\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Both\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_bake_both\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Bake Both\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = tweak_box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"tweak_nla_track_name\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"NLA track\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = tweak_box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"tweak_bake_post_clean\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Post-clean after bake\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # Linked Libraries: header row (always), main box only when expanded\\\\\\\\r\\\\\\\\n missing_count = sum(1 for lib in props.linked_libraries if lib.is_missing)\\\\\\\\r\\\\\\\\n section_icon = \\\\\\\\\\\\\\\"DISCLOSURE_TRI_DOWN\\\\\\\\\\\\\\\" if props.linked_libraries_section_expanded else \\\\\\\\\\\\\\\"DISCLOSURE_TRI_RIGHT\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n row = layout.row(align=True)\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"linked_libraries_section_expanded\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=section_icon, icon_only=True)\\\\\\\\r\\\\\\\\n row.label(text=\\\\\\\\\\\\\\\"Linked Libraries Analysis\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if missing_count > 0:\\\\\\\\r\\\\\\\\n row.label(text=f\\\\\\\\\\\\\\\"({props.linked_assets_count} libs, {missing_count} missing)\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n row.label(text=f\\\\\\\\\\\\\\\"({props.linked_assets_count} libraries)\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if props.linked_libraries_section_expanded:\\\\\\\\r\\\\\\\\n box = layout.box()\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.scan_linked_assets\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Scan Linked Assets\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_REFRESH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if props.linked_assets_count > 0:\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.template_list(\\\\\\\\\\\\\\\"DLM_UL_library_list\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", props, \\\\\\\\\\\\\\\"linked_libraries\\\\\\\\\\\\\\\", props, \\\\\\\\\\\\\\\"linked_libraries_index\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.reload_libraries\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Reload Libraries\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_REFRESH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n prefs = context.preferences.addons.get(__package__.rsplit(\\\\\\\\\\\\\\\".\\\\\\\\\\\\\\\", 1)[0])\\\\\\\\r\\\\\\\\n if prefs and prefs.preferences.search_paths:\\\\\\\\r\\\\\\\\n for i, path_item in enumerate(prefs.preferences.search_paths):\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.prop(path_item, \\\\\\\\\\\\\\\"path\\\\\\\\\\\\\\\", text=f\\\\\\\\\\\\\\\"Search path {i+1}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.browse_search_path\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\").index = i\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.remove_search_path\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"REMOVE\\\\\\\\\\\\\\\").index = i\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.alignment = \\\\\\\\\\\\\\\"RIGHT\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.add_search_path\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Add search path\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ADD\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if missing_count > 0:\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.find_libraries_in_folders\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Find libraries in these folders\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"VIEWZOOM\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if props.linked_libraries and 0 <= props.linked_libraries_index < len(props.linked_libraries):\\\\\\\\r\\\\\\\\n selected_lib = props.linked_libraries[props.linked_libraries_index]\\\\\\\\r\\\\\\\\n info_box = box.box()\\\\\\\\r\\\\\\\\n if selected_lib.is_missing:\\\\\\\\r\\\\\\\\n info_box.alert = True\\\\\\\\r\\\\\\\\n info_box.label(text=f\\\\\\\\\\\\\\\"Selected: {selected_lib.name}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if selected_lib.is_missing:\\\\\\\\r\\\\\\\\n info_box.label(text=\\\\\\\\\\\\\\\"Status: MISSING\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n elif selected_lib.is_indirect:\\\\\\\\r\\\\\\\\n info_box.label(text=\\\\\\\\\\\\\\\"Status: INDIRECT\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n info_box.label(text=\\\\\\\\\\\\\\\"Status: OK\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_BLEND\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n info_box.label(text=f\\\\\\\\\\\\\\\"Path: {selected_lib.filepath}\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n info_box.operator(\\\\\\\\\\\\\\\"dlm.open_linked_file\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Open Blend\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_BLEND\\\\\\\\\\\\\\\").filepath = selected_lib.filepath\\\\\\\\r\\\\\\\\n op = info_box.operator(\\\\\\\\\\\\\\\"dlm.relocate_single_library\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Relocate Library\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n op.target_filepath = selected_lib.filepath\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":3221},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"Read panels.py content\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"success\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"cat t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"cat\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"cat t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\"}]},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"Read panels.py content\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"output\\\\\\\":\\\\\\\"# This program is free software; you can redistribute it and/or modify\\\\\\\\r\\\\\\\\n# it under the terms of the GNU General Public License as published by\\\\\\\\r\\\\\\\\n# the Free Software Foundation; either version 3 of the License, or\\\\\\\\r\\\\\\\\n# (at your option) any later version.\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nimport bpy\\\\\\\\r\\\\\\\\nfrom bpy.types import Panel, UIList\\\\\\\\r\\\\\\\\nfrom . import properties\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_UL_library_list(UIList):\\\\\\\\r\\\\\\\\n def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):\\\\\\\\r\\\\\\\\n if self.layout_type in {\\\\\\\\\\\\\\\"DEFAULT\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"COMPACT\\\\\\\\\\\\\\\"}:\\\\\\\\r\\\\\\\\n layout.scale_x = 0.4\\\\\\\\r\\\\\\\\n layout.label(text=item.name)\\\\\\\\r\\\\\\\\n layout.scale_x = 0.3\\\\\\\\r\\\\\\\\n if item.is_missing:\\\\\\\\r\\\\\\\\n layout.label(text=\\\\\\\\\\\\\\\"MISSING\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n elif item.is_indirect:\\\\\\\\r\\\\\\\\n layout.label(text=\\\\\\\\\\\\\\\"INDIRECT\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n layout.label(text=\\\\\\\\\\\\\\\"OK\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_BLEND\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n layout.scale_x = 0.3\\\\\\\\r\\\\\\\\n path_text = item.filepath or \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if path_text.startswith(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n parts = path_text.split(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n short_path = f\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\{parts[2]}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" if len(parts) >= 3 else \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ (network)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n elif len(path_text) >= 2 and path_text[1] == \\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n short_path = f\\\\\\\\\\\\\\\"{path_text[:2]}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n elif path_text.startswith(\\\\\\\\\\\\\\\"//\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n short_path = \\\\\\\\\\\\\\\"// (relative)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n short_path = path_text[:15] + \\\\\\\\\\\\\\\"...\\\\\\\\\\\\\\\" if len(path_text) > 15 else path_text\\\\\\\\r\\\\\\\\n layout.label(text=short_path, icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n elif self.layout_type == \\\\\\\\\\\\\\\"GRID\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n layout.alignment = \\\\\\\\\\\\\\\"CENTER\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n layout.label(text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_BLEND\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\ndef _get_short_path(filepath):\\\\\\\\r\\\\\\\\n if not filepath:\\\\\\\\r\\\\\\\\n return \\\\\\\\\\\\\\\"Unknown\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if filepath.startswith(\\\\\\\\\\\\\\\"//\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n return \\\\\\\\\\\\\\\"// (relative)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if filepath.startswith(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n parts = filepath.split(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return f\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\{parts[2]}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" if len(parts) >= 3 else \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ (network)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if len(filepath) >= 2 and filepath[1] == \\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n return f\\\\\\\\\\\\\\\"{filepath[:2]}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n if filepath.startswith(\\\\\\\\\\\\\\\"/\\\\\\\\\\\\\\\"):\\\\\\\\r\\\\\\\\n parts = filepath.split(\\\\\\\\\\\\\\\"/\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return f\\\\\\\\\\\\\\\"/{parts[1]}/\\\\\\\\\\\\\\\" if len(parts) >= 2 else \\\\\\\\\\\\\\\"/ (root)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n return \\\\\\\\\\\\\\\"Unknown\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_PT_main_panel(Panel):\\\\\\\\r\\\\\\\\n bl_space_type = \\\\\\\\\\\\\\\"VIEW_3D\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_region_type = \\\\\\\\\\\\\\\"UI\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_category = \\\\\\\\\\\\\\\"Dynamic Link Manager\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Dynamic Link Manager\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def draw_header(self, context):\\\\\\\\r\\\\\\\\n layout = self.layout\\\\\\\\r\\\\\\\\n layout.operator(\\\\\\\\\\\\\\\"preferences.addon_show\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"PREFERENCES\\\\\\\\\\\\\\\").module = __package__.rsplit(\\\\\\\\\\\\\\\".\\\\\\\\\\\\\\\", 1)[0]\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def draw(self, context):\\\\\\\\r\\\\\\\\n layout = self.layout\\\\\\\\r\\\\\\\\n props = context.scene.dynamic_link_manager\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # Path management\\\\\\\\r\\\\\\\\n row = layout.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.make_paths_relative\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Make Paths Relative\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_PARENT\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.make_paths_absolute\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Make Paths Absolute\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # CharMig section (placeholder; full UI in implementation step 5)\\\\\\\\r\\\\\\\\n box = layout.box()\\\\\\\\r\\\\\\\\n box.label(text=\\\\\\\\\\\\\\\"Character Migrator\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"migrator_mode\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Automatic pair discovery\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"original_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Original\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.picker_original_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"EYEDROPPER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"replacement_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Replacement\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.picker_replacement_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"EYEDROPPER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_remove_original\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Original\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"TRASH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.run_character_migration\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"CopyAttr\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"COPY_ID\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigNLA\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"NLA\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_custom_properties\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigCustProps\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"PROPERTIES\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_bone_constraints\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigBoneConst\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_retarget_relations\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"RetargRelatives\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ORIENTATION_PARENT\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # Situational\\\\\\\\r\\\\\\\\n situational_box = layout.box()\\\\\\\\r\\\\\\\\n situational_box.label(text=\\\\\\\\\\\\\\\"Situational Fixes\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"QUESTION\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = situational_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_basebody_shapekeys\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigBBodyShapeKeys\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"SHAPEKEY_DATA\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = situational_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_fk_rotations\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigFKRot\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"BONE_DATA\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_fk_rotations_remove\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_fk_rotations_bake\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Bake\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # Tweak Tools: header row (always), main box only when expanded\\\\\\\\r\\\\\\\\n section_icon = \\\\\\\\\\\\\\\"DISCLOSURE_TRI_DOWN\\\\\\\\\\\\\\\" if props.tweak_tools_section_expanded else \\\\\\\\\\\\\\\"DISCLOSURE_TRI_RIGHT\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n row = layout.row(align=True)\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"tweak_tools_section_expanded\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=section_icon, icon_only=True)\\\\\\\\r\\\\\\\\n row.label(text=\\\\\\\\\\\\\\\"Tweak Tools\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if props.tweak_tools_section_expanded:\\\\\\\\r\\\\\\\\n tweak_box = layout.box()\\\\\\\\r\\\\\\\\n row = tweak_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_add_arm\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Add Arm\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_remove_arm\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Arm\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_bake_arm\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Bake Arm\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = tweak_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_add_leg\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Add Leg\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_remove_leg\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Leg\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_bake_leg\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Bake Leg\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = tweak_box.row(align=True)\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_add_both\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Add Both\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_remove_both\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Both\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.tweak_bake_both\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Bake Both\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = tweak_box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"tweak_nla_track_name\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"NLA track\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = tweak_box.row()\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"tweak_bake_post_clean\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Post-clean after bake\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n # Linked Libraries: header row (always), main box only when expanded\\\\\\\\r\\\\\\\\n missing_count = sum(1 for lib in props.linked_libraries if lib.is_missing)\\\\\\\\r\\\\\\\\n section_icon = \\\\\\\\\\\\\\\"DISCLOSURE_TRI_DOWN\\\\\\\\\\\\\\\" if props.linked_libraries_section_expanded else \\\\\\\\\\\\\\\"DISCLOSURE_TRI_RIGHT\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n row = layout.row(align=True)\\\\\\\\r\\\\\\\\n row.prop(props, \\\\\\\\\\\\\\\"linked_libraries_section_expanded\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=section_icon, icon_only=True)\\\\\\\\r\\\\\\\\n row.label(text=\\\\\\\\\\\\\\\"Linked Libraries Analysis\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if missing_count > 0:\\\\\\\\r\\\\\\\\n row.label(text=f\\\\\\\\\\\\\\\"({props.linked_assets_count} libs, {missing_count} missing)\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n row.label(text=f\\\\\\\\\\\\\\\"({props.linked_assets_count} libraries)\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if props.linked_libraries_section_expanded:\\\\\\\\r\\\\\\\\n box = layout.box()\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.scan_linked_assets\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Scan Linked Assets\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_REFRESH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if props.linked_assets_count > 0:\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.template_list(\\\\\\\\\\\\\\\"DLM_UL_library_list\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", props, \\\\\\\\\\\\\\\"linked_libraries\\\\\\\\\\\\\\\", props, \\\\\\\\\\\\\\\"linked_libraries_index\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.reload_libraries\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Reload Libraries\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_REFRESH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n prefs = context.preferences.addons.get(__package__.rsplit(\\\\\\\\\\\\\\\".\\\\\\\\\\\\\\\", 1)[0])\\\\\\\\r\\\\\\\\n if prefs and prefs.preferences.search_paths:\\\\\\\\r\\\\\\\\n for i, path_item in enumerate(prefs.preferences.search_paths):\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.prop(path_item, \\\\\\\\\\\\\\\"path\\\\\\\\\\\\\\\", text=f\\\\\\\\\\\\\\\"Search path {i+1}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.browse_search_path\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\").index = i\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.remove_search_path\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"REMOVE\\\\\\\\\\\\\\\").index = i\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.alignment = \\\\\\\\\\\\\\\"RIGHT\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.add_search_path\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Add search path\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ADD\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if missing_count > 0:\\\\\\\\r\\\\\\\\n row = box.row()\\\\\\\\r\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.find_libraries_in_folders\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Find libraries in these folders\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"VIEWZOOM\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if props.linked_libraries and 0 <= props.linked_libraries_index < len(props.linked_libraries):\\\\\\\\r\\\\\\\\n selected_lib = props.linked_libraries[props.linked_libraries_index]\\\\\\\\r\\\\\\\\n info_box = box.box()\\\\\\\\r\\\\\\\\n if selected_lib.is_missing:\\\\\\\\r\\\\\\\\n info_box.alert = True\\\\\\\\r\\\\\\\\n info_box.label(text=f\\\\\\\\\\\\\\\"Selected: {selected_lib.name}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n if selected_lib.is_missing:\\\\\\\\r\\\\\\\\n info_box.label(text=\\\\\\\\\\\\\\\"Status: MISSING\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n elif selected_lib.is_indirect:\\\\\\\\r\\\\\\\\n info_box.label(text=\\\\\\\\\\\\\\\"Status: INDIRECT\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n info_box.label(text=\\\\\\\\\\\\\\\"Status: OK\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_BLEND\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n info_box.label(text=f\\\\\\\\\\\\\\\"Path: {selected_lib.filepath}\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n info_box.operator(\\\\\\\\\\\\\\\"dlm.open_linked_file\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Open Blend\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_BLEND\\\\\\\\\\\\\\\").filepath = selected_lib.filepath\\\\\\\\r\\\\\\\\n op = info_box.operator(\\\\\\\\\\\\\\\"dlm.relocate_single_library\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Relocate Library\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"FILE_FOLDER\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n op.target_filepath = selected_lib.filepath\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"574bbe54-dabc-480b-a8b9-20c408e49dd5\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"40ab1c57-e081-4983-9506-19f4d38dd172\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.842Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:1\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"cat t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:1\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"cat\\\\\\\"],\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"cat\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"cat t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\"}]},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"Read operators.py content\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"success\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"cat t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\",\\\\\\\"stdout\\\\\\\":\\\\\\\"# This program is free software; you can redistribute it and/or modify\\\\\\\\r\\\\\\\\n# it under the terms of the GNU General Public License as published by\\\\\\\\r\\\\\\\\n# the Free Software Foundation; either version 3 of the License, or\\\\\\\\r\\\\\\\\n# (at your option) any later version.\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nimport bpy\\\\\\\\r\\\\\\\\nimport os\\\\\\\\r\\\\\\\\nfrom bpy.types import Operator\\\\\\\\r\\\\\\\\nfrom bpy.props import StringProperty, BoolProperty\\\\\\\\r\\\\\\\\nfrom bpy.props import StringProperty, IntProperty\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nADDON_NAME = __package__.rsplit(\\\\\\\\\\\\\\\".\\\\\\\\\\\\\\\", 1)[0] if \\\\\\\\\\\\\\\".\\\\\\\\\\\\\\\" in __package__ else __package__\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\ndef _prefs(context):\\\\\\\\r\\\\\\\\n return context.preferences.addons.get(ADDON_NAME)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_replace_linked_asset(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.replace_linked_asset\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Replace Linked Asset\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Open file browser to replace the linked asset with another file\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n filepath: StringProperty(name=\\\\\\\\\\\\\\\"File Path\\\\\\\\\\\\\\\", description=\\\\\\\\\\\\\\\"Path to the new asset file\\\\\\\\\\\\\\\", subtype=\\\\\\\\\\\\\\\"FILE_PATH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n obj = context.active_object\\\\\\\\r\\\\\\\\n if not obj:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No object selected\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n if getattr(obj, \\\\\\\\\\\\\\\"library\\\\\\\\\\\\\\\", None):\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Object '{obj.name}' is linked from: {obj.library.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n if obj.data and getattr(obj.data, \\\\\\\\\\\\\\\"library\\\\\\\\\\\\\\\", None) and obj.data.library:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Object '{obj.name}' has linked data from: {obj.data.library.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n if obj.type == \\\\\\\\\\\\\\\"ARMATURE\\\\\\\\\\\\\\\" and obj.data and obj.data.name in bpy.data.armatures:\\\\\\\\r\\\\\\\\n ad = bpy.data.armatures[obj.data.name]\\\\\\\\r\\\\\\\\n if getattr(ad, \\\\\\\\\\\\\\\"library\\\\\\\\\\\\\\\", None) and ad.library:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Armature '{obj.name}' data is linked from: {ad.library.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Selected object is not a linked asset\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def invoke(self, context, event):\\\\\\\\r\\\\\\\\n context.window_manager.fileselect_add(self)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"RUNNING_MODAL\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_scan_linked_assets(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.scan_linked_assets\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Scan Linked Libraries\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Scan the current file for linked libraries and list their status\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n from ..ops import library\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n return library.scan_linked_assets(context, self.report)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_find_libraries_in_folders(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.find_libraries_in_folders\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Find Libraries in Folders\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Search addon search paths for missing library blend files\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n from ..ops import library\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n return library.find_libraries_in_folders(context, self.report, ADDON_NAME)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_open_linked_file(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.open_linked_file\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Open Linked File\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Open the selected linked blend file in a new Blender instance\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n filepath: StringProperty(name=\\\\\\\\\\\\\\\"File Path\\\\\\\\\\\\\\\", default=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n if not self.filepath:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No file path specified\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n bpy.ops.wm.path_open(filepath=self.filepath)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Opening linked file: {self.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to open linked file: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_add_search_path(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.add_search_path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Add Search Path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Add a new folder to the list of search paths for finding libraries\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n prefs = _prefs(context)\\\\\\\\r\\\\\\\\n if prefs:\\\\\\\\r\\\\\\\\n p = prefs.preferences.search_paths.add()\\\\\\\\r\\\\\\\\n p.path = \\\\\\\\\\\\\\\"//\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Added search path: {p.path}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_remove_search_path(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.remove_search_path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Search Path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove the selected search path from the list\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n index: IntProperty(name=\\\\\\\\\\\\\\\"Index\\\\\\\\\\\\\\\", default=0)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n prefs = _prefs(context)\\\\\\\\r\\\\\\\\n if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths):\\\\\\\\r\\\\\\\\n prefs.preferences.search_paths.remove(self.index)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed search path at index {self.index}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_attempt_relink(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.attempt_relink\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Attempt Relink\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Try to relink missing libraries using the configured search paths\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n from ..ops import library\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n return library.attempt_relink(context, self.report, ADDON_NAME)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_browse_search_path(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.browse_search_path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Browse Search Path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Browse to set the folder for the selected search path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n index: IntProperty(name=\\\\\\\\\\\\\\\"Index\\\\\\\\\\\\\\\", default=0)\\\\\\\\r\\\\\\\\n filepath: StringProperty(name=\\\\\\\\\\\\\\\"Search Path\\\\\\\\\\\\\\\", subtype=\\\\\\\\\\\\\\\"DIR_PATH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n prefs = _prefs(context)\\\\\\\\r\\\\\\\\n if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths):\\\\\\\\r\\\\\\\\n prefs.preferences.search_paths[self.index].path = self.filepath\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Updated search path {self.index + 1}: {self.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def invoke(self, context, event):\\\\\\\\r\\\\\\\\n prefs = _prefs(context)\\\\\\\\r\\\\\\\\n if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths):\\\\\\\\r\\\\\\\\n self.filepath = prefs.preferences.search_paths[self.index].path\\\\\\\\r\\\\\\\\n context.window_manager.fileselect_add(self)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"RUNNING_MODAL\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_reload_libraries(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.reload_libraries\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Reload Libraries\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Reload all linked libraries (or fallback manual reload)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n bpy.ops.outliner.lib_operation(type=\\\\\\\\\\\\\\\"RELOAD\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Library reload operation completed\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception:\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n for lib in bpy.data.libraries:\\\\\\\\r\\\\\\\\n if lib.filepath and os.path.exists(bpy.path.abspath(lib.filepath)):\\\\\\\\r\\\\\\\\n lib.reload()\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Libraries reloaded manually\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to reload libraries: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_make_paths_relative(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.make_paths_relative\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Make Paths Relative\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Convert all internal file paths to relative\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n bpy.ops.file.make_paths_relative()\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"All file paths made relative\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to make paths relative: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_make_paths_absolute(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.make_paths_absolute\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Make Paths Absolute\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Convert all internal file paths to absolute\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n bpy.ops.file.make_paths_absolute()\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"All file paths made absolute\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to make paths absolute: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_relocate_single_library(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.relocate_single_library\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Relocate Library\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Point the selected library to a new blend file and reload\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n target_filepath: StringProperty(name=\\\\\\\\\\\\\\\"Current Library Path\\\\\\\\\\\\\\\", default=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n filepath: StringProperty(name=\\\\\\\\\\\\\\\"New Library File\\\\\\\\\\\\\\\", subtype=\\\\\\\\\\\\\\\"FILE_PATH\\\\\\\\\\\\\\\", default=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n if not self.target_filepath or not self.filepath:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No target or new file specified\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n abs_match = bpy.path.abspath(self.target_filepath) if self.target_filepath else \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n library = None\\\\\\\\r\\\\\\\\n for lib in bpy.data.libraries:\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n if lib.filepath and bpy.path.abspath(lib.filepath) == abs_match:\\\\\\\\r\\\\\\\\n library = lib\\\\\\\\r\\\\\\\\n break\\\\\\\\r\\\\\\\\n except Exception:\\\\\\\\r\\\\\\\\n if lib.filepath == self.target_filepath:\\\\\\\\r\\\\\\\\n library = lib\\\\\\\\r\\\\\\\\n break\\\\\\\\r\\\\\\\\n if not library:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Could not resolve the selected library\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n library.filepath = self.filepath\\\\\\\\r\\\\\\\\n library.reload()\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Relocated to: {self.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to relocate: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def invoke(self, context, event):\\\\\\\\r\\\\\\\\n if self.target_filepath:\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n self.filepath = bpy.path.abspath(self.target_filepath)\\\\\\\\r\\\\\\\\n except Exception:\\\\\\\\r\\\\\\\\n self.filepath = self.target_filepath\\\\\\\\r\\\\\\\\n context.window_manager.fileselect_add(self)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"RUNNING_MODAL\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\ndef _get_migrator_pair(context):\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"Return (orig, rep) from scene props (manual or automatic). (None, None) if invalid.\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n from ..ops.migrator import get_pair_manual, get_pair_automatic\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n props = getattr(context.scene, \\\\\\\\\\\\\\\"dynamic_link_manager\\\\\\\\\\\\\\\", None)\\\\\\\\r\\\\\\\\n if not props:\\\\\\\\r\\\\\\\\n return None, None\\\\\\\\r\\\\\\\\n use_auto = getattr(props, \\\\\\\\\\\\\\\"migrator_mode\\\\\\\\\\\\\\\", False)\\\\\\\\r\\\\\\\\n orig, rep = get_pair_automatic(context) if use_auto else get_pair_manual(context)\\\\\\\\r\\\\\\\\n return orig, rep\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_copy_attributes(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"CopyAttr\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Copy object and armature attributes from original to replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"COPY_ID\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair (set Original/Replacement or enable Automatic).\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_copy_attr\\\\\\\\r\\\\\\\\n run_copy_attr(orig, rep)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Copy attributes done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_migrate_nla(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigNLA\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Migrate NLA tracks and strips from original to replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"NLA\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_mig_nla\\\\\\\\r\\\\\\\\n run_mig_nla(orig, rep, report=self.report)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_custom_properties(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_custom_properties\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigCustProps\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Copy custom properties from original to replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"PROPERTIES\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_mig_cust_props\\\\\\\\r\\\\\\\\n run_mig_cust_props(orig, rep)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Custom properties done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_bone_constraints(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_bone_constraints\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigBoneConst\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Migrate bone constraints from original to replacement armature\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_mig_bone_const\\\\\\\\r\\\\\\\\n orig_to_rep = {orig: rep}\\\\\\\\r\\\\\\\\n run_mig_bone_const(orig, rep, orig_to_rep)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Bone constraints done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_retarget_relations(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_retarget_relations\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"RetargRelatives\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Retarget parent/child and other relations to the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"ORIENTATION_PARENT\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_retarg_relatives\\\\\\\\r\\\\\\\\n from ..utils import descendants\\\\\\\\r\\\\\\\\n rep_descendants = descendants(rep)\\\\\\\\r\\\\\\\\n orig_to_rep = {orig: rep}\\\\\\\\r\\\\\\\\n run_retarg_relatives(orig, rep, rep_descendants, orig_to_rep)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Retarget relations done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_basebody_shapekeys(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_basebody_shapekeys\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigBBodyShapeKeys\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Migrate base body mesh shape key values from original to replacement\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"SHAPEKEY_DATA\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_mig_bbody_shapekeys\\\\\\\\r\\\\\\\\n from ..utils import descendants\\\\\\\\r\\\\\\\\n rep_descendants = descendants(rep)\\\\\\\\r\\\\\\\\n run_mig_bbody_shapekeys(orig, rep, rep_descendants, context)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Migrate BaseBody shapekeys done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_fk_rotations(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_fk_rotations\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigFKRot\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Copy FK arm and finger rotations from original to replacement (uses constraints)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"BONE_DATA\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.fk_rotations import copy_fk_rotations\\\\\\\\r\\\\\\\\n ok, msg = copy_fk_rotations(context, orig, rep)\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_fk_rotations_bake(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_fk_rotations_bake\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Bake MigFKRot\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Bake FK rotations to keyframes using nla.bake (similar to tweak tools)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n track_name: StringProperty(name=\\\\\\\\\\\\\\\"NLA Track\\\\\\\\\\\\\\\", description=\\\\\\\\\\\\\\\"Optional NLA track name for frame range\\\\\\\\\\\\\\\", default=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n post_clean: BoolProperty(name=\\\\\\\\\\\\\\\"Post-clean\\\\\\\\\\\\\\\", description=\\\\\\\\\\\\\\\"Clean curves after bake\\\\\\\\\\\\\\\", default=False)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.fk_rotations import bake_fk_rotations\\\\\\\\r\\\\\\\\n ok, msg = bake_fk_rotations(context, orig, rep, track_name=self.track_name or None, post_clean=self.post_clean)\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_fk_rotations_remove(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_fk_rotations_remove\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove MigFKRot\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove FK rotation COPY_TRANSFORMS constraints (similar to tweak_remove_arm)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.fk_rotations import remove_fk_rotations\\\\\\\\r\\\\\\\\n ok, msg = remove_fk_rotations(context, rep)\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nMIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_custom_properties\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_bone_constraints\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_retarget_relations\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_basebody_shapekeys\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_remove_original(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_remove_original\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Original\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Delete the original character armature and its data from the scene\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"WARNING\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No original character selected\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n if orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Original and replacement cannot be the same object\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n name = orig.name\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n # Remove from scene\\\\\\\\r\\\\\\\\n bpy.data.objects.remove(orig, do_unlink=True)\\\\\\\\r\\\\\\\\n # Clear the property\\\\\\\\r\\\\\\\\n context.scene.dynamic_link_manager.original_character = None\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed original character: {name}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to remove original: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_run_character_migration(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.run_character_migration\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Run Character Migration\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Run all six migration steps (CopyAttr, MigNLA, MigCustProps, MigBoneConst, RetargRelatives, MigBBodyShapeKeys) in order\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n steps = [\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_copy_attributes,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_migrate_nla,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_custom_properties,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_bone_constraints,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_retarget_relations,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_basebody_shapekeys,\\\\\\\\r\\\\\\\\n ]\\\\\\\\r\\\\\\\\n for i, op in enumerate(steps):\\\\\\\\r\\\\\\\\n result = op()\\\\\\\\r\\\\\\\\n if result != {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Migration failed at step {i + 1}: {MIGRATOR_STEP_OPS[i]}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Migration complete.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_picker_original_character(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.picker_original_character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Pick Original\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Set the original character armature from the active object\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n obj = context.active_object\\\\\\\\r\\\\\\\\n if not obj or obj.type != \\\\\\\\\\\\\\\"ARMATURE\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"WARNING\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Select an armature\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n context.scene.dynamic_link_manager.original_character = obj\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Original: {obj.name}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_picker_replacement_character(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.picker_replacement_character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Pick Replacement\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Set the replacement character armature from the active object\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n obj = context.active_object\\\\\\\\r\\\\\\\\n if not obj or obj.type != \\\\\\\\\\\\\\\"ARMATURE\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"WARNING\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Select an armature\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n context.scene.dynamic_link_manager.replacement_character = obj\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Replacement: {obj.name}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\ndef _tweak_poll(context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n return orig is not None and rep is not None\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_add_arm(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_add_arm\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Add Arm Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Add tweak bone constraints to arm bones on the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n tweak_tools.add_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"arm\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Arm tweak constraints added.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_remove_arm(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_remove_arm\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Arm Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove arm tweak constraints from the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n n = tweak_tools.remove_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"arm\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed {n} arm tweak constraints.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_bake_arm(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_bake_arm\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Bake Arm Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Bake arm tweak constraints to keyframes and optionally remove constraints\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n props = context.scene.dynamic_link_manager\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n ok, msg = tweak_tools.bake_tweak_constraints(\\\\\\\\r\\\\\\\\n context, orig, rep, \\\\\\\\\\\\\\\"arm\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_nla_track_name\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\") or \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_bake_post_clean\\\\\\\\\\\\\\\", False),\\\\\\\\r\\\\\\\\n )\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_add_leg(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_add_leg\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Add Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Add tweak bone constraints to leg bones on the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n tweak_tools.add_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"leg\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Leg tweak constraints added.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_remove_leg(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_remove_leg\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove leg tweak constraints from the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n n = tweak_tools.remove_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"leg\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed {n} leg tweak constraints.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_bake_leg(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_bake_leg\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Bake Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Bake leg tweak constraints to keyframes and optionally remove constraints\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n props = context.scene.dynamic_link_manager\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n ok, msg = tweak_tools.bake_tweak_constraints(\\\\\\\\r\\\\\\\\n context, orig, rep, \\\\\\\\\\\\\\\"leg\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_nla_track_name\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\") or \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_bake_post_clean\\\\\\\\\\\\\\\", False),\\\\\\\\r\\\\\\\\n )\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_add_both(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_add_both\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Add Arm & Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Add tweak bone constraints to both arm and leg bones\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n tweak_tools.add_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"both\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Arm & leg tweak constraints added.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_remove_both(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_remove_both\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Arm & Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove all arm and leg tweak constraints from the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n n = tweak_tools.remove_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"both\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed {n} tweak constraints.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_bake_both(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_bake_both\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Bake Arm & Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Bake all arm and leg tweak constraints to keyframes and optionally remove constraints\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n props = context.scene.dynamic_link_manager\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n ok, msg = tweak_tools.bake_tweak_constraints(\\\\\\\\r\\\\\\\\n context, orig, rep, \\\\\\\\\\\\\\\"both\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_nla_track_name\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\") or \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_bake_post_clean\\\\\\\\\\\\\\\", False),\\\\\\\\r\\\\\\\\n )\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nOPERATOR_CLASSES = [\\\\\\\\r\\\\\\\\n DLM_OT_replace_linked_asset,\\\\\\\\r\\\\\\\\n DLM_OT_scan_linked_assets,\\\\\\\\r\\\\\\\\n DLM_OT_find_libraries_in_folders,\\\\\\\\r\\\\\\\\n DLM_OT_open_linked_file,\\\\\\\\r\\\\\\\\n DLM_OT_add_search_path,\\\\\\\\r\\\\\\\\n DLM_OT_remove_search_path,\\\\\\\\r\\\\\\\\n DLM_OT_browse_search_path,\\\\\\\\r\\\\\\\\n DLM_OT_attempt_relink,\\\\\\\\r\\\\\\\\n DLM_OT_reload_libraries,\\\\\\\\r\\\\\\\\n DLM_OT_make_paths_relative,\\\\\\\\r\\\\\\\\n DLM_OT_make_paths_absolute,\\\\\\\\r\\\\\\\\n DLM_OT_relocate_single_library,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_remove_original,\\\\\\\\r\\\\\\\\n DLM_OT_run_character_migration,\\\\\\\\r\\\\\\\\n DLM_OT_picker_original_character,\\\\\\\\r\\\\\\\\n DLM_OT_picker_replacement_character,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_copy_attributes,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_migrate_nla,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_custom_properties,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_bone_constraints,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_retarget_relations,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_basebody_shapekeys,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_add_arm,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_remove_arm,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_bake_arm,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_add_leg,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_remove_leg,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_bake_leg,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_add_both,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_remove_both,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_bake_both,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_fk_rotations,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_fk_rotations_bake,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_fk_rotations_remove,\\\\\\\\r\\\\\\\\n]\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"executionTime\\\\\\\":2999,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"# This program is free software; you can redistribute it and/or modify\\\\\\\\r\\\\\\\\n# it under the terms of the GNU General Public License as published by\\\\\\\\r\\\\\\\\n# the Free Software Foundation; either version 3 of the License, or\\\\\\\\r\\\\\\\\n# (at your option) any later version.\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nimport bpy\\\\\\\\r\\\\\\\\nimport os\\\\\\\\r\\\\\\\\nfrom bpy.types import Operator\\\\\\\\r\\\\\\\\nfrom bpy.props import StringProperty, BoolProperty\\\\\\\\r\\\\\\\\nfrom bpy.props import StringProperty, IntProperty\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nADDON_NAME = __package__.rsplit(\\\\\\\\\\\\\\\".\\\\\\\\\\\\\\\", 1)[0] if \\\\\\\\\\\\\\\".\\\\\\\\\\\\\\\" in __package__ else __package__\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\ndef _prefs(context):\\\\\\\\r\\\\\\\\n return context.preferences.addons.get(ADDON_NAME)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_replace_linked_asset(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.replace_linked_asset\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Replace Linked Asset\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Open file browser to replace the linked asset with another file\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n filepath: StringProperty(name=\\\\\\\\\\\\\\\"File Path\\\\\\\\\\\\\\\", description=\\\\\\\\\\\\\\\"Path to the new asset file\\\\\\\\\\\\\\\", subtype=\\\\\\\\\\\\\\\"FILE_PATH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n obj = context.active_object\\\\\\\\r\\\\\\\\n if not obj:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No object selected\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n if getattr(obj, \\\\\\\\\\\\\\\"library\\\\\\\\\\\\\\\", None):\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Object '{obj.name}' is linked from: {obj.library.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n if obj.data and getattr(obj.data, \\\\\\\\\\\\\\\"library\\\\\\\\\\\\\\\", None) and obj.data.library:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Object '{obj.name}' has linked data from: {obj.data.library.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n if obj.type == \\\\\\\\\\\\\\\"ARMATURE\\\\\\\\\\\\\\\" and obj.data and obj.data.name in bpy.data.armatures:\\\\\\\\r\\\\\\\\n ad = bpy.data.armatures[obj.data.name]\\\\\\\\r\\\\\\\\n if getattr(ad, \\\\\\\\\\\\\\\"library\\\\\\\\\\\\\\\", None) and ad.library:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Armature '{obj.name}' data is linked from: {ad.library.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Selected object is not a linked asset\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def invoke(self, context, event):\\\\\\\\r\\\\\\\\n context.window_manager.fileselect_add(self)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"RUNNING_MODAL\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_scan_linked_assets(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.scan_linked_assets\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Scan Linked Libraries\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Scan the current file for linked libraries and list their status\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n from ..ops import library\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n return library.scan_linked_assets(context, self.report)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_find_libraries_in_folders(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.find_libraries_in_folders\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Find Libraries in Folders\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Search addon search paths for missing library blend files\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n from ..ops import library\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n return library.find_libraries_in_folders(context, self.report, ADDON_NAME)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_open_linked_file(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.open_linked_file\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Open Linked File\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Open the selected linked blend file in a new Blender instance\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n filepath: StringProperty(name=\\\\\\\\\\\\\\\"File Path\\\\\\\\\\\\\\\", default=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n if not self.filepath:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No file path specified\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n bpy.ops.wm.path_open(filepath=self.filepath)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Opening linked file: {self.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to open linked file: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_add_search_path(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.add_search_path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Add Search Path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Add a new folder to the list of search paths for finding libraries\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n prefs = _prefs(context)\\\\\\\\r\\\\\\\\n if prefs:\\\\\\\\r\\\\\\\\n p = prefs.preferences.search_paths.add()\\\\\\\\r\\\\\\\\n p.path = \\\\\\\\\\\\\\\"//\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Added search path: {p.path}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_remove_search_path(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.remove_search_path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Search Path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove the selected search path from the list\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n index: IntProperty(name=\\\\\\\\\\\\\\\"Index\\\\\\\\\\\\\\\", default=0)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n prefs = _prefs(context)\\\\\\\\r\\\\\\\\n if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths):\\\\\\\\r\\\\\\\\n prefs.preferences.search_paths.remove(self.index)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed search path at index {self.index}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_attempt_relink(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.attempt_relink\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Attempt Relink\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Try to relink missing libraries using the configured search paths\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n from ..ops import library\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n return library.attempt_relink(context, self.report, ADDON_NAME)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_browse_search_path(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.browse_search_path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Browse Search Path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Browse to set the folder for the selected search path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n index: IntProperty(name=\\\\\\\\\\\\\\\"Index\\\\\\\\\\\\\\\", default=0)\\\\\\\\r\\\\\\\\n filepath: StringProperty(name=\\\\\\\\\\\\\\\"Search Path\\\\\\\\\\\\\\\", subtype=\\\\\\\\\\\\\\\"DIR_PATH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n prefs = _prefs(context)\\\\\\\\r\\\\\\\\n if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths):\\\\\\\\r\\\\\\\\n prefs.preferences.search_paths[self.index].path = self.filepath\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Updated search path {self.index + 1}: {self.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def invoke(self, context, event):\\\\\\\\r\\\\\\\\n prefs = _prefs(context)\\\\\\\\r\\\\\\\\n if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths):\\\\\\\\r\\\\\\\\n self.filepath = prefs.preferences.search_paths[self.index].path\\\\\\\\r\\\\\\\\n context.window_manager.fileselect_add(self)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"RUNNING_MODAL\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_reload_libraries(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.reload_libraries\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Reload Libraries\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Reload all linked libraries (or fallback manual reload)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n bpy.ops.outliner.lib_operation(type=\\\\\\\\\\\\\\\"RELOAD\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Library reload operation completed\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception:\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n for lib in bpy.data.libraries:\\\\\\\\r\\\\\\\\n if lib.filepath and os.path.exists(bpy.path.abspath(lib.filepath)):\\\\\\\\r\\\\\\\\n lib.reload()\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Libraries reloaded manually\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to reload libraries: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_make_paths_relative(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.make_paths_relative\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Make Paths Relative\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Convert all internal file paths to relative\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n bpy.ops.file.make_paths_relative()\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"All file paths made relative\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to make paths relative: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_make_paths_absolute(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.make_paths_absolute\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Make Paths Absolute\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Convert all internal file paths to absolute\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n bpy.ops.file.make_paths_absolute()\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"All file paths made absolute\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to make paths absolute: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_relocate_single_library(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.relocate_single_library\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Relocate Library\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Point the selected library to a new blend file and reload\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n target_filepath: StringProperty(name=\\\\\\\\\\\\\\\"Current Library Path\\\\\\\\\\\\\\\", default=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n filepath: StringProperty(name=\\\\\\\\\\\\\\\"New Library File\\\\\\\\\\\\\\\", subtype=\\\\\\\\\\\\\\\"FILE_PATH\\\\\\\\\\\\\\\", default=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n if not self.target_filepath or not self.filepath:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No target or new file specified\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n abs_match = bpy.path.abspath(self.target_filepath) if self.target_filepath else \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n library = None\\\\\\\\r\\\\\\\\n for lib in bpy.data.libraries:\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n if lib.filepath and bpy.path.abspath(lib.filepath) == abs_match:\\\\\\\\r\\\\\\\\n library = lib\\\\\\\\r\\\\\\\\n break\\\\\\\\r\\\\\\\\n except Exception:\\\\\\\\r\\\\\\\\n if lib.filepath == self.target_filepath:\\\\\\\\r\\\\\\\\n library = lib\\\\\\\\r\\\\\\\\n break\\\\\\\\r\\\\\\\\n if not library:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Could not resolve the selected library\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n library.filepath = self.filepath\\\\\\\\r\\\\\\\\n library.reload()\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Relocated to: {self.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to relocate: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def invoke(self, context, event):\\\\\\\\r\\\\\\\\n if self.target_filepath:\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n self.filepath = bpy.path.abspath(self.target_filepath)\\\\\\\\r\\\\\\\\n except Exception:\\\\\\\\r\\\\\\\\n self.filepath = self.target_filepath\\\\\\\\r\\\\\\\\n context.window_manager.fileselect_add(self)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"RUNNING_MODAL\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\ndef _get_migrator_pair(context):\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"Return (orig, rep) from scene props (manual or automatic). (None, None) if invalid.\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n from ..ops.migrator import get_pair_manual, get_pair_automatic\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n props = getattr(context.scene, \\\\\\\\\\\\\\\"dynamic_link_manager\\\\\\\\\\\\\\\", None)\\\\\\\\r\\\\\\\\n if not props:\\\\\\\\r\\\\\\\\n return None, None\\\\\\\\r\\\\\\\\n use_auto = getattr(props, \\\\\\\\\\\\\\\"migrator_mode\\\\\\\\\\\\\\\", False)\\\\\\\\r\\\\\\\\n orig, rep = get_pair_automatic(context) if use_auto else get_pair_manual(context)\\\\\\\\r\\\\\\\\n return orig, rep\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_copy_attributes(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"CopyAttr\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Copy object and armature attributes from original to replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"COPY_ID\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair (set Original/Replacement or enable Automatic).\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_copy_attr\\\\\\\\r\\\\\\\\n run_copy_attr(orig, rep)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Copy attributes done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_migrate_nla(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigNLA\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Migrate NLA tracks and strips from original to replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"NLA\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_mig_nla\\\\\\\\r\\\\\\\\n run_mig_nla(orig, rep, report=self.report)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_custom_properties(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_custom_properties\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigCustProps\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Copy custom properties from original to replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"PROPERTIES\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_mig_cust_props\\\\\\\\r\\\\\\\\n run_mig_cust_props(orig, rep)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Custom properties done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_bone_constraints(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_bone_constraints\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigBoneConst\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Migrate bone constraints from original to replacement armature\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_mig_bone_const\\\\\\\\r\\\\\\\\n orig_to_rep = {orig: rep}\\\\\\\\r\\\\\\\\n run_mig_bone_const(orig, rep, orig_to_rep)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Bone constraints done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_retarget_relations(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_retarget_relations\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"RetargRelatives\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Retarget parent/child and other relations to the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"ORIENTATION_PARENT\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_retarg_relatives\\\\\\\\r\\\\\\\\n from ..utils import descendants\\\\\\\\r\\\\\\\\n rep_descendants = descendants(rep)\\\\\\\\r\\\\\\\\n orig_to_rep = {orig: rep}\\\\\\\\r\\\\\\\\n run_retarg_relatives(orig, rep, rep_descendants, orig_to_rep)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Retarget relations done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_basebody_shapekeys(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_basebody_shapekeys\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigBBodyShapeKeys\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Migrate base body mesh shape key values from original to replacement\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"SHAPEKEY_DATA\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_mig_bbody_shapekeys\\\\\\\\r\\\\\\\\n from ..utils import descendants\\\\\\\\r\\\\\\\\n rep_descendants = descendants(rep)\\\\\\\\r\\\\\\\\n run_mig_bbody_shapekeys(orig, rep, rep_descendants, context)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Migrate BaseBody shapekeys done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_fk_rotations(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_fk_rotations\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigFKRot\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Copy FK arm and finger rotations from original to replacement (uses constraints)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"BONE_DATA\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.fk_rotations import copy_fk_rotations\\\\\\\\r\\\\\\\\n ok, msg = copy_fk_rotations(context, orig, rep)\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_fk_rotations_bake(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_fk_rotations_bake\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Bake MigFKRot\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Bake FK rotations to keyframes using nla.bake (similar to tweak tools)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n track_name: StringProperty(name=\\\\\\\\\\\\\\\"NLA Track\\\\\\\\\\\\\\\", description=\\\\\\\\\\\\\\\"Optional NLA track name for frame range\\\\\\\\\\\\\\\", default=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n post_clean: BoolProperty(name=\\\\\\\\\\\\\\\"Post-clean\\\\\\\\\\\\\\\", description=\\\\\\\\\\\\\\\"Clean curves after bake\\\\\\\\\\\\\\\", default=False)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.fk_rotations import bake_fk_rotations\\\\\\\\r\\\\\\\\n ok, msg = bake_fk_rotations(context, orig, rep, track_name=self.track_name or None, post_clean=self.post_clean)\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_fk_rotations_remove(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_fk_rotations_remove\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove MigFKRot\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove FK rotation COPY_TRANSFORMS constraints (similar to tweak_remove_arm)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.fk_rotations import remove_fk_rotations\\\\\\\\r\\\\\\\\n ok, msg = remove_fk_rotations(context, rep)\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nMIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_custom_properties\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_bone_constraints\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_retarget_relations\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_basebody_shapekeys\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_remove_original(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_remove_original\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Original\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Delete the original character armature and its data from the scene\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"WARNING\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No original character selected\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n if orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Original and replacement cannot be the same object\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n name = orig.name\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n # Remove from scene\\\\\\\\r\\\\\\\\n bpy.data.objects.remove(orig, do_unlink=True)\\\\\\\\r\\\\\\\\n # Clear the property\\\\\\\\r\\\\\\\\n context.scene.dynamic_link_manager.original_character = None\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed original character: {name}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to remove original: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_run_character_migration(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.run_character_migration\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Run Character Migration\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Run all six migration steps (CopyAttr, MigNLA, MigCustProps, MigBoneConst, RetargRelatives, MigBBodyShapeKeys) in order\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n steps = [\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_copy_attributes,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_migrate_nla,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_custom_properties,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_bone_constraints,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_retarget_relations,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_basebody_shapekeys,\\\\\\\\r\\\\\\\\n ]\\\\\\\\r\\\\\\\\n for i, op in enumerate(steps):\\\\\\\\r\\\\\\\\n result = op()\\\\\\\\r\\\\\\\\n if result != {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Migration failed at step {i + 1}: {MIGRATOR_STEP_OPS[i]}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Migration complete.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_picker_original_character(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.picker_original_character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Pick Original\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Set the original character armature from the active object\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n obj = context.active_object\\\\\\\\r\\\\\\\\n if not obj or obj.type != \\\\\\\\\\\\\\\"ARMATURE\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"WARNING\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Select an armature\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n context.scene.dynamic_link_manager.original_character = obj\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Original: {obj.name}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_picker_replacement_character(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.picker_replacement_character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Pick Replacement\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Set the replacement character armature from the active object\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n obj = context.active_object\\\\\\\\r\\\\\\\\n if not obj or obj.type != \\\\\\\\\\\\\\\"ARMATURE\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"WARNING\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Select an armature\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n context.scene.dynamic_link_manager.replacement_character = obj\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Replacement: {obj.name}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\ndef _tweak_poll(context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n return orig is not None and rep is not None\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_add_arm(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_add_arm\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Add Arm Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Add tweak bone constraints to arm bones on the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n tweak_tools.add_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"arm\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Arm tweak constraints added.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_remove_arm(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_remove_arm\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Arm Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove arm tweak constraints from the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n n = tweak_tools.remove_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"arm\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed {n} arm tweak constraints.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_bake_arm(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_bake_arm\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Bake Arm Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Bake arm tweak constraints to keyframes and optionally remove constraints\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n props = context.scene.dynamic_link_manager\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n ok, msg = tweak_tools.bake_tweak_constraints(\\\\\\\\r\\\\\\\\n context, orig, rep, \\\\\\\\\\\\\\\"arm\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_nla_track_name\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\") or \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_bake_post_clean\\\\\\\\\\\\\\\", False),\\\\\\\\r\\\\\\\\n )\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_add_leg(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_add_leg\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Add Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Add tweak bone constraints to leg bones on the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n tweak_tools.add_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"leg\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Leg tweak constraints added.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_remove_leg(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_remove_leg\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove leg tweak constraints from the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n n = tweak_tools.remove_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"leg\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed {n} leg tweak constraints.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_bake_leg(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_bake_leg\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Bake Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Bake leg tweak constraints to keyframes and optionally remove constraints\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n props = context.scene.dynamic_link_manager\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n ok, msg = tweak_tools.bake_tweak_constraints(\\\\\\\\r\\\\\\\\n context, orig, rep, \\\\\\\\\\\\\\\"leg\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_nla_track_name\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\") or \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_bake_post_clean\\\\\\\\\\\\\\\", False),\\\\\\\\r\\\\\\\\n )\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_add_both(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_add_both\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Add Arm & Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Add tweak bone constraints to both arm and leg bones\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n tweak_tools.add_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"both\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Arm & leg tweak constraints added.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_remove_both(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_remove_both\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Arm & Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove all arm and leg tweak constraints from the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n n = tweak_tools.remove_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"both\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed {n} tweak constraints.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_bake_both(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_bake_both\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Bake Arm & Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Bake all arm and leg tweak constraints to keyframes and optionally remove constraints\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n props = context.scene.dynamic_link_manager\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n ok, msg = tweak_tools.bake_tweak_constraints(\\\\\\\\r\\\\\\\\n context, orig, rep, \\\\\\\\\\\\\\\"both\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_nla_track_name\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\") or \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_bake_post_clean\\\\\\\\\\\\\\\", False),\\\\\\\\r\\\\\\\\n )\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nOPERATOR_CLASSES = [\\\\\\\\r\\\\\\\\n DLM_OT_replace_linked_asset,\\\\\\\\r\\\\\\\\n DLM_OT_scan_linked_assets,\\\\\\\\r\\\\\\\\n DLM_OT_find_libraries_in_folders,\\\\\\\\r\\\\\\\\n DLM_OT_open_linked_file,\\\\\\\\r\\\\\\\\n DLM_OT_add_search_path,\\\\\\\\r\\\\\\\\n DLM_OT_remove_search_path,\\\\\\\\r\\\\\\\\n DLM_OT_browse_search_path,\\\\\\\\r\\\\\\\\n DLM_OT_attempt_relink,\\\\\\\\r\\\\\\\\n DLM_OT_reload_libraries,\\\\\\\\r\\\\\\\\n DLM_OT_make_paths_relative,\\\\\\\\r\\\\\\\\n DLM_OT_make_paths_absolute,\\\\\\\\r\\\\\\\\n DLM_OT_relocate_single_library,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_remove_original,\\\\\\\\r\\\\\\\\n DLM_OT_run_character_migration,\\\\\\\\r\\\\\\\\n DLM_OT_picker_original_character,\\\\\\\\r\\\\\\\\n DLM_OT_picker_replacement_character,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_copy_attributes,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_migrate_nla,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_custom_properties,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_bone_constraints,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_retarget_relations,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_basebody_shapekeys,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_add_arm,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_remove_arm,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_bake_arm,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_add_leg,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_remove_leg,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_bake_leg,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_add_both,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_remove_both,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_bake_both,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_fk_rotations,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_fk_rotations_bake,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_fk_rotations_remove,\\\\\\\\r\\\\\\\\n]\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":2959},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"Read operators.py content\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"success\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"cat t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"cat\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"cat t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\"}]},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"Read operators.py content\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"output\\\\\\\":\\\\\\\"# This program is free software; you can redistribute it and/or modify\\\\\\\\r\\\\\\\\n# it under the terms of the GNU General Public License as published by\\\\\\\\r\\\\\\\\n# the Free Software Foundation; either version 3 of the License, or\\\\\\\\r\\\\\\\\n# (at your option) any later version.\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nimport bpy\\\\\\\\r\\\\\\\\nimport os\\\\\\\\r\\\\\\\\nfrom bpy.types import Operator\\\\\\\\r\\\\\\\\nfrom bpy.props import StringProperty, BoolProperty\\\\\\\\r\\\\\\\\nfrom bpy.props import StringProperty, IntProperty\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nADDON_NAME = __package__.rsplit(\\\\\\\\\\\\\\\".\\\\\\\\\\\\\\\", 1)[0] if \\\\\\\\\\\\\\\".\\\\\\\\\\\\\\\" in __package__ else __package__\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\ndef _prefs(context):\\\\\\\\r\\\\\\\\n return context.preferences.addons.get(ADDON_NAME)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_replace_linked_asset(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.replace_linked_asset\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Replace Linked Asset\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Open file browser to replace the linked asset with another file\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n filepath: StringProperty(name=\\\\\\\\\\\\\\\"File Path\\\\\\\\\\\\\\\", description=\\\\\\\\\\\\\\\"Path to the new asset file\\\\\\\\\\\\\\\", subtype=\\\\\\\\\\\\\\\"FILE_PATH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n obj = context.active_object\\\\\\\\r\\\\\\\\n if not obj:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No object selected\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n if getattr(obj, \\\\\\\\\\\\\\\"library\\\\\\\\\\\\\\\", None):\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Object '{obj.name}' is linked from: {obj.library.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n if obj.data and getattr(obj.data, \\\\\\\\\\\\\\\"library\\\\\\\\\\\\\\\", None) and obj.data.library:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Object '{obj.name}' has linked data from: {obj.data.library.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n if obj.type == \\\\\\\\\\\\\\\"ARMATURE\\\\\\\\\\\\\\\" and obj.data and obj.data.name in bpy.data.armatures:\\\\\\\\r\\\\\\\\n ad = bpy.data.armatures[obj.data.name]\\\\\\\\r\\\\\\\\n if getattr(ad, \\\\\\\\\\\\\\\"library\\\\\\\\\\\\\\\", None) and ad.library:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Armature '{obj.name}' data is linked from: {ad.library.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Selected object is not a linked asset\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def invoke(self, context, event):\\\\\\\\r\\\\\\\\n context.window_manager.fileselect_add(self)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"RUNNING_MODAL\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_scan_linked_assets(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.scan_linked_assets\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Scan Linked Libraries\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Scan the current file for linked libraries and list their status\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n from ..ops import library\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n return library.scan_linked_assets(context, self.report)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_find_libraries_in_folders(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.find_libraries_in_folders\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Find Libraries in Folders\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Search addon search paths for missing library blend files\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n from ..ops import library\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n return library.find_libraries_in_folders(context, self.report, ADDON_NAME)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_open_linked_file(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.open_linked_file\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Open Linked File\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Open the selected linked blend file in a new Blender instance\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n filepath: StringProperty(name=\\\\\\\\\\\\\\\"File Path\\\\\\\\\\\\\\\", default=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n if not self.filepath:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No file path specified\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n bpy.ops.wm.path_open(filepath=self.filepath)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Opening linked file: {self.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to open linked file: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_add_search_path(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.add_search_path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Add Search Path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Add a new folder to the list of search paths for finding libraries\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n prefs = _prefs(context)\\\\\\\\r\\\\\\\\n if prefs:\\\\\\\\r\\\\\\\\n p = prefs.preferences.search_paths.add()\\\\\\\\r\\\\\\\\n p.path = \\\\\\\\\\\\\\\"//\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Added search path: {p.path}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_remove_search_path(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.remove_search_path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Search Path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove the selected search path from the list\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n index: IntProperty(name=\\\\\\\\\\\\\\\"Index\\\\\\\\\\\\\\\", default=0)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n prefs = _prefs(context)\\\\\\\\r\\\\\\\\n if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths):\\\\\\\\r\\\\\\\\n prefs.preferences.search_paths.remove(self.index)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed search path at index {self.index}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_attempt_relink(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.attempt_relink\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Attempt Relink\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Try to relink missing libraries using the configured search paths\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n from ..ops import library\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n return library.attempt_relink(context, self.report, ADDON_NAME)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_browse_search_path(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.browse_search_path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Browse Search Path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Browse to set the folder for the selected search path\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n index: IntProperty(name=\\\\\\\\\\\\\\\"Index\\\\\\\\\\\\\\\", default=0)\\\\\\\\r\\\\\\\\n filepath: StringProperty(name=\\\\\\\\\\\\\\\"Search Path\\\\\\\\\\\\\\\", subtype=\\\\\\\\\\\\\\\"DIR_PATH\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n prefs = _prefs(context)\\\\\\\\r\\\\\\\\n if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths):\\\\\\\\r\\\\\\\\n prefs.preferences.search_paths[self.index].path = self.filepath\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Updated search path {self.index + 1}: {self.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def invoke(self, context, event):\\\\\\\\r\\\\\\\\n prefs = _prefs(context)\\\\\\\\r\\\\\\\\n if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths):\\\\\\\\r\\\\\\\\n self.filepath = prefs.preferences.search_paths[self.index].path\\\\\\\\r\\\\\\\\n context.window_manager.fileselect_add(self)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"RUNNING_MODAL\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_reload_libraries(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.reload_libraries\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Reload Libraries\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Reload all linked libraries (or fallback manual reload)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n bpy.ops.outliner.lib_operation(type=\\\\\\\\\\\\\\\"RELOAD\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Library reload operation completed\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception:\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n for lib in bpy.data.libraries:\\\\\\\\r\\\\\\\\n if lib.filepath and os.path.exists(bpy.path.abspath(lib.filepath)):\\\\\\\\r\\\\\\\\n lib.reload()\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Libraries reloaded manually\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to reload libraries: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_make_paths_relative(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.make_paths_relative\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Make Paths Relative\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Convert all internal file paths to relative\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n bpy.ops.file.make_paths_relative()\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"All file paths made relative\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to make paths relative: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_make_paths_absolute(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.make_paths_absolute\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Make Paths Absolute\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Convert all internal file paths to absolute\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n bpy.ops.file.make_paths_absolute()\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"All file paths made absolute\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to make paths absolute: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_relocate_single_library(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.relocate_single_library\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Relocate Library\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Point the selected library to a new blend file and reload\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n target_filepath: StringProperty(name=\\\\\\\\\\\\\\\"Current Library Path\\\\\\\\\\\\\\\", default=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n filepath: StringProperty(name=\\\\\\\\\\\\\\\"New Library File\\\\\\\\\\\\\\\", subtype=\\\\\\\\\\\\\\\"FILE_PATH\\\\\\\\\\\\\\\", default=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n if not self.target_filepath or not self.filepath:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No target or new file specified\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n abs_match = bpy.path.abspath(self.target_filepath) if self.target_filepath else \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n library = None\\\\\\\\r\\\\\\\\n for lib in bpy.data.libraries:\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n if lib.filepath and bpy.path.abspath(lib.filepath) == abs_match:\\\\\\\\r\\\\\\\\n library = lib\\\\\\\\r\\\\\\\\n break\\\\\\\\r\\\\\\\\n except Exception:\\\\\\\\r\\\\\\\\n if lib.filepath == self.target_filepath:\\\\\\\\r\\\\\\\\n library = lib\\\\\\\\r\\\\\\\\n break\\\\\\\\r\\\\\\\\n if not library:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Could not resolve the selected library\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n library.filepath = self.filepath\\\\\\\\r\\\\\\\\n library.reload()\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Relocated to: {self.filepath}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to relocate: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def invoke(self, context, event):\\\\\\\\r\\\\\\\\n if self.target_filepath:\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n self.filepath = bpy.path.abspath(self.target_filepath)\\\\\\\\r\\\\\\\\n except Exception:\\\\\\\\r\\\\\\\\n self.filepath = self.target_filepath\\\\\\\\r\\\\\\\\n context.window_manager.fileselect_add(self)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"RUNNING_MODAL\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\ndef _get_migrator_pair(context):\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"Return (orig, rep) from scene props (manual or automatic). (None, None) if invalid.\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n from ..ops.migrator import get_pair_manual, get_pair_automatic\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n props = getattr(context.scene, \\\\\\\\\\\\\\\"dynamic_link_manager\\\\\\\\\\\\\\\", None)\\\\\\\\r\\\\\\\\n if not props:\\\\\\\\r\\\\\\\\n return None, None\\\\\\\\r\\\\\\\\n use_auto = getattr(props, \\\\\\\\\\\\\\\"migrator_mode\\\\\\\\\\\\\\\", False)\\\\\\\\r\\\\\\\\n orig, rep = get_pair_automatic(context) if use_auto else get_pair_manual(context)\\\\\\\\r\\\\\\\\n return orig, rep\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_copy_attributes(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"CopyAttr\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Copy object and armature attributes from original to replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"COPY_ID\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair (set Original/Replacement or enable Automatic).\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_copy_attr\\\\\\\\r\\\\\\\\n run_copy_attr(orig, rep)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Copy attributes done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_migrate_nla(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigNLA\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Migrate NLA tracks and strips from original to replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"NLA\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_mig_nla\\\\\\\\r\\\\\\\\n run_mig_nla(orig, rep, report=self.report)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_custom_properties(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_custom_properties\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigCustProps\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Copy custom properties from original to replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"PROPERTIES\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_mig_cust_props\\\\\\\\r\\\\\\\\n run_mig_cust_props(orig, rep)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Custom properties done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_bone_constraints(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_bone_constraints\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigBoneConst\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Migrate bone constraints from original to replacement armature\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"CONSTRAINT_BONE\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_mig_bone_const\\\\\\\\r\\\\\\\\n orig_to_rep = {orig: rep}\\\\\\\\r\\\\\\\\n run_mig_bone_const(orig, rep, orig_to_rep)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Bone constraints done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_retarget_relations(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_retarget_relations\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"RetargRelatives\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Retarget parent/child and other relations to the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"ORIENTATION_PARENT\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_retarg_relatives\\\\\\\\r\\\\\\\\n from ..utils import descendants\\\\\\\\r\\\\\\\\n rep_descendants = descendants(rep)\\\\\\\\r\\\\\\\\n orig_to_rep = {orig: rep}\\\\\\\\r\\\\\\\\n run_retarg_relatives(orig, rep, rep_descendants, orig_to_rep)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Retarget relations done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_basebody_shapekeys(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_basebody_shapekeys\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigBBodyShapeKeys\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Migrate base body mesh shape key values from original to replacement\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"SHAPEKEY_DATA\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.migrator import run_mig_bbody_shapekeys\\\\\\\\r\\\\\\\\n from ..utils import descendants\\\\\\\\r\\\\\\\\n rep_descendants = descendants(rep)\\\\\\\\r\\\\\\\\n run_mig_bbody_shapekeys(orig, rep, rep_descendants, context)\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Migrate BaseBody shapekeys done.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_fk_rotations(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_fk_rotations\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"MigFKRot\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Copy FK arm and finger rotations from original to replacement (uses constraints)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"BONE_DATA\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.fk_rotations import copy_fk_rotations\\\\\\\\r\\\\\\\\n ok, msg = copy_fk_rotations(context, orig, rep)\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_fk_rotations_bake(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_fk_rotations_bake\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Bake MigFKRot\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Bake FK rotations to keyframes using nla.bake (similar to tweak tools)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"KEYFRAME\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n track_name: StringProperty(name=\\\\\\\\\\\\\\\"NLA Track\\\\\\\\\\\\\\\", description=\\\\\\\\\\\\\\\"Optional NLA track name for frame range\\\\\\\\\\\\\\\", default=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n post_clean: BoolProperty(name=\\\\\\\\\\\\\\\"Post-clean\\\\\\\\\\\\\\\", description=\\\\\\\\\\\\\\\"Clean curves after bake\\\\\\\\\\\\\\\", default=False)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.fk_rotations import bake_fk_rotations\\\\\\\\r\\\\\\\\n ok, msg = bake_fk_rotations(context, orig, rep, track_name=self.track_name or None, post_clean=self.post_clean)\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_fk_rotations_remove(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_fk_rotations_remove\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove MigFKRot\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove FK rotation COPY_TRANSFORMS constraints (similar to tweak_remove_arm)\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_icon = \\\\\\\\\\\\\\\"X\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig or not rep or orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No valid character pair.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n from ..ops.fk_rotations import remove_fk_rotations\\\\\\\\r\\\\\\\\n ok, msg = remove_fk_rotations(context, rep)\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n else:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, str(e))\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nMIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_custom_properties\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_bone_constraints\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_retarget_relations\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_basebody_shapekeys\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_migrator_remove_original(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.migrator_remove_original\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Original\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Delete the original character armature and its data from the scene\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n if not orig:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"WARNING\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"No original character selected\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n if orig == rep:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Original and replacement cannot be the same object\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n name = orig.name\\\\\\\\r\\\\\\\\n try:\\\\\\\\r\\\\\\\\n # Remove from scene\\\\\\\\r\\\\\\\\n bpy.data.objects.remove(orig, do_unlink=True)\\\\\\\\r\\\\\\\\n # Clear the property\\\\\\\\r\\\\\\\\n context.scene.dynamic_link_manager.original_character = None\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed original character: {name}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n except Exception as e:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Failed to remove original: {e}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_run_character_migration(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.run_character_migration\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Run Character Migration\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Run all six migration steps (CopyAttr, MigNLA, MigCustProps, MigBoneConst, RetargRelatives, MigBBodyShapeKeys) in order\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n steps = [\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_copy_attributes,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_migrate_nla,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_custom_properties,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_bone_constraints,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_retarget_relations,\\\\\\\\r\\\\\\\\n bpy.ops.dlm.migrator_basebody_shapekeys,\\\\\\\\r\\\\\\\\n ]\\\\\\\\r\\\\\\\\n for i, op in enumerate(steps):\\\\\\\\r\\\\\\\\n result = op()\\\\\\\\r\\\\\\\\n if result != {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Migration failed at step {i + 1}: {MIGRATOR_STEP_OPS[i]}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Migration complete.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_picker_original_character(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.picker_original_character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Pick Original\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Set the original character armature from the active object\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n obj = context.active_object\\\\\\\\r\\\\\\\\n if not obj or obj.type != \\\\\\\\\\\\\\\"ARMATURE\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"WARNING\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Select an armature\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n context.scene.dynamic_link_manager.original_character = obj\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Original: {obj.name}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_picker_replacement_character(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.picker_replacement_character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Pick Replacement\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Set the replacement character armature from the active object\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n obj = context.active_object\\\\\\\\r\\\\\\\\n if not obj or obj.type != \\\\\\\\\\\\\\\"ARMATURE\\\\\\\\\\\\\\\":\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"WARNING\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Select an armature\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n context.scene.dynamic_link_manager.replacement_character = obj\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Replacement: {obj.name}\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\ndef _tweak_poll(context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n return orig is not None and rep is not None\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_add_arm(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_add_arm\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Add Arm Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Add tweak bone constraints to arm bones on the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n tweak_tools.add_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"arm\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Arm tweak constraints added.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_remove_arm(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_remove_arm\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Arm Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove arm tweak constraints from the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n n = tweak_tools.remove_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"arm\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed {n} arm tweak constraints.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_bake_arm(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_bake_arm\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Bake Arm Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Bake arm tweak constraints to keyframes and optionally remove constraints\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n props = context.scene.dynamic_link_manager\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n ok, msg = tweak_tools.bake_tweak_constraints(\\\\\\\\r\\\\\\\\n context, orig, rep, \\\\\\\\\\\\\\\"arm\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_nla_track_name\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\") or \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_bake_post_clean\\\\\\\\\\\\\\\", False),\\\\\\\\r\\\\\\\\n )\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_add_leg(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_add_leg\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Add Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Add tweak bone constraints to leg bones on the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n tweak_tools.add_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"leg\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Leg tweak constraints added.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_remove_leg(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_remove_leg\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove leg tweak constraints from the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n n = tweak_tools.remove_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"leg\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed {n} leg tweak constraints.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_bake_leg(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_bake_leg\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Bake Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Bake leg tweak constraints to keyframes and optionally remove constraints\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n props = context.scene.dynamic_link_manager\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n ok, msg = tweak_tools.bake_tweak_constraints(\\\\\\\\r\\\\\\\\n context, orig, rep, \\\\\\\\\\\\\\\"leg\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_nla_track_name\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\") or \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_bake_post_clean\\\\\\\\\\\\\\\", False),\\\\\\\\r\\\\\\\\n )\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_add_both(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_add_both\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Add Arm & Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Add tweak bone constraints to both arm and leg bones\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n tweak_tools.add_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"both\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Arm & leg tweak constraints added.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_remove_both(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_remove_both\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Remove Arm & Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Remove all arm and leg tweak constraints from the replacement character\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n n = tweak_tools.remove_tweak_constraints(orig, rep, \\\\\\\\\\\\\\\"both\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Removed {n} tweak constraints.\\\\\\\\\\\\\\\")\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nclass DLM_OT_tweak_bake_both(Operator):\\\\\\\\r\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.tweak_bake_both\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_label = \\\\\\\\\\\\\\\"Bake Arm & Leg Tweaks\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_description = \\\\\\\\\\\\\\\"Bake all arm and leg tweak constraints to keyframes and optionally remove constraints\\\\\\\\\\\\\\\"\\\\\\\\r\\\\\\\\n bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n @classmethod\\\\\\\\r\\\\\\\\n def poll(cls, context):\\\\\\\\r\\\\\\\\n return _tweak_poll(context)\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n def execute(self, context):\\\\\\\\r\\\\\\\\n orig, rep = _get_migrator_pair(context)\\\\\\\\r\\\\\\\\n props = context.scene.dynamic_link_manager\\\\\\\\r\\\\\\\\n from ..ops import tweak_tools\\\\\\\\r\\\\\\\\n ok, msg = tweak_tools.bake_tweak_constraints(\\\\\\\\r\\\\\\\\n context, orig, rep, \\\\\\\\\\\\\\\"both\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_nla_track_name\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\") or \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n getattr(props, \\\\\\\\\\\\\\\"tweak_bake_post_clean\\\\\\\\\\\\\\\", False),\\\\\\\\r\\\\\\\\n )\\\\\\\\r\\\\\\\\n if ok:\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, msg)\\\\\\\\r\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nOPERATOR_CLASSES = [\\\\\\\\r\\\\\\\\n DLM_OT_replace_linked_asset,\\\\\\\\r\\\\\\\\n DLM_OT_scan_linked_assets,\\\\\\\\r\\\\\\\\n DLM_OT_find_libraries_in_folders,\\\\\\\\r\\\\\\\\n DLM_OT_open_linked_file,\\\\\\\\r\\\\\\\\n DLM_OT_add_search_path,\\\\\\\\r\\\\\\\\n DLM_OT_remove_search_path,\\\\\\\\r\\\\\\\\n DLM_OT_browse_search_path,\\\\\\\\r\\\\\\\\n DLM_OT_attempt_relink,\\\\\\\\r\\\\\\\\n DLM_OT_reload_libraries,\\\\\\\\r\\\\\\\\n DLM_OT_make_paths_relative,\\\\\\\\r\\\\\\\\n DLM_OT_make_paths_absolute,\\\\\\\\r\\\\\\\\n DLM_OT_relocate_single_library,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_remove_original,\\\\\\\\r\\\\\\\\n DLM_OT_run_character_migration,\\\\\\\\r\\\\\\\\n DLM_OT_picker_original_character,\\\\\\\\r\\\\\\\\n DLM_OT_picker_replacement_character,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_copy_attributes,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_migrate_nla,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_custom_properties,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_bone_constraints,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_retarget_relations,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_basebody_shapekeys,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_add_arm,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_remove_arm,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_bake_arm,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_add_leg,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_remove_leg,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_bake_leg,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_add_both,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_remove_both,\\\\\\\\r\\\\\\\\n DLM_OT_tweak_bake_both,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_fk_rotations,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_fk_rotations_bake,\\\\\\\\r\\\\\\\\n DLM_OT_migrator_fk_rotations_remove,\\\\\\\\r\\\\\\\\n]\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"deca4b3e-c536-45f2-b189-6f64ec728fda\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"1a2ef471-0add-458c-92f7-4626adb01a88\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.842Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"thinking\\\":{\\\"text\\\":\\\"I have the content of both files. Now I need to:\\\\n\\\\n1. From panels.py: Remove the line with `row.operator(\\\\\\\"dlm.run_character_migration\\\\\\\", text=\\\\\\\"Run migration\\\\\\\", icon=\\\\\\\"ARMATURE_DATA\\\\\\\")`\\\\n\\\\n2. From operators.py:\\\\n - Remove the DLM_OT_run_character_migration class definition (lines ~295-310)\\\\n - Remove DLM_OT_run_character_migration from the OPERATOR_CLASSES list (line ~380)\\\\n - Remove the MIGRATOR_STEP_OPS constant if it's no longer used\\\\n\\\\nLet me first check if MIGRATOR_STEP_OPS is used anywhere else. From the output I can see the DLM_OT_run_character_migration class uses it, but if I remove the class, I need to check if anything else uses it.\\\\n\\\\nLet me use Python to make these edits. First, let me create a Python script to make these changes.\\\",\\\"signature\\\":\\\"\\\"},\\\"capabilityType\\\":30}\",\"7642f9c0-fa52-4346-8574-867ce4f370c5\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"5917631d-5d00-4f66-ac66-5a803e29a599\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.842Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"Now I'll create a Python script to make these edits.\\\"}\",\"d2a3d6d3-703c-401a-b8e4-e3c21d925ab9\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"4bcce616-946b-4c96-a844-5f01395545ac\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.842Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:2\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"python << 'EOF'\\\\\\\\nimport re\\\\\\\\n\\\\\\\\n# 1. Edit panels.py - remove the Run migration operator line\\\\\\\\npanels_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n panels_content = f.read()\\\\\\\\n\\\\\\\\noriginal_panels = panels_content\\\\\\\\n\\\\\\\\n# Remove the specific line with run_character_migration\\\\\\\\npanels_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s*row\\\\\\\\\\\\\\\\.operator\\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\"dlm\\\\\\\\\\\\\\\\.run_character_migration\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n panels_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(panels_content)\\\\\\\\n\\\\\\\\nif original_panels != panels_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: No changes made (line not found)\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove DLM_OT_run_character_migration from OPERATOR_CLASSES list\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s+DLM_OT_run_character_migration,\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n operators_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(operators_content)\\\\\\\\n\\\\\\\\nif original_operators != operators_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed DLM_OT_run_character_migration class\\\\\\\\\\\\\\\")\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed from OPERATOR_CLASSES list\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: No changes made\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\nprint(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\nEdits complete!\\\\\\\\\\\\\\\")\\\\\\\\nEOF\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:2\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"python\\\\\\\"],\\\\\\\"hasInputRedirect\\\\\\\":true,\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"python\\\\\\\",\\\\\\\"fullText\\\\\\\":\\\\\\\"python\\\\\\\"}],\\\\\\\"hasRedirects\\\\\\\":true},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"Remove Run Migration command from addon files\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"failure\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"python << 'EOF'\\\\\\\\nimport re\\\\\\\\n\\\\\\\\n# 1. Edit panels.py - remove the Run migration operator line\\\\\\\\npanels_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n panels_content = f.read()\\\\\\\\n\\\\\\\\noriginal_panels = panels_content\\\\\\\\n\\\\\\\\n# Remove the specific line with run_character_migration\\\\\\\\npanels_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s*row\\\\\\\\\\\\\\\\.operator\\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\"dlm\\\\\\\\\\\\\\\\.run_character_migration\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n panels_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(panels_content)\\\\\\\\n\\\\\\\\nif original_panels != panels_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: No changes made (line not found)\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove DLM_OT_run_character_migration from OPERATOR_CLASSES list\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s+DLM_OT_run_character_migration,\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n operators_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(operators_content)\\\\\\\\n\\\\\\\\nif original_operators != operators_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed DLM_OT_run_character_migration class\\\\\\\\\\\\\\\")\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed from OPERATOR_CLASSES list\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: No changes made\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\nprint(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\nEdits complete!\\\\\\\\\\\\\\\")\\\\\\\\nEOF\\\\\\\",\\\\\\\"exitCode\\\\\\\":1,\\\\\\\"stderr\\\\\\\":\\\\\\\"ParserError: C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\Nathan\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\ps-script-f3e1a616-7a88-4d8c-b91b-ac1cb59a50ea.ps1:113\\\\\\\\r\\\\\\\\nLine |\\\\\\\\r\\\\\\\\n 113 | python << 'EOF'\\\\\\\\r\\\\\\\\n | ~\\\\\\\\r\\\\\\\\n | Missing file specification after redirection operator.\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"executionTime\\\\\\\":645,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"ParserError: C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\Nathan\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\ps-script-f3e1a616-7a88-4d8c-b91b-ac1cb59a50ea.ps1:113\\\\\\\\r\\\\\\\\nLine |\\\\\\\\r\\\\\\\\n 113 | python << 'EOF'\\\\\\\\r\\\\\\\\n | ~\\\\\\\\r\\\\\\\\n | Missing file specification after redirection operator.\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":595},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"Remove Run Migration command from addon files\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"error\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"python << 'EOF'\\\\\\\\nimport re\\\\\\\\n\\\\\\\\n# 1. Edit panels.py - remove the Run migration operator line\\\\\\\\npanels_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n panels_content = f.read()\\\\\\\\n\\\\\\\\noriginal_panels = panels_content\\\\\\\\n\\\\\\\\n# Remove the specific line with run_character_migration\\\\\\\\npanels_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s*row\\\\\\\\\\\\\\\\.operator\\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\"dlm\\\\\\\\\\\\\\\\.run_character_migration\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n panels_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(panels_content)\\\\\\\\n\\\\\\\\nif original_panels != panels_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: No changes made (line not found)\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove DLM_OT_run_character_migration from OPERATOR_CLASSES list\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s+DLM_OT_run_character_migration,\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n operators_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(operators_content)\\\\\\\\n\\\\\\\\nif original_operators != operators_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed DLM_OT_run_character_migration class\\\\\\\\\\\\\\\")\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed from OPERATOR_CLASSES list\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: No changes made\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\nprint(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\nEdits complete!\\\\\\\\\\\\\\\")\\\\\\\\nEOF\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"python\\\\\\\",\\\\\\\"fullText\\\\\\\":\\\\\\\"python\\\\\\\"}],\\\\\\\"hasRedirects\\\\\\\":true},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"Remove Run Migration command from addon files\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"output\\\\\\\":\\\\\\\"ParserError: C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\Nathan\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\ps-script-f3e1a616-7a88-4d8c-b91b-ac1cb59a50ea.ps1:113\\\\\\\\r\\\\\\\\nLine |\\\\\\\\r\\\\\\\\n 113 | python << 'EOF'\\\\\\\\r\\\\\\\\n | ~\\\\\\\\r\\\\\\\\n | Missing file specification after redirection operator.\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"exitCode\\\\\\\":1,\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"c5b5bd5b-c76c-464a-82f2-39adf5b4c4fe\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"05f9f1fb-f0da-4b6e-9c5c-71e73e1c6295\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.842Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"thinking\\\":{\\\"text\\\":\\\"The heredoc syntax isn't working in PowerShell. Let me write the Python script to a file and then execute it.\\\",\\\"signature\\\":\\\"\\\"},\\\"capabilityType\\\":30}\",\"71ef729a-f095-403b-9187-97e833d00400\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"5dfb683a-5fcb-4fb6-9383-1a9da8b5d879\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.842Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"Let me write the Python script to a file first, then execute it.\\\"}\",\"85decfe5-b782-453a-a46b-9bc6447577cd\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"84e7a27b-6ea1-41ce-8399-ec2867e97b95\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.842Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:3\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"cat > t:\\\\\\\\\\\\\\\\remove_migration.py << 'PYEOF'\\\\\\\\nimport re\\\\\\\\n\\\\\\\\n# 1. Edit panels.py - remove the Run migration operator line\\\\\\\\npanels_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n panels_content = f.read()\\\\\\\\n\\\\\\\\noriginal_panels = panels_content\\\\\\\\n\\\\\\\\n# Remove the specific line with run_character_migration\\\\\\\\npanels_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s*row\\\\\\\\\\\\\\\\.operator\\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\"dlm\\\\\\\\\\\\\\\\.run_character_migration\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n panels_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(panels_content)\\\\\\\\n\\\\\\\\nif original_panels != panels_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: No changes made (line not found)\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove DLM_OT_run_character_migration from OPERATOR_CLASSES list\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s+DLM_OT_run_character_migration,\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n operators_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(operators_content)\\\\\\\\n\\\\\\\\nif original_operators != operators_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed DLM_OT_run_character_migration class\\\\\\\\\\\\\\\")\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed from OPERATOR_CLASSES list\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: No changes made\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\nprint(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\nEdits complete!\\\\\\\\\\\\\\\")\\\\\\\\nPYEOF\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:3\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"cat\\\\\\\"],\\\\\\\"hasInputRedirect\\\\\\\":true,\\\\\\\"hasOutputRedirect\\\\\\\":true,\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"cat\\\\\\\",\\\\\\\"fullText\\\\\\\":\\\\\\\"cat\\\\\\\"}],\\\\\\\"hasRedirects\\\\\\\":true},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"Write Python script to file\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"failure\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"cat > t:\\\\\\\\\\\\\\\\remove_migration.py << 'PYEOF'\\\\\\\\nimport re\\\\\\\\n\\\\\\\\n# 1. Edit panels.py - remove the Run migration operator line\\\\\\\\npanels_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n panels_content = f.read()\\\\\\\\n\\\\\\\\noriginal_panels = panels_content\\\\\\\\n\\\\\\\\n# Remove the specific line with run_character_migration\\\\\\\\npanels_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s*row\\\\\\\\\\\\\\\\.operator\\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\"dlm\\\\\\\\\\\\\\\\.run_character_migration\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n panels_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(panels_content)\\\\\\\\n\\\\\\\\nif original_panels != panels_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: No changes made (line not found)\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove DLM_OT_run_character_migration from OPERATOR_CLASSES list\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s+DLM_OT_run_character_migration,\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n operators_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(operators_content)\\\\\\\\n\\\\\\\\nif original_operators != operators_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed DLM_OT_run_character_migration class\\\\\\\\\\\\\\\")\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed from OPERATOR_CLASSES list\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: No changes made\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\nprint(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\nEdits complete!\\\\\\\\\\\\\\\")\\\\\\\\nPYEOF\\\\\\\",\\\\\\\"exitCode\\\\\\\":1,\\\\\\\"stderr\\\\\\\":\\\\\\\"ParserError: C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\Nathan\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\ps-script-cee3986e-ecfa-410a-bda6-8f3c3f91b8bc.ps1:113\\\\\\\\r\\\\\\\\nLine |\\\\\\\\r\\\\\\\\n 113 | cat > t:\\\\\\\\\\\\\\\\remove_migration.py << 'PYEOF'\\\\\\\\r\\\\\\\\n | ~\\\\\\\\r\\\\\\\\n | Missing file specification after redirection operator.\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"executionTime\\\\\\\":713,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"ParserError: C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\Nathan\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\ps-script-cee3986e-ecfa-410a-bda6-8f3c3f91b8bc.ps1:113\\\\\\\\r\\\\\\\\nLine |\\\\\\\\r\\\\\\\\n 113 | cat > t:\\\\\\\\\\\\\\\\remove_migration.py << 'PYEOF'\\\\\\\\r\\\\\\\\n | ~\\\\\\\\r\\\\\\\\n | Missing file specification after redirection operator.\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":673},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"Write Python script to file\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"error\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"cat > t:\\\\\\\\\\\\\\\\remove_migration.py << 'PYEOF'\\\\\\\\nimport re\\\\\\\\n\\\\\\\\n# 1. Edit panels.py - remove the Run migration operator line\\\\\\\\npanels_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n panels_content = f.read()\\\\\\\\n\\\\\\\\noriginal_panels = panels_content\\\\\\\\n\\\\\\\\n# Remove the specific line with run_character_migration\\\\\\\\npanels_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s*row\\\\\\\\\\\\\\\\.operator\\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\"dlm\\\\\\\\\\\\\\\\.run_character_migration\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n panels_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(panels_content)\\\\\\\\n\\\\\\\\nif original_panels != panels_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: No changes made (line not found)\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove DLM_OT_run_character_migration from OPERATOR_CLASSES list\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s+DLM_OT_run_character_migration,\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n operators_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(operators_content)\\\\\\\\n\\\\\\\\nif original_operators != operators_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed DLM_OT_run_character_migration class\\\\\\\\\\\\\\\")\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed from OPERATOR_CLASSES list\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: No changes made\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\nprint(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\nEdits complete!\\\\\\\\\\\\\\\")\\\\\\\\nPYEOF\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"cat\\\\\\\",\\\\\\\"fullText\\\\\\\":\\\\\\\"cat\\\\\\\"}],\\\\\\\"hasRedirects\\\\\\\":true},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"Write Python script to file\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"output\\\\\\\":\\\\\\\"ParserError: C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\Nathan\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\ps-script-cee3986e-ecfa-410a-bda6-8f3c3f91b8bc.ps1:113\\\\\\\\r\\\\\\\\nLine |\\\\\\\\r\\\\\\\\n 113 | cat > t:\\\\\\\\\\\\\\\\remove_migration.py << 'PYEOF'\\\\\\\\r\\\\\\\\n | ~\\\\\\\\r\\\\\\\\n | Missing file specification after redirection operator.\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"exitCode\\\\\\\":1,\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"6090424e-c206-46e8-b894-311cd0987135\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"5c94bcc2-4124-4277-b279-10700c9d92c4\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"thinking\\\":{\\\"text\\\":\\\"Heredocs don't work in PowerShell. Let me try using echo or a different approach to write the script file.\\\",\\\"signature\\\":\\\"\\\"},\\\"capabilityType\\\":30}\",\"85175617-b96d-426e-9067-10cbea5cb301\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"5d97a5c3-ef77-4ad3-9f44-1baf0b6159e9\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:4\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"Set-Content -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\\\\\\\\\" -Value @\\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\n# 1. Edit panels.py - remove the Run migration operator line\\\\\\\\npanels_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n panels_content = f.read()\\\\\\\\n\\\\\\\\noriginal_panels = panels_content\\\\\\\\n\\\\\\\\n# Remove the specific line with run_character_migration\\\\\\\\npanels_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s*row\\\\\\\\\\\\\\\\.operator\\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"dlm\\\\\\\\\\\\\\\\.run_character_migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n panels_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(panels_content)\\\\\\\\n\\\\\\\\nif original_panels != panels_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: No changes made (line not found)\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove DLM_OT_run_character_migration from OPERATOR_CLASSES list\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s+DLM_OT_run_character_migration,\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n operators_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(operators_content)\\\\\\\\n\\\\\\\\nif original_operators != operators_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed DLM_OT_run_character_migration class\\\\\\\\\\\\\\\")\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed from OPERATOR_CLASSES list\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: No changes made\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\nprint(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\nEdits complete!\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\\\\\\\\"@\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:4\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"Set-Content\\\\\\\",\\\\\\\"line\\\\\\\",\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\"],\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"Set-Content\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Path\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Value\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"@\\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\n# 1. Edit panels.py - remove the Run migration operator line\\\\\\\\npanels_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n panels_content = f.read()\\\\\\\\n\\\\\\\\noriginal_panels = panels_content\\\\\\\\n\\\\\\\\n# Remove the specific line with run_character_migration\\\\\\\\npanels_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s*row\\\\\\\\\\\\\\\\.operator\\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"dlm\\\\\\\\\\\\\\\\.run_character_migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n panels_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(panels_content)\\\\\\\\n\\\\\\\\nif original_panels != panels_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py:\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"Removed\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"raw_string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"'Run migration'\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"operator\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"line\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py:\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"No\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"changes\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"made\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"Set-Content -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\\\\\\\\\" -Value @\\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\n# 1. Edit panels.py - remove the Run migration operator line\\\\\\\\npanels_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n panels_content = f.read()\\\\\\\\n\\\\\\\\noriginal_panels = panels_content\\\\\\\\n\\\\\\\\n# Remove the specific line with run_character_migration\\\\\\\\npanels_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s*row\\\\\\\\\\\\\\\\.operator\\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"dlm\\\\\\\\\\\\\\\\.run_character_migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n panels_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(panels_content)\\\\\\\\n\\\\\\\\nif original_panels != panels_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: No changes made\\\\\\\"},{\\\\\\\"name\\\\\\\":\\\\\\\"line\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"not\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"found\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"line not found\\\\\\\"},{\\\\\\\"name\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\nclass\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"DLM_OT_picker_original_character\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove DLM_OT_run_character_migration from OPERATOR_CLASSES list\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s+DLM_OT_run_character_migration,\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n operators_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(operators_content)\\\\\\\\n\\\\\\\\nif original_operators != operators_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py:\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"Removed\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"DLM_OT_run_character_migration\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"class\\\\\\\\\\\\\\\")\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py:\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"Removed\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"from\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"OPERATOR_CLASSES\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"list\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py:\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"No\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"changes\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"made\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\nprint(\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\\nEdits\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"complete!\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\\\\\\\\"@\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove DLM_OT_run_character_migration from OPERATOR_CLASSES list\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s+DLM_OT_run_character_migration,\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n operators_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(operators_content)\\\\\\\\n\\\\\\\\nif original_operators != operators_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed DLM_OT_run_character_migration class\\\\\\\\\\\\\\\")\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed from OPERATOR_CLASSES list\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: No changes made\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\nprint(\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\\nEdits complete!\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\\\\\\\\"@\\\\\\\"}]},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"Write Python script using PowerShell\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"success\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"Set-Content -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\\\\\\\\\" -Value @\\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\n# 1. Edit panels.py - remove the Run migration operator line\\\\\\\\npanels_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n panels_content = f.read()\\\\\\\\n\\\\\\\\noriginal_panels = panels_content\\\\\\\\n\\\\\\\\n# Remove the specific line with run_character_migration\\\\\\\\npanels_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s*row\\\\\\\\\\\\\\\\.operator\\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"dlm\\\\\\\\\\\\\\\\.run_character_migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n panels_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(panels_content)\\\\\\\\n\\\\\\\\nif original_panels != panels_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: No changes made (line not found)\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove DLM_OT_run_character_migration from OPERATOR_CLASSES list\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s+DLM_OT_run_character_migration,\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n operators_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(operators_content)\\\\\\\\n\\\\\\\\nif original_operators != operators_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed DLM_OT_run_character_migration class\\\\\\\\\\\\\\\")\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed from OPERATOR_CLASSES list\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: No changes made\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\nprint(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\nEdits complete!\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\\\\\\\\"@\\\\\\\",\\\\\\\"executionTime\\\\\\\":2857,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":2811},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"Write Python script using PowerShell\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"success\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"Set-Content -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\\\\\\\\\" -Value @\\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\n# 1. Edit panels.py - remove the Run migration operator line\\\\\\\\npanels_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n panels_content = f.read()\\\\\\\\n\\\\\\\\noriginal_panels = panels_content\\\\\\\\n\\\\\\\\n# Remove the specific line with run_character_migration\\\\\\\\npanels_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s*row\\\\\\\\\\\\\\\\.operator\\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"dlm\\\\\\\\\\\\\\\\.run_character_migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n panels_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(panels_content)\\\\\\\\n\\\\\\\\nif original_panels != panels_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: No changes made (line not found)\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove DLM_OT_run_character_migration from OPERATOR_CLASSES list\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s+DLM_OT_run_character_migration,\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n operators_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(operators_content)\\\\\\\\n\\\\\\\\nif original_operators != operators_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed DLM_OT_run_character_migration class\\\\\\\\\\\\\\\")\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed from OPERATOR_CLASSES list\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: No changes made\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\nprint(\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\nEdits complete!\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\\\\\\\\"@\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"Set-Content\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Path\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Value\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"@\\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\n# 1. Edit panels.py - remove the Run migration operator line\\\\\\\\npanels_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n panels_content = f.read()\\\\\\\\n\\\\\\\\noriginal_panels = panels_content\\\\\\\\n\\\\\\\\n# Remove the specific line with run_character_migration\\\\\\\\npanels_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s*row\\\\\\\\\\\\\\\\.operator\\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"dlm\\\\\\\\\\\\\\\\.run_character_migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n panels_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(panels_content)\\\\\\\\n\\\\\\\\nif original_panels != panels_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py:\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"Removed\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"raw_string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"'Run migration'\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"operator\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"line\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py:\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"No\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"changes\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"made\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"Set-Content -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\\\\\\\\\" -Value @\\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\n# 1. Edit panels.py - remove the Run migration operator line\\\\\\\\npanels_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n panels_content = f.read()\\\\\\\\n\\\\\\\\noriginal_panels = panels_content\\\\\\\\n\\\\\\\\n# Remove the specific line with run_character_migration\\\\\\\\npanels_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s*row\\\\\\\\\\\\\\\\.operator\\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"dlm\\\\\\\\\\\\\\\\.run_character_migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n panels_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(panels_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(panels_content)\\\\\\\\n\\\\\\\\nif original_panels != panels_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"panels.py: No changes made\\\\\\\"},{\\\\\\\"name\\\\\\\":\\\\\\\"line\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"not\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"found\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"line not found\\\\\\\"},{\\\\\\\"name\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\nclass\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"DLM_OT_picker_original_character\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove DLM_OT_run_character_migration from OPERATOR_CLASSES list\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s+DLM_OT_run_character_migration,\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n operators_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(operators_content)\\\\\\\\n\\\\\\\\nif original_operators != operators_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py:\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"Removed\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"DLM_OT_run_character_migration\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"class\\\\\\\\\\\\\\\")\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py:\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"Removed\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"from\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"OPERATOR_CLASSES\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"list\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py:\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"No\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"changes\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"made\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\nprint(\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\\nEdits\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"complete!\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\\\\\\\\"@\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\n# 2. Edit operators.py - remove the class and from OPERATOR_CLASSES list\\\\\\\\noperators_file = r\\\\\\\\\\\\\\\"T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n operators_content = f.read()\\\\\\\\n\\\\\\\\noriginal_operators = operators_content\\\\\\\\n\\\\\\\\n# Remove MIGRATOR_STEP_OPS constant\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\[.*?\\\\\\\\\\\\\\\\]\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove the DLM_OT_run_character_migration class\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\nclass DLM_OT_run_character_migration\\\\\\\\\\\\\\\\(Operator\\\\\\\\\\\\\\\\):.*?\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character',\\\\\\\\n \\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\nclass DLM_OT_picker_original_character\\\\\\\\\\\\\\\",\\\\\\\\n operators_content,\\\\\\\\n flags=re.DOTALL\\\\\\\\n)\\\\\\\\n\\\\\\\\n# Remove DLM_OT_run_character_migration from OPERATOR_CLASSES list\\\\\\\\noperators_content = re.sub(\\\\\\\\n r'\\\\\\\\\\\\\\\\s+DLM_OT_run_character_migration,\\\\\\\\\\\\\\\\n',\\\\\\\\n \\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\",\\\\\\\\n operators_content\\\\\\\\n)\\\\\\\\n\\\\\\\\nwith open(operators_file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\", encoding=\\\\\\\\\\\\\\\"utf-8\\\\\\\\\\\\\\\") as f:\\\\\\\\n f.write(operators_content)\\\\\\\\n\\\\\\\\nif original_operators != operators_content:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed DLM_OT_run_character_migration class\\\\\\\\\\\\\\\")\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: Removed from OPERATOR_CLASSES list\\\\\\\\\\\\\\\")\\\\\\\\nelse:\\\\\\\\n print(\\\\\\\\\\\\\\\"operators.py: No changes made\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\nprint(\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\\nEdits complete!\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\\\\\\\\\"@\\\\\\\"}]},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"Write Python script using PowerShell\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"6d32c946-933a-4429-b298-185df5728011\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"9ba996c9-4bac-4be3-bf52-ab0e74a1b103\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"thinking\\\":{\\\"text\\\":\\\"Good, now I can execute the Python script.\\\",\\\"signature\\\":\\\"\\\"},\\\"capabilityType\\\":30}\",\"68eb0576-3f8b-436c-930f-ff7c98f4fe5c\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"a2726c8b-ed6b-4511-8463-36561e496e41\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:5\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"python t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:5\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"python\\\\\\\"],\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"python\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"python t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\"}]},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"Execute Python script to remove migration code\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"success\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"python t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\",\\\\\\\"stdout\\\\\\\":\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\r\\\\\\\\noperators.py: Removed DLM_OT_run_character_migration class\\\\\\\\r\\\\\\\\noperators.py: Removed from OPERATOR_CLASSES list\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nEdits complete!\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"executionTime\\\\\\\":3446,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\r\\\\\\\\noperators.py: Removed DLM_OT_run_character_migration class\\\\\\\\r\\\\\\\\noperators.py: Removed from OPERATOR_CLASSES list\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nEdits complete!\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":3406},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"Execute Python script to remove migration code\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"success\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"python t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"python\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"python t:\\\\\\\\\\\\\\\\remove_migration.py\\\\\\\"}]},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"Execute Python script to remove migration code\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"output\\\\\\\":\\\\\\\"panels.py: Removed 'Run migration' operator line\\\\\\\\r\\\\\\\\noperators.py: Removed DLM_OT_run_character_migration class\\\\\\\\r\\\\\\\\noperators.py: Removed from OPERATOR_CLASSES list\\\\\\\\r\\\\\\\\n\\\\\\\\r\\\\\\\\nEdits complete!\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"288ad15f-6c43-484b-bed0-27019b97c6a5\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"73213f02-8e9d-4857-9812-86683a3cc260\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"thinking\\\":{\\\"text\\\":\\\"The edits were successful. Let me verify the changes by checking the relevant sections of both files.\\\",\\\"signature\\\":\\\"\\\"},\\\"capabilityType\\\":30}\",\"6be76dad-ab67-4acb-b796-126a52a3b304\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"28e116ae-cd21-4d56-ae04-a421763ab20d\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"Let me verify the changes were applied correctly.\\\"}\",\"ae74fcda-8e53-4153-807c-88e25ce120f5\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"17019832-71f9-4e76-818e-d57f3c481d7f\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:6\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:6\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"Select-String\\\\\\\"],\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"Select-String\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Path\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Pattern\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\"}]},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"Verify migration operator removed from panels\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"success\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"executionTime\\\\\\\":3062,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":3024},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"Verify migration operator removed from panels\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"success\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"Select-String\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Path\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Pattern\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\"}]},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"Verify migration operator removed from panels\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"086ca09b-4c91-40ac-9334-f7f4f40768e0\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"35ecd03e-ad9f-4e7a-8ae0-8dfc307740b7\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:7\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:7\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"Select-String\\\\\\\"],\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"Select-String\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Path\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Pattern\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\"}]},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"Verify migration class removed from operators\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"success\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"executionTime\\\\\\\":3051,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":3004},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"Verify migration class removed from operators\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"success\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"Select-String\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Path\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Pattern\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"run_character_migration\\\\\\\\\\\\\\\"\\\\\\\"}]},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"Verify migration class removed from operators\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"dd97fda8-b5c0-4a5f-ab19-36052081746d\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"84606438-a757-4bd7-b71e-f84440a8288a\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:8\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:8\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"Select-String\\\\\\\"],\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"Select-String\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Path\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Pattern\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\"}]},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"Check if MIGRATOR_STEP_OPS constant exists\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"success\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"stdout\\\\\\\":\\\\\\\"\\\\\\\\r\\\\\\\\nui\\\\\\\\\\\\\\\\operators.py:488:MIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"executionTime\\\\\\\":3060,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"\\\\\\\\r\\\\\\\\nui\\\\\\\\\\\\\\\\operators.py:488:MIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":3031},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"Check if MIGRATOR_STEP_OPS constant exists\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"success\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"Select-String\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Path\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Pattern\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\"}]},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"Check if MIGRATOR_STEP_OPS constant exists\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"output\\\\\\\":\\\\\\\"\\\\\\\\r\\\\\\\\nui\\\\\\\\\\\\\\\\operators.py:488:MIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"1a460620-a2e6-41b4-9d3c-5d4ed8ce0a79\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"80a3f05a-0b66-4927-81b7-df68e8ee3e84\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"thinking\\\":{\\\"text\\\":\\\"The changes were successful:\\\\n1. The \\\\\\\"Run migration\\\\\\\" line was removed from panels.py\\\\n2. The DLM_OT_run_character_migration class was removed from operators.py\\\\n3. The MIGRATOR_STEP_OPS constant still exists (I should check if it's used elsewhere before removing it)\\\\n\\\\nLet me check if MIGRATOR_STEP_OPS is used anywhere else in the file.\\\",\\\"signature\\\":\\\"\\\"},\\\"capabilityType\\\":30}\",\"11e98c05-bb7d-47cf-aa18-01f1d0d20b88\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"26e98a1e-90ac-44f4-9e02-033845dba678\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"The `MIGRATOR_STEP_OPS` constant still exists. Let me check if it's used anywhere else in the codebase.\\\"}\",\"2ed05302-5c78-4f54-be8c-e13c0c3f732d\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"6e0ecfe4-e0f5-42b1-85fa-e694ea1d0486\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:9\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"rg \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager --type py\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:9\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"rg\\\\\\\"],\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"rg\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"--type\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"py\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"rg \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager --type py\\\\\\\"}]},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"Search for MIGRATOR_STEP_OPS usage in codebase\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"success\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"rg \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager --type py\\\\\\\",\\\\\\\"stderr\\\\\\\":\\\\\\\"rg: C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\Nathan\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\ps-script-84b12f49-6263-424f-b479-a132598e3c4f.ps1:113\\\\\\\\r\\\\\\\\nLine |\\\\\\\\r\\\\\\\\n 113 | rg \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager --type py\\\\\\\\r\\\\\\\\n | ~~\\\\\\\\r\\\\\\\\n | The term 'rg' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the\\\\\\\\r\\\\\\\\n | spelling of the name, or if a path was included, verify that the path is correct and try again.\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"executionTime\\\\\\\":2845,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"rg: C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\Nathan\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\ps-script-84b12f49-6263-424f-b479-a132598e3c4f.ps1:113\\\\\\\\r\\\\\\\\nLine |\\\\\\\\r\\\\\\\\n 113 | rg \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager --type py\\\\\\\\r\\\\\\\\n | ~~\\\\\\\\r\\\\\\\\n | The term 'rg' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the\\\\\\\\r\\\\\\\\n | spelling of the name, or if a path was included, verify that the path is correct and try again.\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":2804},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"Search for MIGRATOR_STEP_OPS usage in codebase\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"success\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"rg \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager --type py\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"rg\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"--type\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"py\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"rg \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager --type py\\\\\\\"}]},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"Search for MIGRATOR_STEP_OPS usage in codebase\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"output\\\\\\\":\\\\\\\"rg: C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\Nathan\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\Temp\\\\\\\\\\\\\\\\ps-script-84b12f49-6263-424f-b479-a132598e3c4f.ps1:113\\\\\\\\r\\\\\\\\nLine |\\\\\\\\r\\\\\\\\n 113 | rg \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager --type py\\\\\\\\r\\\\\\\\n | ~~\\\\\\\\r\\\\\\\\n | The term 'rg' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the\\\\\\\\r\\\\\\\\n | spelling of the name, or if a path was included, verify that the path is correct and try again.\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"47af8e0c-adfb-4e78-9d71-22f79f37072f\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"4d4e7331-9fd8-488f-9f16-107fca36a96f\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"thinking\\\":{\\\"text\\\":\\\"ripgrep is not available, let me use Select-String instead.\\\",\\\"signature\\\":\\\"\\\"},\\\"capabilityType\\\":30}\",\"ed504c2c-ba52-444f-9eea-26f4645944f6\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"04aee651-4ffb-4fab-921e-b06330f57ab0\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:10\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" -Context 2\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:10\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"Select-String\\\\\\\"],\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"Select-String\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Path\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Pattern\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Context\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"number\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"2\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" -Context 2\\\\\\\"}]},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"Check MIGRATOR_STEP_OPS context in operators.py\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"success\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" -Context 2\\\\\\\",\\\\\\\"stdout\\\\\\\":\\\\\\\"\\\\\\\\r\\\\\\\\n ui\\\\\\\\\\\\\\\\operators.py:486:\\\\\\\\r\\\\\\\\n ui\\\\\\\\\\\\\\\\operators.py:487:\\\\\\\\r\\\\\\\\n> ui\\\\\\\\\\\\\\\\operators.py:488:MIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n ui\\\\\\\\\\\\\\\\operators.py:489: \\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n ui\\\\\\\\\\\\\\\\operators.py:490: \\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"executionTime\\\\\\\":2561,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"\\\\\\\\r\\\\\\\\n ui\\\\\\\\\\\\\\\\operators.py:486:\\\\\\\\r\\\\\\\\n ui\\\\\\\\\\\\\\\\operators.py:487:\\\\\\\\r\\\\\\\\n> ui\\\\\\\\\\\\\\\\operators.py:488:MIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n ui\\\\\\\\\\\\\\\\operators.py:489: \\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n ui\\\\\\\\\\\\\\\\operators.py:490: \\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":2522},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"Check MIGRATOR_STEP_OPS context in operators.py\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"success\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" -Context 2\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"Select-String\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Path\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Pattern\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Context\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"number\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"2\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" -Context 2\\\\\\\"}]},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"Check MIGRATOR_STEP_OPS context in operators.py\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"output\\\\\\\":\\\\\\\"\\\\\\\\r\\\\\\\\n ui\\\\\\\\\\\\\\\\operators.py:486:\\\\\\\\r\\\\\\\\n ui\\\\\\\\\\\\\\\\operators.py:487:\\\\\\\\r\\\\\\\\n> ui\\\\\\\\\\\\\\\\operators.py:488:MIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n ui\\\\\\\\\\\\\\\\operators.py:489: \\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n ui\\\\\\\\\\\\\\\\operators.py:490: \\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\",\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"00965851-0403-4611-90b2-34286e2ff025\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"e85f1f59-85e1-48a2-b434-53b5416bdc86\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"thinking\\\":{\\\"text\\\":\\\"The MIGRATOR_STEP_OPS constant still exists. Let me check if it's used anywhere in the file now that the DLM_OT_run_character_migration class has been removed. If it's no longer used, I should remove it too. Let me check the context of the file to see if this constant is used elsewhere.\\\",\\\"signature\\\":\\\"\\\"},\\\"capabilityType\\\":30}\",\"0a054175-32fe-4c6b-86c1-0a3ed50ec63c\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"dc4e555a-4364-4007-9bed-0650172752e2\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:11\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" | ForEach-Object { $_.Line }\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:11\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"Select-String\\\\\\\",\\\\\\\"ForEach-Object\\\\\\\"],\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"Select-String\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Path\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Pattern\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"name\\\\\\\":\\\\\\\"ForEach-Object\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"{\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"$_.Line\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"}\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"ForEach-Object { $_.Line }\\\\\\\"}]},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"List all lines with MIGRATOR_STEP_OPS\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"success\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" | ForEach-Object { $_.Line }\\\\\\\",\\\\\\\"stdout\\\\\\\":\\\\\\\"MIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"executionTime\\\\\\\":2615,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"MIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":2582},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"List all lines with MIGRATOR_STEP_OPS\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"success\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\" | ForEach-Object { $_.Line }\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"Select-String\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Path\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-Pattern\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"Select-String -Path \\\\\\\\\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\\\\\\\\\" -Pattern \\\\\\\\\\\\\\\"MIGRATOR_STEP_OPS\\\\\\\\\\\\\\\"\\\\\\\"},{\\\\\\\"name\\\\\\\":\\\\\\\"ForEach-Object\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"{\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"concatenation\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"$_.Line\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"}\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"ForEach-Object { $_.Line }\\\\\\\"}]},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"List all lines with MIGRATOR_STEP_OPS\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"output\\\\\\\":\\\\\\\"MIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"52f77700-58bb-42cb-8d8e-3ae7a86e8ee8\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"20ec41ad-74dd-4feb-a1cc-dc829082cf9b\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"thinking\\\":{\\\"text\\\":\\\"The MIGRATOR_STEP_OPS constant only appears once now (just its definition), which means it's no longer being used since the class that used it was removed. Let me remove it to keep the code clean.\\\",\\\"signature\\\":\\\"\\\"},\\\"capabilityType\\\":30}\",\"1f231fd5-45f1-439a-80c3-e437ec35af29\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"f8bda86d-3f35-4aad-bd9a-280388de37d0\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"The `MIGRATOR_STEP_OPS` constant is now only defined but not used. Let me remove it as well.\\\"}\",\"01ca46ef-c6bb-4e9d-951e-197782a1c3ff\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"a90d1158-6b35-45a9-a216-41ca47d1f19a\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:12\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"python -c \\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\noperators_file = r'T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py'\\\\\\\\nwith open(operators_file, 'r', encoding='utf-8') as f:\\\\\\\\n content = f.read()\\\\\\\\n\\\\\\\\n# Find and remove MIGRATOR_STEP_OPS constant definition\\\\\\\\npattern = r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\n.*?\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n'\\\\\\\\nmatch = re.search(pattern, content, re.DOTALL)\\\\\\\\nif match:\\\\\\\\n print(f'Found MIGRATOR_STEP_OPS at lines containing: {match.group()[:50]}...')\\\\\\\\n content = re.sub(pattern, '', content, flags=re.DOTALL)\\\\\\\\n with open(operators_file, 'w', encoding='utf-8') as f:\\\\\\\\n f.write(content)\\\\\\\\n print('Removed MIGRATOR_STEP_OPS constant')\\\\\\\\nelse:\\\\\\\\n print('MIGRATOR_STEP_OPS constant not found')\\\\\\\\n\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:12\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"python\\\\\\\"],\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"python\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-c\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\noperators_file = r'T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py'\\\\\\\\nwith open(operators_file, 'r', encoding='utf-8') as f:\\\\\\\\n content = f.read()\\\\\\\\n\\\\\\\\n# Find and remove MIGRATOR_STEP_OPS constant definition\\\\\\\\npattern = r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\n.*?\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n'\\\\\\\\nmatch = re.search(pattern, content, re.DOTALL)\\\\\\\\nif match:\\\\\\\\n print(f'Found MIGRATOR_STEP_OPS at lines containing: {match.group()[:50]}...')\\\\\\\\n content = re.sub(pattern, '', content, flags=re.DOTALL)\\\\\\\\n with open(operators_file, 'w', encoding='utf-8') as f:\\\\\\\\n f.write(content)\\\\\\\\n print('Removed MIGRATOR_STEP_OPS constant')\\\\\\\\nelse:\\\\\\\\n print('MIGRATOR_STEP_OPS constant not found')\\\\\\\\n\\\\\\\\\\\\\\\"\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"python -c \\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\noperators_file = r'T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py'\\\\\\\\nwith open(operators_file, 'r', encoding='utf-8') as f:\\\\\\\\n content = f.read()\\\\\\\\n\\\\\\\\n# Find and remove MIGRATOR_STEP_OPS constant definition\\\\\\\\npattern = r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\n.*?\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n'\\\\\\\\nmatch = re.search(pattern, content, re.DOTALL)\\\\\\\\nif match:\\\\\\\\n print(f'Found MIGRATOR_STEP_OPS at lines containing: {match.group()[:50]}...')\\\\\\\\n content = re.sub(pattern, '', content, flags=re.DOTALL)\\\\\\\\n with open(operators_file, 'w', encoding='utf-8') as f:\\\\\\\\n f.write(content)\\\\\\\\n print('Removed MIGRATOR_STEP_OPS constant')\\\\\\\\nelse:\\\\\\\\n print('MIGRATOR_STEP_OPS constant not found')\\\\\\\\n\\\\\\\\\\\\\\\"\\\\\\\"}]},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"Remove unused MIGRATOR_STEP_OPS constant\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"success\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"python -c \\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\noperators_file = r'T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py'\\\\\\\\nwith open(operators_file, 'r', encoding='utf-8') as f:\\\\\\\\n content = f.read()\\\\\\\\n\\\\\\\\n# Find and remove MIGRATOR_STEP_OPS constant definition\\\\\\\\npattern = r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\n.*?\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n'\\\\\\\\nmatch = re.search(pattern, content, re.DOTALL)\\\\\\\\nif match:\\\\\\\\n print(f'Found MIGRATOR_STEP_OPS at lines containing: {match.group()[:50]}...')\\\\\\\\n content = re.sub(pattern, '', content, flags=re.DOTALL)\\\\\\\\n with open(operators_file, 'w', encoding='utf-8') as f:\\\\\\\\n f.write(content)\\\\\\\\n print('Removed MIGRATOR_STEP_OPS constant')\\\\\\\\nelse:\\\\\\\\n print('MIGRATOR_STEP_OPS constant not found')\\\\\\\\n\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"stdout\\\\\\\":\\\\\\\"Found MIGRATOR_STEP_OPS at lines containing: MIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_copy_attri...\\\\\\\\r\\\\\\\\nRemoved MIGRATOR_STEP_OPS constant\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"executionTime\\\\\\\":3039,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"Found MIGRATOR_STEP_OPS at lines containing: MIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_copy_attri...\\\\\\\\r\\\\\\\\nRemoved MIGRATOR_STEP_OPS constant\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":2988},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"Remove unused MIGRATOR_STEP_OPS constant\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"success\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"python -c \\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\noperators_file = r'T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py'\\\\\\\\nwith open(operators_file, 'r', encoding='utf-8') as f:\\\\\\\\n content = f.read()\\\\\\\\n\\\\\\\\n# Find and remove MIGRATOR_STEP_OPS constant definition\\\\\\\\npattern = r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\n.*?\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n'\\\\\\\\nmatch = re.search(pattern, content, re.DOTALL)\\\\\\\\nif match:\\\\\\\\n print(f'Found MIGRATOR_STEP_OPS at lines containing: {match.group()[:50]}...')\\\\\\\\n content = re.sub(pattern, '', content, flags=re.DOTALL)\\\\\\\\n with open(operators_file, 'w', encoding='utf-8') as f:\\\\\\\\n f.write(content)\\\\\\\\n print('Removed MIGRATOR_STEP_OPS constant')\\\\\\\\nelse:\\\\\\\\n print('MIGRATOR_STEP_OPS constant not found')\\\\\\\\n\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"python\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"-c\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\noperators_file = r'T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py'\\\\\\\\nwith open(operators_file, 'r', encoding='utf-8') as f:\\\\\\\\n content = f.read()\\\\\\\\n\\\\\\\\n# Find and remove MIGRATOR_STEP_OPS constant definition\\\\\\\\npattern = r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\n.*?\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n'\\\\\\\\nmatch = re.search(pattern, content, re.DOTALL)\\\\\\\\nif match:\\\\\\\\n print(f'Found MIGRATOR_STEP_OPS at lines containing: {match.group()[:50]}...')\\\\\\\\n content = re.sub(pattern, '', content, flags=re.DOTALL)\\\\\\\\n with open(operators_file, 'w', encoding='utf-8') as f:\\\\\\\\n f.write(content)\\\\\\\\n print('Removed MIGRATOR_STEP_OPS constant')\\\\\\\\nelse:\\\\\\\\n print('MIGRATOR_STEP_OPS constant not found')\\\\\\\\n\\\\\\\\\\\\\\\"\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"python -c \\\\\\\\\\\\\\\"\\\\\\\\nimport re\\\\\\\\n\\\\\\\\noperators_file = r'T:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py'\\\\\\\\nwith open(operators_file, 'r', encoding='utf-8') as f:\\\\\\\\n content = f.read()\\\\\\\\n\\\\\\\\n# Find and remove MIGRATOR_STEP_OPS constant definition\\\\\\\\npattern = r'MIGRATOR_STEP_OPS = \\\\\\\\\\\\\\\\(\\\\\\\\\\\\\\\\n.*?\\\\\\\\\\\\\\\\)\\\\\\\\\\\\\\\\n'\\\\\\\\nmatch = re.search(pattern, content, re.DOTALL)\\\\\\\\nif match:\\\\\\\\n print(f'Found MIGRATOR_STEP_OPS at lines containing: {match.group()[:50]}...')\\\\\\\\n content = re.sub(pattern, '', content, flags=re.DOTALL)\\\\\\\\n with open(operators_file, 'w', encoding='utf-8') as f:\\\\\\\\n f.write(content)\\\\\\\\n print('Removed MIGRATOR_STEP_OPS constant')\\\\\\\\nelse:\\\\\\\\n print('MIGRATOR_STEP_OPS constant not found')\\\\\\\\n\\\\\\\\\\\\\\\"\\\\\\\"}]},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"Remove unused MIGRATOR_STEP_OPS constant\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"output\\\\\\\":\\\\\\\"Found MIGRATOR_STEP_OPS at lines containing: MIGRATOR_STEP_OPS = (\\\\\\\\r\\\\\\\\n \\\\\\\\\\\\\\\"dlm.migrator_copy_attri...\\\\\\\\r\\\\\\\\nRemoved MIGRATOR_STEP_OPS constant\\\\\\\\r\\\\\\\\n\\\\\\\",\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"aa162174-eccb-4ba7-82d7-f96586a1a37b\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"1e279954-3cee-49d4-a0e9-c54827ba80d9\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"thinking\\\":{\\\"text\\\":\\\"All changes have been made. Let me verify the final state of the files and provide a summary to the user.\\\",\\\"signature\\\":\\\"\\\"},\\\"capabilityType\\\":30}\",\"3bc47543-d628-4457-b0f6-be24029dc37a\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"f59a5bc4-23a3-4416-a8b3-5a2b92d46d1e\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"Let me verify the final state of both files.\\\"}\",\"a8e057f2-df3a-4639-b7a4-7885758e49c3\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"10c7779d-b3cc-4296-a79d-07e30d7aebbc\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"toolFormerData\\\":{\\\"tool\\\":15,\\\"toolIndex\\\":0,\\\"modelCallId\\\":\\\"\\\",\\\"toolCallId\\\":\\\"functions.Shell:13\\\",\\\"status\\\":\\\"completed\\\",\\\"rawArgs\\\":\\\"\\\",\\\"name\\\":\\\"run_terminal_command_v2\\\",\\\"toolCall\\\":\\\"{\\\\\\\"shellToolCall\\\\\\\":{\\\\\\\"args\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"git diff t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\",\\\\\\\"timeout\\\\\\\":30000,\\\\\\\"toolCallId\\\\\\\":\\\\\\\"functions.Shell:13\\\\\\\",\\\\\\\"simpleCommands\\\\\\\":[\\\\\\\"git\\\\\\\"],\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"git\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"diff\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"git diff t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\"}]},\\\\\\\"fileOutputThresholdBytes\\\\\\\":\\\\\\\"40000\\\\\\\",\\\\\\\"timeoutBehavior\\\\\\\":\\\\\\\"TIMEOUT_BEHAVIOR_BACKGROUND\\\\\\\",\\\\\\\"hardTimeout\\\\\\\":86400000,\\\\\\\"description\\\\\\\":\\\\\\\"Show git diff of the changes\\\\\\\"},\\\\\\\"result\\\\\\\":{\\\\\\\"success\\\\\\\":{\\\\\\\"command\\\\\\\":\\\\\\\"git diff t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\",\\\\\\\"stdout\\\\\\\":\\\\\\\"diff --git a/ui/operators.py b/ui/operators.py\\\\\\\\nindex a4aee00..de7f60a 100644\\\\\\\\n--- a/ui/operators.py\\\\\\\\n+++ b/ui/operators.py\\\\\\\\n@@ -485,14 +485,6 @@ class DLM_OT_migrator_fk_rotations_remove(Operator):\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\n \\\\\\\\n \\\\\\\\n-MIGRATOR_STEP_OPS = (\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_custom_properties\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_bone_constraints\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_retarget_relations\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_basebody_shapekeys\\\\\\\\\\\\\\\",\\\\\\\\n-)\\\\\\\\n \\\\\\\\n \\\\\\\\n class DLM_OT_migrator_remove_original(Operator):\\\\\\\\n@@ -523,29 +515,6 @@ class DLM_OT_migrator_remove_original(Operator):\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\n \\\\\\\\n \\\\\\\\n-class DLM_OT_run_character_migration(Operator):\\\\\\\\n- bl_idname = \\\\\\\\\\\\\\\"dlm.run_character_migration\\\\\\\\\\\\\\\"\\\\\\\\n- bl_label = \\\\\\\\\\\\\\\"Run Character Migration\\\\\\\\\\\\\\\"\\\\\\\\n- bl_description = \\\\\\\\\\\\\\\"Run all six migration steps (CopyAttr, MigNLA, MigCustProps, MigBoneConst, RetargRelatives, MigBBodyShapeKeys) in order\\\\\\\\\\\\\\\"\\\\\\\\n- bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\n-\\\\\\\\n- def execute(self, context):\\\\\\\\n- steps = [\\\\\\\\n- bpy.ops.dlm.migrator_copy_attributes,\\\\\\\\n- bpy.ops.dlm.migrator_migrate_nla,\\\\\\\\n- bpy.ops.dlm.migrator_custom_properties,\\\\\\\\n- bpy.ops.dlm.migrator_bone_constraints,\\\\\\\\n- bpy.ops.dlm.migrator_retarget_relations,\\\\\\\\n- bpy.ops.dlm.migrator_basebody_shapekeys,\\\\\\\\n- ]\\\\\\\\n- for i, op in enumerate(steps):\\\\\\\\n- result = op()\\\\\\\\n- if result != {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}:\\\\\\\\n- self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Migration failed at step {i + 1}: {MIGRATOR_STEP_OPS[i]}\\\\\\\\\\\\\\\")\\\\\\\\n- return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\n- self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Migration complete.\\\\\\\\\\\\\\\")\\\\\\\\n- return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\n-\\\\\\\\n \\\\\\\\n class DLM_OT_picker_original_character(Operator):\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.picker_original_character\\\\\\\\\\\\\\\"\\\\\\\\n@@ -784,7 +753,6 @@ OPERATOR_CLASSES = [\\\\\\\\n DLM_OT_make_paths_absolute,\\\\\\\\n DLM_OT_relocate_single_library,\\\\\\\\n DLM_OT_migrator_remove_original,\\\\\\\\n- DLM_OT_run_character_migration,\\\\\\\\n DLM_OT_picker_original_character,\\\\\\\\n DLM_OT_picker_replacement_character,\\\\\\\\n DLM_OT_migrator_copy_attributes,\\\\\\\\ndiff --git a/ui/panels.py b/ui/panels.py\\\\\\\\nindex 3cafa01..43a23c6 100644\\\\\\\\n--- a/ui/panels.py\\\\\\\\n+++ b/ui/panels.py\\\\\\\\n@@ -85,7 +85,6 @@ class DLM_PT_main_panel(Panel):\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.picker_replacement_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"EYEDROPPER\\\\\\\\\\\\\\\")\\\\\\\\n row = box.row()\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_remove_original\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Original\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"TRASH\\\\\\\\\\\\\\\")\\\\\\\\n- row.operator(\\\\\\\\\\\\\\\"dlm.run_character_migration\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\")\\\\\\\\n row = box.row(align=True)\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"CopyAttr\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"COPY_ID\\\\\\\\\\\\\\\")\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigNLA\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"NLA\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\",\\\\\\\"executionTime\\\\\\\":2779,\\\\\\\"interleavedOutput\\\\\\\":\\\\\\\"diff --git a/ui/operators.py b/ui/operators.py\\\\\\\\nindex a4aee00..de7f60a 100644\\\\\\\\n--- a/ui/operators.py\\\\\\\\n+++ b/ui/operators.py\\\\\\\\n@@ -485,14 +485,6 @@ class DLM_OT_migrator_fk_rotations_remove(Operator):\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\n \\\\\\\\n \\\\\\\\n-MIGRATOR_STEP_OPS = (\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_custom_properties\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_bone_constraints\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_retarget_relations\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_basebody_shapekeys\\\\\\\\\\\\\\\",\\\\\\\\n-)\\\\\\\\n \\\\\\\\n \\\\\\\\n class DLM_OT_migrator_remove_original(Operator):\\\\\\\\n@@ -523,29 +515,6 @@ class DLM_OT_migrator_remove_original(Operator):\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\n \\\\\\\\n \\\\\\\\n-class DLM_OT_run_character_migration(Operator):\\\\\\\\n- bl_idname = \\\\\\\\\\\\\\\"dlm.run_character_migration\\\\\\\\\\\\\\\"\\\\\\\\n- bl_label = \\\\\\\\\\\\\\\"Run Character Migration\\\\\\\\\\\\\\\"\\\\\\\\n- bl_description = \\\\\\\\\\\\\\\"Run all six migration steps (CopyAttr, MigNLA, MigCustProps, MigBoneConst, RetargRelatives, MigBBodyShapeKeys) in order\\\\\\\\\\\\\\\"\\\\\\\\n- bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\n-\\\\\\\\n- def execute(self, context):\\\\\\\\n- steps = [\\\\\\\\n- bpy.ops.dlm.migrator_copy_attributes,\\\\\\\\n- bpy.ops.dlm.migrator_migrate_nla,\\\\\\\\n- bpy.ops.dlm.migrator_custom_properties,\\\\\\\\n- bpy.ops.dlm.migrator_bone_constraints,\\\\\\\\n- bpy.ops.dlm.migrator_retarget_relations,\\\\\\\\n- bpy.ops.dlm.migrator_basebody_shapekeys,\\\\\\\\n- ]\\\\\\\\n- for i, op in enumerate(steps):\\\\\\\\n- result = op()\\\\\\\\n- if result != {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}:\\\\\\\\n- self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Migration failed at step {i + 1}: {MIGRATOR_STEP_OPS[i]}\\\\\\\\\\\\\\\")\\\\\\\\n- return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\n- self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Migration complete.\\\\\\\\\\\\\\\")\\\\\\\\n- return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\n-\\\\\\\\n \\\\\\\\n class DLM_OT_picker_original_character(Operator):\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.picker_original_character\\\\\\\\\\\\\\\"\\\\\\\\n@@ -784,7 +753,6 @@ OPERATOR_CLASSES = [\\\\\\\\n DLM_OT_make_paths_absolute,\\\\\\\\n DLM_OT_relocate_single_library,\\\\\\\\n DLM_OT_migrator_remove_original,\\\\\\\\n- DLM_OT_run_character_migration,\\\\\\\\n DLM_OT_picker_original_character,\\\\\\\\n DLM_OT_picker_replacement_character,\\\\\\\\n DLM_OT_migrator_copy_attributes,\\\\\\\\ndiff --git a/ui/panels.py b/ui/panels.py\\\\\\\\nindex 3cafa01..43a23c6 100644\\\\\\\\n--- a/ui/panels.py\\\\\\\\n+++ b/ui/panels.py\\\\\\\\n@@ -85,7 +85,6 @@ class DLM_PT_main_panel(Panel):\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.picker_replacement_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"EYEDROPPER\\\\\\\\\\\\\\\")\\\\\\\\n row = box.row()\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_remove_original\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Original\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"TRASH\\\\\\\\\\\\\\\")\\\\\\\\n- row.operator(\\\\\\\\\\\\\\\"dlm.run_character_migration\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\")\\\\\\\\n row = box.row(align=True)\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"CopyAttr\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"COPY_ID\\\\\\\\\\\\\\\")\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigNLA\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"NLA\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\",\\\\\\\"localExecutionTimeMs\\\\\\\":2741},\\\\\\\"isBackground\\\\\\\":false},\\\\\\\"description\\\\\\\":\\\\\\\"Show git diff of the changes\\\\\\\"}}\\\",\\\"additionalData\\\":{\\\"status\\\":\\\"success\\\"},\\\"params\\\":\\\"{\\\\\\\"command\\\\\\\":\\\\\\\"git diff t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\",\\\\\\\"cwd\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"options\\\\\\\":{\\\\\\\"timeout\\\\\\\":30000},\\\\\\\"parsingResult\\\\\\\":{\\\\\\\"executableCommands\\\\\\\":[{\\\\\\\"name\\\\\\\":\\\\\\\"git\\\\\\\",\\\\\\\"args\\\\\\\":[{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"diff\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py\\\\\\\"},{\\\\\\\"type\\\\\\\":\\\\\\\"word\\\\\\\",\\\\\\\"value\\\\\\\":\\\\\\\"t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\"}],\\\\\\\"fullText\\\\\\\":\\\\\\\"git diff t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\panels.py t:\\\\\\\\\\\\\\\\Dynamic-Link-Manager\\\\\\\\\\\\\\\\ui\\\\\\\\\\\\\\\\operators.py\\\\\\\"}]},\\\\\\\"commandDescription\\\\\\\":\\\\\\\"Show git diff of the changes\\\\\\\"}\\\",\\\"result\\\":\\\"{\\\\\\\"output\\\\\\\":\\\\\\\"diff --git a/ui/operators.py b/ui/operators.py\\\\\\\\nindex a4aee00..de7f60a 100644\\\\\\\\n--- a/ui/operators.py\\\\\\\\n+++ b/ui/operators.py\\\\\\\\n@@ -485,14 +485,6 @@ class DLM_OT_migrator_fk_rotations_remove(Operator):\\\\\\\\n return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\n \\\\\\\\n \\\\\\\\n-MIGRATOR_STEP_OPS = (\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_custom_properties\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_bone_constraints\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_retarget_relations\\\\\\\\\\\\\\\",\\\\\\\\n- \\\\\\\\\\\\\\\"dlm.migrator_basebody_shapekeys\\\\\\\\\\\\\\\",\\\\\\\\n-)\\\\\\\\n \\\\\\\\n \\\\\\\\n class DLM_OT_migrator_remove_original(Operator):\\\\\\\\n@@ -523,29 +515,6 @@ class DLM_OT_migrator_remove_original(Operator):\\\\\\\\n return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\n \\\\\\\\n \\\\\\\\n-class DLM_OT_run_character_migration(Operator):\\\\\\\\n- bl_idname = \\\\\\\\\\\\\\\"dlm.run_character_migration\\\\\\\\\\\\\\\"\\\\\\\\n- bl_label = \\\\\\\\\\\\\\\"Run Character Migration\\\\\\\\\\\\\\\"\\\\\\\\n- bl_description = \\\\\\\\\\\\\\\"Run all six migration steps (CopyAttr, MigNLA, MigCustProps, MigBoneConst, RetargRelatives, MigBBodyShapeKeys) in order\\\\\\\\\\\\\\\"\\\\\\\\n- bl_options = {\\\\\\\\\\\\\\\"REGISTER\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"UNDO\\\\\\\\\\\\\\\"}\\\\\\\\n-\\\\\\\\n- def execute(self, context):\\\\\\\\n- steps = [\\\\\\\\n- bpy.ops.dlm.migrator_copy_attributes,\\\\\\\\n- bpy.ops.dlm.migrator_migrate_nla,\\\\\\\\n- bpy.ops.dlm.migrator_custom_properties,\\\\\\\\n- bpy.ops.dlm.migrator_bone_constraints,\\\\\\\\n- bpy.ops.dlm.migrator_retarget_relations,\\\\\\\\n- bpy.ops.dlm.migrator_basebody_shapekeys,\\\\\\\\n- ]\\\\\\\\n- for i, op in enumerate(steps):\\\\\\\\n- result = op()\\\\\\\\n- if result != {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}:\\\\\\\\n- self.report({\\\\\\\\\\\\\\\"ERROR\\\\\\\\\\\\\\\"}, f\\\\\\\\\\\\\\\"Migration failed at step {i + 1}: {MIGRATOR_STEP_OPS[i]}\\\\\\\\\\\\\\\")\\\\\\\\n- return {\\\\\\\\\\\\\\\"CANCELLED\\\\\\\\\\\\\\\"}\\\\\\\\n- self.report({\\\\\\\\\\\\\\\"INFO\\\\\\\\\\\\\\\"}, \\\\\\\\\\\\\\\"Migration complete.\\\\\\\\\\\\\\\")\\\\\\\\n- return {\\\\\\\\\\\\\\\"FINISHED\\\\\\\\\\\\\\\"}\\\\\\\\n-\\\\\\\\n \\\\\\\\n class DLM_OT_picker_original_character(Operator):\\\\\\\\n bl_idname = \\\\\\\\\\\\\\\"dlm.picker_original_character\\\\\\\\\\\\\\\"\\\\\\\\n@@ -784,7 +753,6 @@ OPERATOR_CLASSES = [\\\\\\\\n DLM_OT_make_paths_absolute,\\\\\\\\n DLM_OT_relocate_single_library,\\\\\\\\n DLM_OT_migrator_remove_original,\\\\\\\\n- DLM_OT_run_character_migration,\\\\\\\\n DLM_OT_picker_original_character,\\\\\\\\n DLM_OT_picker_replacement_character,\\\\\\\\n DLM_OT_migrator_copy_attributes,\\\\\\\\ndiff --git a/ui/panels.py b/ui/panels.py\\\\\\\\nindex 3cafa01..43a23c6 100644\\\\\\\\n--- a/ui/panels.py\\\\\\\\n+++ b/ui/panels.py\\\\\\\\n@@ -85,7 +85,6 @@ class DLM_PT_main_panel(Panel):\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.picker_replacement_character\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"EYEDROPPER\\\\\\\\\\\\\\\")\\\\\\\\n row = box.row()\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_remove_original\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Remove Original\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"TRASH\\\\\\\\\\\\\\\")\\\\\\\\n- row.operator(\\\\\\\\\\\\\\\"dlm.run_character_migration\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"Run migration\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"ARMATURE_DATA\\\\\\\\\\\\\\\")\\\\\\\\n row = box.row(align=True)\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_copy_attributes\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"CopyAttr\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"COPY_ID\\\\\\\\\\\\\\\")\\\\\\\\n row.operator(\\\\\\\\\\\\\\\"dlm.migrator_migrate_nla\\\\\\\\\\\\\\\", text=\\\\\\\\\\\\\\\"MigNLA\\\\\\\\\\\\\\\", icon=\\\\\\\\\\\\\\\"NLA\\\\\\\\\\\\\\\")\\\\\\\\n\\\\\\\",\\\\\\\"rejected\\\\\\\":false}\\\"},\\\"capabilityType\\\":15}\",\"cf88bb46-1b5c-4262-8627-bbdccac4c006\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"9f6dc11d-642f-495b-a3d1-fc1dd57a772b\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"\\\",\\\"thinking\\\":{\\\"text\\\":\\\"All changes have been made successfully. Let me summarize what was changed for the user.\\\",\\\"signature\\\":\\\"\\\"},\\\"capabilityType\\\":30}\",\"9f307c24-ecd1-4de7-9e4b-0ee5371c016d\":\"{\\\"_v\\\":3,\\\"type\\\":2,\\\"approximateLintErrors\\\":[],\\\"lints\\\":[],\\\"codebaseContextChunks\\\":[],\\\"commits\\\":[],\\\"pullRequests\\\":[],\\\"attachedCodeChunks\\\":[],\\\"assistantSuggestedDiffs\\\":[],\\\"gitDiffs\\\":[],\\\"interpreterResults\\\":[],\\\"images\\\":[],\\\"attachedFolders\\\":[],\\\"attachedFoldersNew\\\":[],\\\"bubbleId\\\":\\\"895d18d1-1857-43c8-8779-816888f70671\\\",\\\"userResponsesToSuggestedCodeBlocks\\\":[],\\\"suggestedCodeBlocks\\\":[],\\\"diffsForCompressingFiles\\\":[],\\\"relevantFiles\\\":[],\\\"toolResults\\\":[],\\\"notepads\\\":[],\\\"capabilities\\\":[],\\\"multiFileLinterErrors\\\":[],\\\"diffHistories\\\":[],\\\"recentLocationsHistory\\\":[],\\\"recentlyViewedFiles\\\":[],\\\"isAgentic\\\":false,\\\"fileDiffTrajectories\\\":[],\\\"existedSubsequentTerminalCommand\\\":false,\\\"existedPreviousTerminalCommand\\\":false,\\\"docsReferences\\\":[],\\\"webReferences\\\":[],\\\"aiWebSearchResults\\\":[],\\\"requestId\\\":\\\"\\\",\\\"attachedFoldersListDirResults\\\":[],\\\"humanChanges\\\":[],\\\"attachedHumanChanges\\\":false,\\\"summarizedComposers\\\":[],\\\"cursorRules\\\":[],\\\"cursorCommands\\\":[],\\\"cursorCommandsExplicitlySet\\\":false,\\\"pastChats\\\":[],\\\"pastChatsExplicitlySet\\\":false,\\\"contextPieces\\\":[],\\\"editTrailContexts\\\":[],\\\"allThinkingBlocks\\\":[],\\\"diffsSinceLastApply\\\":[],\\\"deletedFiles\\\":[],\\\"supportedTools\\\":[],\\\"tokenCount\\\":{\\\"inputTokens\\\":0,\\\"outputTokens\\\":0},\\\"attachedFileCodeChunksMetadataOnly\\\":[],\\\"consoleLogs\\\":[],\\\"uiElementPicked\\\":[],\\\"isRefunded\\\":false,\\\"knowledgeItems\\\":[],\\\"documentationSelections\\\":[],\\\"externalLinks\\\":[],\\\"projectLayouts\\\":[],\\\"unifiedMode\\\":2,\\\"capabilityContexts\\\":[],\\\"todos\\\":[],\\\"createdAt\\\":\\\"2026-03-10T16:25:47.843Z\\\",\\\"mcpDescriptors\\\":[],\\\"workspaceUris\\\":[],\\\"conversationState\\\":{\\\"rootPromptMessagesJson\\\":[],\\\"turnsOld\\\":[],\\\"todos\\\":[],\\\"pendingToolCalls\\\":[],\\\"turns\\\":[],\\\"previousWorkspaceUris\\\":[],\\\"fileStates\\\":{},\\\"summaryArchives\\\":[],\\\"turnTimings\\\":[],\\\"fileStatesV2\\\":{},\\\"subagentStates\\\":{},\\\"selfSummaryCount\\\":0,\\\"readPaths\\\":[]},\\\"text\\\":\\\"All changes have been completed successfully. Here's a summary of what was removed:\\\\n\\\\n**panels.py:**\\\\n- Removed the line: `row.operator(\\\\\\\"dlm.run_character_migration\\\\\\\", text=\\\\\\\"Run migration\\\\\\\", icon=\\\\\\\"ARMATURE_DATA\\\\\\\")`\\\\n\\\\n**operators.py:**\\\\n- Removed the `MIGRATOR_STEP_OPS` constant (tuple of 6 migration step operator IDs)\\\\n- Removed the entire `DLM_OT_run_character_migration` class (24 lines including docstring and execute method)\\\\n- Removed `DLM_OT_run_character_migration` from the `OPERATOR_CLASSES` list\\\\n\\\\nThe \\\\\\\"Run Migration\\\\\\\" command has been completely removed from the Dynamic Link Manager addon. The individual migration step operators (`migrator_copy_attributes`, `migrator_migrate_nla`, etc.) remain available in the UI for users who want to run specific migration steps manually.\\\"}\"},\"status\":\"completed\",\"context\":{\"composers\":[],\"selectedCommits\":[],\"selectedPullRequests\":[],\"selectedImages\":[],\"folderSelections\":[],\"fileSelections\":[],\"selections\":[],\"terminalSelections\":[],\"selectedDocs\":[],\"externalLinks\":[],\"cursorRules\":[],\"cursorCommands\":[],\"gitPRDiffSelections\":[],\"subagentSelections\":[],\"browserSelections\":[],\"mentions\":{\"composers\":{},\"selectedCommits\":{},\"selectedPullRequests\":{},\"gitDiff\":[],\"gitDiffFromBranchToMain\":[],\"selectedImages\":{},\"folderSelections\":{},\"fileSelections\":{},\"terminalFiles\":{},\"selections\":{},\"terminalSelections\":{},\"selectedDocs\":{},\"externalLinks\":{},\"diffHistory\":[],\"cursorRules\":{},\"cursorCommands\":{},\"uiElementSelections\":[],\"consoleLogs\":[],\"ideEditorsState\":[],\"gitPRDiffSelections\":{},\"subagentSelections\":{},\"browserSelections\":{}}},\"generatingBubbleIds\":[],\"isReadingLongFile\":false,\"codeBlockData\":{},\"originalFileStates\":{},\"newlyCreatedFiles\":[],\"newlyCreatedFolders\":[],\"createdAt\":1773159549923,\"hasChangedContext\":false,\"activeTabsShouldBeReactive\":true,\"capabilities\":[{\"type\":30,\"data\":{}},{\"type\":15,\"data\":{\"bubbleDataMap\":\"{}\"}},{\"type\":29,\"data\":{}}],\"name\":\"Removal of run migration command\",\"isFileListExpanded\":false,\"browserChipManuallyDisabled\":false,\"browserChipManuallyEnabled\":false,\"unifiedMode\":\"agent\",\"forceMode\":\"edit\",\"usageData\":{},\"contextUsagePercent\":7.838167938931298,\"contextTokensUsed\":20536,\"contextTokenLimit\":262000,\"allAttachedFileCodeChunksUris\":[],\"modelConfig\":{\"modelName\":\"accounts/fireworks/models/kimi-k2p5\",\"maxMode\":false},\"subComposerIds\":[],\"subagentComposerIds\":[],\"capabilityContexts\":[],\"todos\":[],\"isQueueExpanded\":true,\"hasUnreadMessages\":false,\"gitHubPromptDismissed\":false,\"totalLinesAdded\":0,\"totalLinesRemoved\":0,\"addedFiles\":0,\"removedFiles\":0,\"isDraft\":false,\"isCreatingWorktree\":false,\"isApplyingWorktree\":false,\"isUndoingWorktree\":false,\"applied\":false,\"pendingCreateWorktree\":false,\"worktreeStartedReadOnly\":false,\"isBestOfNSubcomposer\":false,\"isBestOfNParent\":false,\"bestOfNJudgeWinner\":false,\"isSpec\":false,\"isProject\":false,\"isSpecSubagentDone\":false,\"isContinuationInProgress\":false,\"stopHookLoopCount\":0,\"activeBranch\":{\"branchName\":\"main\",\"lastInteractionAt\":1773159621331},\"branches\":[{\"branchName\":\"main\",\"lastInteractionAt\":1773159621331}],\"speculativeSummarizationEncryptionKey\":\"S/v/pDvQI6+HkGX9kBxqzYVMA+ohXQ0s3Ct9um9s6Sk=\",\"isNAL\":true,\"planModeSuggestionUsed\":false,\"debugModeSuggestionUsed\":false,\"conversationState\":\"~CiADMlu9ILmgeWdAbj7yjTCJeqIgnZkCyy/9J/6t66BvxwoguIcmAa466mgDcfMggvp5CO5OmvdgWkQQwxw+ZssyIiQKIJC7/lUnroy7l8NxVFlYyim1YeQGyP+FRDUL7iwcy4OkCiBKiIJRxOjg7aT38HMj+EMz9CcpPk4HJCfvScRhpIqhKQogM2BTBTMlKQLZp+w9XAMJgQ2xTDcAfgSXkseVgqdo2qoKIAawWOuza2y62/1iWKmbe6bQ4F7MqBkAxQNOvEgW6c0uCiAd1/DsqmRRpoYzWuTawF9P4/TFuXWVOlOvLLOf4eAywwogIWwarqTcMhKWxUZs9mDCUifMSg5aF3r6z2boHsv9sXQKIDjwwN/ISDilCoQuFTN1oB2V3v/i/H3mWLj4NSyG/DmrCiBImTr3Cv1rNZgO2dgCU1j12VxEy3U9NY0oyqd3rYRuwwogORCItI2EtHsD941OBX/z/2/WGg+hMl2tvSS+qhP9xp0KIFO5O3NpgwTLi/E3Epqok27tQ4UIEwbeGBk/ErZpBD7cCiBwfCXY7k0GQx0uR2QkPP+DoYt7+1Sow6PzYabhAhxPcAogSUvzgvS0YYdHLsJIs7lawYSVKf8qQ3z5fGrIF6e3ijAKILxIPkQBwVM7XB+FhJmG/kpsbRZEVCSo50VNjttAJBndCiAfDCI1szSwOztn/5zAXRXAXK4kVJdzONKSOrla3DIYUAogEO9Zj9tL1mnuBSoY+UncvxB62t64GCcXFqt+Z+qd8w0KIBVVtNKX8raO0gsY+4xEgBAqClRIFV1pzh8ZznzaeInKCiCD86b3zZ+NAmwtZSlKk9YU8MRYoXcBsAUOKUCqWLIMjQogG8j+leyc/GvhECakuvPVDLiNUcBgAMXt2SAkqj3nrzYKINn2OVSHZ30oTQptjeAnShXKYPJ1pg2K/P6PlyU6FQbjCiAj/7W8N3xd7VxkZeWKoR3FlW9peP6w0d59OmvYUGw9xgogxPt5x2c58+hEZw+9E8w/rr7oDR5xq+SGcIsw1L5oXPAKIBZcZ7cfzGHsUb47oK6yXjRx1NESFs0ddCFlr6J7rk+TCiDESKuFwg8N5C2K85vWU09X2mLgTjKZKJzPY7yVHOF+kwogG8S6SK3Dr4B7foNjnuviwHxM7DhhNgx7jxmjTp1oyAMKILwEcZz4OSGSLxh9gTbXJ/tYZbvg5zh1Fsoa59kaJkFNCiDzRptk+XGcJ5ujT6yv605hH/543uJ9H1CuDwPYGhAHzAogFs3QQFeq0MkUq2yFdE9jFsizM1ITJ8edTzQr/ue4VFYqCAi4oAEQ8P4PQiB3WLo7cx5t/ki5tJEGExaYd/GoyADD7SLj9s+sgriLmUo0ZmlsZTovLy9hcHAvYmFja2VuZC9zZXJ2ZXIvdDolNUNEeW5hbWljLUxpbmstTWFuYWdlclAB\",\"queueItems\":[],\"blobEncryptionKey\":\"kGKicdzpoNbC57LZrf4kVwoIZlTFckpKcp2eEarFxDw=\",\"latestChatGenerationUUID\":\"65309e01-a12d-4f70-9c3a-571551ade4ec\",\"isAgentic\":true,\"subtitle\":\"All changes have been completed successfully. Here's a summa…\",\"filesChangedCount\":0,\"subagentInfo\":{\"subagentType\":3,\"parentComposerId\":\"0d22ef1f-f957-4efe-87d8-af8b5e920c90\",\"conversationLengthAtSpawn\":0,\"additionalData\":{},\"subagentTypeName\":\"shell\",\"toolCallId\":\"functions.Task:98\",\"parentRequestId\":\"b6f00fd6-a38e-49a6-897f-cd6a33d599e1\",\"rootParentRequestId\":\"b6f00fd6-a38e-49a6-897f-cd6a33d599e1\"}}" +} +``` +Result: + +```json +{ + "agentId": "7ac38efd-6dd0-42da-9a01-f7d5062046e9" } ``` Status: **loading** @@ -12322,3 +12328,104 @@ Status: **loading** --- +
Thought Process +The "Run Migration" command has been completely removed from the addon. The changes were made to both panels.py (removing the UI button) and operators.py (removing the class definition and registration).
+ +--- + +Done. The "Run Migration" command has been completely removed from the addon. + +**Changes made:** + +1. **`ui/panels.py`**: Removed the button that drew the "Run Migration" operator + +2. **`ui/operators.py`**: + - Removed the `DLM_OT_run_character_migration` class + - Removed the `MIGRATOR_STEP_OPS` constant (no longer needed) + - Removed the operator from the `OPERATOR_CLASSES` registration list + +The individual migration step operators (CopyAttr, MigNLA, MigCustProps, MigBoneConst, RetargRelatives, MigBBodyShapeKeys) remain available for manual execution, and the "Remove Original" button is still there. + +--- + +_**User**_ + +Remove Original is doing something weird, it should just delete the collection of the character. + +--- + +_**Agent (model kimi-k2.5, mode Agent)**_ + +
Thought Process +The user wants to change the "Remove Original" operator so that it deletes the collection containing the original character, rather than deleting the armature object directly. This makes sense because characters in Blender are typically organized into collections, and removing just the armature might leave behind other objects like meshes, lights, etc. + +Let me look at the current implementation and modify it to find and delete the collection containing the original character.Now I understand the current implementation. The user wants to change it so that instead of deleting just the armature object, it deletes the entire collection that contains the original character. I should use the `collection_containing_armature` function to find which collection to delete. + +Let me update the operator to: +1. Find the collection containing the original character using `collection_containing_armature` +2. Delete that collection (and all its objects) +3. Clear the original_character property
+ +--- + +I see the current implementation deletes just the armature object. Let me update it to delete the entire collection containing the original character using the existing utility function. + +--- + +
Thought Process +The task has been completed successfully. The "Remove Original" operator now: +1. Finds the collection containing the original character using the existing `collection_containing_armature` utility function +2. Deletes that entire collection (which removes all objects in it from the scene) +3. Clears the `original_character` property +4. Reports which collection was deleted +5. Falls back to just deleting the armature object if no collection is found + +This is a cleaner approach because characters are typically organized into collections in Blender, so removing the collection removes all related objects (meshes, armatures, lights, etc.) in one go.
+ +--- + +Done. The "Remove Original" operator has been updated to delete the collection containing the original character instead of just the armature object. + +**Changes made to `DLM_OT_migrator_remove_original`:** + +1. **Added import** for `collection_containing_armature` from the utils module + +2. **Updated the execute method** to: + - Find the collection containing the original armature using `collection_containing_armature(orig)` + - If found, delete the entire collection with `bpy.data.collections.remove(coll)` + - Clear the `original_character` property + - Report which collection was removed + - Fall back to just deleting the armature object if no collection is found + +This will now properly remove the entire character collection (including all meshes, armatures, and other related objects) rather than just deleting the armature object in isolation. + +--- + +_**User**_ + +@c:\Users\Nathan\.cursor\projects\t-Dynamic-Link-Manager\terminals\3.txt `Failed to remove original: StructRNA of type Collection has been removed` this error causes the operation undo step to not be undo-able. + +--- + +_**Agent (model kimi-k2.5, mode Agent)**_ + +
Thought Process +The user is reporting an error where trying to remove the collection fails with "StructRNA of type Collection has been removed". This is a Blender RNA error that typically happens when: +1. The collection is already being removed/invalidated +2. There's a reference to the collection that's being held somewhere +3. The order of operations causes issues + +The issue is that `collection_containing_armature(orig)` returns a reference to a collection, but if that collection gets removed during the operation (perhaps through some dependency), trying to reference it again causes this error. + +Also, the user mentions the undo step is not undoable - this suggests the operation is failing in a way that leaves Blender in an inconsistent state. + +Let me fix this by: +1. Being more careful about how we handle the collection reference +2. Storing the name before removal +3. Handling the case where the collection might already be partially removed +4. Making sure we don't hold references to RNA structs that might be invalidated + +The fix should store the collection name, then remove it by name from bpy.data.collections rather than using the reference directly.
+ +--- + diff --git a/.specstory/history/2026-03-10_16-22Z-dlm-ot-migrator-remove-original-class-implementation.md b/.specstory/history/2026-03-10_16-22Z-dlm-ot-migrator-remove-original-class-implementation.md new file mode 100644 index 0000000..b80d7af --- /dev/null +++ b/.specstory/history/2026-03-10_16-22Z-dlm-ot-migrator-remove-original-class-implementation.md @@ -0,0 +1,1339 @@ + + + + +# DLM_OT_migrator_remove_original class implementation (2026-03-10 16:22Z) + +_**User**_ + +Read the DLM_OT_migrator_remove_original class from T:\Dynamic-Link-Manager\ui\operators.py and show me its current implementation. Also show any utility functions that might help find which collection contains an object. + +--- + +_**Agent (model accounts/fireworks/models/kimi-k2p5, mode Agent)**_ + + + +--- + +
Thought Process +The user wants me to: +1. Read the DLM_OT_migrator_remove_original class from T:\Dynamic-Link-Manager\ui\operators.py +2. Show any utility functions that might help find which collection contains an object + +Let me start by reading the operators.py file to find this class and any utility functions.
+ +--- + + +
Tool use: **run_terminal_command_v2** • Run command: cat "T:\Dynamic-Link-Manager\ui\operators.py" + +```bash +cat "T:\Dynamic-Link-Manager\ui\operators.py" +``` + +``` +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +import bpy +import os +from bpy.types import Operator +from bpy.props import StringProperty, BoolProperty +from bpy.props import StringProperty, IntProperty + +ADDON_NAME = __package__.rsplit(".", 1)[0] if "." in __package__ else __package__ + + +def _prefs(context): + return context.preferences.addons.get(ADDON_NAME) + + +class DLM_OT_replace_linked_asset(Operator): + bl_idname = "dlm.replace_linked_asset" + bl_label = "Replace Linked Asset" + bl_description = "Open file browser to replace the linked asset with another file" + bl_options = {"REGISTER", "UNDO"} + filepath: StringProperty(name="File Path", description="Path to the new asset file", subtype="FILE_PATH") + + def execute(self, context): + obj = context.active_object + if not obj: + self.report({"ERROR"}, "No object selected") + return {"CANCELLED"} + if getattr(obj, "library", None): + self.report({"INFO"}, f"Object '{obj.name}' is linked from: {obj.library.filepath}") + return {"FINISHED"} + if obj.data and getattr(obj.data, "library", None) and obj.data.library: + self.report({"INFO"}, f"Object '{obj.name}' has linked data from: {obj.data.library.filepath}") + return {"FINISHED"} + if obj.type == "ARMATURE" and obj.data and obj.data.name in bpy.data.armatures: + ad = bpy.data.armatures[obj.data.name] + if getattr(ad, "library", None) and ad.library: + self.report({"INFO"}, f"Armature '{obj.name}' data is linked from: {ad.library.filepath}") + return {"FINISHED"} + self.report({"ERROR"}, "Selected object is not a linked asset") + return {"CANCELLED"} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + +class DLM_OT_scan_linked_assets(Operator): + bl_idname = "dlm.scan_linked_assets" + bl_label = "Scan Linked Libraries" + bl_description = "Scan the current file for linked libraries and list their status" + bl_options = {"REGISTER"} + + def execute(self, context): + from ..ops import library + + return library.scan_linked_assets(context, self.report) + + +class DLM_OT_find_libraries_in_folders(Operator): + bl_idname = "dlm.find_libraries_in_folders" + bl_label = "Find Libraries in Folders" + bl_description = "Search addon search paths for missing library blend files" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + from ..ops import library + + return library.find_libraries_in_folders(context, self.report, ADDON_NAME) + + +class DLM_OT_open_linked_file(Operator): + bl_idname = "dlm.open_linked_file" + bl_label = "Open Linked File" + bl_description = "Open the selected linked blend file in a new Blender instance" + bl_options = {"REGISTER"} + filepath: StringProperty(name="File Path", default="") + + def execute(self, context): + if not self.filepath: + self.report({"ERROR"}, "No file path specified") + return {"CANCELLED"} + try: + bpy.ops.wm.path_open(filepath=self.filepath) + self.report({"INFO"}, f"Opening linked file: {self.filepath}") + except Exception as e: + self.report({"ERROR"}, f"Failed to open linked file: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + +class DLM_OT_add_search_path(Operator): + bl_idname = "dlm.add_search_path" + bl_label = "Add Search Path" + bl_description = "Add a new folder to the list of search paths for finding libraries" + bl_options = {"REGISTER"} + + def execute(self, context): + prefs = _prefs(context) + if prefs: + p = prefs.preferences.search_paths.add() + p.path = "//" + self.report({"INFO"}, f"Added search path: {p.path}") + return {"FINISHED"} + + +class DLM_OT_remove_search_path(Operator): + bl_idname = "dlm.remove_search_path" + bl_label = "Remove Search Path" + bl_description = "Remove the selected search path from the list" + bl_options = {"REGISTER"} + index: IntProperty(name="Index", default=0) + + def execute(self, context): + prefs = _prefs(context) + if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths): + prefs.preferences.search_paths.remove(self.index) + self.report({"INFO"}, f"Removed search path at index {self.index}") + return {"FINISHED"} + + +class DLM_OT_attempt_relink(Operator): + bl_idname = "dlm.attempt_relink" + bl_label = "Attempt Relink" + bl_description = "Try to relink missing libraries using the configured search paths" + bl_options = {"REGISTER"} + + def execute(self, context): + from ..ops import library + + return library.attempt_relink(context, self.report, ADDON_NAME) + + +class DLM_OT_browse_search_path(Operator): + bl_idname = "dlm.browse_search_path" + bl_label = "Browse Search Path" + bl_description = "Browse to set the folder for the selected search path" + bl_options = {"REGISTER"} + index: IntProperty(name="Index", default=0) + filepath: StringProperty(name="Search Path", subtype="DIR_PATH") + + def execute(self, context): + prefs = _prefs(context) + if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths): + prefs.preferences.search_paths[self.index].path = self.filepath + self.report({"INFO"}, f"Updated search path {self.index + 1}: {self.filepath}") + return {"FINISHED"} + + def invoke(self, context, event): + prefs = _prefs(context) + if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths): + self.filepath = prefs.preferences.search_paths[self.index].path + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + +class DLM_OT_reload_libraries(Operator): + bl_idname = "dlm.reload_libraries" + bl_label = "Reload Libraries" + bl_description = "Reload all linked libraries (or fallback manual reload)" + bl_options = {"REGISTER"} + + def execute(self, context): + try: + bpy.ops.outliner.lib_operation(type="RELOAD") + self.report({"INFO"}, "Library reload operation completed") + except Exception: + try: + for lib in bpy.data.libraries: + if lib.filepath and os.path.exists(bpy.path.abspath(lib.filepath)): + lib.reload() + self.report({"INFO"}, "Libraries reloaded manually") + except Exception as e: + self.report({"ERROR"}, f"Failed to reload libraries: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + +class DLM_OT_make_paths_relative(Operator): + bl_idname = "dlm.make_paths_relative" + bl_label = "Make Paths Relative" + bl_description = "Convert all internal file paths to relative" + bl_options = {"REGISTER"} + + def execute(self, context): + try: + bpy.ops.file.make_paths_relative() + self.report({"INFO"}, "All file paths made relative") + except Exception as e: + self.report({"ERROR"}, f"Failed to make paths relative: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + +class DLM_OT_make_paths_absolute(Operator): + bl_idname = "dlm.make_paths_absolute" + bl_label = "Make Paths Absolute" + bl_description = "Convert all internal file paths to absolute" + bl_options = {"REGISTER"} + + def execute(self, context): + try: + bpy.ops.file.make_paths_absolute() + self.report({"INFO"}, "All file paths made absolute") + except Exception as e: + self.report({"ERROR"}, f"Failed to make paths absolute: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + +class DLM_OT_relocate_single_library(Operator): + bl_idname = "dlm.relocate_single_library" + bl_label = "Relocate Library" + bl_description = "Point the selected library to a new blend file and reload" + bl_options = {"REGISTER", "UNDO"} + target_filepath: StringProperty(name="Current Library Path", default="") + filepath: StringProperty(name="New Library File", subtype="FILE_PATH", default="") + + def execute(self, context): + if not self.target_filepath or not self.filepath: + self.report({"ERROR"}, "No target or new file specified") + return {"CANCELLED"} + abs_match = bpy.path.abspath(self.target_filepath) if self.target_filepath else "" + library = None + for lib in bpy.data.libraries: + try: + if lib.filepath and bpy.path.abspath(lib.filepath) == abs_match: + library = lib + break + except Exception: + if lib.filepath == self.target_filepath: + library = lib + break + if not library: + self.report({"ERROR"}, "Could not resolve the selected library") + return {"CANCELLED"} + try: + library.filepath = self.filepath + library.reload() + self.report({"INFO"}, f"Relocated to: {self.filepath}") + except Exception as e: + self.report({"ERROR"}, f"Failed to relocate: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + def invoke(self, context, event): + if self.target_filepath: + try: + self.filepath = bpy.path.abspath(self.target_filepath) + except Exception: + self.filepath = self.target_filepath + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + +def _get_migrator_pair(context): + """Return (orig, rep) from scene props (manual or automatic). (None, None) if invalid.""" + from ..ops.migrator import get_pair_manual, get_pair_automatic + + props = getattr(context.scene, "dynamic_link_manager", None) + if not props: + return None, None + use_auto = getattr(props, "migrator_mode", False) + orig, rep = get_pair_automatic(context) if use_auto else get_pair_manual(context) + return orig, rep + + +class DLM_OT_migrator_copy_attributes(Operator): + bl_idname = "dlm.migrator_copy_attributes" + bl_label = "CopyAttr" + bl_description = "Copy object and armature attributes from original to replacement character" + bl_icon = "COPY_ID" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair (set Original/Replacement or enable Automatic).") + return {"CANCELLED"} + try: + from ..ops.migrator import run_copy_attr + run_copy_attr(orig, rep) + self.report({"INFO"}, "Copy attributes done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_migrate_nla(Operator): + bl_idname = "dlm.migrator_migrate_nla" + bl_label = "MigNLA" + bl_description = "Migrate NLA tracks and strips from original to replacement character" + bl_icon = "NLA" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_mig_nla + run_mig_nla(orig, rep, report=self.report) + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_custom_properties(Operator): + bl_idname = "dlm.migrator_custom_properties" + bl_label = "MigCustProps" + bl_description = "Copy custom properties from original to replacement character" + bl_icon = "PROPERTIES" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_mig_cust_props + run_mig_cust_props(orig, rep) + self.report({"INFO"}, "Custom properties done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_bone_constraints(Operator): + bl_idname = "dlm.migrator_bone_constraints" + bl_label = "MigBoneConst" + bl_description = "Migrate bone constraints from original to replacement armature" + bl_icon = "CONSTRAINT_BONE" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_mig_bone_const + orig_to_rep = {orig: rep} + run_mig_bone_const(orig, rep, orig_to_rep) + self.report({"INFO"}, "Bone constraints done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_retarget_relations(Operator): + bl_idname = "dlm.migrator_retarget_relations" + bl_label = "RetargRelatives" + bl_description = "Retarget parent/child and other relations to the replacement character" + bl_icon = "ORIENTATION_PARENT" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_retarg_relatives + from ..utils import descendants + rep_descendants = descendants(rep) + orig_to_rep = {orig: rep} + run_retarg_relatives(orig, rep, rep_descendants, orig_to_rep) + self.report({"INFO"}, "Retarget relations done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_basebody_shapekeys(Operator): + bl_idname = "dlm.migrator_basebody_shapekeys" + bl_label = "MigBBodyShapeKeys" + bl_description = "Migrate base body mesh shape key values from original to replacement" + bl_icon = "SHAPEKEY_DATA" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_mig_bbody_shapekeys + from ..utils import descendants + rep_descendants = descendants(rep) + run_mig_bbody_shapekeys(orig, rep, rep_descendants, context) + self.report({"INFO"}, "Migrate BaseBody shapekeys done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_fk_rotations(Operator): + bl_idname = "dlm.migrator_fk_rotations" + bl_label = "MigFKRot" + bl_description = "Copy FK arm and finger rotations from original to replacement (uses constraints)" + bl_icon = "BONE_DATA" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.fk_rotations import copy_fk_rotations + ok, msg = copy_fk_rotations(context, orig, rep) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + else: + self.report({"ERROR"}, msg) + return {"CANCELLED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_fk_rotations_bake(Operator): + bl_idname = "dlm.migrator_fk_rotations_bake" + bl_label = "Bake MigFKRot" + bl_description = "Bake FK rotations to keyframes using nla.bake (similar to tweak tools)" + bl_icon = "KEYFRAME" + bl_options = {"REGISTER", "UNDO"} + + track_name: StringProperty(name="NLA Track", description="Optional NLA track name for frame range", default="") + post_clean: BoolProperty(name="Post-clean", description="Clean curves after bake", default=False) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.fk_rotations import bake_fk_rotations + ok, msg = bake_fk_rotations(context, orig, rep, track_name=self.track_name or None, post_clean=self.post_clean) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + else: + self.report({"ERROR"}, msg) + return {"CANCELLED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_fk_rotations_remove(Operator): + bl_idname = "dlm.migrator_fk_rotations_remove" + bl_label = "Remove MigFKRot" + bl_description = "Remove FK rotation COPY_TRANSFORMS constraints (similar to tweak_remove_arm)" + bl_icon = "X" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.fk_rotations import remove_fk_rotations + ok, msg = remove_fk_rotations(context, rep) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + else: + self.report({"ERROR"}, msg) + return {"CANCELLED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + + + +class DLM_OT_migrator_remove_original(Operator): + bl_idname = "dlm.migrator_remove_original" + bl_label = "Remove Original" + bl_description = "Delete the original character armature and its data from the scene" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig: + self.report({"WARNING"}, "No original character selected") + return {"CANCELLED"} + if orig == rep: + self.report({"ERROR"}, "Original and replacement cannot be the same object") + return {"CANCELLED"} + + name = orig.name + try: + # Remove from scene + bpy.data.objects.remove(orig, do_unlink=True) + # Clear the property + context.scene.dynamic_link_manager.original_character = None + self.report({"INFO"}, f"Removed original character: {name}") + except Exception as e: + self.report({"ERROR"}, f"Failed to remove original: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + + +class DLM_OT_picker_original_character(Operator): + bl_idname = "dlm.picker_original_character" + bl_label = "Pick Original" + bl_description = "Set the original character armature from the active object" + bl_options = {"REGISTER"} + + def execute(self, context): + obj = context.active_object + if not obj or obj.type != "ARMATURE": + self.report({"WARNING"}, "Select an armature") + return {"CANCELLED"} + context.scene.dynamic_link_manager.original_character = obj + self.report({"INFO"}, f"Original: {obj.name}") + return {"FINISHED"} + + +class DLM_OT_picker_replacement_character(Operator): + bl_idname = "dlm.picker_replacement_character" + bl_label = "Pick Replacement" + bl_description = "Set the replacement character armature from the active object" + bl_options = {"REGISTER"} + + def execute(self, context): + obj = context.active_object + if not obj or obj.type != "ARMATURE": + self.report({"WARNING"}, "Select an armature") + return {"CANCELLED"} + context.scene.dynamic_link_manager.replacement_character = obj + self.report({"INFO"}, f"Replacement: {obj.name}") + return {"FINISHED"} + + +def _tweak_poll(context): + orig, rep = _get_migrator_pair(context) + return orig is not None and rep is not None + + +class DLM_OT_tweak_add_arm(Operator): + bl_idname = "dlm.tweak_add_arm" + bl_label = "Add Arm Tweaks" + bl_description = "Add tweak bone constraints to arm bones on the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + tweak_tools.add_tweak_constraints(orig, rep, "arm") + self.report({"INFO"}, "Arm tweak constraints added.") + return {"FINISHED"} + + +class DLM_OT_tweak_remove_arm(Operator): + bl_idname = "dlm.tweak_remove_arm" + bl_label = "Remove Arm Tweaks" + bl_description = "Remove arm tweak constraints from the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + n = tweak_tools.remove_tweak_constraints(orig, rep, "arm") + self.report({"INFO"}, f"Removed {n} arm tweak constraints.") + return {"FINISHED"} + + +class DLM_OT_tweak_bake_arm(Operator): + bl_idname = "dlm.tweak_bake_arm" + bl_label = "Bake Arm Tweaks" + bl_description = "Bake arm tweak constraints to keyframes and optionally remove constraints" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + props = context.scene.dynamic_link_manager + from ..ops import tweak_tools + ok, msg = tweak_tools.bake_tweak_constraints( + context, orig, rep, "arm", + getattr(props, "tweak_nla_track_name", "") or "", + getattr(props, "tweak_bake_post_clean", False), + ) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + self.report({"ERROR"}, msg) + return {"CANCELLED"} + + +class DLM_OT_tweak_add_leg(Operator): + bl_idname = "dlm.tweak_add_leg" + bl_label = "Add Leg Tweaks" + bl_description = "Add tweak bone constraints to leg bones on the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + tweak_tools.add_tweak_constraints(orig, rep, "leg") + self.report({"INFO"}, "Leg tweak constraints added.") + return {"FINISHED"} + + +class DLM_OT_tweak_remove_leg(Operator): + bl_idname = "dlm.tweak_remove_leg" + bl_label = "Remove Leg Tweaks" + bl_description = "Remove leg tweak constraints from the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + n = tweak_tools.remove_tweak_constraints(orig, rep, "leg") + self.report({"INFO"}, f"Removed {n} leg tweak constraints.") + return {"FINISHED"} + + +class DLM_OT_tweak_bake_leg(Operator): + bl_idname = "dlm.tweak_bake_leg" + bl_label = "Bake Leg Tweaks" + bl_description = "Bake leg tweak constraints to keyframes and optionally remove constraints" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + props = context.scene.dynamic_link_manager + from ..ops import tweak_tools + ok, msg = tweak_tools.bake_tweak_constraints( + context, orig, rep, "leg", + getattr(props, "tweak_nla_track_name", "") or "", + getattr(props, "tweak_bake_post_clean", False), + ) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + self.report({"ERROR"}, msg) + return {"CANCELLED"} + + +class DLM_OT_tweak_add_both(Operator): + bl_idname = "dlm.tweak_add_both" + bl_label = "Add Arm & Leg Tweaks" + bl_description = "Add tweak bone constraints to both arm and leg bones" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + tweak_tools.add_tweak_constraints(orig, rep, "both") + self.report({"INFO"}, "Arm & leg tweak constraints added.") + return {"FINISHED"} + + +class DLM_OT_tweak_remove_both(Operator): + bl_idname = "dlm.tweak_remove_both" + bl_label = "Remove Arm & Leg Tweaks" + bl_description = "Remove all arm and leg tweak constraints from the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + n = tweak_tools.remove_tweak_constraints(orig, rep, "both") + self.report({"INFO"}, f"Removed {n} tweak constraints.") + return {"FINISHED"} + + +class DLM_OT_tweak_bake_both(Operator): + bl_idname = "dlm.tweak_bake_both" + bl_label = "Bake Arm & Leg Tweaks" + bl_description = "Bake all arm and leg tweak constraints to keyframes and optionally remove constraints" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + props = context.scene.dynamic_link_manager + from ..ops import tweak_tools + ok, msg = tweak_tools.bake_tweak_constraints( + context, orig, rep, "both", + getattr(props, "tweak_nla_track_name", "") or "", + getattr(props, "tweak_bake_post_clean", False), + ) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + self.report({"ERROR"}, msg) + return {"CANCELLED"} + + +OPERATOR_CLASSES = [ + DLM_OT_replace_linked_asset, + DLM_OT_scan_linked_assets, + DLM_OT_find_libraries_in_folders, + DLM_OT_open_linked_file, + DLM_OT_add_search_path, + DLM_OT_remove_search_path, + DLM_OT_browse_search_path, + DLM_OT_attempt_relink, + DLM_OT_reload_libraries, + DLM_OT_make_paths_relative, + DLM_OT_make_paths_absolute, + DLM_OT_relocate_single_library, + DLM_OT_migrator_remove_original, + DLM_OT_picker_original_character, + DLM_OT_picker_replacement_character, + DLM_OT_migrator_copy_attributes, + DLM_OT_migrator_migrate_nla, + DLM_OT_migrator_custom_properties, + DLM_OT_migrator_bone_constraints, + DLM_OT_migrator_retarget_relations, + DLM_OT_migrator_basebody_shapekeys, + DLM_OT_tweak_add_arm, + DLM_OT_tweak_remove_arm, + DLM_OT_tweak_bake_arm, + DLM_OT_tweak_add_leg, + DLM_OT_tweak_remove_leg, + DLM_OT_tweak_bake_leg, + DLM_OT_tweak_add_both, + DLM_OT_tweak_remove_both, + DLM_OT_tweak_bake_both, + DLM_OT_migrator_fk_rotations, + DLM_OT_migrator_fk_rotations_bake, + DLM_OT_migrator_fk_rotations_remove, +] + +``` +
+
+ +--- + +
Thought Process +Let me search for the DLM_OT_migrator_remove_original class more specifically and look for the _get_migrator_pair function which is used to get the original and replacement objects. I also need to find utility functions that help find which collection contains an object. + +Let me search for these patterns in the file.
+ +--- + +Let me search for more specific sections, including the `_get_migrator_pair` function and any collection-related utilities. + +--- + + +
Tool use: **run_terminal_command_v2** • Run command: rg "def _get_migrator_pair|def .*collection.*object|DLM_OT_migrator_remove_original" "T:\Dynamic-Link-Manager\ui\operators.py" -A 20 + +```bash +rg "def _get_migrator_pair|def .*collection.*object|DLM_OT_migrator_remove_original" "T:\Dynamic-Link-Manager\ui\operators.py" -A 20 +``` + +``` +rg: C:\Users\Nathan\AppData\Local\Temp\ps-script-4c7a9963-de74-435a-877d-ea6ffb008b73.ps1:113 +Line | + 113 | rg "def _get_migrator_pair|def .*collection.*object|DLM_OT_migrator_r . + | ~~ + | The term 'rg' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the + | spelling of the name, or if a path was included, verify that the path is correct and try again. + +``` +
+
+ +--- + +
Thought Process +rg (ripgrep) is not available on Windows by default. Let me use PowerShell's Select-String instead.
+ +--- + + +
Tool use: **run_terminal_command_v2** • Run command: Select-String -Path "T:\Dynamic-Link-Manager\ui\operators.py" -Pattern "_get_migrator_pair|collection.*object|DLM_OT_migrator_remove_original" -Context 0,15 + +```bash +Select-String -Path "T:\Dynamic-Link-Manager\ui\operators.py" -Pattern "_get_migrator_pair|collection.*object|DLM_OT_migrator_remove_original" -Context 0,15 +``` + +``` + +> ui\operators.py:258:def _get_migrator_pair(context): + ui\operators.py:259: """Return (orig, rep) from scene props (manual or automatic). (None, None) if invalid.""" + ui\operators.py:260: from ..ops.migrator import get_pair_manual, get_pair_automatic + ui\operators.py:261: + ui\operators.py:262: props = getattr(context.scene, "dynamic_link_manager", None) + ui\operators.py:263: if not props: + ui\operators.py:264: return None, None + ui\operators.py:265: use_auto = getattr(props, "migrator_mode", False) + ui\operators.py:266: orig, rep = get_pair_automatic(context) if use_auto else get_pair_manual(context) + ui\operators.py:267: return orig, rep + ui\operators.py:268: + ui\operators.py:269: + ui\operators.py:270:class DLM_OT_migrator_copy_attributes(Operator): + ui\operators.py:271: bl_idname = "dlm.migrator_copy_attributes" + ui\operators.py:272: bl_label = "CopyAttr" + ui\operators.py:273: bl_description = "Copy object and armature attributes from original to replacement character" +> ui\operators.py:278: orig, rep = _get_migrator_pair(context) + ui\operators.py:279: if not orig or not rep or orig == rep: + ui\operators.py:280: self.report({"ERROR"}, "No valid character pair (set Original/Replacement or enable +Automatic).") + ui\operators.py:281: return {"CANCELLED"} + ui\operators.py:282: try: + ui\operators.py:283: from ..ops.migrator import run_copy_attr + ui\operators.py:284: run_copy_attr(orig, rep) + ui\operators.py:285: self.report({"INFO"}, "Copy attributes done.") + ui\operators.py:286: return {"FINISHED"} + ui\operators.py:287: except Exception as e: + ui\operators.py:288: self.report({"ERROR"}, str(e)) + ui\operators.py:289: return {"CANCELLED"} + ui\operators.py:290: + ui\operators.py:291: + ui\operators.py:292:class DLM_OT_migrator_migrate_nla(Operator): + ui\operators.py:293: bl_idname = "dlm.migrator_migrate_nla" +> ui\operators.py:300: orig, rep = _get_migrator_pair(context) + ui\operators.py:301: if not orig or not rep or orig == rep: + ui\operators.py:302: self.report({"ERROR"}, "No valid character pair.") + ui\operators.py:303: return {"CANCELLED"} + ui\operators.py:304: try: + ui\operators.py:305: from ..ops.migrator import run_mig_nla + ui\operators.py:306: run_mig_nla(orig, rep, report=self.report) + ui\operators.py:307: return {"FINISHED"} + ui\operators.py:308: except Exception as e: + ui\operators.py:309: self.report({"ERROR"}, str(e)) + ui\operators.py:310: return {"CANCELLED"} + ui\operators.py:311: + ui\operators.py:312: + ui\operators.py:313:class DLM_OT_migrator_custom_properties(Operator): + ui\operators.py:314: bl_idname = "dlm.migrator_custom_properties" + ui\operators.py:315: bl_label = "MigCustProps" +> ui\operators.py:321: orig, rep = _get_migrator_pair(context) + ui\operators.py:322: if not orig or not rep or orig == rep: + ui\operators.py:323: self.report({"ERROR"}, "No valid character pair.") + ui\operators.py:324: return {"CANCELLED"} + ui\operators.py:325: try: + ui\operators.py:326: from ..ops.migrator import run_mig_cust_props + ui\operators.py:327: run_mig_cust_props(orig, rep) + ui\operators.py:328: self.report({"INFO"}, "Custom properties done.") + ui\operators.py:329: return {"FINISHED"} + ui\operators.py:330: except Exception as e: + ui\operators.py:331: self.report({"ERROR"}, str(e)) + ui\operators.py:332: return {"CANCELLED"} + ui\operators.py:333: + ui\operators.py:334: + ui\operators.py:335:class DLM_OT_migrator_bone_constraints(Operator): + ui\operators.py:336: bl_idname = "dlm.migrator_bone_constraints" +> ui\operators.py:343: orig, rep = _get_migrator_pair(context) + ui\operators.py:344: if not orig or not rep or orig == rep: + ui\operators.py:345: self.report({"ERROR"}, "No valid character pair.") + ui\operators.py:346: return {"CANCELLED"} + ui\operators.py:347: try: + ui\operators.py:348: from ..ops.migrator import run_mig_bone_const + ui\operators.py:349: orig_to_rep = {orig: rep} + ui\operators.py:350: run_mig_bone_const(orig, rep, orig_to_rep) + ui\operators.py:351: self.report({"INFO"}, "Bone constraints done.") + ui\operators.py:352: return {"FINISHED"} + ui\operators.py:353: except Exception as e: + ui\operators.py:354: self.report({"ERROR"}, str(e)) + ui\operators.py:355: return {"CANCELLED"} + ui\operators.py:356: + ui\operators.py:357: + ui\operators.py:358:class DLM_OT_migrator_retarget_relations(Operator): +> ui\operators.py:366: orig, rep = _get_migrator_pair(context) + ui\operators.py:367: if not orig or not rep or orig == rep: + ui\operators.py:368: self.report({"ERROR"}, "No valid character pair.") + ui\operators.py:369: return {"CANCELLED"} + ui\operators.py:370: try: + ui\operators.py:371: from ..ops.migrator import run_retarg_relatives + ui\operators.py:372: from ..utils import descendants + ui\operators.py:373: rep_descendants = descendants(rep) + ui\operators.py:374: orig_to_rep = {orig: rep} + ui\operators.py:375: run_retarg_relatives(orig, rep, rep_descendants, orig_to_rep) + ui\operators.py:376: self.report({"INFO"}, "Retarget relations done.") + ui\operators.py:377: return {"FINISHED"} + ui\operators.py:378: except Exception as e: + ui\operators.py:379: self.report({"ERROR"}, str(e)) + ui\operators.py:380: return {"CANCELLED"} + ui\operators.py:381: +> ui\operators.py:391: orig, rep = _get_migrator_pair(context) + ui\operators.py:392: if not orig or not rep or orig == rep: + ui\operators.py:393: self.report({"ERROR"}, "No valid character pair.") + ui\operators.py:394: return {"CANCELLED"} + ui\operators.py:395: try: + ui\operators.py:396: from ..ops.migrator import run_mig_bbody_shapekeys + ui\operators.py:397: from ..utils import descendants + ui\operators.py:398: rep_descendants = descendants(rep) + ui\operators.py:399: run_mig_bbody_shapekeys(orig, rep, rep_descendants, context) + ui\operators.py:400: self.report({"INFO"}, "Migrate BaseBody shapekeys done.") + ui\operators.py:401: return {"FINISHED"} + ui\operators.py:402: except Exception as e: + ui\operators.py:403: self.report({"ERROR"}, str(e)) + ui\operators.py:404: return {"CANCELLED"} + ui\operators.py:405: + ui\operators.py:406: +> ui\operators.py:415: orig, rep = _get_migrator_pair(context) + ui\operators.py:416: if not orig or not rep or orig == rep: + ui\operators.py:417: self.report({"ERROR"}, "No valid character pair.") + ui\operators.py:418: return {"CANCELLED"} + ui\operators.py:419: try: + ui\operators.py:420: from ..ops.fk_rotations import copy_fk_rotations + ui\operators.py:421: ok, msg = copy_fk_rotations(context, orig, rep) + ui\operators.py:422: if ok: + ui\operators.py:423: self.report({"INFO"}, msg) + ui\operators.py:424: return {"FINISHED"} + ui\operators.py:425: else: + ui\operators.py:426: self.report({"ERROR"}, msg) + ui\operators.py:427: return {"CANCELLED"} + ui\operators.py:428: except Exception as e: + ui\operators.py:429: self.report({"ERROR"}, str(e)) + ui\operators.py:430: return {"CANCELLED"} +> ui\operators.py:444: orig, rep = _get_migrator_pair(context) + ui\operators.py:445: if not orig or not rep or orig == rep: + ui\operators.py:446: self.report({"ERROR"}, "No valid character pair.") + ui\operators.py:447: return {"CANCELLED"} + ui\operators.py:448: try: + ui\operators.py:449: from ..ops.fk_rotations import bake_fk_rotations + ui\operators.py:450: ok, msg = bake_fk_rotations(context, orig, rep, track_name=self.track_name or None, +post_clean=self.post_clean) + ui\operators.py:451: if ok: + ui\operators.py:452: self.report({"INFO"}, msg) + ui\operators.py:453: return {"FINISHED"} + ui\operators.py:454: else: + ui\operators.py:455: self.report({"ERROR"}, msg) + ui\operators.py:456: return {"CANCELLED"} + ui\operators.py:457: except Exception as e: + ui\operators.py:458: self.report({"ERROR"}, str(e)) + ui\operators.py:459: return {"CANCELLED"} +> ui\operators.py:470: orig, rep = _get_migrator_pair(context) + ui\operators.py:471: if not orig or not rep or orig == rep: + ui\operators.py:472: self.report({"ERROR"}, "No valid character pair.") + ui\operators.py:473: return {"CANCELLED"} + ui\operators.py:474: try: + ui\operators.py:475: from ..ops.fk_rotations import remove_fk_rotations + ui\operators.py:476: ok, msg = remove_fk_rotations(context, rep) + ui\operators.py:477: if ok: + ui\operators.py:478: self.report({"INFO"}, msg) + ui\operators.py:479: return {"FINISHED"} + ui\operators.py:480: else: + ui\operators.py:481: self.report({"ERROR"}, msg) + ui\operators.py:482: return {"CANCELLED"} + ui\operators.py:483: except Exception as e: + ui\operators.py:484: self.report({"ERROR"}, str(e)) + ui\operators.py:485: return {"CANCELLED"} +> ui\operators.py:490:class DLM_OT_migrator_remove_original(Operator): + ui\operators.py:491: bl_idname = "dlm.migrator_remove_original" + ui\operators.py:492: bl_label = "Remove Original" + ui\operators.py:493: bl_description = "Delete the original character armature and its data from the scene" + ui\operators.py:494: bl_options = {"REGISTER", "UNDO"} + ui\operators.py:495: + ui\operators.py:496: def execute(self, context): +> ui\operators.py:497: orig, rep = _get_migrator_pair(context) + ui\operators.py:498: if not orig: + ui\operators.py:499: self.report({"WARNING"}, "No original character selected") + ui\operators.py:500: return {"CANCELLED"} + ui\operators.py:501: if orig == rep: + ui\operators.py:502: self.report({"ERROR"}, "Original and replacement cannot be the same object") + ui\operators.py:503: return {"CANCELLED"} + ui\operators.py:504: + ui\operators.py:505: name = orig.name + ui\operators.py:506: try: + ui\operators.py:507: # Remove from scene + ui\operators.py:508: bpy.data.objects.remove(orig, do_unlink=True) + ui\operators.py:509: # Clear the property + ui\operators.py:510: context.scene.dynamic_link_manager.original_character = None + ui\operators.py:511: self.report({"INFO"}, f"Removed original character: {name}") + ui\operators.py:512: except Exception as e: +> ui\operators.py:552: orig, rep = _get_migrator_pair(context) + ui\operators.py:553: return orig is not None and rep is not None + ui\operators.py:554: + ui\operators.py:555: + ui\operators.py:556:class DLM_OT_tweak_add_arm(Operator): + ui\operators.py:557: bl_idname = "dlm.tweak_add_arm" + ui\operators.py:558: bl_label = "Add Arm Tweaks" + ui\operators.py:559: bl_description = "Add tweak bone constraints to arm bones on the replacement character" + ui\operators.py:560: bl_options = {"REGISTER", "UNDO"} + ui\operators.py:561: + ui\operators.py:562: @classmethod + ui\operators.py:563: def poll(cls, context): + ui\operators.py:564: return _tweak_poll(context) + ui\operators.py:565: + ui\operators.py:566: def execute(self, context): +> ui\operators.py:567: orig, rep = _get_migrator_pair(context) + ui\operators.py:568: from ..ops import tweak_tools + ui\operators.py:569: tweak_tools.add_tweak_constraints(orig, rep, "arm") + ui\operators.py:570: self.report({"INFO"}, "Arm tweak constraints added.") + ui\operators.py:571: return {"FINISHED"} + ui\operators.py:572: + ui\operators.py:573: + ui\operators.py:574:class DLM_OT_tweak_remove_arm(Operator): + ui\operators.py:575: bl_idname = "dlm.tweak_remove_arm" + ui\operators.py:576: bl_label = "Remove Arm Tweaks" + ui\operators.py:577: bl_description = "Remove arm tweak constraints from the replacement character" + ui\operators.py:578: bl_options = {"REGISTER", "UNDO"} + ui\operators.py:579: + ui\operators.py:580: @classmethod + ui\operators.py:581: def poll(cls, context): + ui\operators.py:582: return _tweak_poll(context) +> ui\operators.py:585: orig, rep = _get_migrator_pair(context) + ui\operators.py:586: from ..ops import tweak_tools + ui\operators.py:587: n = tweak_tools.remove_tweak_constraints(orig, rep, "arm") + ui\operators.py:588: self.report({"INFO"}, f"Removed {n} arm tweak constraints.") + ui\operators.py:589: return {"FINISHED"} + ui\operators.py:590: + ui\operators.py:591: + ui\operators.py:592:class DLM_OT_tweak_bake_arm(Operator): + ui\operators.py:593: bl_idname = "dlm.tweak_bake_arm" + ui\operators.py:594: bl_label = "Bake Arm Tweaks" + ui\operators.py:595: bl_description = "Bake arm tweak constraints to keyframes and optionally remove constraints" + ui\operators.py:596: bl_options = {"REGISTER", "UNDO"} + ui\operators.py:597: + ui\operators.py:598: @classmethod + ui\operators.py:599: def poll(cls, context): + ui\operators.py:600: return _tweak_poll(context) +> ui\operators.py:603: orig, rep = _get_migrator_pair(context) + ui\operators.py:604: props = context.scene.dynamic_link_manager + ui\operators.py:605: from ..ops import tweak_tools + ui\operators.py:606: ok, msg = tweak_tools.bake_tweak_constraints( + ui\operators.py:607: context, orig, rep, "arm", + ui\operators.py:608: getattr(props, "tweak_nla_track_name", "") or "", + ui\operators.py:609: getattr(props, "tweak_bake_post_clean", False), + ui\operators.py:610: ) + ui\operators.py:611: if ok: + ui\operators.py:612: self.report({"INFO"}, msg) + ui\operators.py:613: return {"FINISHED"} + ui\operators.py:614: self.report({"ERROR"}, msg) + ui\operators.py:615: return {"CANCELLED"} + ui\operators.py:616: + ui\operators.py:617: + ui\operators.py:618:class DLM_OT_tweak_add_leg(Operator): +> ui\operators.py:629: orig, rep = _get_migrator_pair(context) + ui\operators.py:630: from ..ops import tweak_tools + ui\operators.py:631: tweak_tools.add_tweak_constraints(orig, rep, "leg") + ui\operators.py:632: self.report({"INFO"}, "Leg tweak constraints added.") + ui\operators.py:633: return {"FINISHED"} + ui\operators.py:634: + ui\operators.py:635: + ui\operators.py:636:class DLM_OT_tweak_remove_leg(Operator): + ui\operators.py:637: bl_idname = "dlm.tweak_remove_leg" + ui\operators.py:638: bl_label = "Remove Leg Tweaks" + ui\operators.py:639: bl_description = "Remove leg tweak constraints from the replacement character" + ui\operators.py:640: bl_options = {"REGISTER", "UNDO"} + ui\operators.py:641: + ui\operators.py:642: @classmethod + ui\operators.py:643: def poll(cls, context): + ui\operators.py:644: return _tweak_poll(context) +> ui\operators.py:647: orig, rep = _get_migrator_pair(context) + ui\operators.py:648: from ..ops import tweak_tools + ui\operators.py:649: n = tweak_tools.remove_tweak_constraints(orig, rep, "leg") + ui\operators.py:650: self.report({"INFO"}, f"Removed {n} leg tweak constraints.") + ui\operators.py:651: return {"FINISHED"} + ui\operators.py:652: + ui\operators.py:653: + ui\operators.py:654:class DLM_OT_tweak_bake_leg(Operator): + ui\operators.py:655: bl_idname = "dlm.tweak_bake_leg" + ui\operators.py:656: bl_label = "Bake Leg Tweaks" + ui\operators.py:657: bl_description = "Bake leg tweak constraints to keyframes and optionally remove constraints" + ui\operators.py:658: bl_options = {"REGISTER", "UNDO"} + ui\operators.py:659: + ui\operators.py:660: @classmethod + ui\operators.py:661: def poll(cls, context): + ui\operators.py:662: return _tweak_poll(context) +> ui\operators.py:665: orig, rep = _get_migrator_pair(context) + ui\operators.py:666: props = context.scene.dynamic_link_manager + ui\operators.py:667: from ..ops import tweak_tools + ui\operators.py:668: ok, msg = tweak_tools.bake_tweak_constraints( + ui\operators.py:669: context, orig, rep, "leg", + ui\operators.py:670: getattr(props, "tweak_nla_track_name", "") or "", + ui\operators.py:671: getattr(props, "tweak_bake_post_clean", False), + ui\operators.py:672: ) + ui\operators.py:673: if ok: + ui\operators.py:674: self.report({"INFO"}, msg) + ui\operators.py:675: return {"FINISHED"} + ui\operators.py:676: self.report({"ERROR"}, msg) + ui\operators.py:677: return {"CANCELLED"} + ui\operators.py:678: + ui\operators.py:679: + ui\operators.py:680:class DLM_OT_tweak_add_both(Operator): +> ui\operators.py:691: orig, rep = _get_migrator_pair(context) + ui\operators.py:692: from ..ops import tweak_tools + ui\operators.py:693: tweak_tools.add_tweak_constraints(orig, rep, "both") + ui\operators.py:694: self.report({"INFO"}, "Arm & leg tweak constraints added.") + ui\operators.py:695: return {"FINISHED"} + ui\operators.py:696: + ui\operators.py:697: + ui\operators.py:698:class DLM_OT_tweak_remove_both(Operator): + ui\operators.py:699: bl_idname = "dlm.tweak_remove_both" + ui\operators.py:700: bl_label = "Remove Arm & Leg Tweaks" + ui\operators.py:701: bl_description = "Remove all arm and leg tweak constraints from the replacement character" + ui\operators.py:702: bl_options = {"REGISTER", "UNDO"} + ui\operators.py:703: + ui\operators.py:704: @classmethod + ui\operators.py:705: def poll(cls, context): + ui\operators.py:706: return _tweak_poll(context) +> ui\operators.py:709: orig, rep = _get_migrator_pair(context) + ui\operators.py:710: from ..ops import tweak_tools + ui\operators.py:711: n = tweak_tools.remove_tweak_constraints(orig, rep, "both") + ui\operators.py:712: self.report({"INFO"}, f"Removed {n} tweak constraints.") + ui\operators.py:713: return {"FINISHED"} + ui\operators.py:714: + ui\operators.py:715: + ui\operators.py:716:class DLM_OT_tweak_bake_both(Operator): + ui\operators.py:717: bl_idname = "dlm.tweak_bake_both" + ui\operators.py:718: bl_label = "Bake Arm & Leg Tweaks" + ui\operators.py:719: bl_description = "Bake all arm and leg tweak constraints to keyframes and optionally remove +constraints" + ui\operators.py:720: bl_options = {"REGISTER", "UNDO"} + ui\operators.py:721: + ui\operators.py:722: @classmethod + ui\operators.py:723: def poll(cls, context): + ui\operators.py:724: return _tweak_poll(context) +> ui\operators.py:727: orig, rep = _get_migrator_pair(context) + ui\operators.py:728: props = context.scene.dynamic_link_manager + ui\operators.py:729: from ..ops import tweak_tools + ui\operators.py:730: ok, msg = tweak_tools.bake_tweak_constraints( + ui\operators.py:731: context, orig, rep, "both", + ui\operators.py:732: getattr(props, "tweak_nla_track_name", "") or "", + ui\operators.py:733: getattr(props, "tweak_bake_post_clean", False), + ui\operators.py:734: ) + ui\operators.py:735: if ok: + ui\operators.py:736: self.report({"INFO"}, msg) + ui\operators.py:737: return {"FINISHED"} + ui\operators.py:738: self.report({"ERROR"}, msg) + ui\operators.py:739: return {"CANCELLED"} + ui\operators.py:740: + ui\operators.py:741: + ui\operators.py:742:OPERATOR_CLASSES = [ +> ui\operators.py:755: DLM_OT_migrator_remove_original, + ui\operators.py:756: DLM_OT_picker_original_character, + ui\operators.py:757: DLM_OT_picker_replacement_character, + ui\operators.py:758: DLM_OT_migrator_copy_attributes, + ui\operators.py:759: DLM_OT_migrator_migrate_nla, + ui\operators.py:760: DLM_OT_migrator_custom_properties, + ui\operators.py:761: DLM_OT_migrator_bone_constraints, + ui\operators.py:762: DLM_OT_migrator_retarget_relations, + ui\operators.py:763: DLM_OT_migrator_basebody_shapekeys, + ui\operators.py:764: DLM_OT_tweak_add_arm, + ui\operators.py:765: DLM_OT_tweak_remove_arm, + ui\operators.py:766: DLM_OT_tweak_bake_arm, + ui\operators.py:767: DLM_OT_tweak_add_leg, + ui\operators.py:768: DLM_OT_tweak_remove_leg, + ui\operators.py:769: DLM_OT_tweak_bake_leg, + ui\operators.py:770: DLM_OT_tweak_add_both, + +``` +
+
+ +--- + +
Thought Process +Now I need to find the exact line number for DLM_OT_migrator_remove_original class. Let me search for it specifically with more context.
+ +--- + + +
Tool use: **run_terminal_command_v2** • Run command: Select-String -Path "T:\Dynamic-Link-Manager\ui\operators.py" -Pattern "class DLM_OT_migrator_remove_original" -Context 0,25 + +```bash +Select-String -Path "T:\Dynamic-Link-Manager\ui\operators.py" -Pattern "class DLM_OT_migrator_remove_original" -Context 0,25 +``` + +``` + +> ui\operators.py:490:class DLM_OT_migrator_remove_original(Operator): + ui\operators.py:491: bl_idname = "dlm.migrator_remove_original" + ui\operators.py:492: bl_label = "Remove Original" + ui\operators.py:493: bl_description = "Delete the original character armature and its data from the scene" + ui\operators.py:494: bl_options = {"REGISTER", "UNDO"} + ui\operators.py:495: + ui\operators.py:496: def execute(self, context): + ui\operators.py:497: orig, rep = _get_migrator_pair(context) + ui\operators.py:498: if not orig: + ui\operators.py:499: self.report({"WARNING"}, "No original character selected") + ui\operators.py:500: return {"CANCELLED"} + ui\operators.py:501: if orig == rep: + ui\operators.py:502: self.report({"ERROR"}, "Original and replacement cannot be the same object") + ui\operators.py:503: return {"CANCELLED"} + ui\operators.py:504: + ui\operators.py:505: name = orig.name + ui\operators.py:506: try: + ui\operators.py:507: # Remove from scene + ui\operators.py:508: bpy.data.objects.remove(orig, do_unlink=True) + ui\operators.py:509: # Clear the property + ui\operators.py:510: context.scene.dynamic_link_manager.original_character = None + ui\operators.py:511: self.report({"INFO"}, f"Removed original character: {name}") + ui\operators.py:512: except Exception as e: + ui\operators.py:513: self.report({"ERROR"}, f"Failed to remove original: {e}") + ui\operators.py:514: return {"CANCELLED"} + ui\operators.py:515: return {"FINISHED"} + +``` +
+
+ +--- + +
Thought Process +Now I have the class. Let me also check for utility functions that might help find which collection contains an object. Let me search in the utils directory or check for any collection-related utilities.
+ +--- + +Now let me search for utility functions that help find collections containing objects. + +--- + + +
Tool use: **run_terminal_command_v2** • Run command: Select-String -Path "T:\Dynamic-Link-Manager" -Filter "*.py" -Pattern "def .*collection|collection.*object|objects.*collection|find_collection" -Recurse + +```bash +Select-String -Path "T:\Dynamic-Link-Manager" -Filter "*.py" -Pattern "def .*collection|collection.*object|objects.*collection|find_collection" -Recurse +``` + +``` +Select-String: C:\Users\Nathan\AppData\Local\Temp\ps-script-9851db49-1073-4a74-a36d-ca9976789164.ps1:113 +Line | + 113 | Select-String -Path "T:\Dynamic-Link-Manager" -Filter "*.py" -Pattern . + | ~~~~~~~ + | A parameter cannot be found that matches parameter name 'Filter'. + +``` +
+
+ +--- + +
Thought Process +Let me try a different approach - use Get-ChildItem with Select-String.
+ +--- + + +
Tool use: **run_terminal_command_v2** • Run command: Get-ChildItem -Path "T:\Dynamic-Link-Manager" -Filter "*.py" -Recurse | Select-String -Pattern "def .*collection|find_collection|object.*collection|collection.*object" | Select-Object -First 30 + +```bash +Get-ChildItem -Path "T:\Dynamic-Link-Manager" -Filter "*.py" -Recurse | Select-String -Pattern "def .*collection|find_collection|object.*collection|collection.*object" | Select-Object -First 30 +``` + +``` + +ops\library.py:64: for idb in list(bpy.data.objects) + list(bpy.data.meshes) + list(bpy.data.armatures) + +list(bpy.data.materials) + list(bpy.data.node_groups) + list(bpy.data.images) + list(bpy.data.texts) + +list(bpy.data.collections) + list(bpy.data.cameras) + list(bpy.data.lights): +ops\migrator.py:462: """Retarget relations: parents, constraint targets, Armature modifiers to rep. Skip objects in +orig's hierarchy (linked collection).""" +ops\migrator.py:502:def _objects_in_collection_recursive(coll): +ops\migrator.py:503: """Yield all objects in collection and nested collections.""" +ops\migrator.py:507: yield from _objects_in_collection_recursive(child) +ops\migrator.py:532: found, candidates = gather_candidates(_objects_in_collection_recursive(coll)) +utils\__init__.py:24:def collection_containing_armature(armature): + +``` +
+
+ +--- + diff --git a/.specstory/history/2026-03-10_16-23Z-dlm-ot-migrator-remove-original-class-update.md b/.specstory/history/2026-03-10_16-23Z-dlm-ot-migrator-remove-original-class-update.md new file mode 100644 index 0000000..6be7120 --- /dev/null +++ b/.specstory/history/2026-03-10_16-23Z-dlm-ot-migrator-remove-original-class-update.md @@ -0,0 +1,905 @@ + + + + +# DLM_OT_migrator_remove_original class update (2026-03-10 16:23Z) + +_**User**_ + +Update the DLM_OT_migrator_remove_original class in T:\Dynamic-Link-Manager\ui\operators.py to delete the collection containing the original character instead of just deleting the armature object. + +Current implementation: +```python +def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig: + self.report({"WARNING"}, "No original character selected") + return {"CANCELLED"} + if orig == rep: + self.report({"ERROR"}, "Original and replacement cannot be the same object") + return {"CANCELLED"} + + name = orig.name + try: + # Remove from scene + bpy.data.objects.remove(orig, do_unlink=True) + # Clear the property + context.scene.dynamic_link_manager.original_character = None + self.report({"INFO"}, f"Removed original character: {name}") + except Exception as e: + self.report({"ERROR"}, f"Failed to remove original: {e}") + return {"CANCELLED"} + return {"FINISHED"} +``` + +Change it to: +1. Import and use `collection_containing_armature` from `..utils` to find the collection +2. Delete the collection (which removes all objects in it) +3. Clear the original_character property +4. Report which collection was deleted + +If no collection is found, fall back to just deleting the armature object. + +--- + +_**Agent (model accounts/fireworks/models/kimi-k2p5, mode Agent)**_ + + + +--- + +
Thought Process +The user wants me to update a class in a file. Let me first read the file to see the current implementation and understand the context.
+ +--- + + +
Tool use: **run_terminal_command_v2** • Run command: cat "T:\Dynamic-Link-Manager\ui\operators.py" + +```bash +cat "T:\Dynamic-Link-Manager\ui\operators.py" +``` + +``` +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +import bpy +import os +from bpy.types import Operator +from bpy.props import StringProperty, BoolProperty +from bpy.props import StringProperty, IntProperty + +ADDON_NAME = __package__.rsplit(".", 1)[0] if "." in __package__ else __package__ + + +def _prefs(context): + return context.preferences.addons.get(ADDON_NAME) + + +class DLM_OT_replace_linked_asset(Operator): + bl_idname = "dlm.replace_linked_asset" + bl_label = "Replace Linked Asset" + bl_description = "Open file browser to replace the linked asset with another file" + bl_options = {"REGISTER", "UNDO"} + filepath: StringProperty(name="File Path", description="Path to the new asset file", subtype="FILE_PATH") + + def execute(self, context): + obj = context.active_object + if not obj: + self.report({"ERROR"}, "No object selected") + return {"CANCELLED"} + if getattr(obj, "library", None): + self.report({"INFO"}, f"Object '{obj.name}' is linked from: {obj.library.filepath}") + return {"FINISHED"} + if obj.data and getattr(obj.data, "library", None) and obj.data.library: + self.report({"INFO"}, f"Object '{obj.name}' has linked data from: {obj.data.library.filepath}") + return {"FINISHED"} + if obj.type == "ARMATURE" and obj.data and obj.data.name in bpy.data.armatures: + ad = bpy.data.armatures[obj.data.name] + if getattr(ad, "library", None) and ad.library: + self.report({"INFO"}, f"Armature '{obj.name}' data is linked from: {ad.library.filepath}") + return {"FINISHED"} + self.report({"ERROR"}, "Selected object is not a linked asset") + return {"CANCELLED"} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + +class DLM_OT_scan_linked_assets(Operator): + bl_idname = "dlm.scan_linked_assets" + bl_label = "Scan Linked Libraries" + bl_description = "Scan the current file for linked libraries and list their status" + bl_options = {"REGISTER"} + + def execute(self, context): + from ..ops import library + + return library.scan_linked_assets(context, self.report) + + +class DLM_OT_find_libraries_in_folders(Operator): + bl_idname = "dlm.find_libraries_in_folders" + bl_label = "Find Libraries in Folders" + bl_description = "Search addon search paths for missing library blend files" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + from ..ops import library + + return library.find_libraries_in_folders(context, self.report, ADDON_NAME) + + +class DLM_OT_open_linked_file(Operator): + bl_idname = "dlm.open_linked_file" + bl_label = "Open Linked File" + bl_description = "Open the selected linked blend file in a new Blender instance" + bl_options = {"REGISTER"} + filepath: StringProperty(name="File Path", default="") + + def execute(self, context): + if not self.filepath: + self.report({"ERROR"}, "No file path specified") + return {"CANCELLED"} + try: + bpy.ops.wm.path_open(filepath=self.filepath) + self.report({"INFO"}, f"Opening linked file: {self.filepath}") + except Exception as e: + self.report({"ERROR"}, f"Failed to open linked file: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + +class DLM_OT_add_search_path(Operator): + bl_idname = "dlm.add_search_path" + bl_label = "Add Search Path" + bl_description = "Add a new folder to the list of search paths for finding libraries" + bl_options = {"REGISTER"} + + def execute(self, context): + prefs = _prefs(context) + if prefs: + p = prefs.preferences.search_paths.add() + p.path = "//" + self.report({"INFO"}, f"Added search path: {p.path}") + return {"FINISHED"} + + +class DLM_OT_remove_search_path(Operator): + bl_idname = "dlm.remove_search_path" + bl_label = "Remove Search Path" + bl_description = "Remove the selected search path from the list" + bl_options = {"REGISTER"} + index: IntProperty(name="Index", default=0) + + def execute(self, context): + prefs = _prefs(context) + if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths): + prefs.preferences.search_paths.remove(self.index) + self.report({"INFO"}, f"Removed search path at index {self.index}") + return {"FINISHED"} + + +class DLM_OT_attempt_relink(Operator): + bl_idname = "dlm.attempt_relink" + bl_label = "Attempt Relink" + bl_description = "Try to relink missing libraries using the configured search paths" + bl_options = {"REGISTER"} + + def execute(self, context): + from ..ops import library + + return library.attempt_relink(context, self.report, ADDON_NAME) + + +class DLM_OT_browse_search_path(Operator): + bl_idname = "dlm.browse_search_path" + bl_label = "Browse Search Path" + bl_description = "Browse to set the folder for the selected search path" + bl_options = {"REGISTER"} + index: IntProperty(name="Index", default=0) + filepath: StringProperty(name="Search Path", subtype="DIR_PATH") + + def execute(self, context): + prefs = _prefs(context) + if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths): + prefs.preferences.search_paths[self.index].path = self.filepath + self.report({"INFO"}, f"Updated search path {self.index + 1}: {self.filepath}") + return {"FINISHED"} + + def invoke(self, context, event): + prefs = _prefs(context) + if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths): + self.filepath = prefs.preferences.search_paths[self.index].path + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + +class DLM_OT_reload_libraries(Operator): + bl_idname = "dlm.reload_libraries" + bl_label = "Reload Libraries" + bl_description = "Reload all linked libraries (or fallback manual reload)" + bl_options = {"REGISTER"} + + def execute(self, context): + try: + bpy.ops.outliner.lib_operation(type="RELOAD") + self.report({"INFO"}, "Library reload operation completed") + except Exception: + try: + for lib in bpy.data.libraries: + if lib.filepath and os.path.exists(bpy.path.abspath(lib.filepath)): + lib.reload() + self.report({"INFO"}, "Libraries reloaded manually") + except Exception as e: + self.report({"ERROR"}, f"Failed to reload libraries: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + +class DLM_OT_make_paths_relative(Operator): + bl_idname = "dlm.make_paths_relative" + bl_label = "Make Paths Relative" + bl_description = "Convert all internal file paths to relative" + bl_options = {"REGISTER"} + + def execute(self, context): + try: + bpy.ops.file.make_paths_relative() + self.report({"INFO"}, "All file paths made relative") + except Exception as e: + self.report({"ERROR"}, f"Failed to make paths relative: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + +class DLM_OT_make_paths_absolute(Operator): + bl_idname = "dlm.make_paths_absolute" + bl_label = "Make Paths Absolute" + bl_description = "Convert all internal file paths to absolute" + bl_options = {"REGISTER"} + + def execute(self, context): + try: + bpy.ops.file.make_paths_absolute() + self.report({"INFO"}, "All file paths made absolute") + except Exception as e: + self.report({"ERROR"}, f"Failed to make paths absolute: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + +class DLM_OT_relocate_single_library(Operator): + bl_idname = "dlm.relocate_single_library" + bl_label = "Relocate Library" + bl_description = "Point the selected library to a new blend file and reload" + bl_options = {"REGISTER", "UNDO"} + target_filepath: StringProperty(name="Current Library Path", default="") + filepath: StringProperty(name="New Library File", subtype="FILE_PATH", default="") + + def execute(self, context): + if not self.target_filepath or not self.filepath: + self.report({"ERROR"}, "No target or new file specified") + return {"CANCELLED"} + abs_match = bpy.path.abspath(self.target_filepath) if self.target_filepath else "" + library = None + for lib in bpy.data.libraries: + try: + if lib.filepath and bpy.path.abspath(lib.filepath) == abs_match: + library = lib + break + except Exception: + if lib.filepath == self.target_filepath: + library = lib + break + if not library: + self.report({"ERROR"}, "Could not resolve the selected library") + return {"CANCELLED"} + try: + library.filepath = self.filepath + library.reload() + self.report({"INFO"}, f"Relocated to: {self.filepath}") + except Exception as e: + self.report({"ERROR"}, f"Failed to relocate: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + def invoke(self, context, event): + if self.target_filepath: + try: + self.filepath = bpy.path.abspath(self.target_filepath) + except Exception: + self.filepath = self.target_filepath + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + +def _get_migrator_pair(context): + """Return (orig, rep) from scene props (manual or automatic). (None, None) if invalid.""" + from ..ops.migrator import get_pair_manual, get_pair_automatic + + props = getattr(context.scene, "dynamic_link_manager", None) + if not props: + return None, None + use_auto = getattr(props, "migrator_mode", False) + orig, rep = get_pair_automatic(context) if use_auto else get_pair_manual(context) + return orig, rep + + +class DLM_OT_migrator_copy_attributes(Operator): + bl_idname = "dlm.migrator_copy_attributes" + bl_label = "CopyAttr" + bl_description = "Copy object and armature attributes from original to replacement character" + bl_icon = "COPY_ID" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair (set Original/Replacement or enable Automatic).") + return {"CANCELLED"} + try: + from ..ops.migrator import run_copy_attr + run_copy_attr(orig, rep) + self.report({"INFO"}, "Copy attributes done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_migrate_nla(Operator): + bl_idname = "dlm.migrator_migrate_nla" + bl_label = "MigNLA" + bl_description = "Migrate NLA tracks and strips from original to replacement character" + bl_icon = "NLA" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_mig_nla + run_mig_nla(orig, rep, report=self.report) + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_custom_properties(Operator): + bl_idname = "dlm.migrator_custom_properties" + bl_label = "MigCustProps" + bl_description = "Copy custom properties from original to replacement character" + bl_icon = "PROPERTIES" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_mig_cust_props + run_mig_cust_props(orig, rep) + self.report({"INFO"}, "Custom properties done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_bone_constraints(Operator): + bl_idname = "dlm.migrator_bone_constraints" + bl_label = "MigBoneConst" + bl_description = "Migrate bone constraints from original to replacement armature" + bl_icon = "CONSTRAINT_BONE" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_mig_bone_const + orig_to_rep = {orig: rep} + run_mig_bone_const(orig, rep, orig_to_rep) + self.report({"INFO"}, "Bone constraints done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_retarget_relations(Operator): + bl_idname = "dlm.migrator_retarget_relations" + bl_label = "RetargRelatives" + bl_description = "Retarget parent/child and other relations to the replacement character" + bl_icon = "ORIENTATION_PARENT" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_retarg_relatives + from ..utils import descendants + rep_descendants = descendants(rep) + orig_to_rep = {orig: rep} + run_retarg_relatives(orig, rep, rep_descendants, orig_to_rep) + self.report({"INFO"}, "Retarget relations done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_basebody_shapekeys(Operator): + bl_idname = "dlm.migrator_basebody_shapekeys" + bl_label = "MigBBodyShapeKeys" + bl_description = "Migrate base body mesh shape key values from original to replacement" + bl_icon = "SHAPEKEY_DATA" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_mig_bbody_shapekeys + from ..utils import descendants + rep_descendants = descendants(rep) + run_mig_bbody_shapekeys(orig, rep, rep_descendants, context) + self.report({"INFO"}, "Migrate BaseBody shapekeys done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_fk_rotations(Operator): + bl_idname = "dlm.migrator_fk_rotations" + bl_label = "MigFKRot" + bl_description = "Copy FK arm and finger rotations from original to replacement (uses constraints)" + bl_icon = "BONE_DATA" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.fk_rotations import copy_fk_rotations + ok, msg = copy_fk_rotations(context, orig, rep) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + else: + self.report({"ERROR"}, msg) + return {"CANCELLED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_fk_rotations_bake(Operator): + bl_idname = "dlm.migrator_fk_rotations_bake" + bl_label = "Bake MigFKRot" + bl_description = "Bake FK rotations to keyframes using nla.bake (similar to tweak tools)" + bl_icon = "KEYFRAME" + bl_options = {"REGISTER", "UNDO"} + + track_name: StringProperty(name="NLA Track", description="Optional NLA track name for frame range", default="") + post_clean: BoolProperty(name="Post-clean", description="Clean curves after bake", default=False) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.fk_rotations import bake_fk_rotations + ok, msg = bake_fk_rotations(context, orig, rep, track_name=self.track_name or None, post_clean=self.post_clean) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + else: + self.report({"ERROR"}, msg) + return {"CANCELLED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_fk_rotations_remove(Operator): + bl_idname = "dlm.migrator_fk_rotations_remove" + bl_label = "Remove MigFKRot" + bl_description = "Remove FK rotation COPY_TRANSFORMS constraints (similar to tweak_remove_arm)" + bl_icon = "X" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.fk_rotations import remove_fk_rotations + ok, msg = remove_fk_rotations(context, rep) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + else: + self.report({"ERROR"}, msg) + return {"CANCELLED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + + + +class DLM_OT_migrator_remove_original(Operator): + bl_idname = "dlm.migrator_remove_original" + bl_label = "Remove Original" + bl_description = "Delete the original character armature and its data from the scene" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig: + self.report({"WARNING"}, "No original character selected") + return {"CANCELLED"} + if orig == rep: + self.report({"ERROR"}, "Original and replacement cannot be the same object") + return {"CANCELLED"} + + name = orig.name + try: + # Remove from scene + bpy.data.objects.remove(orig, do_unlink=True) + # Clear the property + context.scene.dynamic_link_manager.original_character = None + self.report({"INFO"}, f"Removed original character: {name}") + except Exception as e: + self.report({"ERROR"}, f"Failed to remove original: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + + +class DLM_OT_picker_original_character(Operator): + bl_idname = "dlm.picker_original_character" + bl_label = "Pick Original" + bl_description = "Set the original character armature from the active object" + bl_options = {"REGISTER"} + + def execute(self, context): + obj = context.active_object + if not obj or obj.type != "ARMATURE": + self.report({"WARNING"}, "Select an armature") + return {"CANCELLED"} + context.scene.dynamic_link_manager.original_character = obj + self.report({"INFO"}, f"Original: {obj.name}") + return {"FINISHED"} + + +class DLM_OT_picker_replacement_character(Operator): + bl_idname = "dlm.picker_replacement_character" + bl_label = "Pick Replacement" + bl_description = "Set the replacement character armature from the active object" + bl_options = {"REGISTER"} + + def execute(self, context): + obj = context.active_object + if not obj or obj.type != "ARMATURE": + self.report({"WARNING"}, "Select an armature") + return {"CANCELLED"} + context.scene.dynamic_link_manager.replacement_character = obj + self.report({"INFO"}, f"Replacement: {obj.name}") + return {"FINISHED"} + + +def _tweak_poll(context): + orig, rep = _get_migrator_pair(context) + return orig is not None and rep is not None + + +class DLM_OT_tweak_add_arm(Operator): + bl_idname = "dlm.tweak_add_arm" + bl_label = "Add Arm Tweaks" + bl_description = "Add tweak bone constraints to arm bones on the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + tweak_tools.add_tweak_constraints(orig, rep, "arm") + self.report({"INFO"}, "Arm tweak constraints added.") + return {"FINISHED"} + + +class DLM_OT_tweak_remove_arm(Operator): + bl_idname = "dlm.tweak_remove_arm" + bl_label = "Remove Arm Tweaks" + bl_description = "Remove arm tweak constraints from the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + n = tweak_tools.remove_tweak_constraints(orig, rep, "arm") + self.report({"INFO"}, f"Removed {n} arm tweak constraints.") + return {"FINISHED"} + + +class DLM_OT_tweak_bake_arm(Operator): + bl_idname = "dlm.tweak_bake_arm" + bl_label = "Bake Arm Tweaks" + bl_description = "Bake arm tweak constraints to keyframes and optionally remove constraints" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + props = context.scene.dynamic_link_manager + from ..ops import tweak_tools + ok, msg = tweak_tools.bake_tweak_constraints( + context, orig, rep, "arm", + getattr(props, "tweak_nla_track_name", "") or "", + getattr(props, "tweak_bake_post_clean", False), + ) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + self.report({"ERROR"}, msg) + return {"CANCELLED"} + + +class DLM_OT_tweak_add_leg(Operator): + bl_idname = "dlm.tweak_add_leg" + bl_label = "Add Leg Tweaks" + bl_description = "Add tweak bone constraints to leg bones on the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + tweak_tools.add_tweak_constraints(orig, rep, "leg") + self.report({"INFO"}, "Leg tweak constraints added.") + return {"FINISHED"} + + +class DLM_OT_tweak_remove_leg(Operator): + bl_idname = "dlm.tweak_remove_leg" + bl_label = "Remove Leg Tweaks" + bl_description = "Remove leg tweak constraints from the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + n = tweak_tools.remove_tweak_constraints(orig, rep, "leg") + self.report({"INFO"}, f"Removed {n} leg tweak constraints.") + return {"FINISHED"} + + +class DLM_OT_tweak_bake_leg(Operator): + bl_idname = "dlm.tweak_bake_leg" + bl_label = "Bake Leg Tweaks" + bl_description = "Bake leg tweak constraints to keyframes and optionally remove constraints" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + props = context.scene.dynamic_link_manager + from ..ops import tweak_tools + ok, msg = tweak_tools.bake_tweak_constraints( + context, orig, rep, "leg", + getattr(props, "tweak_nla_track_name", "") or "", + getattr(props, "tweak_bake_post_clean", False), + ) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + self.report({"ERROR"}, msg) + return {"CANCELLED"} + + +class DLM_OT_tweak_add_both(Operator): + bl_idname = "dlm.tweak_add_both" + bl_label = "Add Arm & Leg Tweaks" + bl_description = "Add tweak bone constraints to both arm and leg bones" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + tweak_tools.add_tweak_constraints(orig, rep, "both") + self.report({"INFO"}, "Arm & leg tweak constraints added.") + return {"FINISHED"} + + +class DLM_OT_tweak_remove_both(Operator): + bl_idname = "dlm.tweak_remove_both" + bl_label = "Remove Arm & Leg Tweaks" + bl_description = "Remove all arm and leg tweak constraints from the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + n = tweak_tools.remove_tweak_constraints(orig, rep, "both") + self.report({"INFO"}, f"Removed {n} tweak constraints.") + return {"FINISHED"} + + +class DLM_OT_tweak_bake_both(Operator): + bl_idname = "dlm.tweak_bake_both" + bl_label = "Bake Arm & Leg Tweaks" + bl_description = "Bake all arm and leg tweak constraints to keyframes and optionally remove constraints" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + props = context.scene.dynamic_link_manager + from ..ops import tweak_tools + ok, msg = tweak_tools.bake_tweak_constraints( + context, orig, rep, "both", + getattr(props, "tweak_nla_track_name", "") or "", + getattr(props, "tweak_bake_post_clean", False), + ) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + self.report({"ERROR"}, msg) + return {"CANCELLED"} + + +OPERATOR_CLASSES = [ + DLM_OT_replace_linked_asset, + DLM_OT_scan_linked_assets, + DLM_OT_find_libraries_in_folders, + DLM_OT_open_linked_file, + DLM_OT_add_search_path, + DLM_OT_remove_search_path, + DLM_OT_browse_search_path, + DLM_OT_attempt_relink, + DLM_OT_reload_libraries, + DLM_OT_make_paths_relative, + DLM_OT_make_paths_absolute, + DLM_OT_relocate_single_library, + DLM_OT_migrator_remove_original, + DLM_OT_picker_original_character, + DLM_OT_picker_replacement_character, + DLM_OT_migrator_copy_attributes, + DLM_OT_migrator_migrate_nla, + DLM_OT_migrator_custom_properties, + DLM_OT_migrator_bone_constraints, + DLM_OT_migrator_retarget_relations, + DLM_OT_migrator_basebody_shapekeys, + DLM_OT_tweak_add_arm, + DLM_OT_tweak_remove_arm, + DLM_OT_tweak_bake_arm, + DLM_OT_tweak_add_leg, + DLM_OT_tweak_remove_leg, + DLM_OT_tweak_bake_leg, + DLM_OT_tweak_add_both, + DLM_OT_tweak_remove_both, + DLM_OT_tweak_bake_both, + DLM_OT_migrator_fk_rotations, + DLM_OT_migrator_fk_rotations_bake, + DLM_OT_migrator_fk_rotations_remove, +] + +``` +
+
+ +--- + + +
Tool use: **run_terminal_command_v2** • Run command: cat "T:\Dynamic-Link-Manager\utils\__init__.py" + +```bash +cat "T:\Dynamic-Link-Manager\utils\__init__.py" +``` + +``` +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +"""Shared helpers for Dynamic Link Manager.""" + +import bpy + + +def descendants(armature): + """Return a set of objects whose parent chain leads to the given armature.""" + out = set() + for ob in bpy.data.objects: + p = ob.parent + while p: + if p == armature: + out.add(ob) + break + p = p.parent + return out + + +def collection_containing_armature(armature): + """ + Return a collection that contains the armature (for linked character context). + Prefers a collection whose name matches the character base (e.g. "Steve" for Steve_Rigify). + """ + if not armature or armature.name not in bpy.data.objects: + return None + colls = getattr(armature, "users_collection", []) or [] + if not colls: + return None + name = armature.name + base = name.replace("_Rigify", "").replace(".001", "").rstrip("0123456789.") + for c in colls: + if c.name == base or base in c.name or c.name in name: + return c + return colls[0] + +``` +
+
+ +--- + +
Thought Process +I found the `collection_containing_armature` function in the utils module. Now I need to find the exact line numbers for the `DLM_OT
+ +--- + diff --git a/.specstory/history/2026-03-10_16-25Z-collection-removal-error-handling.md b/.specstory/history/2026-03-10_16-25Z-collection-removal-error-handling.md new file mode 100644 index 0000000..4df4d10 --- /dev/null +++ b/.specstory/history/2026-03-10_16-25Z-collection-removal-error-handling.md @@ -0,0 +1,1019 @@ + + + + +# Collection removal error handling (2026-03-10 16:25Z) + +_**User**_ + +Fix the error in DLM_OT_migrator_remove_original in T:\Dynamic-Link-Manager\ui\operators.py. + +The error is: `Failed to remove original: StructRNA of type Collection has been removed` + +This happens because we're holding a reference to a Collection RNA struct that gets invalidated. The fix: + +1. Store the collection name before removal +2. Use bpy.data.collections.remove() with the stored reference +3. But be careful - if the collection is already being removed by some other process, handle that gracefully + +Current code: +```python +coll = collection_containing_armature(orig) +if coll: + bpy.data.collections.remove(coll) +``` + +Change it to store the name first, then remove by the actual reference but wrap in try-except. Also, the issue might be that we're trying to remove a collection that's already linked/being removed. Let me check what the proper safe removal pattern is. + +Actually, looking at the error - the issue is likely that `collection_containing_armature(orig)` returns a reference, but by the time we try to remove it, something has invalidated it. The fix should be: + +```python +coll = collection_containing_armature(orig) +if coll: + coll_name = coll.name # Store name before removal + try: + bpy.data.collections.remove(coll) + self.report({"INFO"}, f"Removed collection: {coll_name}") + except ReferenceError: + # Collection was already removed + self.report({"WARNING"}, f"Collection {coll_name} was already removed") +``` + +But actually ReferenceError is for Python weakrefs, not Blender RNA. For Blender RNA we need RuntimeError or Exception. + +Make the fix that: +1. Stores the collection name +2. Tries to remove the collection +3. Catches any exception and falls back to just removing the object +4. Always clears the property and reports what happened + +--- + +_**Agent (model accounts/fireworks/models/kimi-k2p5, mode Agent)**_ + + + +--- + +
Thought Process +The user wants me to fix an error in the `DLM_OT_migrator_remove_original` operator in `T:\Dynamic-Link-Manager\ui\operators.py`. The error is about trying to remove a collection that has already been invalidated. + +Let me first read the current code to see the full context, then apply the fix.
+ +--- + + +
Tool use: **run_terminal_command_v2** • Run command: cat "T:\Dynamic-Link-Manager\ui\operators.py" + +```bash +cat "T:\Dynamic-Link-Manager\ui\operators.py" +``` + +``` +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +import bpy +import os +from bpy.types import Operator +from bpy.props import StringProperty, BoolProperty +from bpy.props import StringProperty, IntProperty + +from ..utils import collection_containing_armature + +ADDON_NAME = __package__.rsplit(".", 1)[0] if "." in __package__ else __package__ + + +def _prefs(context): + return context.preferences.addons.get(ADDON_NAME) + + +class DLM_OT_replace_linked_asset(Operator): + bl_idname = "dlm.replace_linked_asset" + bl_label = "Replace Linked Asset" + bl_description = "Open file browser to replace the linked asset with another file" + bl_options = {"REGISTER", "UNDO"} + filepath: StringProperty(name="File Path", description="Path to the new asset file", subtype="FILE_PATH") + + def execute(self, context): + obj = context.active_object + if not obj: + self.report({"ERROR"}, "No object selected") + return {"CANCELLED"} + if getattr(obj, "library", None): + self.report({"INFO"}, f"Object '{obj.name}' is linked from: {obj.library.filepath}") + return {"FINISHED"} + if obj.data and getattr(obj.data, "library", None) and obj.data.library: + self.report({"INFO"}, f"Object '{obj.name}' has linked data from: {obj.data.library.filepath}") + return {"FINISHED"} + if obj.type == "ARMATURE" and obj.data and obj.data.name in bpy.data.armatures: + ad = bpy.data.armatures[obj.data.name] + if getattr(ad, "library", None) and ad.library: + self.report({"INFO"}, f"Armature '{obj.name}' data is linked from: {ad.library.filepath}") + return {"FINISHED"} + self.report({"ERROR"}, "Selected object is not a linked asset") + return {"CANCELLED"} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + +class DLM_OT_scan_linked_assets(Operator): + bl_idname = "dlm.scan_linked_assets" + bl_label = "Scan Linked Libraries" + bl_description = "Scan the current file for linked libraries and list their status" + bl_options = {"REGISTER"} + + def execute(self, context): + from ..ops import library + + return library.scan_linked_assets(context, self.report) + + +class DLM_OT_find_libraries_in_folders(Operator): + bl_idname = "dlm.find_libraries_in_folders" + bl_label = "Find Libraries in Folders" + bl_description = "Search addon search paths for missing library blend files" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + from ..ops import library + + return library.find_libraries_in_folders(context, self.report, ADDON_NAME) + + +class DLM_OT_open_linked_file(Operator): + bl_idname = "dlm.open_linked_file" + bl_label = "Open Linked File" + bl_description = "Open the selected linked blend file in a new Blender instance" + bl_options = {"REGISTER"} + filepath: StringProperty(name="File Path", default="") + + def execute(self, context): + if not self.filepath: + self.report({"ERROR"}, "No file path specified") + return {"CANCELLED"} + try: + bpy.ops.wm.path_open(filepath=self.filepath) + self.report({"INFO"}, f"Opening linked file: {self.filepath}") + except Exception as e: + self.report({"ERROR"}, f"Failed to open linked file: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + +class DLM_OT_add_search_path(Operator): + bl_idname = "dlm.add_search_path" + bl_label = "Add Search Path" + bl_description = "Add a new folder to the list of search paths for finding libraries" + bl_options = {"REGISTER"} + + def execute(self, context): + prefs = _prefs(context) + if prefs: + p = prefs.preferences.search_paths.add() + p.path = "//" + self.report({"INFO"}, f"Added search path: {p.path}") + return {"FINISHED"} + + +class DLM_OT_remove_search_path(Operator): + bl_idname = "dlm.remove_search_path" + bl_label = "Remove Search Path" + bl_description = "Remove the selected search path from the list" + bl_options = {"REGISTER"} + index: IntProperty(name="Index", default=0) + + def execute(self, context): + prefs = _prefs(context) + if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths): + prefs.preferences.search_paths.remove(self.index) + self.report({"INFO"}, f"Removed search path at index {self.index}") + return {"FINISHED"} + + +class DLM_OT_attempt_relink(Operator): + bl_idname = "dlm.attempt_relink" + bl_label = "Attempt Relink" + bl_description = "Try to relink missing libraries using the configured search paths" + bl_options = {"REGISTER"} + + def execute(self, context): + from ..ops import library + + return library.attempt_relink(context, self.report, ADDON_NAME) + + +class DLM_OT_browse_search_path(Operator): + bl_idname = "dlm.browse_search_path" + bl_label = "Browse Search Path" + bl_description = "Browse to set the folder for the selected search path" + bl_options = {"REGISTER"} + index: IntProperty(name="Index", default=0) + filepath: StringProperty(name="Search Path", subtype="DIR_PATH") + + def execute(self, context): + prefs = _prefs(context) + if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths): + prefs.preferences.search_paths[self.index].path = self.filepath + self.report({"INFO"}, f"Updated search path {self.index + 1}: {self.filepath}") + return {"FINISHED"} + + def invoke(self, context, event): + prefs = _prefs(context) + if prefs and prefs.preferences.search_paths and 0 <= self.index < len(prefs.preferences.search_paths): + self.filepath = prefs.preferences.search_paths[self.index].path + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + +class DLM_OT_reload_libraries(Operator): + bl_idname = "dlm.reload_libraries" + bl_label = "Reload Libraries" + bl_description = "Reload all linked libraries (or fallback manual reload)" + bl_options = {"REGISTER"} + + def execute(self, context): + try: + bpy.ops.outliner.lib_operation(type="RELOAD") + self.report({"INFO"}, "Library reload operation completed") + except Exception: + try: + for lib in bpy.data.libraries: + if lib.filepath and os.path.exists(bpy.path.abspath(lib.filepath)): + lib.reload() + self.report({"INFO"}, "Libraries reloaded manually") + except Exception as e: + self.report({"ERROR"}, f"Failed to reload libraries: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + +class DLM_OT_make_paths_relative(Operator): + bl_idname = "dlm.make_paths_relative" + bl_label = "Make Paths Relative" + bl_description = "Convert all internal file paths to relative" + bl_options = {"REGISTER"} + + def execute(self, context): + try: + bpy.ops.file.make_paths_relative() + self.report({"INFO"}, "All file paths made relative") + except Exception as e: + self.report({"ERROR"}, f"Failed to make paths relative: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + +class DLM_OT_make_paths_absolute(Operator): + bl_idname = "dlm.make_paths_absolute" + bl_label = "Make Paths Absolute" + bl_description = "Convert all internal file paths to absolute" + bl_options = {"REGISTER"} + + def execute(self, context): + try: + bpy.ops.file.make_paths_absolute() + self.report({"INFO"}, "All file paths made absolute") + except Exception as e: + self.report({"ERROR"}, f"Failed to make paths absolute: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + +class DLM_OT_relocate_single_library(Operator): + bl_idname = "dlm.relocate_single_library" + bl_label = "Relocate Library" + bl_description = "Point the selected library to a new blend file and reload" + bl_options = {"REGISTER", "UNDO"} + target_filepath: StringProperty(name="Current Library Path", default="") + filepath: StringProperty(name="New Library File", subtype="FILE_PATH", default="") + + def execute(self, context): + if not self.target_filepath or not self.filepath: + self.report({"ERROR"}, "No target or new file specified") + return {"CANCELLED"} + abs_match = bpy.path.abspath(self.target_filepath) if self.target_filepath else "" + library = None + for lib in bpy.data.libraries: + try: + if lib.filepath and bpy.path.abspath(lib.filepath) == abs_match: + library = lib + break + except Exception: + if lib.filepath == self.target_filepath: + library = lib + break + if not library: + self.report({"ERROR"}, "Could not resolve the selected library") + return {"CANCELLED"} + try: + library.filepath = self.filepath + library.reload() + self.report({"INFO"}, f"Relocated to: {self.filepath}") + except Exception as e: + self.report({"ERROR"}, f"Failed to relocate: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + def invoke(self, context, event): + if self.target_filepath: + try: + self.filepath = bpy.path.abspath(self.target_filepath) + except Exception: + self.filepath = self.target_filepath + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + +def _get_migrator_pair(context): + """Return (orig, rep) from scene props (manual or automatic). (None, None) if invalid.""" + from ..ops.migrator import get_pair_manual, get_pair_automatic + + props = getattr(context.scene, "dynamic_link_manager", None) + if not props: + return None, None + use_auto = getattr(props, "migrator_mode", False) + orig, rep = get_pair_automatic(context) if use_auto else get_pair_manual(context) + return orig, rep + + +class DLM_OT_migrator_copy_attributes(Operator): + bl_idname = "dlm.migrator_copy_attributes" + bl_label = "CopyAttr" + bl_description = "Copy object and armature attributes from original to replacement character" + bl_icon = "COPY_ID" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair (set Original/Replacement or enable Automatic).") + return {"CANCELLED"} + try: + from ..ops.migrator import run_copy_attr + run_copy_attr(orig, rep) + self.report({"INFO"}, "Copy attributes done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_migrate_nla(Operator): + bl_idname = "dlm.migrator_migrate_nla" + bl_label = "MigNLA" + bl_description = "Migrate NLA tracks and strips from original to replacement character" + bl_icon = "NLA" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_mig_nla + run_mig_nla(orig, rep, report=self.report) + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_custom_properties(Operator): + bl_idname = "dlm.migrator_custom_properties" + bl_label = "MigCustProps" + bl_description = "Copy custom properties from original to replacement character" + bl_icon = "PROPERTIES" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_mig_cust_props + run_mig_cust_props(orig, rep) + self.report({"INFO"}, "Custom properties done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_bone_constraints(Operator): + bl_idname = "dlm.migrator_bone_constraints" + bl_label = "MigBoneConst" + bl_description = "Migrate bone constraints from original to replacement armature" + bl_icon = "CONSTRAINT_BONE" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_mig_bone_const + orig_to_rep = {orig: rep} + run_mig_bone_const(orig, rep, orig_to_rep) + self.report({"INFO"}, "Bone constraints done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_retarget_relations(Operator): + bl_idname = "dlm.migrator_retarget_relations" + bl_label = "RetargRelatives" + bl_description = "Retarget parent/child and other relations to the replacement character" + bl_icon = "ORIENTATION_PARENT" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_retarg_relatives + from ..utils import descendants + rep_descendants = descendants(rep) + orig_to_rep = {orig: rep} + run_retarg_relatives(orig, rep, rep_descendants, orig_to_rep) + self.report({"INFO"}, "Retarget relations done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_basebody_shapekeys(Operator): + bl_idname = "dlm.migrator_basebody_shapekeys" + bl_label = "MigBBodyShapeKeys" + bl_description = "Migrate base body mesh shape key values from original to replacement" + bl_icon = "SHAPEKEY_DATA" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.migrator import run_mig_bbody_shapekeys + from ..utils import descendants + rep_descendants = descendants(rep) + run_mig_bbody_shapekeys(orig, rep, rep_descendants, context) + self.report({"INFO"}, "Migrate BaseBody shapekeys done.") + return {"FINISHED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_fk_rotations(Operator): + bl_idname = "dlm.migrator_fk_rotations" + bl_label = "MigFKRot" + bl_description = "Copy FK arm and finger rotations from original to replacement (uses constraints)" + bl_icon = "BONE_DATA" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.fk_rotations import copy_fk_rotations + ok, msg = copy_fk_rotations(context, orig, rep) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + else: + self.report({"ERROR"}, msg) + return {"CANCELLED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_fk_rotations_bake(Operator): + bl_idname = "dlm.migrator_fk_rotations_bake" + bl_label = "Bake MigFKRot" + bl_description = "Bake FK rotations to keyframes using nla.bake (similar to tweak tools)" + bl_icon = "KEYFRAME" + bl_options = {"REGISTER", "UNDO"} + + track_name: StringProperty(name="NLA Track", description="Optional NLA track name for frame range", default="") + post_clean: BoolProperty(name="Post-clean", description="Clean curves after bake", default=False) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.fk_rotations import bake_fk_rotations + ok, msg = bake_fk_rotations(context, orig, rep, track_name=self.track_name or None, post_clean=self.post_clean) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + else: + self.report({"ERROR"}, msg) + return {"CANCELLED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + +class DLM_OT_migrator_fk_rotations_remove(Operator): + bl_idname = "dlm.migrator_fk_rotations_remove" + bl_label = "Remove MigFKRot" + bl_description = "Remove FK rotation COPY_TRANSFORMS constraints (similar to tweak_remove_arm)" + bl_icon = "X" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig or not rep or orig == rep: + self.report({"ERROR"}, "No valid character pair.") + return {"CANCELLED"} + try: + from ..ops.fk_rotations import remove_fk_rotations + ok, msg = remove_fk_rotations(context, rep) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + else: + self.report({"ERROR"}, msg) + return {"CANCELLED"} + except Exception as e: + self.report({"ERROR"}, str(e)) + return {"CANCELLED"} + + + + +class DLM_OT_migrator_remove_original(Operator): + bl_idname = "dlm.migrator_remove_original" + bl_label = "Remove Original" + bl_description = "Delete the original character armature and its data from the scene" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig: + self.report({"WARNING"}, "No original character selected") + return {"CANCELLED"} + if orig == rep: + self.report({"ERROR"}, "Original and replacement cannot be the same object") + return {"CANCELLED"} + + name = orig.name + try: + # Try to find and delete the collection containing the original character + coll = collection_containing_armature(orig) + if coll: + bpy.data.collections.remove(coll) + context.scene.dynamic_link_manager.original_character = None + self.report({"INFO"}, f"Removed collection: {coll.name}") + else: + # Fallback: just delete the armature object + bpy.data.objects.remove(orig, do_unlink=True) + context.scene.dynamic_link_manager.original_character = None + self.report({"INFO"}, f"Removed original character: {name}") + except Exception as e: + self.report({"ERROR"}, f"Failed to remove original: {e}") + return {"CANCELLED"} + return {"FINISHED"} + + + +class DLM_OT_picker_original_character(Operator): + bl_idname = "dlm.picker_original_character" + bl_label = "Pick Original" + bl_description = "Set the original character armature from the active object" + bl_options = {"REGISTER"} + + def execute(self, context): + obj = context.active_object + if not obj or obj.type != "ARMATURE": + self.report({"WARNING"}, "Select an armature") + return {"CANCELLED"} + context.scene.dynamic_link_manager.original_character = obj + self.report({"INFO"}, f"Original: {obj.name}") + return {"FINISHED"} + + +class DLM_OT_picker_replacement_character(Operator): + bl_idname = "dlm.picker_replacement_character" + bl_label = "Pick Replacement" + bl_description = "Set the replacement character armature from the active object" + bl_options = {"REGISTER"} + + def execute(self, context): + obj = context.active_object + if not obj or obj.type != "ARMATURE": + self.report({"WARNING"}, "Select an armature") + return {"CANCELLED"} + context.scene.dynamic_link_manager.replacement_character = obj + self.report({"INFO"}, f"Replacement: {obj.name}") + return {"FINISHED"} + + +def _tweak_poll(context): + orig, rep = _get_migrator_pair(context) + return orig is not None and rep is not None + + +class DLM_OT_tweak_add_arm(Operator): + bl_idname = "dlm.tweak_add_arm" + bl_label = "Add Arm Tweaks" + bl_description = "Add tweak bone constraints to arm bones on the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + tweak_tools.add_tweak_constraints(orig, rep, "arm") + self.report({"INFO"}, "Arm tweak constraints added.") + return {"FINISHED"} + + +class DLM_OT_tweak_remove_arm(Operator): + bl_idname = "dlm.tweak_remove_arm" + bl_label = "Remove Arm Tweaks" + bl_description = "Remove arm tweak constraints from the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + n = tweak_tools.remove_tweak_constraints(orig, rep, "arm") + self.report({"INFO"}, f"Removed {n} arm tweak constraints.") + return {"FINISHED"} + + +class DLM_OT_tweak_bake_arm(Operator): + bl_idname = "dlm.tweak_bake_arm" + bl_label = "Bake Arm Tweaks" + bl_description = "Bake arm tweak constraints to keyframes and optionally remove constraints" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + props = context.scene.dynamic_link_manager + from ..ops import tweak_tools + ok, msg = tweak_tools.bake_tweak_constraints( + context, orig, rep, "arm", + getattr(props, "tweak_nla_track_name", "") or "", + getattr(props, "tweak_bake_post_clean", False), + ) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + self.report({"ERROR"}, msg) + return {"CANCELLED"} + + +class DLM_OT_tweak_add_leg(Operator): + bl_idname = "dlm.tweak_add_leg" + bl_label = "Add Leg Tweaks" + bl_description = "Add tweak bone constraints to leg bones on the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + tweak_tools.add_tweak_constraints(orig, rep, "leg") + self.report({"INFO"}, "Leg tweak constraints added.") + return {"FINISHED"} + + +class DLM_OT_tweak_remove_leg(Operator): + bl_idname = "dlm.tweak_remove_leg" + bl_label = "Remove Leg Tweaks" + bl_description = "Remove leg tweak constraints from the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + n = tweak_tools.remove_tweak_constraints(orig, rep, "leg") + self.report({"INFO"}, f"Removed {n} leg tweak constraints.") + return {"FINISHED"} + + +class DLM_OT_tweak_bake_leg(Operator): + bl_idname = "dlm.tweak_bake_leg" + bl_label = "Bake Leg Tweaks" + bl_description = "Bake leg tweak constraints to keyframes and optionally remove constraints" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + props = context.scene.dynamic_link_manager + from ..ops import tweak_tools + ok, msg = tweak_tools.bake_tweak_constraints( + context, orig, rep, "leg", + getattr(props, "tweak_nla_track_name", "") or "", + getattr(props, "tweak_bake_post_clean", False), + ) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + self.report({"ERROR"}, msg) + return {"CANCELLED"} + + +class DLM_OT_tweak_add_both(Operator): + bl_idname = "dlm.tweak_add_both" + bl_label = "Add Arm & Leg Tweaks" + bl_description = "Add tweak bone constraints to both arm and leg bones" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + tweak_tools.add_tweak_constraints(orig, rep, "both") + self.report({"INFO"}, "Arm & leg tweak constraints added.") + return {"FINISHED"} + + +class DLM_OT_tweak_remove_both(Operator): + bl_idname = "dlm.tweak_remove_both" + bl_label = "Remove Arm & Leg Tweaks" + bl_description = "Remove all arm and leg tweak constraints from the replacement character" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + from ..ops import tweak_tools + n = tweak_tools.remove_tweak_constraints(orig, rep, "both") + self.report({"INFO"}, f"Removed {n} tweak constraints.") + return {"FINISHED"} + + +class DLM_OT_tweak_bake_both(Operator): + bl_idname = "dlm.tweak_bake_both" + bl_label = "Bake Arm & Leg Tweaks" + bl_description = "Bake all arm and leg tweak constraints to keyframes and optionally remove constraints" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return _tweak_poll(context) + + def execute(self, context): + orig, rep = _get_migrator_pair(context) + props = context.scene.dynamic_link_manager + from ..ops import tweak_tools + ok, msg = tweak_tools.bake_tweak_constraints( + context, orig, rep, "both", + getattr(props, "tweak_nla_track_name", "") or "", + getattr(props, "tweak_bake_post_clean", False), + ) + if ok: + self.report({"INFO"}, msg) + return {"FINISHED"} + self.report({"ERROR"}, msg) + return {"CANCELLED"} + + +OPERATOR_CLASSES = [ + DLM_OT_replace_linked_asset, + DLM_OT_scan_linked_assets, + DLM_OT_find_libraries_in_folders, + DLM_OT_open_linked_file, + DLM_OT_add_search_path, + DLM_OT_remove_search_path, + DLM_OT_browse_search_path, + DLM_OT_attempt_relink, + DLM_OT_reload_libraries, + DLM_OT_make_paths_relative, + DLM_OT_make_paths_absolute, + DLM_OT_relocate_single_library, + DLM_OT_migrator_remove_original, + DLM_OT_picker_original_character, + DLM_OT_picker_replacement_character, + DLM_OT_migrator_copy_attributes, + DLM_OT_migrator_migrate_nla, + DLM_OT_migrator_custom_properties, + DLM_OT_migrator_bone_constraints, + DLM_OT_migrator_retarget_relations, + DLM_OT_migrator_basebody_shapekeys, + DLM_OT_tweak_add_arm, + DLM_OT_tweak_remove_arm, + DLM_OT_tweak_bake_arm, + DLM_OT_tweak_add_leg, + DLM_OT_tweak_remove_leg, + DLM_OT_tweak_bake_leg, + DLM_OT_tweak_add_both, + DLM_OT_tweak_remove_both, + DLM_OT_tweak_bake_both, + DLM_OT_migrator_fk_rotations, + DLM_OT_migrator_fk_rotations_bake, + DLM_OT_migrator_fk_rotations_remove, +] + +``` +
+
+ +--- + +
Thought Process +I can see the `DLM_OT_migrator_remove_original` class in the file. Looking at the `execute` method, the issue is clear: after `bpy.data.collections.remove(coll)` is called, the code tries to access `coll.name` for the report, but `coll` is now an invalidated RNA reference. The error happens because: + +1. `coll = collection_containing_armature(orig)` gets a reference to the collection +2. `bpy.data.collections.remove(coll)` removes the collection and invalidates the RNA struct +3. `self.report({"INFO"}, f"Removed collection: {coll.name}")` tries to access `coll.name` which now fails + +The fix needs to: +1. Store the collection name before removal +2. Clear the property and report before attempting the remove (or catch exceptions properly) + +Let me look at the exact lines to fix. The current code is around the middle of the file. Let me find the exact line numbers and then make the fix.
+ +--- + +I can see the issue in the `DLM_OT_migrator_remove_original.execute` method. The problem is that `coll.name` is accessed AFTER `bpy.data.collections.remove(coll)` has already invalidated the RNA reference. + +Let me apply the fix by modifying the code to store the name first and handle exceptions gracefully. + +--- + + +
Tool use: **run_terminal_command_v2** • Run command: sed -n '230,260p' "T:\Dynamic-Link-Manager\ui\operators.py" + +```bash +sed -n '230,260p' "T:\Dynamic-Link-Manager\ui\operators.py" +``` + +``` +sed: C:\Users\Nathan\AppData\Local\Temp\ps-script-3ae04e65-b0d2-472b-b4b5-8acedea11bd4.ps1:113 +Line | + 113 | sed -n '230,260p' "T:\Dynamic-Link-Manager\ui\operators.py" + | ~~~ + | The term 'sed' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the + | spelling of the name, or if a path was included, verify that the path is correct and try again. + +``` +
+
+ +--- + +
Thought Process +`sed` is not available on Windows. Let me use PowerShell or another approach to find the exact lines. Let me just use Python to read the file and find the lines.
+ +--- + +Let me use Python to find the exact line numbers and make the edit. + +--- + + +
Tool use: **run_terminal_command_v2** • Run command: python -c " +with open(r'T:\Dynamic-Link-Manager\ui\operators.py', 'r') as f: + lines = f.readlines() + for i, line in enumerate(lines, 1): + if 'DLM_OT_migrator_remove_original' in line: + print(f'Class starts at line {i}: {line.strip()}') + if 'bpy.data.collections.remove' in line: + print(f'Remove call at line {i}: {line.strip()}') +" + +```bash +python -c " +with open(r'T:\Dynamic-Link-Manager\ui\operators.py', 'r') as f: + lines = f.readlines() + for i, line in enumerate(lines, 1): + if 'DLM_OT_migrator_remove_original' in line: + print(f'Class starts at line {i}: {line.strip()}') + if 'bpy.data.collections.remove' in line: + print(f'Remove call at line {i}: {line.strip()}') +" +``` + +``` +Class starts at line 492: class DLM_OT_migrator_remove_original(Operator): +Remove call at line 512: bpy.data.collections.remove(coll) +Class starts at line 763: DLM_OT_migrator_remove_original, + +``` +
+
+ +--- + +
Thought Process +Good, I found the line numbers. The class starts at line 492 and the `bpy.data.collections.remove(coll)` call is at line 512. Let me view the context around lines 492-525 to see the full execute method that needs to be fixed.
+ +--- + + +
Tool use: **run_terminal_command_v2** • Run command: python -c " +with open(r'T:\Dynamic-Link-Manager\ui\operators.py', 'r') as f: + lines = f.readlines() + for i in range(491, 525): + print(f'{i+1}: {lines[i]}', end='') +" + +```bash +python -c " +with open(r'T:\Dynamic-Link-Manager\ui\operators.py', 'r') as f: + lines = f.readlines() + for i in range(491, 525): + print(f'{i+1}: {lines[i]}', end='') +" +``` + +``` +492: class DLM_OT_migrator_remove_original(Operator): +493: bl_idname = "dlm.migrator_remove_original" +494: bl_label = "Remove Original" +495: bl_description = "Delete the original character armature and its data from the scene" +496: bl_options = {"REGISTER", "UNDO"} +497: +498: def execute(self, context): +499: orig, rep = _get_migrator_pair(context) +500: if not orig: +501: self.report({"WARNING"}, "No original character selected") +502: return {"CANCELLED"} +503: if orig == rep: +504: self.report({"ERROR"}, "Original and replacement cannot be the same object") +505: return {"CANCELLED"} +506: +507: name = orig.name +508: try: +509: # Try to find and delete the collection containing the original character +510: coll = collection_containing_armature(orig) +511: if coll: +512: bpy.data.collections.remove(coll) +513: context.scene.dynamic_link_manager.original_character = None +514: self.report({"INFO"}, f"Removed collection: {coll.name}") +515: else: +516: # Fallback: just delete the armature object +517: bpy.data.objects.remove(orig, do_unlink=True) +518: context.scene.dynamic_link_manager.original_character = None +519: self.report({"INFO"}, f"Removed original character: {name}") +520: except Exception as e: +521: self.report({"ERROR"}, f"Failed to remove original: {e}") +522: return {"CANCELLED"} +523: return {"FINISHED"} +524: +525: + +``` +
+
+ +--- + +
Thought Process +Now I can see the exact lines. The issue is: +- Line 512: `bpy.data.collections.remove(coll)` removes the collection and invalidates `coll` +- Line 514: `self.report({"INFO"}, f"Removed collection: {
+ +--- + diff --git a/.specstory/history/2026-03-10_16-25Z-dlm-ot-migrator-remove-original-operator-error-handling.md b/.specstory/history/2026-03-10_16-25Z-dlm-ot-migrator-remove-original-operator-error-handling.md new file mode 100644 index 0000000..ac02309 --- /dev/null +++ b/.specstory/history/2026-03-10_16-25Z-dlm-ot-migrator-remove-original-operator-error-handling.md @@ -0,0 +1,83 @@ + + + + +# DLM_OT_migrator_remove_original operator error handling (2026-03-10 16:25Z) + +_**User**_ + +The DLM_OT_migrator_remove_original operator in T:\Dynamic-Link-Manager\ui\operators.py is failing with "StructRNA of type Collection has been removed" error. + +This likely happens because: +1. The collection might be linked or an override that can't be removed directly +2. Other addons (like Animation Layers) might be holding references + +Update the operator to: +1. First check if the collection is local (not linked) before trying to remove it +2. If collection removal fails, catch the specific error and fall back to removing just the objects in the collection +3. Handle the case where the collection is already being processed + +Here's the improved logic: +```python +def execute(self, context): + orig, rep = _get_migrator_pair(context) + if not orig: + self.report({"WARNING"}, "No original character selected") + return {"CANCELLED"} + if orig == rep: + self.report({"ERROR"}, "Original and replacement cannot be the same object") + return {"CANCELLED"} + + name = orig.name + try: + # Try to find the collection containing the original character + coll = collection_containing_armature(orig) + if coll and not coll.library: # Only remove local collections + # Get all objects in the collection before removing it + objects_to_remove = list(coll.objects) + # Remove the collection first + bpy.data.collections.remove(coll) + # Then remove the objects + for obj in objects_to_remove: + if obj and obj.name in bpy.data.objects: + bpy.data.objects.remove(obj, do_unlink=True) + context.scene.dynamic_link_manager.original_character = None + self.report({"INFO"}, f"Removed character collection: {coll.name}") + else: + # Fallback: just delete the armature object + if orig.name in bpy.data.objects: + bpy.data.objects.remove(orig, do_unlink=True) + context.scene.dynamic_link_manager.original_character = None + if coll: + self.report({"INFO"}, f"Removed original (linked collection cannot be deleted): {name}") + else: + self.report({"INFO"}, f"Removed original character: {name}") + except Exception as e: + self.report({"ERROR"}, f"Failed to remove original: {e}") + return {"CANCELLED"} + return {"FINISHED"} +``` + +Make this change to the file. + +--- + +_**Agent (model accounts/fireworks/models/kimi-k2p5, mode Agent)**_ + + + +--- + +
Thought Process +The user wants me to update the `DLM_OT_migrator_remove_original` operator in `T:\Dynamic-Link-Manager\ui\operators.py`. Let me first read the file to see the current implementation and then make the requested changes.
+ +--- + +I'll read the current file to see the existing implementation of the operator. + +--- + +Cancelled + +--- + diff --git a/ui/operators.py b/ui/operators.py index de7f60a..ea7be93 100644 --- a/ui/operators.py +++ b/ui/operators.py @@ -9,6 +9,8 @@ from bpy.types import Operator from bpy.props import StringProperty, BoolProperty from bpy.props import StringProperty, IntProperty +from ..utils import collection_containing_armature + ADDON_NAME = __package__.rsplit(".", 1)[0] if "." in __package__ else __package__ @@ -504,11 +506,22 @@ class DLM_OT_migrator_remove_original(Operator): name = orig.name try: - # Remove from scene - bpy.data.objects.remove(orig, do_unlink=True) - # Clear the property - context.scene.dynamic_link_manager.original_character = None - self.report({"INFO"}, f"Removed original character: {name}") + # Try to find and delete the collection containing the original character + coll = collection_containing_armature(orig) + if coll: + coll_name = coll.name # Store name BEFORE removal (RNA invalidates after remove) + context.scene.dynamic_link_manager.original_character = None + try: + bpy.data.collections.remove(coll) + self.report({"INFO"}, f"Removed collection: {coll_name}") + except Exception as remove_err: + # Collection may have already been removed by another process + self.report({"WARNING"}, f"Collection {coll_name} removal issue: {remove_err}") + else: + # Fallback: just delete the armature object + bpy.data.objects.remove(orig, do_unlink=True) + context.scene.dynamic_link_manager.original_character = None + self.report({"INFO"}, f"Removed original character: {name}") except Exception as e: self.report({"ERROR"}, f"Failed to remove original: {e}") return {"CANCELLED"}