X-Git-Url: https://git.r.bdr.sh/rbdr/map/blobdiff_plain/fdb4633d3e9158e457d57e820df6e1efb4df39c2..144915635bdfc90445321189914929a911fe77d4:/Map.xcodeproj/project.pbxproj

diff --git a/Map.xcodeproj/project.pbxproj b/Map.xcodeproj/project.pbxproj
index 9cd5d87..5601b8e 100644
--- a/Map.xcodeproj/project.pbxproj
+++ b/Map.xcodeproj/project.pbxproj
@@ -3,134 +3,139 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 53;
+	objectVersion = 60;
 	objects = {
 
 /* Begin PBXBuildFile section */
-		B523C73D25C98D9800C44061 /* NSImage+writePNG.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C73C25C98D9800C44061 /* NSImage+writePNG.swift */; };
-		B523C74625C9BD3500C44061 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B523C74525C9BD3500C44061 /* CloudKit.framework */; };
-		B523C74B25C9C1BA00C44061 /* EmptyMapDetailScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C74A25C9C1BA00C44061 /* EmptyMapDetailScreen.swift */; };
-		B523C75A25C9FD4900C44061 /* MapAxes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C75925C9FD4900C44061 /* MapAxes.swift */; };
-		B523C76225CA05A300C44061 /* MapStages.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C76125CA05A300C44061 /* MapStages.swift */; };
-		B523C76725CA071B00C44061 /* MapVertices.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C76625CA071B00C44061 /* MapVertices.swift */; };
-		B523C76C25CA0DFA00C44061 /* MapEdges.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C76B25CA0DFA00C44061 /* MapEdges.swift */; };
-		B523C77125CA121300C44061 /* MapBlockers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C77025CA121300C44061 /* MapBlockers.swift */; };
-		B523C77E25CA294C00C44061 /* MapOpportunities.swift in Sources */ = {isa = PBXBuildFile; fileRef = B523C77D25CA294C00C44061 /* MapOpportunities.swift */; };
-		B526257225C874F9003E73B7 /* MapApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526257125C874F9003E73B7 /* MapApp.swift */; };
-		B526257425C874F9003E73B7 /* MapEditorWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526257325C874F9003E73B7 /* MapEditorWindow.swift */; };
-		B526257625C874FA003E73B7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B526257525C874FA003E73B7 /* Assets.xcassets */; };
-		B526257925C874FA003E73B7 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B526257825C874FA003E73B7 /* Preview Assets.xcassets */; };
-		B526257B25C874FA003E73B7 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526257A25C874FA003E73B7 /* Persistence.swift */; };
-		B526257E25C874FA003E73B7 /* Map.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B526257C25C874FA003E73B7 /* Map.xcdatamodeld */; };
-		B526258A25C874FA003E73B7 /* MapTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526258925C874FA003E73B7 /* MapTests.swift */; };
-		B526259525C874FA003E73B7 /* MapUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526259425C874FA003E73B7 /* MapUITests.swift */; };
-		B52625A625C876C3003E73B7 /* MapDetailScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52625A525C876C3003E73B7 /* MapDetailScreen.swift */; };
-		B52625AB25C87909003E73B7 /* Date+format.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52625AA25C87909003E73B7 /* Date+format.swift */; };
-		B52625B025C87C14003E73B7 /* MapRenderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52625AF25C87C14003E73B7 /* MapRenderView.swift */; };
-		B52625BB25C884C2003E73B7 /* Map+parse.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52625BA25C884C2003E73B7 /* Map+parse.swift */; };
-		B52625C625C8BD2A003E73B7 /* Stage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52625C525C8BD2A003E73B7 /* Stage.swift */; };
-		B539516C25CB0C9300959F72 /* Store.swift in Sources */ = {isa = PBXBuildFile; fileRef = B539516B25CB0C9200959F72 /* Store.swift */; };
-		B539517425CB0CA400959F72 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B539517325CB0CA400959F72 /* AppState.swift */; };
-		B539518125CB2D7A00959F72 /* MapTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B539518025CB2D7A00959F72 /* MapTextEditor.swift */; };
-		B5CF75C925CC19FC003BFF3D /* EvolutionPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75C825CC19FC003BFF3D /* EvolutionPicker.swift */; };
-		B5CF75CF25CC7965003BFF3D /* MapParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75CE25CC7965003BFF3D /* MapParser.swift */; };
-		B5CF75D825CC79BC003BFF3D /* VertexParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75D725CC79BC003BFF3D /* VertexParserStrategy.swift */; };
-		B5CF75DD25CC79D7003BFF3D /* EdgeParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75DC25CC79D7003BFF3D /* EdgeParserStrategy.swift */; };
-		B5CF75E225CC79ED003BFF3D /* BlockerParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75E125CC79ED003BFF3D /* BlockerParserStrategy.swift */; };
-		B5CF75EA25CC7A13003BFF3D /* OpportunityParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75E925CC7A13003BFF3D /* OpportunityParserStrategy.swift */; };
-		B5CF75EF25CC7A4A003BFF3D /* StageParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75EE25CC7A4A003BFF3D /* StageParserStrategy.swift */; };
-		B5CF75F725CC97CA003BFF3D /* Debouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CF75F625CC97CA003BFF3D /* Debouncer.swift */; };
-		B5F8D3082A06DD8C000EEA24 /* Font+Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F8D3072A06DD8C000EEA24 /* Font+Theme.swift */; };
-		B5F8D30B2A06E3E6000EEA24 /* Color+Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F8D30A2A06E3E6000EEA24 /* Color+Theme.swift */; };
-		B5F8D30E2A06E5C2000EEA24 /* Patterns in Frameworks */ = {isa = PBXBuildFile; productRef = B5F8D30D2A06E5C2000EEA24 /* Patterns */; };
-		B5F8D3102A07B33D000EEA24 /* NSColor+Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F8D30F2A07B33D000EEA24 /* NSColor+Theme.swift */; };
-		B5F8D3122A07B690000EEA24 /* NoteParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F8D3112A07B690000EEA24 /* NoteParserStrategy.swift */; };
-		B5F8D3142A07C05F000EEA24 /* MapNotes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F8D3132A07C05F000EEA24 /* MapNotes.swift */; };
+		B5012E3F2C96232A00AC4D68 /* EvolutionPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E3E2C96232300AC4D68 /* EvolutionPicker.swift */; };
+		B5012E422C96235E00AC4D68 /* Stage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E412C96235B00AC4D68 /* Stage.swift */; };
+		B5012E452C9623C700AC4D68 /* Font+theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E442C9623C500AC4D68 /* Font+theme.swift */; };
+		B5012E472C96243C00AC4D68 /* MapTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E462C96243500AC4D68 /* MapTextEditor.swift */; };
+		B5012E492C96245B00AC4D68 /* Color+theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E482C96245800AC4D68 /* Color+theme.swift */; };
+		B5012E4B2C96246F00AC4D68 /* NSColor+theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E4A2C96246D00AC4D68 /* NSColor+theme.swift */; };
+		B5012E572C96249400AC4D68 /* NoteParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E4D2C96249400AC4D68 /* NoteParserStrategy.swift */; };
+		B5012E582C96249400AC4D68 /* BlockerParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E4F2C96249400AC4D68 /* BlockerParserStrategy.swift */; };
+		B5012E592C96249400AC4D68 /* VertexParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E4C2C96249400AC4D68 /* VertexParserStrategy.swift */; };
+		B5012E5A2C96249400AC4D68 /* MapParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E532C96249400AC4D68 /* MapParser.swift */; };
+		B5012E5B2C96249400AC4D68 /* OpportunityParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E502C96249400AC4D68 /* OpportunityParserStrategy.swift */; };
+		B5012E5C2C96249400AC4D68 /* EdgeParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E4E2C96249400AC4D68 /* EdgeParserStrategy.swift */; };
+		B5012E5D2C96249400AC4D68 /* StageParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E512C96249400AC4D68 /* StageParserStrategy.swift */; };
+		B5012E5E2C96249400AC4D68 /* Debouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E552C96249400AC4D68 /* Debouncer.swift */; };
+		B5012E622C96254700AC4D68 /* MapRenderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E5F2C96254700AC4D68 /* MapRenderView.swift */; };
+		B5012E6B2C96255A00AC4D68 /* MapAxes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E632C96255A00AC4D68 /* MapAxes.swift */; };
+		B5012E6C2C96255A00AC4D68 /* MapVertices.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E652C96255A00AC4D68 /* MapVertices.swift */; };
+		B5012E6D2C96255A00AC4D68 /* MapStages.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E642C96255A00AC4D68 /* MapStages.swift */; };
+		B5012E6E2C96255A00AC4D68 /* MapNotes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E662C96255A00AC4D68 /* MapNotes.swift */; };
+		B5012E6F2C96255A00AC4D68 /* MapEdges.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E672C96255A00AC4D68 /* MapEdges.swift */; };
+		B5012E702C96255A00AC4D68 /* MapOpportunities.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E692C96255A00AC4D68 /* MapOpportunities.swift */; };
+		B5012E712C96255A00AC4D68 /* MapBlockers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E682C96255A00AC4D68 /* MapBlockers.swift */; };
+		B5012E742C9625E200AC4D68 /* Patterns in Frameworks */ = {isa = PBXBuildFile; productRef = B5012E732C9625E200AC4D68 /* Patterns */; };
+		B5012E7A2C96F02F00AC4D68 /* Dimensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E792C96F02E00AC4D68 /* Dimensions.swift */; };
+		B5012E7C2C972B6C00AC4D68 /* GroupParserStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E7B2C972B6600AC4D68 /* GroupParserStrategy.swift */; };
+		B5012E7F2C97315800AC4D68 /* ConcaveHull in Frameworks */ = {isa = PBXBuildFile; productRef = B5012E7E2C97315800AC4D68 /* ConcaveHull */; };
+		B5012E812C97318600AC4D68 /* MapGroups.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E802C97318300AC4D68 /* MapGroups.swift */; };
+		B5012E872C97874600AC4D68 /* MapGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E862C97874400AC4D68 /* MapGroup.swift */; };
+		B5012E8A2C98235500AC4D68 /* MapCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E892C98235300AC4D68 /* MapCommands.swift */; };
+		B5012E8C2C98244000AC4D68 /* ViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E8B2C98243E00AC4D68 /* ViewStyle.swift */; };
+		B5012E8E2C9828D000AC4D68 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5012E8D2C9828CE00AC4D68 /* Constants.swift */; };
+		B51A45F52C982FAE00870ED5 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = B51A45F42C982FAE00870ED5 /* Sparkle */; };
+		B51A45F72C982FEA00870ED5 /* UpdateCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51A45F62C982FE700870ED5 /* UpdateCommands.swift */; };
+		B54587102C961E9C0067B788 /* MapApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B545870F2C961E9C0067B788 /* MapApp.swift */; };
+		B54587122C961E9C0067B788 /* MapDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54587112C961E9C0067B788 /* MapDocument.swift */; };
+		B54587142C961E9C0067B788 /* MapEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54587132C961E9C0067B788 /* MapEditor.swift */; };
+		B54587162C961E9E0067B788 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B54587152C961E9E0067B788 /* Assets.xcassets */; };
+		B54587192C961E9E0067B788 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B54587182C961E9E0067B788 /* Preview Assets.xcassets */; };
+		B54587252C961E9E0067B788 /* MapTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54587242C961E9E0067B788 /* MapTests.swift */; };
+		B545872F2C961E9E0067B788 /* MapUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B545872E2C961E9E0067B788 /* MapUITests.swift */; };
+		B54587312C961E9E0067B788 /* MapUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54587302C961E9E0067B788 /* MapUITestsLaunchTests.swift */; };
+		B5D42DC22C984E870075473D /* FocusedValues+document.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D42DC12C984E7F0075473D /* FocusedValues+document.swift */; };
+		B5D42DC42C9851ED0075473D /* SearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D42DC32C9851ED0075473D /* SearchBar.swift */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
-		B526258625C874FA003E73B7 /* PBXContainerItemProxy */ = {
+		B54587212C961E9E0067B788 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
-			containerPortal = B526256625C874F9003E73B7 /* Project object */;
+			containerPortal = B54587042C961E9C0067B788 /* Project object */;
 			proxyType = 1;
-			remoteGlobalIDString = B526256D25C874F9003E73B7;
-			remoteInfo = Map;
+			remoteGlobalIDString = B545870B2C961E9C0067B788;
+			remoteInfo = Map2;
 		};
