Init Gitea

This commit is contained in:
dqj
2025-10-06 21:40:18 +09:00
parent a6ff4707fb
commit 86928b85ed
26 changed files with 1278 additions and 2 deletions

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@
## User settings
xcuserdata/
.DS_Store

View File

@@ -1,2 +0,0 @@
# v-browser

BIN
etc/v-browser.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 KiB

View File

@@ -0,0 +1,629 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 56;
objects = {
/* Begin PBXBuildFile section */
2550BFAA2C9AF8140033B562 /* VectorManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2550BFA92C9AF80A0033B562 /* VectorManager.swift */; };
2550BFAD2C9AFFFA0033B562 /* SimilaritySearchKit in Frameworks */ = {isa = PBXBuildFile; productRef = 2550BFAC2C9AFFFA0033B562 /* SimilaritySearchKit */; };
DE4D74282C8D65BD0072A4A7 /* v_browserApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4D74272C8D65BD0072A4A7 /* v_browserApp.swift */; };
DE4D742A2C8D65BD0072A4A7 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4D74292C8D65BD0072A4A7 /* ContentView.swift */; };
DE4D742C2C8D65BF0072A4A7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DE4D742B2C8D65BF0072A4A7 /* Assets.xcassets */; };
DE4D742F2C8D65BF0072A4A7 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DE4D742E2C8D65BF0072A4A7 /* Preview Assets.xcassets */; };
DE4D743A2C8D65BF0072A4A7 /* v_browserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4D74392C8D65BF0072A4A7 /* v_browserTests.swift */; };
DE4D74442C8D65BF0072A4A7 /* v_browserUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4D74432C8D65BF0072A4A7 /* v_browserUITests.swift */; };
DE4D74462C8D65BF0072A4A7 /* v_browserUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4D74452C8D65BF0072A4A7 /* v_browserUITestsLaunchTests.swift */; };
DE4D74532C8D6F860072A4A7 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4D74522C8D6F860072A4A7 /* Logger.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
DE4D74362C8D65BF0072A4A7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DE4D741C2C8D65BD0072A4A7 /* Project object */;
proxyType = 1;
remoteGlobalIDString = DE4D74232C8D65BD0072A4A7;
remoteInfo = "v-browser";
};
DE4D74402C8D65BF0072A4A7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DE4D741C2C8D65BD0072A4A7 /* Project object */;
proxyType = 1;
remoteGlobalIDString = DE4D74232C8D65BD0072A4A7;
remoteInfo = "v-browser";
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
2550BFA92C9AF80A0033B562 /* VectorManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VectorManager.swift; sourceTree = "<group>"; };
DE4D74242C8D65BD0072A4A7 /* v-browser.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "v-browser.app"; sourceTree = BUILT_PRODUCTS_DIR; };
DE4D74272C8D65BD0072A4A7 /* v_browserApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = v_browserApp.swift; sourceTree = "<group>"; };
DE4D74292C8D65BD0072A4A7 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
DE4D742B2C8D65BF0072A4A7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
DE4D742E2C8D65BF0072A4A7 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
DE4D74302C8D65BF0072A4A7 /* v_browser.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = v_browser.entitlements; sourceTree = "<group>"; };
DE4D74352C8D65BF0072A4A7 /* v-browserTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "v-browserTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
DE4D74392C8D65BF0072A4A7 /* v_browserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = v_browserTests.swift; sourceTree = "<group>"; };
DE4D743F2C8D65BF0072A4A7 /* v-browserUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "v-browserUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
DE4D74432C8D65BF0072A4A7 /* v_browserUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = v_browserUITests.swift; sourceTree = "<group>"; };
DE4D74452C8D65BF0072A4A7 /* v_browserUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = v_browserUITestsLaunchTests.swift; sourceTree = "<group>"; };
DE4D74522C8D6F860072A4A7 /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
DE4D74212C8D65BD0072A4A7 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2550BFAD2C9AFFFA0033B562 /* SimilaritySearchKit in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DE4D74322C8D65BF0072A4A7 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
DE4D743C2C8D65BF0072A4A7 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
DE4D741B2C8D65BD0072A4A7 = {
isa = PBXGroup;
children = (
DE4D74262C8D65BD0072A4A7 /* v-browser */,
DE4D74382C8D65BF0072A4A7 /* v-browserTests */,
DE4D74422C8D65BF0072A4A7 /* v-browserUITests */,
DE4D74252C8D65BD0072A4A7 /* Products */,
);
sourceTree = "<group>";
};
DE4D74252C8D65BD0072A4A7 /* Products */ = {
isa = PBXGroup;
children = (
DE4D74242C8D65BD0072A4A7 /* v-browser.app */,
DE4D74352C8D65BF0072A4A7 /* v-browserTests.xctest */,
DE4D743F2C8D65BF0072A4A7 /* v-browserUITests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
DE4D74262C8D65BD0072A4A7 /* v-browser */ = {
isa = PBXGroup;
children = (
2550BFA92C9AF80A0033B562 /* VectorManager.swift */,
DE4D74522C8D6F860072A4A7 /* Logger.swift */,
DE4D74272C8D65BD0072A4A7 /* v_browserApp.swift */,
DE4D74292C8D65BD0072A4A7 /* ContentView.swift */,
DE4D742B2C8D65BF0072A4A7 /* Assets.xcassets */,
DE4D74302C8D65BF0072A4A7 /* v_browser.entitlements */,
DE4D742D2C8D65BF0072A4A7 /* Preview Content */,
);
path = "v-browser";
sourceTree = "<group>";
};
DE4D742D2C8D65BF0072A4A7 /* Preview Content */ = {
isa = PBXGroup;
children = (
DE4D742E2C8D65BF0072A4A7 /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
DE4D74382C8D65BF0072A4A7 /* v-browserTests */ = {
isa = PBXGroup;
children = (
DE4D74392C8D65BF0072A4A7 /* v_browserTests.swift */,
);
path = "v-browserTests";
sourceTree = "<group>";
};
DE4D74422C8D65BF0072A4A7 /* v-browserUITests */ = {
isa = PBXGroup;
children = (
DE4D74432C8D65BF0072A4A7 /* v_browserUITests.swift */,
DE4D74452C8D65BF0072A4A7 /* v_browserUITestsLaunchTests.swift */,
);
path = "v-browserUITests";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
DE4D74232C8D65BD0072A4A7 /* v-browser */ = {
isa = PBXNativeTarget;
buildConfigurationList = DE4D74492C8D65BF0072A4A7 /* Build configuration list for PBXNativeTarget "v-browser" */;
buildPhases = (
DE4D74202C8D65BD0072A4A7 /* Sources */,
DE4D74212C8D65BD0072A4A7 /* Frameworks */,
DE4D74222C8D65BD0072A4A7 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "v-browser";
packageProductDependencies = (
2550BFAC2C9AFFFA0033B562 /* SimilaritySearchKit */,
);
productName = "v-browser";
productReference = DE4D74242C8D65BD0072A4A7 /* v-browser.app */;
productType = "com.apple.product-type.application";
};
DE4D74342C8D65BF0072A4A7 /* v-browserTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = DE4D744C2C8D65BF0072A4A7 /* Build configuration list for PBXNativeTarget "v-browserTests" */;
buildPhases = (
DE4D74312C8D65BF0072A4A7 /* Sources */,
DE4D74322C8D65BF0072A4A7 /* Frameworks */,
DE4D74332C8D65BF0072A4A7 /* Resources */,
);
buildRules = (
);
dependencies = (
DE4D74372C8D65BF0072A4A7 /* PBXTargetDependency */,
);
name = "v-browserTests";
productName = "v-browserTests";
productReference = DE4D74352C8D65BF0072A4A7 /* v-browserTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
DE4D743E2C8D65BF0072A4A7 /* v-browserUITests */ = {
isa = PBXNativeTarget;
buildConfigurationList = DE4D744F2C8D65BF0072A4A7 /* Build configuration list for PBXNativeTarget "v-browserUITests" */;
buildPhases = (
DE4D743B2C8D65BF0072A4A7 /* Sources */,
DE4D743C2C8D65BF0072A4A7 /* Frameworks */,
DE4D743D2C8D65BF0072A4A7 /* Resources */,
);
buildRules = (
);
dependencies = (
DE4D74412C8D65BF0072A4A7 /* PBXTargetDependency */,
);
name = "v-browserUITests";
productName = "v-browserUITests";
productReference = DE4D743F2C8D65BF0072A4A7 /* v-browserUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
DE4D741C2C8D65BD0072A4A7 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1540;
LastUpgradeCheck = 1600;
TargetAttributes = {
DE4D74232C8D65BD0072A4A7 = {
CreatedOnToolsVersion = 15.4;
};
DE4D74342C8D65BF0072A4A7 = {
CreatedOnToolsVersion = 15.4;
TestTargetID = DE4D74232C8D65BD0072A4A7;
};
DE4D743E2C8D65BF0072A4A7 = {
CreatedOnToolsVersion = 15.4;
TestTargetID = DE4D74232C8D65BD0072A4A7;
};
};
};
buildConfigurationList = DE4D741F2C8D65BD0072A4A7 /* Build configuration list for PBXProject "v-browser" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = DE4D741B2C8D65BD0072A4A7;
packageReferences = (
2550BFAB2C9AFFFA0033B562 /* XCRemoteSwiftPackageReference "similarity-search-kit" */,
);
productRefGroup = DE4D74252C8D65BD0072A4A7 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
DE4D74232C8D65BD0072A4A7 /* v-browser */,
DE4D74342C8D65BF0072A4A7 /* v-browserTests */,
DE4D743E2C8D65BF0072A4A7 /* v-browserUITests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
DE4D74222C8D65BD0072A4A7 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DE4D742F2C8D65BF0072A4A7 /* Preview Assets.xcassets in Resources */,
DE4D742C2C8D65BF0072A4A7 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DE4D74332C8D65BF0072A4A7 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
DE4D743D2C8D65BF0072A4A7 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
DE4D74202C8D65BD0072A4A7 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DE4D742A2C8D65BD0072A4A7 /* ContentView.swift in Sources */,
2550BFAA2C9AF8140033B562 /* VectorManager.swift in Sources */,
DE4D74532C8D6F860072A4A7 /* Logger.swift in Sources */,
DE4D74282C8D65BD0072A4A7 /* v_browserApp.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DE4D74312C8D65BF0072A4A7 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DE4D743A2C8D65BF0072A4A7 /* v_browserTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DE4D743B2C8D65BF0072A4A7 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DE4D74462C8D65BF0072A4A7 /* v_browserUITestsLaunchTests.swift in Sources */,
DE4D74442C8D65BF0072A4A7 /* v_browserUITests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
DE4D74372C8D65BF0072A4A7 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DE4D74232C8D65BD0072A4A7 /* v-browser */;
targetProxy = DE4D74362C8D65BF0072A4A7 /* PBXContainerItemProxy */;
};
DE4D74412C8D65BF0072A4A7 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DE4D74232C8D65BD0072A4A7 /* v-browser */;
targetProxy = DE4D74402C8D65BF0072A4A7 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
DE4D74472C8D65BF0072A4A7 /* 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++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
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;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 14.5;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
DE4D74482C8D65BF0072A4A7 /* 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++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
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;
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;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 14.5;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
};
name = Release;
};
DE4D744A2C8D65BF0072A4A7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = "v-browser/v_browser.entitlements";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "\"v-browser/Preview Content\"";
DEVELOPMENT_TEAM = RQQ6N82NA8;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = "v-browser";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "dqj.v-browser";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
DE4D744B2C8D65BF0072A4A7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = "v-browser/v_browser.entitlements";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "\"v-browser/Preview Content\"";
DEVELOPMENT_TEAM = RQQ6N82NA8;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = "v-browser";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "dqj.v-browser";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
};
name = Release;
};
DE4D744D2C8D65BF0072A4A7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = RQQ6N82NA8;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 14.5;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "dqj.v-browserTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/v-browser.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/v-browser";
};
name = Debug;
};
DE4D744E2C8D65BF0072A4A7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = RQQ6N82NA8;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 14.5;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "dqj.v-browserTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/v-browser.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/v-browser";
};
name = Release;
};
DE4D74502C8D65BF0072A4A7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = RQQ6N82NA8;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "dqj.v-browserUITests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TEST_TARGET_NAME = "v-browser";
};
name = Debug;
};
DE4D74512C8D65BF0072A4A7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = RQQ6N82NA8;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "dqj.v-browserUITests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TEST_TARGET_NAME = "v-browser";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
DE4D741F2C8D65BD0072A4A7 /* Build configuration list for PBXProject "v-browser" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DE4D74472C8D65BF0072A4A7 /* Debug */,
DE4D74482C8D65BF0072A4A7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
DE4D74492C8D65BF0072A4A7 /* Build configuration list for PBXNativeTarget "v-browser" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DE4D744A2C8D65BF0072A4A7 /* Debug */,
DE4D744B2C8D65BF0072A4A7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
DE4D744C2C8D65BF0072A4A7 /* Build configuration list for PBXNativeTarget "v-browserTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DE4D744D2C8D65BF0072A4A7 /* Debug */,
DE4D744E2C8D65BF0072A4A7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
DE4D744F2C8D65BF0072A4A7 /* Build configuration list for PBXNativeTarget "v-browserUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DE4D74502C8D65BF0072A4A7 /* Debug */,
DE4D74512C8D65BF0072A4A7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
2550BFAB2C9AFFFA0033B562 /* XCRemoteSwiftPackageReference "similarity-search-kit" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/ZachNagengast/similarity-search-kit";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.0.15;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
2550BFAC2C9AFFFA0033B562 /* SimilaritySearchKit */ = {
isa = XCSwiftPackageProductDependency;
package = 2550BFAB2C9AFFFA0033B562 /* XCRemoteSwiftPackageReference "similarity-search-kit" */;
productName = SimilaritySearchKit;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = DE4D741C2C8D65BD0072A4A7 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,15 @@
{
"originHash" : "a351174101179e10377155e91d3d1a4a5648760804ce27142488847d1ca85286",
"pins" : [
{
"identity" : "similarity-search-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ZachNagengast/similarity-search-kit.git",
"state" : {
"revision" : "9bec54706c8124bb9b20a3a06d566066a9f55712",
"version" : "0.0.15"
}
}
],
"version" : 3
}

View File

@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@@ -0,0 +1 @@
{"images":[{"size":"128x128","expected-size":"128","filename":"128.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"256x256","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"128x128","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"256x256","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"512x512","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"16","filename":"16.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"64","filename":"64.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"512x512","expected-size":"1024","filename":"1024.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"}]}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

344
v-browser/ContentView.swift Normal file
View File

@@ -0,0 +1,344 @@
//
// ContentView.swift
// v-browser
//
// Created by Du Qingjie on 2024/09/08.
//
import SwiftUI
import WebKit
import AppKit
// WebPage structure
class WebPage: NSObject, ObservableObject, Identifiable, WKNavigationDelegate, WKUIDelegate {
let id = UUID()
var url: String
var title: String
var summary: String
var wkWebView: WKWebView?
var view: ContentView?
@Published var canGoBack = false
@Published var canGoForward = false
@Published var favicon: Image?
@Published var showCloseIcon = false
init(view: ContentView, url: String, title: String, summary: String) {
self.view = view
self.url = url
self.title = title
self.summary = summary
super.init()
self.wkWebView = WebKit.WKWebView()
self.wkWebView?.navigationDelegate = self
self.wkWebView?.uiDelegate = self
if let url = URL(string: url) {
let request = URLRequest(url: url)
self.wkWebView?.load(request)
self.loadFavicon(for: url)
}
}
func loadFavicon(for url: URL) {
let faviconURL = url.appendingPathComponent("favicon.ico")
URLSession.shared.dataTask(with: faviconURL) { data, response, error in
if let data = data, let nsImage = NSImage(data: data) {
DispatchQueue.main.async {
self.favicon = Image(nsImage: nsImage) // Set the fetched favicon
}
} else {
DispatchQueue.main.async {
// Favicon not found, load the app icon instead
self.favicon = Image(nsImage: NSApp.applicationIconImage)
}
}
}.resume()
}
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if let url = navigationAction.request.url {
// Instead of creating a new web view, loaod the URL in the current web view
webView.load(URLRequest(url: url))
canGoBack = true
}
return nil // Return nil to prevent creating a new window
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
DispatchQueue.main.async {
self.canGoBack = webView.canGoBack
self.canGoForward = webView.canGoForward
self.url = webView.url?.absoluteString ?? ""
self.loadFavicon(for: URL(string: self.url)!)
self.objectWillChange.send() // Notify SwiftUI that a change occurred
let cur = self.view?.selectedTab
self.view?.selectedTab = nil
self.view?.selectedTab = cur
}
}
}
struct WebViewWrapper: NSViewRepresentable {
var webView: WKWebView
func makeNSView(context: Context) -> WKWebView {
return webView
}
func updateNSView(_ nsView: WKWebView, context: Context) {
// No need to update, as the WKWebView is already initialized and managed by WebPage
}
}
struct ContentView: View {
@State private var tabs: [WebPage] = [
//WebPage(url: "https://amipro.me", title: "amiPro", summary: "Search the web"),
//WebPage(url: "https://apple.com", title: "Apple", summary: "Apple's official website.")
]
@State public var selectedTab: WebPage? = nil
@State private var browsingHistory: [WebPage] = []
@State private var currentURL: String = ""
@State private var leftPanelWidth: CGFloat = 200
@State private var rightPanelWidth: CGFloat = 200
@State private var lastDragLocationX: CGFloat = -1000000
@State private var curHoverTab: WebPage?
var body: some View {
VStack {
// Address bar and navigation buttons
HStack {
TextField("Enter URL or Ask AI", text: $currentURL)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(maxWidth: .infinity)
.onSubmit {
openTab(urlTxt: currentURL)
}
Button("Go") {
openTab(urlTxt: currentURL)
}
.padding(.leading, 5)
Button("<") {
goBack()
}
.disabled(!(selectedTab?.canGoBack ?? false))
Button(">") {
goForward()
}
.disabled(!(selectedTab?.canGoForward ?? false))
}
.padding()
// Main body with draggable panels
HStack(spacing: 0) {
// Left panel (Tabs)
VStack(spacing: 0) {
ScrollView {
ForEach(tabs) { tab in
HStack{
if tab.showCloseIcon {
Image(systemName: "xmark.circle.fill") // Show close icon on hover
.onTapGesture {
closeTab(tab: tab)
}
.frame(width: 16, height: 16)
} else {
tab.favicon?.resizable()
.frame(width: 16, height: 16) // Show favicon
}
Button(action: { selectedTab = tab }) {
Text(tab.title)
.lineLimit(1)
.truncationMode(.tail)
.padding(6)
.frame(width: leftPanelWidth - 32, alignment: .leading)
.foregroundColor(tab == selectedTab ? Color.primary : Color.secondary) // Text color
.background(
tab == selectedTab ? Color.accentColor.opacity(0.2) : Color.gray.opacity(0.1) // Adaptive background color
)
}.buttonStyle(PlainButtonStyle()).frame(height: 21)
}.onHover { hovering in
if nil != curHoverTab{
curHoverTab?.showCloseIcon = false
}
curHoverTab = tab
tab.showCloseIcon = hovering // Toggle between favicon and close icon
let cur = self.selectedTab
self.selectedTab = nil
self.selectedTab = cur
}
}
}
.frame(width: leftPanelWidth)
.background(Color.gray.opacity(0.1))
.gesture(DragGesture()
.onChanged { value in
let chg = (-1000000 == lastDragLocationX) ? value.location.x-value.startLocation.x: value.location.x-lastDragLocationX
lastDragLocationX = value.location.x
let newWidth = leftPanelWidth + chg //value.translation.width
if newWidth > 30 && newWidth < 600 {
leftPanelWidth = newWidth
}
}
.onEnded { value in
lastDragLocationX = -1000000
}
)
}
// Draggable divider between tabs and WebView
Rectangle()
.frame(width: 1)
.foregroundColor(.gray)
.gesture(DragGesture()
.onChanged { value in
let chg = (-1000000 == lastDragLocationX) ? value.location.x-value.startLocation.x: value.location.x-lastDragLocationX
lastDragLocationX = value.location.x
let newWidth = leftPanelWidth + chg //value.translation.width
if newWidth > 30 && newWidth < 600 {
leftPanelWidth = newWidth
}
}
.onEnded{value in
lastDragLocationX = -1000000
}
)
.onHover { hovering in
if hovering {
NSCursor.resizeLeftRight.set() // Set cursor to left-right resize
} else {
NSCursor.arrow.set() // Reset cursor when not hovering
}
}
// Center panel (WebView or AI result)
VStack {
if let selectedTab = selectedTab, let webView = selectedTab.wkWebView {
WebViewWrapper(webView: webView)
.id(selectedTab.id) // Force SwiftUI to reinitialize when the tab changes
.frame(maxWidth: .infinity, maxHeight: .infinity)
} else {
Text("No tab selected")
.font(.headline)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
Rectangle()
.frame(width: 1)
.foregroundColor(.gray)
.gesture(DragGesture()
.onChanged { value in
let newWidth = rightPanelWidth - value.translation.width
if newWidth > 100 && newWidth < 600 {
rightPanelWidth = newWidth
}
}
)
.onHover { hovering in
if hovering {
NSCursor.resizeLeftRight.set() // Set cursor to left-right resize
} else {
NSCursor.arrow.set() // Reset cursor when not hovering
}
}
// Right panel (Browsing History)
VStack {
ScrollView {
ForEach(browsingHistory) { page in
Text(page.title)
.padding(10)
.frame(maxWidth: .infinity, alignment: .leading)
.background(page == selectedTab ? Color.blue.opacity(0.2) : Color.clear)
.cornerRadius(5)
.onTapGesture {
selectedTab = page
}
}
}
.frame(width: rightPanelWidth)
.background(Color.gray.opacity(0.1))
.gesture(DragGesture()
.onChanged { value in
let newWidth = rightPanelWidth - value.translation.width
if newWidth > 100 && newWidth < 400 {
rightPanelWidth = newWidth
}
}
)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
// Bottom bar with system status
HStack {
Text("System Status: OK")
.font(.footnote)
Spacer()
}
.padding([.leading, .bottom])
.background(Color.gray.opacity(0.1))
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.onAppear {
// Automatically open a tab when the view appears
openTab(urlTxt: "https://amipro.me")
}
}
func isValidURL(_ urlString: String) -> Bool {
if let url = URL(string: urlString) {
// Check if the URL has a valid scheme (http, https, etc.)
return ((url.scheme) != nil)
}
return false
}
func openTab(urlTxt: String){
if isValidURL(urlTxt){
createTab(url: URL(string: urlTxt)?.absoluteString ?? "", title: "Loading...", summary: "Loading...")
}else if isValidURL("https://"+urlTxt){
createTab(url: URL(string: "https://"+urlTxt)?.absoluteString ?? "", title: "Loading...", summary: "Loading...")
}else{
createTab(url: "https://www.google.com/search?q="+urlTxt.replacingOccurrences(of: " ", with: "+"), title: "Loading...", summary: "Loading...")
//try to ask AI
}
}
func createTab(url: String, title: String, summary: String) {
let newPage = WebPage(view: self, url: url, title: title, summary: summary)
tabs.append(newPage)
selectedTab = newPage
}
func closeTab(tab: WebPage) {
if let index = tabs.firstIndex(where: { $0.id == tab.id }) {
tabs.remove(at: index)
if selectedTab?.id == tab.id {
selectedTab = tabs.last
}
}
}
func goBack() {
if let selectedTab = selectedTab, selectedTab.canGoBack == true {
selectedTab.wkWebView?.goBack()
selectedTab.canGoForward = true
}
}
func goForward() {
if let selectedTab = selectedTab, selectedTab.canGoForward == true {
selectedTab.wkWebView?.goForward()
selectedTab.canGoBack = true
}
}
}
/*Preview {
ContentView()
}*/

28
v-browser/Logger.swift Normal file
View File

@@ -0,0 +1,28 @@
//
// Logger.swift
// vectorsearch
//
// Created by Du Qingjie on 2024/08/31.
//
import os
import Foundation
class Logger {
static let shared = Logger()
// Correctly initialize with subsystem and category
private let logger = os.Logger(subsystem: Bundle.main.bundleIdentifier ?? "dqj.vectorsearch", category: "VectorSearch")
func info(_ message: String) {
logger.log("\(message, privacy: .public)")
}
func err(_ message: String) {
logger.error("\(message, privacy: .public)")
}
func debug(_ message: String) {
logger.debug("\(message, privacy: .public)")
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,84 @@
//
// AIRunner.swift
// v-browser
//
// Created by dqj on 2024/09/18.
//
import SimilaritySearchKit
import Foundation
class VectorManager: ObservableObject {
static let shared = VectorManager()
private var similarityIndex: SimilarityIndex?
init() {
Task {
await load()
}
}
func load() async {
similarityIndex = await SimilarityIndex(
model: NativeEmbeddings(),
metric: CosineSimilarity()
)
if let data = UserDefaults.standard.data(forKey: "vector_db") {
let items = try? JSONDecoder().decode([SimilarityIndex.IndexItem].self, from: data)
similarityIndex?.indexItems = items ?? []
}else{
similarityIndex?.indexItems = []
}
}
func setFileItem(path: String, text: String, modify_time: Int) async{
guard let index = similarityIndex else { return }
let curItem = index.getItem(id: path)
if(curItem != nil && Int(curItem?.metadata["mt"] ?? String(Int.max)) ?? Int.max > Int(modify_time)){
index.updateItem(id: path, text: text, embedding: nil, metadata: ["mt": String(modify_time)] )
if let encoded = try? JSONEncoder().encode(index.indexItems) {
UserDefaults.standard.set(encoded, forKey: "vector_db")
}
}else if(curItem == nil){
await index.addItem(id: path, text: text, metadata: ["mt": String(modify_time)])
if let encoded = try? JSONEncoder().encode(index.indexItems) {
UserDefaults.standard.set(encoded, forKey: "vector_db")
}
}
}
func search(query: String) async -> [SimilarityIndex.SearchResult]{
guard let index = similarityIndex else { return []}
let results = await index.search(query, top: 100)
return results
}
func deleteFileItem(path: String){
guard let index = similarityIndex else { return }
index.removeItem(id: path)
UserDefaults.standard.setValue(index.indexItems, forKey: "vector_db")
}
func clear() {
guard let index = similarityIndex else { return }
index.removeAll()
UserDefaults.standard.setValue(index.indexItems, forKey: "vector_db")
}
func getFileItem(id: String) -> SimilarityIndex.IndexItem?{
guard let index = similarityIndex else { return nil }
return index.getItem(id: id)
}
}
class SummaryBot:ObservableObject{
}

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,17 @@
//
// v_browserApp.swift
// v-browser
//
// Created by Du Qingjie on 2024/09/08.
//
import SwiftUI
@main
struct v_browserApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

View File

@@ -0,0 +1,36 @@
//
// v_browserTests.swift
// v-browserTests
//
// Created by Du Qingjie on 2024/09/08.
//
import XCTest
@testable import v_browser
final class v_browserTests: XCTestCase {
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
// Any test you write for XCTest can be annotated as throws and async.
// Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
// Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
}
func testPerformanceExample() throws {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}

View File

@@ -0,0 +1,41 @@
//
// v_browserUITests.swift
// v-browserUITests
//
// Created by Du Qingjie on 2024/09/08.
//
import XCTest
final class v_browserUITests: XCTestCase {
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
// In UI tests its important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() throws {
// UI tests must launch the application that they test.
let app = XCUIApplication()
app.launch()
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testLaunchPerformance() throws {
if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
// This measures how long it takes to launch your application.
measure(metrics: [XCTApplicationLaunchMetric()]) {
XCUIApplication().launch()
}
}
}
}

View File

@@ -0,0 +1,32 @@
//
// v_browserUITestsLaunchTests.swift
// v-browserUITests
//
// Created by Du Qingjie on 2024/09/08.
//
import XCTest
final class v_browserUITestsLaunchTests: XCTestCase {
override class var runsForEachTargetApplicationUIConfiguration: Bool {
true
}
override func setUpWithError() throws {
continueAfterFailure = false
}
func testLaunch() throws {
let app = XCUIApplication()
app.launch()
// Insert steps here to perform after app launch but before taking a screenshot,
// such as logging into a test account or navigating somewhere in the app
let attachment = XCTAttachment(screenshot: app.screenshot())
attachment.name = "Launch Screen"
attachment.lifetime = .keepAlways
add(attachment)
}
}