-		B526259125C874FA003E73B7 /* PBXContainerItemProxy */ = {
+		B545872B2C961E9E0067B788 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
-			containerPortal = B526256625C874F9003E73B7 /* Project object */;
+			containerPortal = B54587042C961E9C0067B788 /* Project object */;
 			proxyType = 1;
-			remoteGlobalIDString = B526256D25C874F9003E73B7;
-			remoteInfo = Map;
+			remoteGlobalIDString = B545870B2C961E9C0067B788;
+			remoteInfo = Map2;
 		};
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
-		B523C73C25C98D9800C44061 /* NSImage+writePNG.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSImage+writePNG.swift"; sourceTree = "<group>"; };
-		B523C74525C9BD3500C44061 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; };
-		B523C74A25C9C1BA00C44061 /* EmptyMapDetailScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyMapDetailScreen.swift; sourceTree = "<group>"; };
-		B523C75925C9FD4900C44061 /* MapAxes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapAxes.swift; sourceTree = "<group>"; };
-		B523C76125CA05A300C44061 /* MapStages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapStages.swift; sourceTree = "<group>"; };
-		B523C76625CA071B00C44061 /* MapVertices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapVertices.swift; sourceTree = "<group>"; };
-		B523C76B25CA0DFA00C44061 /* MapEdges.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapEdges.swift; sourceTree = "<group>"; };
-		B523C77025CA121300C44061 /* MapBlockers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapBlockers.swift; sourceTree = "<group>"; };
-		B523C77D25CA294C00C44061 /* MapOpportunities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapOpportunities.swift; sourceTree = "<group>"; };
-		B526256E25C874F9003E73B7 /* Map.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Map.app; sourceTree = BUILT_PRODUCTS_DIR; };
-		B526257125C874F9003E73B7 /* MapApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapApp.swift; sourceTree = "<group>"; };
-		B526257325C874F9003E73B7 /* MapEditorWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapEditorWindow.swift; sourceTree = "<group>"; };
-		B526257525C874FA003E73B7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
-		B526257825C874FA003E73B7 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
-		B526257A25C874FA003E73B7 /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
-		B526257D25C874FA003E73B7 /* Map.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Map.xcdatamodel; sourceTree = "<group>"; };
-		B526257F25C874FA003E73B7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
-		B526258025C874FA003E73B7 /* Map.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Map.entitlements; sourceTree = "<group>"; };
-		B526258525C874FA003E73B7 /* MapTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MapTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
-		B526258925C874FA003E73B7 /* MapTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTests.swift; sourceTree = "<group>"; };
-		B526258B25C874FA003E73B7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
-		B526259025C874FA003E73B7 /* MapUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MapUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
-		B526259425C874FA003E73B7 /* MapUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapUITests.swift; sourceTree = "<group>"; };
-		B526259625C874FA003E73B7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
-		B52625A525C876C3003E73B7 /* MapDetailScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapDetailScreen.swift; sourceTree = "<group>"; };
-		B52625AA25C87909003E73B7 /* Date+format.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+format.swift"; sourceTree = "<group>"; };
-		B52625AF25C87C14003E73B7 /* MapRenderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapRenderView.swift; sourceTree = "<group>"; };
-		B52625BA25C884C2003E73B7 /* Map+parse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Map+parse.swift"; sourceTree = "<group>"; };
-		B52625C525C8BD2A003E73B7 /* Stage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stage.swift; sourceTree = "<group>"; };
-		B539516B25CB0C9200959F72 /* Store.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Store.swift; sourceTree = "<group>"; };
-		B539517325CB0CA400959F72 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
-		B539518025CB2D7A00959F72 /* MapTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTextEditor.swift; sourceTree = "<group>"; };
-		B5CF75C825CC19FC003BFF3D /* EvolutionPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EvolutionPicker.swift; sourceTree = "<group>"; };
-		B5CF75CE25CC7965003BFF3D /* MapParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapParser.swift; sourceTree = "<group>"; };
-		B5CF75D725CC79BC003BFF3D /* VertexParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VertexParserStrategy.swift; sourceTree = "<group>"; };
-		B5CF75DC25CC79D7003BFF3D /* EdgeParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EdgeParserStrategy.swift; sourceTree = "<group>"; };
-		B5CF75E125CC79ED003BFF3D /* BlockerParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockerParserStrategy.swift; sourceTree = "<group>"; };
-		B5CF75E925CC7A13003BFF3D /* OpportunityParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpportunityParserStrategy.swift; sourceTree = "<group>"; };
-		B5CF75EE25CC7A4A003BFF3D /* StageParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StageParserStrategy.swift; sourceTree = "<group>"; };
-		B5CF75F625CC97CA003BFF3D /* Debouncer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Debouncer.swift; sourceTree = "<group>"; };
-		B5F8D3072A06DD8C000EEA24 /* Font+Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Font+Theme.swift"; sourceTree = "<group>"; };
-		B5F8D30A2A06E3E6000EEA24 /* Color+Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Theme.swift"; sourceTree = "<group>"; };
-		B5F8D30F2A07B33D000EEA24 /* NSColor+Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSColor+Theme.swift"; sourceTree = "<group>"; };
-		B5F8D3112A07B690000EEA24 /* NoteParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteParserStrategy.swift; sourceTree = "<group>"; };
-		B5F8D3132A07C05F000EEA24 /* MapNotes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapNotes.swift; sourceTree = "<group>"; };
+		B5012E3E2C96232300AC4D68 /* EvolutionPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EvolutionPicker.swift; sourceTree = "<group>"; };
+		B5012E412C96235B00AC4D68 /* Stage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stage.swift; sourceTree = "<group>"; };
+		B5012E442C9623C500AC4D68 /* Font+theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Font+theme.swift"; sourceTree = "<group>"; };
+		B5012E462C96243500AC4D68 /* MapTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTextEditor.swift; sourceTree = "<group>"; };
+		B5012E482C96245800AC4D68 /* Color+theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+theme.swift"; sourceTree = "<group>"; };
+		B5012E4A2C96246D00AC4D68 /* NSColor+theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSColor+theme.swift"; sourceTree = "<group>"; };
+		B5012E4C2C96249400AC4D68 /* VertexParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VertexParserStrategy.swift; sourceTree = "<group>"; };
+		B5012E4D2C96249400AC4D68 /* NoteParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteParserStrategy.swift; sourceTree = "<group>"; };
+		B5012E4E2C96249400AC4D68 /* EdgeParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EdgeParserStrategy.swift; sourceTree = "<group>"; };
+		B5012E4F2C96249400AC4D68 /* BlockerParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockerParserStrategy.swift; sourceTree = "<group>"; };
+		B5012E502C96249400AC4D68 /* OpportunityParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpportunityParserStrategy.swift; sourceTree = "<group>"; };
+		B5012E512C96249400AC4D68 /* StageParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StageParserStrategy.swift; sourceTree = "<group>"; };
+		B5012E532C96249400AC4D68 /* MapParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapParser.swift; sourceTree = "<group>"; };
+		B5012E552C96249400AC4D68 /* Debouncer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Debouncer.swift; sourceTree = "<group>"; };
+		B5012E5F2C96254700AC4D68 /* MapRenderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapRenderView.swift; sourceTree = "<group>"; };
+		B5012E632C96255A00AC4D68 /* MapAxes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapAxes.swift; sourceTree = "<group>"; };
+		B5012E642C96255A00AC4D68 /* MapStages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapStages.swift; sourceTree = "<group>"; };
+		B5012E652C96255A00AC4D68 /* MapVertices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapVertices.swift; sourceTree = "<group>"; };
+		B5012E662C96255A00AC4D68 /* MapNotes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapNotes.swift; sourceTree = "<group>"; };
+		B5012E672C96255A00AC4D68 /* MapEdges.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapEdges.swift; sourceTree = "<group>"; };
+		B5012E682C96255A00AC4D68 /* MapBlockers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapBlockers.swift; sourceTree = "<group>"; };
+		B5012E692C96255A00AC4D68 /* MapOpportunities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapOpportunities.swift; sourceTree = "<group>"; };
+		B5012E792C96F02E00AC4D68 /* Dimensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dimensions.swift; sourceTree = "<group>"; };
+		B5012E7B2C972B6600AC4D68 /* GroupParserStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupParserStrategy.swift; sourceTree = "<group>"; };
+		B5012E802C97318300AC4D68 /* MapGroups.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapGroups.swift; sourceTree = "<group>"; };
+		B5012E862C97874400AC4D68 /* MapGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapGroup.swift; sourceTree = "<group>"; };
+		B5012E892C98235300AC4D68 /* MapCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapCommands.swift; sourceTree = "<group>"; };
+		B5012E8B2C98243E00AC4D68 /* ViewStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewStyle.swift; sourceTree = "<group>"; };
+		B5012E8D2C9828CE00AC4D68 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
+		B51A45F62C982FE700870ED5 /* UpdateCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateCommands.swift; sourceTree = "<group>"; };
+		B545870C2C961E9C0067B788 /* Map.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Map.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		B545870F2C961E9C0067B788 /* MapApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapApp.swift; sourceTree = "<group>"; };
+		B54587112C961E9C0067B788 /* MapDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapDocument.swift; sourceTree = "<group>"; };
+		B54587132C961E9C0067B788 /* MapEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapEditor.swift; sourceTree = "<group>"; };
+		B54587152C961E9E0067B788 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+		B54587182C961E9E0067B788 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
+		B545871A2C961E9E0067B788 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		B545871B2C961E9E0067B788 /* Map.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Map.entitlements; sourceTree = "<group>"; };
+		B54587202C961E9E0067B788 /* MapTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MapTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+		B54587242C961E9E0067B788 /* MapTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTests.swift; sourceTree = "<group>"; };
+		B545872A2C961E9E0067B788 /* Map2UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Map2UITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+		B545872E2C961E9E0067B788 /* MapUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapUITests.swift; sourceTree = "<group>"; };
+		B54587302C961E9E0067B788 /* MapUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapUITestsLaunchTests.swift; sourceTree = "<group>"; };
+		B5D42DC12C984E7F0075473D /* FocusedValues+document.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FocusedValues+document.swift"; sourceTree = "<group>"; };
+		B5D42DC32C9851ED0075473D /* SearchBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBar.swift; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
-		B526256B25C874F9003E73B7 /* Frameworks */ = {
+		B54587092C961E9C0067B788 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				B523C74625C9BD3500C44061 /* CloudKit.framework in Frameworks */,
-				B5F8D30E2A06E5C2000EEA24 /* Patterns in Frameworks */,
+				B51A45F52C982FAE00870ED5 /* Sparkle in Frameworks */,
+				B5012E742C9625E200AC4D68 /* Patterns in Frameworks */,
+				B5012E7F2C97315800AC4D68 /* ConcaveHull in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
-		B526258225C874FA003E73B7 /* Frameworks */ = {
+		B545871D2C961E9E0067B788 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
-		B526258D25C874FA003E73B7 /* Frameworks */ = {
+		B54587272C961E9E0067B788 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
@@ -140,219 +145,195 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
-		B523C74425C9BD3500C44061 /* Frameworks */ = {
+		B5012E3C2C96222E00AC4D68 /* Data */ = {
 			isa = PBXGroup;
 			children = (
-				B523C74525C9BD3500C44061 /* CloudKit.framework */,
+				B5D42DC12C984E7F0075473D /* FocusedValues+document.swift */,
+				B5012E412C96235B00AC4D68 /* Stage.swift */,
+				B54587112C961E9C0067B788 /* MapDocument.swift */,
 			);
-			name = Frameworks;
-			sourceTree = "<group>";
-		};
-		B523C75825C9FD3A00C44061 /* MapRender */ = {
-			isa = PBXGroup;
-			children = (
-				B523C75925C9FD4900C44061 /* MapAxes.swift */,
-				B523C76125CA05A300C44061 /* MapStages.swift */,
-				B523C76625CA071B00C44061 /* MapVertices.swift */,
-				B5F8D3132A07C05F000EEA24 /* MapNotes.swift */,
-				B523C76B25CA0DFA00C44061 /* MapEdges.swift */,
-				B523C77025CA121300C44061 /* MapBlockers.swift */,
-				B523C77D25CA294C00C44061 /* MapOpportunities.swift */,
-			);
-			path = MapRender;
-			sourceTree = "<group>";
-		};
-		B526256525C874F9003E73B7 = {
-			isa = PBXGroup;
-			children = (
-				B526257025C874F9003E73B7 /* Map */,
-				B526258825C874FA003E73B7 /* MapTests */,
-				B526259325C874FA003E73B7 /* MapUITests */,
-				B526256F25C874F9003E73B7 /* Products */,
-				B523C74425C9BD3500C44061 /* Frameworks */,
-			);
-			sourceTree = "<group>";
-		};
-		B526256F25C874F9003E73B7 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				B526256E25C874F9003E73B7 /* Map.app */,
-				B526258525C874FA003E73B7 /* MapTests.xctest */,
-				B526259025C874FA003E73B7 /* MapUITests.xctest */,
-			);
-			name = Products;
+			path = Data;
 			sourceTree = "<group>";
 		};
-		B526257025C874F9003E73B7 /* Map */ = {
+		B5012E3D2C96223800AC4D68 /* Presentation */ = {
 			isa = PBXGroup;
 			children = (
-				B526257125C874F9003E73B7 /* MapApp.swift */,
-				B5F8D2FE2A06DB3A000EEA24 /* Data */,
-				B5F8D3092A06DE1A000EEA24 /* Logic */,
-				B5F8D2FF2A06DB40000EEA24 /* Presentation */,
-				B52625B425C87D54003E73B7 /* Core Extensions */,
-				B526257525C874FA003E73B7 /* Assets.xcassets */,
-				B526257F25C874FA003E73B7 /* Info.plist */,
-				B526258025C874FA003E73B7 /* Map.entitlements */,
-				B526257C25C874FA003E73B7 /* Map.xcdatamodeld */,
-				B526257725C874FA003E73B7 /* Preview Content */,
+				B5012E8B2C98243E00AC4D68 /* ViewStyle.swift */,
+				B5012E882C98234F00AC4D68 /* Commands */,
+				B5012E612C96254700AC4D68 /* Complex Components */,
+				B5012E432C9623BC00AC4D68 /* Theme */,
+				B5012E402C96232E00AC4D68 /* Base Components */,
+				B54587132C961E9C0067B788 /* MapEditor.swift */,
 			);
-			path = Map;
+			path = Presentation;
 			sourceTree = "<group>";
 		};
-		B526257725C874FA003E73B7 /* Preview Content */ = {
+		B5012E402C96232E00AC4D68 /* Base Components */ = {
 			isa = PBXGroup;
 			children = (
-				B526257825C874FA003E73B7 /* Preview Assets.xcassets */,
+				B5012E6A2C96255A00AC4D68 /* MapRender */,
+				B5012E462C96243500AC4D68 /* MapTextEditor.swift */,
+				B5012E3E2C96232300AC4D68 /* EvolutionPicker.swift */,
+				B5D42DC32C9851ED0075473D /* SearchBar.swift */,
 			);
-			path = "Preview Content";
+			path = "Base Components";
 			sourceTree = "<group>";
 		};
-		B526258825C874FA003E73B7 /* MapTests */ = {
+		B5012E432C9623BC00AC4D68 /* Theme */ = {
 			isa = PBXGroup;
 			children = (
-				B526258925C874FA003E73B7 /* MapTests.swift */,
-				B526258B25C874FA003E73B7 /* Info.plist */,
+				B5012E792C96F02E00AC4D68 /* Dimensions.swift */,
+				B5012E4A2C96246D00AC4D68 /* NSColor+theme.swift */,
+				B5012E482C96245800AC4D68 /* Color+theme.swift */,
+				B5012E442C9623C500AC4D68 /* Font+theme.swift */,
 			);
-			path = MapTests;
+			path = Theme;
 			sourceTree = "<group>";
 		};
-		B526259325C874FA003E73B7 /* MapUITests */ = {
+		B5012E522C96249400AC4D68 /* Strategies */ = {
 			isa = PBXGroup;
 			children = (
-				B526259425C874FA003E73B7 /* MapUITests.swift */,
-				B526259625C874FA003E73B7 /* Info.plist */,
+				B5012E7B2C972B6600AC4D68 /* GroupParserStrategy.swift */,
+				B5012E4C2C96249400AC4D68 /* VertexParserStrategy.swift */,
+				B5012E4D2C96249400AC4D68 /* NoteParserStrategy.swift */,
+				B5012E4E2C96249400AC4D68 /* EdgeParserStrategy.swift */,
+				B5012E4F2C96249400AC4D68 /* BlockerParserStrategy.swift */,
+				B5012E502C96249400AC4D68 /* OpportunityParserStrategy.swift */,
+				B5012E512C96249400AC4D68 /* StageParserStrategy.swift */,
 			);
-			path = MapUITests;
+			path = Strategies;
 			sourceTree = "<group>";
 		};
-		B52625B425C87D54003E73B7 /* Core Extensions */ = {
+		B5012E542C96249400AC4D68 /* MapParser */ = {
 			isa = PBXGroup;
 			children = (
-				B52625AA25C87909003E73B7 /* Date+format.swift */,
-				B523C73C25C98D9800C44061 /* NSImage+writePNG.swift */,
-				B5F8D3072A06DD8C000EEA24 /* Font+Theme.swift */,
-				B5F8D30F2A07B33D000EEA24 /* NSColor+Theme.swift */,
-				B5F8D30A2A06E3E6000EEA24 /* Color+Theme.swift */,
+				B5012E522C96249400AC4D68 /* Strategies */,
+				B5012E532C96249400AC4D68 /* MapParser.swift */,
 			);
-			path = "Core Extensions";
+			path = MapParser;
 			sourceTree = "<group>";
 		};
-		B5CF75CD25CC7953003BFF3D /* MapParser */ = {
+		B5012E562C96249400AC4D68 /* Logic */ = {
 			isa = PBXGroup;
 			children = (
-				B5CF75D625CC79A4003BFF3D /* Strategies */,
-				B5CF75CE25CC7965003BFF3D /* MapParser.swift */,
+				B5012E8D2C9828CE00AC4D68 /* Constants.swift */,
+				B5012E542C96249400AC4D68 /* MapParser */,
+				B5012E552C96249400AC4D68 /* Debouncer.swift */,
 			);
-			path = MapParser;
+			path = Logic;
 			sourceTree = "<group>";
 		};
-		B5CF75D625CC79A4003BFF3D /* Strategies */ = {
+		B5012E602C96254700AC4D68 /* MapRender */ = {
 			isa = PBXGroup;
 			children = (
-				B5CF75D725CC79BC003BFF3D /* VertexParserStrategy.swift */,
-				B5F8D3112A07B690000EEA24 /* NoteParserStrategy.swift */,
-				B5CF75DC25CC79D7003BFF3D /* EdgeParserStrategy.swift */,
-				B5CF75E125CC79ED003BFF3D /* BlockerParserStrategy.swift */,
-				B5CF75E925CC7A13003BFF3D /* OpportunityParserStrategy.swift */,
-				B5CF75EE25CC7A4A003BFF3D /* StageParserStrategy.swift */,
+				B5012E5F2C96254700AC4D68 /* MapRenderView.swift */,
 			);
-			path = Strategies;
+			path = MapRender;
 			sourceTree = "<group>";
 		};
-		B5F8D2FE2A06DB3A000EEA24 /* Data */ = {
+		B5012E612C96254700AC4D68 /* Complex Components */ = {
 			isa = PBXGroup;
 			children = (
-				B5F8D3012A06DB75000EEA24 /* Models */,
-				B52625C525C8BD2A003E73B7 /* Stage.swift */,
-				B526257A25C874FA003E73B7 /* Persistence.swift */,
-				B539516B25CB0C9200959F72 /* Store.swift */,
-				B539517325CB0CA400959F72 /* AppState.swift */,
+				B5012E602C96254700AC4D68 /* MapRender */,
 			);
-			path = Data;
+			path = "Complex Components";
 			sourceTree = "<group>";
 		};
-		B5F8D2FF2A06DB40000EEA24 /* Presentation */ = {
+		B5012E6A2C96255A00AC4D68 /* MapRender */ = {
 			isa = PBXGroup;
 			children = (
-				B5F8D3022A06DBC3000EEA24 /* Windows */,
-				B5F8D3032A06DC2D000EEA24 /* Screens */,
-				B5F8D3052A06DCF3000EEA24 /* Complex Components */,
-				B5F8D3042A06DCC4000EEA24 /* Base Components */,
+				B5012E802C97318300AC4D68 /* MapGroups.swift */,
+				B5012E862C97874400AC4D68 /* MapGroup.swift */,
+				B5012E632C96255A00AC4D68 /* MapAxes.swift */,
+				B5012E642C96255A00AC4D68 /* MapStages.swift */,
+				B5012E652C96255A00AC4D68 /* MapVertices.swift */,
+				B5012E662C96255A00AC4D68 /* MapNotes.swift */,
+				B5012E672C96255A00AC4D68 /* MapEdges.swift */,
+				B5012E682C96255A00AC4D68 /* MapBlockers.swift */,
+				B5012E692C96255A00AC4D68 /* MapOpportunities.swift */,
 			);
-			path = Presentation;
+			path = MapRender;
 			sourceTree = "<group>";
 		};
-		B5F8D3012A06DB75000EEA24 /* Models */ = {
+		B5012E882C98234F00AC4D68 /* Commands */ = {
 			isa = PBXGroup;
 			children = (
-				B52625BA25C884C2003E73B7 /* Map+parse.swift */,
+				B51A45F62C982FE700870ED5 /* UpdateCommands.swift */,
+				B5012E892C98235300AC4D68 /* MapCommands.swift */,
 			);
-			path = Models;
+			path = Commands;
 			sourceTree = "<group>";
 		};
-		B5F8D3022A06DBC3000EEA24 /* Windows */ = {
+		B54587032C961E9C0067B788 = {
 			isa = PBXGroup;
 			children = (
-				B526257325C874F9003E73B7 /* MapEditorWindow.swift */,
+				B545870E2C961E9C0067B788 /* Map */,
+				B54587232C961E9E0067B788 /* MapTests */,
+				B545872D2C961E9E0067B788 /* MapUITests */,
+				B545870D2C961E9C0067B788 /* Products */,
 			);
-			path = Windows;
 			sourceTree = "<group>";
 		};
-		B5F8D3032A06DC2D000EEA24 /* Screens */ = {
+		B545870D2C961E9C0067B788 /* Products */ = {
 			isa = PBXGroup;
 			children = (
-				B523C74A25C9C1BA00C44061 /* EmptyMapDetailScreen.swift */,
-				B52625A525C876C3003E73B7 /* MapDetailScreen.swift */,
+				B545870C2C961E9C0067B788 /* Map.app */,
+				B54587202C961E9E0067B788 /* MapTests.xctest */,
+				B545872A2C961E9E0067B788 /* Map2UITests.xctest */,
 			);
-			path = Screens;
+			name = Products;
 			sourceTree = "<group>";
 		};
-		B5F8D3042A06DCC4000EEA24 /* Base Components */ = {
+		B545870E2C961E9C0067B788 /* Map */ = {
 			isa = PBXGroup;
 			children = (
-				B5CF75C825CC19FC003BFF3D /* EvolutionPicker.swift */,
-				B539518025CB2D7A00959F72 /* MapTextEditor.swift */,
-				B523C75825C9FD3A00C44061 /* MapRender */,
+				B5012E562C96249400AC4D68 /* Logic */,
+				B5012E3C2C96222E00AC4D68 /* Data */,
+				B5012E3D2C96223800AC4D68 /* Presentation */,
+				B545870F2C961E9C0067B788 /* MapApp.swift */,
+				B54587152C961E9E0067B788 /* Assets.xcassets */,
+				B545871A2C961E9E0067B788 /* Info.plist */,
+				B545871B2C961E9E0067B788 /* Map.entitlements */,
+				B54587172C961E9E0067B788 /* Preview Content */,
 			);
-			path = "Base Components";
+			path = Map;
 			sourceTree = "<group>";
 		};
-		B5F8D3052A06DCF3000EEA24 /* Complex Components */ = {
+		B54587172C961E9E0067B788 /* Preview Content */ = {
 			isa = PBXGroup;
 			children = (
-				B5F8D3062A06DD2A000EEA24 /* MapRender */,
+				B54587182C961E9E0067B788 /* Preview Assets.xcassets */,
 			);
-			path = "Complex Components";
+			path = "Preview Content";
 			sourceTree = "<group>";
 		};
-		B5F8D3062A06DD2A000EEA24 /* MapRender */ = {
+		B54587232C961E9E0067B788 /* MapTests */ = {
 			isa = PBXGroup;
 			children = (
-				B52625AF25C87C14003E73B7 /* MapRenderView.swift */,
+				B54587242C961E9E0067B788 /* MapTests.swift */,
 			);
-			path = MapRender;
+			path = MapTests;
 			sourceTree = "<group>";
 		};
-		B5F8D3092A06DE1A000EEA24 /* Logic */ = {
+		B545872D2C961E9E0067B788 /* MapUITests */ = {
 			isa = PBXGroup;
 			children = (
-				B5CF75CD25CC7953003BFF3D /* MapParser */,
-				B5CF75F625CC97CA003BFF3D /* Debouncer.swift */,
+				B545872E2C961E9E0067B788 /* MapUITests.swift */,
+				B54587302C961E9E0067B788 /* MapUITestsLaunchTests.swift */,
 			);
-			path = Logic;
+			path = MapUITests;
 			sourceTree = "<group>";
 		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
-		B526256D25C874F9003E73B7 /* Map */ = {
+		B545870B2C961E9C0067B788 /* Map */ = {
 			isa = PBXNativeTarget;
-			buildConfigurationList = B526259925C874FA003E73B7 /* Build configuration list for PBXNativeTarget "Map" */;
+			buildConfigurationList = B54587342C961E9E0067B788 /* Build configuration list for PBXNativeTarget "Map" */;
 			buildPhases = (
-				B526256A25C874F9003E73B7 /* Sources */,
-				B526256B25C874F9003E73B7 /* Frameworks */,
-				B526256C25C874F9003E73B7 /* Resources */,
+				B54587082C961E9C0067B788 /* Sources */,
+				B54587092C961E9C0067B788 /* Frameworks */,
+				B545870A2C961E9C0067B788 /* Resources */,
 			);
 			buildRules = (
 			);
@@ -360,112 +341,116 @@
 			);
 			name = Map;
 			packageProductDependencies = (
-				B5F8D30D2A06E5C2000EEA24 /* Patterns */,
+				B5012E732C9625E200AC4D68 /* Patterns */,
+				B5012E7E2C97315800AC4D68 /* ConcaveHull */,
+				B51A45F42C982FAE00870ED5 /* Sparkle */,
 			);
-			productName = Map;
-			productReference = B526256E25C874F9003E73B7 /* Map.app */;
+			productName = Map2;
+			productReference = B545870C2C961E9C0067B788 /* Map.app */;
 			productType = "com.apple.product-type.application";
 		};
-		B526258425C874FA003E73B7 /* MapTests */ = {
+		B545871F2C961E9E0067B788 /* MapTests */ = {
 			isa = PBXNativeTarget;
-			buildConfigurationList = B526259C25C874FA003E73B7 /* Build configuration list for PBXNativeTarget "MapTests" */;
+			buildConfigurationList = B54587372C961E9E0067B788 /* Build configuration list for PBXNativeTarget "MapTests" */;
 			buildPhases = (
-				B526258125C874FA003E73B7 /* Sources */,
-				B526258225C874FA003E73B7 /* Frameworks */,
-				B526258325C874FA003E73B7 /* Resources */,
+				B545871C2C961E9E0067B788 /* Sources */,
+				B545871D2C961E9E0067B788 /* Frameworks */,
+				B545871E2C961E9E0067B788 /* Resources */,
 			);
 			buildRules = (
 			);
 			dependencies = (
-				B526258725C874FA003E73B7 /* PBXTargetDependency */,
+				B54587222C961E9E0067B788 /* PBXTargetDependency */,
 			);
 			name = MapTests;
-			productName = MapTests;
-			productReference = B526258525C874FA003E73B7 /* MapTests.xctest */;
+			productName = Map2Tests;
+			productReference = B54587202C961E9E0067B788 /* MapTests.xctest */;
 			productType = "com.apple.product-type.bundle.unit-test";
 		};
-		B526258F25C874FA003E73B7 /* MapUITests */ = {
+		B54587292C961E9E0067B788 /* Map2UITests */ = {
 			isa = PBXNativeTarget;
-			buildConfigurationList = B526259F25C874FA003E73B7 /* Build configuration list for PBXNativeTarget "MapUITests" */;
+			buildConfigurationList = B545873A2C961E9E0067B788 /* Build configuration list for PBXNativeTarget "Map2UITests" */;
 			buildPhases = (
-				B526258C25C874FA003E73B7 /* Sources */,
-				B526258D25C874FA003E73B7 /* Frameworks */,
-				B526258E25C874FA003E73B7 /* Resources */,
+				B54587262C961E9E0067B788 /* Sources */,
+				B54587272C961E9E0067B788 /* Frameworks */,
+				B54587282C961E9E0067B788 /* Resources */,
 			);
 			buildRules = (
 			);
 			dependencies = (
-				B526259225C874FA003E73B7 /* PBXTargetDependency */,
+				B545872C2C961E9E0067B788 /* PBXTargetDependency */,
 			);
-			name = MapUITests;
-			productName = MapUITests;
-			productReference = B526259025C874FA003E73B7 /* MapUITests.xctest */;
+			name = Map2UITests;
+			productName = Map2UITests;
+			productReference = B545872A2C961E9E0067B788 /* Map2UITests.xctest */;
 			productType = "com.apple.product-type.bundle.ui-testing";
 		};
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
-		B526256625C874F9003E73B7 /* Project object */ = {
+		B54587042C961E9C0067B788 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				BuildIndependentTargetsInParallel = YES;
-				LastSwiftUpdateCheck = 1240;
-				LastUpgradeCheck = 1430;
+				BuildIndependentTargetsInParallel = 1;
+				LastSwiftUpdateCheck = 1600;
+				LastUpgradeCheck = 1600;
 				TargetAttributes = {
-					B526256D25C874F9003E73B7 = {
-						CreatedOnToolsVersion = 12.4;
+					B545870B2C961E9C0067B788 = {
+						CreatedOnToolsVersion = 16.0;
 					};
-					B526258425C874FA003E73B7 = {
-						CreatedOnToolsVersion = 12.4;
-						TestTargetID = B526256D25C874F9003E73B7;
+					B545871F2C961E9E0067B788 = {
+						CreatedOnToolsVersion = 16.0;
+						TestTargetID = B545870B2C961E9C0067B788;
 					};
-					B526258F25C874FA003E73B7 = {
-						CreatedOnToolsVersion = 12.4;
-						TestTargetID = B526256D25C874F9003E73B7;
+					B54587292C961E9E0067B788 = {
+						CreatedOnToolsVersion = 16.0;
+						TestTargetID = B545870B2C961E9C0067B788;
 					};
 				};
 			};
-			buildConfigurationList = B526256925C874F9003E73B7 /* Build configuration list for PBXProject "Map" */;
-			compatibilityVersion = "Xcode 9.3";
+			buildConfigurationList = B54587072C961E9C0067B788 /* Build configuration list for PBXProject "Map" */;
+			compatibilityVersion = "Xcode 15.0";
 			developmentRegion = en;
 			hasScannedForEncodings = 0;
 			knownRegions = (
 				en,
 				Base,
 			);
-			mainGroup = B526256525C874F9003E73B7;
+			mainGroup = B54587032C961E9C0067B788;
 			packageReferences = (
-				B5F8D30C2A06E5C2000EEA24 /* XCRemoteSwiftPackageReference "patterns" */,
+				B5012E722C9625E200AC4D68 /* XCRemoteSwiftPackageReference "patterns" */,
+				B5012E7D2C97315800AC4D68 /* XCRemoteSwiftPackageReference "ConcaveHull" */,
+				B51A45F32C982FAE00870ED5 /* XCRemoteSwiftPackageReference "Sparkle" */,
 			);
-			productRefGroup = B526256F25C874F9003E73B7 /* Products */;
+			productRefGroup = B545870D2C961E9C0067B788 /* Products */;
 			projectDirPath = "";
 			projectRoot = "";
 			targets = (
-				B526256D25C874F9003E73B7 /* Map */,
-				B526258425C874FA003E73B7 /* MapTests */,
-				B526258F25C874FA003E73B7 /* MapUITests */,
+				B545870B2C961E9C0067B788 /* Map */,
+				B545871F2C961E9E0067B788 /* MapTests */,
+				B54587292C961E9E0067B788 /* Map2UITests */,
 			);
 		};
 /* End PBXProject section */
 
 /* Begin PBXResourcesBuildPhase section */
-		B526256C25C874F9003E73B7 /* Resources */ = {
+		B545870A2C961E9C0067B788 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				B526257925C874FA003E73B7 /* Preview Assets.xcassets in Resources */,
-				B526257625C874FA003E73B7 /* Assets.xcassets in Resources */,
+				B54587192C961E9E0067B788 /* Preview Assets.xcassets in Resources */,
+				B54587162C961E9E0067B788 /* Assets.xcassets in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
-		B526258325C874FA003E73B7 /* Resources */ = {
+		B545871E2C961E9E0067B788 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
-		B526258E25C874FA003E73B7 /* Resources */ = {
+		B54587282C961E9E0067B788 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
@@ -475,86 +460,89 @@
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
-		B526256A25C874F9003E73B7 /* Sources */ = {
+		B54587082C961E9C0067B788 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				B52625B025C87C14003E73B7 /* MapRenderView.swift in Sources */,
-				B523C77E25CA294C00C44061 /* MapOpportunities.swift in Sources */,
-				B52625AB25C87909003E73B7 /* Date+format.swift in Sources */,
-				B5CF75D825CC79BC003BFF3D /* VertexParserStrategy.swift in Sources */,
-				B5CF75EA25CC7A13003BFF3D /* OpportunityParserStrategy.swift in Sources */,
-				B5F8D3142A07C05F000EEA24 /* MapNotes.swift in Sources */,
-				B523C77125CA121300C44061 /* MapBlockers.swift in Sources */,
-				B523C76725CA071B00C44061 /* MapVertices.swift in Sources */,
-				B5CF75CF25CC7965003BFF3D /* MapParser.swift in Sources */,
-				B5CF75E225CC79ED003BFF3D /* BlockerParserStrategy.swift in Sources */,
-				B5F8D3102A07B33D000EEA24 /* NSColor+Theme.swift in Sources */,
-				B5F8D30B2A06E3E6000EEA24 /* Color+Theme.swift in Sources */,
-				B539517425CB0CA400959F72 /* AppState.swift in Sources */,
-				B523C75A25C9FD4900C44061 /* MapAxes.swift in Sources */,
-				B539518125CB2D7A00959F72 /* MapTextEditor.swift in Sources */,
-				B52625BB25C884C2003E73B7 /* Map+parse.swift in Sources */,
-				B52625C625C8BD2A003E73B7 /* Stage.swift in Sources */,
-				B523C73D25C98D9800C44061 /* NSImage+writePNG.swift in Sources */,
-				B5F8D3122A07B690000EEA24 /* NoteParserStrategy.swift in Sources */,
-				B526257B25C874FA003E73B7 /* Persistence.swift in Sources */,
-				B5F8D3082A06DD8C000EEA24 /* Font+Theme.swift in Sources */,
-				B5CF75EF25CC7A4A003BFF3D /* StageParserStrategy.swift in Sources */,
-				B5CF75DD25CC79D7003BFF3D /* EdgeParserStrategy.swift in Sources */,
-				B526257425C874F9003E73B7 /* MapEditorWindow.swift in Sources */,
-				B526257E25C874FA003E73B7 /* Map.xcdatamodeld in Sources */,
-				B5CF75C925CC19FC003BFF3D /* EvolutionPicker.swift in Sources */,
-				B523C74B25C9C1BA00C44061 /* EmptyMapDetailScreen.swift in Sources */,
-				B539516C25CB0C9300959F72 /* Store.swift in Sources */,
-				B526257225C874F9003E73B7 /* MapApp.swift in Sources */,
-				B52625A625C876C3003E73B7 /* MapDetailScreen.swift in Sources */,
-				B523C76225CA05A300C44061 /* MapStages.swift in Sources */,
-				B5CF75F725CC97CA003BFF3D /* Debouncer.swift in Sources */,
-				B523C76C25CA0DFA00C44061 /* MapEdges.swift in Sources */,
+				B5012E872C97874600AC4D68 /* MapGroup.swift in Sources */,
+				B5012E472C96243C00AC4D68 /* MapTextEditor.swift in Sources */,
+				B5012E622C96254700AC4D68 /* MapRenderView.swift in Sources */,
+				B5012E492C96245B00AC4D68 /* Color+theme.swift in Sources */,
+				B54587122C961E9C0067B788 /* MapDocument.swift in Sources */,
+				B54587102C961E9C0067B788 /* MapApp.swift in Sources */,
+				B5012E8C2C98244000AC4D68 /* ViewStyle.swift in Sources */,
+				B5D42DC42C9851ED0075473D /* SearchBar.swift in Sources */,
+				B5012E8E2C9828D000AC4D68 /* Constants.swift in Sources */,
+				B5012E7C2C972B6C00AC4D68 /* GroupParserStrategy.swift in Sources */,
+				B5012E6B2C96255A00AC4D68 /* MapAxes.swift in Sources */,
+				B5012E6C2C96255A00AC4D68 /* MapVertices.swift in Sources */,
+				B5012E6D2C96255A00AC4D68 /* MapStages.swift in Sources */,
+				B5012E7A2C96F02F00AC4D68 /* Dimensions.swift in Sources */,
+				B5012E6E2C96255A00AC4D68 /* MapNotes.swift in Sources */,
+				B5012E6F2C96255A00AC4D68 /* MapEdges.swift in Sources */,
+				B5012E702C96255A00AC4D68 /* MapOpportunities.swift in Sources */,
+				B5012E712C96255A00AC4D68 /* MapBlockers.swift in Sources */,
+				B5012E4B2C96246F00AC4D68 /* NSColor+theme.swift in Sources */,
+				B54587142C961E9C0067B788 /* MapEditor.swift in Sources */,
+				B5012E3F2C96232A00AC4D68 /* EvolutionPicker.swift in Sources */,
+				B5012E572C96249400AC4D68 /* NoteParserStrategy.swift in Sources */,
+				B51A45F72C982FEA00870ED5 /* UpdateCommands.swift in Sources */,
+				B5012E582C96249400AC4D68 /* BlockerParserStrategy.swift in Sources */,
+				B5012E592C96249400AC4D68 /* VertexParserStrategy.swift in Sources */,
+				B5012E5A2C96249400AC4D68 /* MapParser.swift in Sources */,
+				B5012E5B2C96249400AC4D68 /* OpportunityParserStrategy.swift in Sources */,
+				B5012E5C2C96249400AC4D68 /* EdgeParserStrategy.swift in Sources */,
+				B5012E5D2C96249400AC4D68 /* StageParserStrategy.swift in Sources */,
+				B5D42DC22C984E870075473D /* FocusedValues+document.swift in Sources */,
+				B5012E812C97318600AC4D68 /* MapGroups.swift in Sources */,
+				B5012E8A2C98235500AC4D68 /* MapCommands.swift in Sources */,
+				B5012E5E2C96249400AC4D68 /* Debouncer.swift in Sources */,
+				B5012E452C9623C700AC4D68 /* Font+theme.swift in Sources */,
+				B5012E422C96235E00AC4D68 /* Stage.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
-		B526258125C874FA003E73B7 /* Sources */ = {
+		B545871C2C961E9E0067B788 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				B526258A25C874FA003E73B7 /* MapTests.swift in Sources */,
+				B54587252C961E9E0067B788 /* MapTests.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
-		B526258C25C874FA003E73B7 /* Sources */ = {
+		B54587262C961E9E0067B788 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				B526259525C874FA003E73B7 /* MapUITests.swift in Sources */,
+				B54587312C961E9E0067B788 /* MapUITestsLaunchTests.swift in Sources */,
+				B545872F2C961E9E0067B788 /* MapUITests.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
-		B526258725C874FA003E73B7 /* PBXTargetDependency */ = {
+		B54587222C961E9E0067B788 /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
-			target = B526256D25C874F9003E73B7 /* Map */;
-			targetProxy = B526258625C874FA003E73B7 /* PBXContainerItemProxy */;
+			target = B545870B2C961E9C0067B788 /* Map */;
+			targetProxy = B54587212C961E9E0067B788 /* PBXContainerItemProxy */;
 		};
-		B526259225C874FA003E73B7 /* PBXTargetDependency */ = {
+		B545872C2C961E9E0067B788 /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
-			target = B526256D25C874F9003E73B7 /* Map */;
-			targetProxy = B526259125C874FA003E73B7 /* PBXContainerItemProxy */;
+			target = B545870B2C961E9C0067B788 /* Map */;
+			targetProxy = B545872B2C961E9E0067B788 /* PBXContainerItemProxy */;
 		};
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
-		B526259725C874FA003E73B7 /* Debug */ = {
+		B54587322C961E9E0067B788 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
+				ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
 				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
-				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
 				CLANG_ENABLE_MODULES = YES;
 				CLANG_ENABLE_OBJC_ARC = YES;
 				CLANG_ENABLE_OBJC_WEAK = YES;
@@ -581,11 +569,11 @@
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
-				DEAD_CODE_STRIPPING = YES;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;
-				GCC_C_LANGUAGE_STANDARD = gnu11;
+				ENABLE_USER_SCRIPT_SANDBOXING = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu17;
 				GCC_DYNAMIC_NO_PIC = NO;
 				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_OPTIMIZATION_LEVEL = 0;
@@ -599,24 +587,25 @@
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				MACOSX_DEPLOYMENT_TARGET = 11.1;
+				LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+				MACOSX_DEPLOYMENT_TARGET = 15.0;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				ONLY_ACTIVE_ARCH = YES;
 				SDKROOT = macosx;
-				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
 				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
 			};
 			name = Debug;
 		};
-		B526259825C874FA003E73B7 /* Release */ = {
+		B54587332C961E9E0067B788 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
+				ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
 				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
-				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
 				CLANG_ENABLE_MODULES = YES;
 				CLANG_ENABLE_OBJC_ARC = YES;
 				CLANG_ENABLE_OBJC_WEAK = YES;
@@ -643,11 +632,11 @@
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
-				DEAD_CODE_STRIPPING = YES;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				ENABLE_NS_ASSERTIONS = NO;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
-				GCC_C_LANGUAGE_STANDARD = gnu11;
+				ENABLE_USER_SCRIPT_SANDBOXING = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu17;
 				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
@@ -655,16 +644,16 @@
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				MACOSX_DEPLOYMENT_TARGET = 11.1;
+				LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+				MACOSX_DEPLOYMENT_TARGET = 15.0;
 				MTL_ENABLE_DEBUG_INFO = NO;
 				MTL_FAST_MATH = YES;
 				SDKROOT = macosx;
 				SWIFT_COMPILATION_MODE = wholemodule;
-				SWIFT_OPTIMIZATION_LEVEL = "-O";
 			};
 			name = Release;
 		};
-		B526259A25C874FA003E73B7 /* Debug */ = {
+		B54587352C961E9E0067B788 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
@@ -673,25 +662,28 @@
 				CODE_SIGN_STYLE = Automatic;
 				COMBINE_HIDPI_IMAGES = YES;
 				CURRENT_PROJECT_VERSION = 4;
-				DEAD_CODE_STRIPPING = YES;
 				DEVELOPMENT_ASSET_PATHS = "\"Map/Preview Content\"";
 				DEVELOPMENT_TEAM = S68NHQVJXW;
 				ENABLE_HARDENED_RUNTIME = YES;
 				ENABLE_PREVIEWS = YES;
+				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = Map/Info.plist;
+				INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity";
+				INFOPLIST_KEY_NSHumanReadableCopyright = "";
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/../Frameworks",
 				);
-				MACOSX_DEPLOYMENT_TARGET = 12.0;
-				MARKETING_VERSION = 2.0.0;
-				PRODUCT_BUNDLE_IDENTIFIER = pizza.unlimited.Map;
+				MACOSX_DEPLOYMENT_TARGET = 14.0;
+				MARKETING_VERSION = 3.0.1;
+				PRODUCT_BUNDLE_IDENTIFIER = systems.tranquil.Map;
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_EMIT_LOC_STRINGS = YES;
 				SWIFT_VERSION = 5.0;
 			};
 			name = Debug;
 		};
-		B526259B25C874FA003E73B7 /* Release */ = {
+		B54587362C961E9E0067B788 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
@@ -700,147 +692,130 @@
 				CODE_SIGN_STYLE = Automatic;
 				COMBINE_HIDPI_IMAGES = YES;
 				CURRENT_PROJECT_VERSION = 4;
-				DEAD_CODE_STRIPPING = YES;
 				DEVELOPMENT_ASSET_PATHS = "\"Map/Preview Content\"";
 				DEVELOPMENT_TEAM = S68NHQVJXW;
 				ENABLE_HARDENED_RUNTIME = YES;
 				ENABLE_PREVIEWS = YES;
+				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = Map/Info.plist;
+				INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity";
+				INFOPLIST_KEY_NSHumanReadableCopyright = "";
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/../Frameworks",
 				);
-				MACOSX_DEPLOYMENT_TARGET = 12.0;
-				MARKETING_VERSION = 2.0.0;
-				PRODUCT_BUNDLE_IDENTIFIER = pizza.unlimited.Map;
+				MACOSX_DEPLOYMENT_TARGET = 14.0;
+				MARKETING_VERSION = 3.0.1;
+				PRODUCT_BUNDLE_IDENTIFIER = systems.tranquil.Map;
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_EMIT_LOC_STRINGS = YES;
 				SWIFT_VERSION = 5.0;
 			};
 			name = Release;
 		};
-		B526259D25C874FA003E73B7 /* Debug */ = {
+		B54587382C961E9E0067B788 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
 				BUNDLE_LOADER = "$(TEST_HOST)";
 				CODE_SIGN_STYLE = Automatic;
-				COMBINE_HIDPI_IMAGES = YES;
-				DEAD_CODE_STRIPPING = YES;
+				CURRENT_PROJECT_VERSION = 1;
 				DEVELOPMENT_TEAM = S68NHQVJXW;
-				INFOPLIST_FILE = MapTests/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = (
-					"$(inherited)",
-					"@executable_path/../Frameworks",
-					"@loader_path/../Frameworks",
-				);
-				MACOSX_DEPLOYMENT_TARGET = 11.0;
-				PRODUCT_BUNDLE_IDENTIFIER = pizza.unlimited.MapTests;
+				GENERATE_INFOPLIST_FILE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 15.0;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = systems.tranquil.Map2Tests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_EMIT_LOC_STRINGS = NO;
 				SWIFT_VERSION = 5.0;
-				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Map.app/Contents/MacOS/Map";
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Map2.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Map2";
 			};
 			name = Debug;
 		};
-		B526259E25C874FA003E73B7 /* Release */ = {
+		B54587392C961E9E0067B788 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
 				BUNDLE_LOADER = "$(TEST_HOST)";
 				CODE_SIGN_STYLE = Automatic;
-				COMBINE_HIDPI_IMAGES = YES;
-				DEAD_CODE_STRIPPING = YES;
+				CURRENT_PROJECT_VERSION = 1;
 				DEVELOPMENT_TEAM = S68NHQVJXW;
-				INFOPLIST_FILE = MapTests/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = (
-					"$(inherited)",
-					"@executable_path/../Frameworks",
-					"@loader_path/../Frameworks",
-				);
-				MACOSX_DEPLOYMENT_TARGET = 11.0;
-				PRODUCT_BUNDLE_IDENTIFIER = pizza.unlimited.MapTests;
+				GENERATE_INFOPLIST_FILE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 15.0;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = systems.tranquil.Map2Tests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_EMIT_LOC_STRINGS = NO;
 				SWIFT_VERSION = 5.0;
-				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Map.app/Contents/MacOS/Map";
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Map2.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Map2";
 			};
 			name = Release;
 		};
-		B52625A025C874FA003E73B7 /* Debug */ = {
+		B545873B2C961E9E0067B788 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
 				CODE_SIGN_STYLE = Automatic;
-				COMBINE_HIDPI_IMAGES = YES;
-				DEAD_CODE_STRIPPING = YES;
+				CURRENT_PROJECT_VERSION = 1;
 				DEVELOPMENT_TEAM = S68NHQVJXW;
-				INFOPLIST_FILE = MapUITests/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = (
-					"$(inherited)",
-					"@executable_path/../Frameworks",
-					"@loader_path/../Frameworks",
-				);
-				PRODUCT_BUNDLE_IDENTIFIER = pizza.unlimited.MapUITests;
+				GENERATE_INFOPLIST_FILE = YES;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = systems.tranquil.Map2UITests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_EMIT_LOC_STRINGS = NO;
 				SWIFT_VERSION = 5.0;
-				TEST_TARGET_NAME = Map;
+				TEST_TARGET_NAME = Map2;
 			};
 			name = Debug;
 		};
-		B52625A125C874FA003E73B7 /* Release */ = {
+		B545873C2C961E9E0067B788 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
 				CODE_SIGN_STYLE = Automatic;
-				COMBINE_HIDPI_IMAGES = YES;
-				DEAD_CODE_STRIPPING = YES;
+				CURRENT_PROJECT_VERSION = 1;
 				DEVELOPMENT_TEAM = S68NHQVJXW;
-				INFOPLIST_FILE = MapUITests/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = (
-					"$(inherited)",
-					"@executable_path/../Frameworks",
-					"@loader_path/../Frameworks",
-				);
-				PRODUCT_BUNDLE_IDENTIFIER = pizza.unlimited.MapUITests;
+				GENERATE_INFOPLIST_FILE = YES;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = systems.tranquil.Map2UITests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_EMIT_LOC_STRINGS = NO;
 				SWIFT_VERSION = 5.0;
-				TEST_TARGET_NAME = Map;
+				TEST_TARGET_NAME = Map2;
 			};
 			name = Release;
 		};
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
-		B526256925C874F9003E73B7 /* Build configuration list for PBXProject "Map" */ = {
+		B54587072C961E9C0067B788 /* Build configuration list for PBXProject "Map" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
-				B526259725C874FA003E73B7 /* Debug */,
-				B526259825C874FA003E73B7 /* Release */,
+				B54587322C961E9E0067B788 /* Debug */,
+				B54587332C961E9E0067B788 /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
-		B526259925C874FA003E73B7 /* Build configuration list for PBXNativeTarget "Map" */ = {
+		B54587342C961E9E0067B788 /* Build configuration list for PBXNativeTarget "Map" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
-				B526259A25C874FA003E73B7 /* Debug */,
-				B526259B25C874FA003E73B7 /* Release */,
+				B54587352C961E9E0067B788 /* Debug */,
+				B54587362C961E9E0067B788 /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
-		B526259C25C874FA003E73B7 /* Build configuration list for PBXNativeTarget "MapTests" */ = {
+		B54587372C961E9E0067B788 /* Build configuration list for PBXNativeTarget "MapTests" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
-				B526259D25C874FA003E73B7 /* Debug */,
-				B526259E25C874FA003E73B7 /* Release */,
+				B54587382C961E9E0067B788 /* Debug */,
+				B54587392C961E9E0067B788 /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
-		B526259F25C874FA003E73B7 /* Build configuration list for PBXNativeTarget "MapUITests" */ = {
+		B545873A2C961E9E0067B788 /* Build configuration list for PBXNativeTarget "Map2UITests" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
-				B52625A025C874FA003E73B7 /* Debug */,
-				B52625A125C874FA003E73B7 /* Release */,
+				B545873B2C961E9E0067B788 /* Debug */,
+				B545873C2C961E9E0067B788 /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
@@ -848,7 +823,7 @@
 /* End XCConfigurationList section */
 
 /* Begin XCRemoteSwiftPackageReference section */
-		B5F8D30C2A06E5C2000EEA24 /* XCRemoteSwiftPackageReference "patterns" */ = {
+		B5012E722C9625E200AC4D68 /* XCRemoteSwiftPackageReference "patterns" */ = {
 			isa = XCRemoteSwiftPackageReference;
 			repositoryURL = "https://git.sr.ht/~rbdr/patterns";
 			requirement = {
@@ -856,28 +831,41 @@
 				minimumVersion = 2.0.0;
 			};
 		};
+		B5012E7D2C97315800AC4D68 /* XCRemoteSwiftPackageReference "ConcaveHull" */ = {
+			isa = XCRemoteSwiftPackageReference;
+			repositoryURL = "https://github.com/Syncheo/ConcaveHull";
+			requirement = {
+				branch = master;
+				kind = branch;
+			};
+		};
+		B51A45F32C982FAE00870ED5 /* XCRemoteSwiftPackageReference "Sparkle" */ = {
+			isa = XCRemoteSwiftPackageReference;
+			repositoryURL = "https://github.com/sparkle-project/Sparkle";
+			requirement = {
+				kind = upToNextMajorVersion;
+				minimumVersion = 2.6.4;
+			};
+		};
 /* End XCRemoteSwiftPackageReference section */
 
 /* Begin XCSwiftPackageProductDependency section */
-		B5F8D30D2A06E5C2000EEA24 /* Patterns */ = {
+		B5012E732C9625E200AC4D68 /* Patterns */ = {
 			isa = XCSwiftPackageProductDependency;
-			package = B5F8D30C2A06E5C2000EEA24 /* XCRemoteSwiftPackageReference "patterns" */;
+			package = B5012E722C9625E200AC4D68 /* XCRemoteSwiftPackageReference "patterns" */;
 			productName = Patterns;
 		};
-/* End XCSwiftPackageProductDependency section */
-
-/* Begin XCVersionGroup section */
-		B526257C25C874FA003E73B7 /* Map.xcdatamodeld */ = {
-			isa = XCVersionGroup;
-			children = (
-				B526257D25C874FA003E73B7 /* Map.xcdatamodel */,
-			);
-			currentVersion = B526257D25C874FA003E73B7 /* Map.xcdatamodel */;
-			path = Map.xcdatamodeld;
-			sourceTree = "<group>";
-			versionGroupType = wrapper.xcdatamodel;
+		B5012E7E2C97315800AC4D68 /* ConcaveHull */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = B5012E7D2C97315800AC4D68 /* XCRemoteSwiftPackageReference "ConcaveHull" */;
+			productName = ConcaveHull;
 		};
-/* End XCVersionGroup section */
+		B51A45F42C982FAE00870ED5 /* Sparkle */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = B51A45F32C982FAE00870ED5 /* XCRemoteSwiftPackageReference "Sparkle" */;
+			productName = Sparkle;
+		};
+/* End XCSwiftPackageProductDependency section */
 	};
-	rootObject = B526256625C874F9003E73B7 /* Project object */;
+	rootObject = B54587042C961E9C0067B788 /* Project object */;
 }