From d7a00a5a63cb3c10509f6ee6352c864e867f203f Mon Sep 17 00:00:00 2001 From: kigawa Date: Sun, 24 Mar 2024 00:02:56 +0900 Subject: [PATCH] feature/marge-mcsm (#25) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Release/3.0.0 (#24) * fix * Feature/migrate gradle (#23) * change to gradle * change: action * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * .java を .kt に名前変更 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * release: 3.0.0 * .java を .kt に名前変更 * logger * .java を .kt に名前変更 * fix: compile err * fix: compile err * fix: compile warn * add test * add test * add test * add test --- .github/workflows/deploy_maven_central.yml | 19 +- .github/workflows/test_on_push.yml | 29 + .gitignore | 3 +- README.md | 8 +- api/build.gradle.kts | 3 +- .../kotlin/net/kigawa/kutil/kutil/api/Func.kt | 10 + .../net/kigawa/kutil/kutil/api/Kutil.java | 9 - .../net/kigawa/kutil/kutil/api/Kutil.kt | 56 + .../kigawa/kutil/kutil/api/KutilArray.java | 39 - .../net/kigawa/kutil/kutil/api/KutilArray.kt | 7 + .../net/kigawa/kutil/kutil/api/KutilFile.java | 45 - .../net/kigawa/kutil/kutil/api/KutilFile.kt | 9 + .../kigawa/kutil/kutil/api/KutilPlatform.kt | 7 + .../net/kigawa/kutil/kutil/api/Option.kt | 10 + .../net/kigawa/kutil/kutil/api/OptionStore.kt | 16 + .../net/kigawa/kutil/kutil/api/Paths.kt | 11 + .../kutil/kutil/api/PlatFormInstance.kt | 6 + .../kigawa/kutil/kutil/api/SignalHandler.kt | 6 + .../net/kigawa/kutil/kutil/api/Version.kt | 45 + .../kutil/api/concurrent/AsyncExecutor.kt | 106 - .../kigawa/kutil/kutil/api/concurrent/Box.kt | 14 - .../api/concurrent/CoroutineException.kt | 7 + .../concurrent/CoroutineLaunchException.kt | 8 + .../kutil/kutil/api/concurrent/Coroutines.kt | 80 + .../kutil/kutil/api/concurrent/ExecuteTask.kt | 58 - .../kutil/kutil/api/concurrent/PCoroutines.kt | 7 + .../kutil/kutil/api/concurrent/ResultTask.kt | 11 - .../kutil/kutil/api/concurrent/SyncQueue.kt | 23 + .../kutil/kutil/api/concurrent/SyncVal.kt | 8 + .../kigawa/kutil/kutil/api/concurrent/Task.kt | 9 - .../kigawa/kutil/kutil/api/concurrent/Var.kt | 32 - .../kutil/kutil/api/debug/KutilDebug.kt | 32 - .../kutil/api/dependency/Dependencies.kt | 8 +- .../kigawa/kutil/kutil/api/diff/KutilDiff.kt | 5 +- .../kutil/kutil/api/err/ErrorHandler.kt | 16 - .../kigawa/kutil/kutil/api/err/KutilErr.kt | 1 - .../kutil/kutil/api/err/StreamErrorHandler.kt | 16 - .../kutil/kutil/api/file/FileExtension.java | 54 - .../kutil/kutil/api/file/FileExtension.kt | 46 + .../kutil/api/function/ThrowRunnable.java | 10 - .../kutil/api/function/ThrowSupplier.java | 11 - .../kutil/api/function/ThrowTriConsumer.java | 11 - .../kutil/kutil/api/function/TriConsumer.java | 10 - .../kutil/api/interfaces/LoggerInterface.java | 65 - .../kutil/kutil/api/io/ChannelReaderIo.kt | 18 + .../kutil/kutil/api/io/ChannelWriterIo.kt | 11 + .../kigawa/kutil/kutil/api/io/DefaultIo.kt | 7 + .../kutil/kutil/api/io/FunctionWriterIo.kt | 9 + .../net/kigawa/kutil/kutil/api/io/Io.kt | 3 + .../kigawa/kutil/kutil/api/io/IoException.kt | 4 + .../kigawa/kutil/kutil/api/io/KuCloseable.kt | 6 + .../net/kigawa/kutil/kutil/api/io/KutilIo.kt | 18 + .../kutil/api/io/NotDirectoryException.kt | 3 + .../net/kigawa/kutil/kutil/api/io/ReaderIo.kt | 6 + .../kutil/kutil/api/io/SuspendCloseable.kt | 5 + .../net/kigawa/kutil/kutil/api/io/WriterIo.kt | 5 + .../kutil/kutil/api/io/fs/KuDirectory.kt | 6 + .../kigawa/kutil/kutil/api/io/fs/KuFile.kt | 4 + .../kigawa/kutil/kutil/api/io/fs/KuPath.kt | 20 + .../kutil/kutil/api/list/ConcurrentMap.kt | 74 - .../kutil/kutil/api/list/ConcurrentSet.kt | 75 - .../net/kigawa/kutil/kutil/api/list/Func.kt | 18 + .../kutil/kutil/api/list/GenerateMap.java | 177 -- .../kutil/kutil/api/list/KCollectionStream.kt | 6 - .../net/kigawa/kutil/kutil/api/list/KList.kt | 66 - .../kigawa/kutil/kutil/api/list/KListImpl.kt | 82 - .../kutil/kutil/api/list/KListStream.kt | 73 - .../kigawa/kutil/kutil/api/list/KutilList.kt | 15 - .../kutil/api/locale/DirLocalerResource.kt | 51 - .../kutil/kutil/api/locale/LocaleData.kt | 23 - .../kigawa/kutil/kutil/api/locale/Localer.kt | 22 - .../kutil/kutil/api/locale/LocalerResource.kt | 10 - .../kutil/api/locale/LocalerResources.kt | 27 - .../kigawa/kutil/kutil/api/logger/KuLogger.kt | 15 + .../kigawa/kutil/kutil/api/logger/LogLevel.kt | 5 + .../kutil/kutil/api/logger/LoggerHandler.kt | 8 + .../kutil/kutil/api/logger/LoggerRecord.kt | 7 + .../kutil/kutil/api/logger/PKuLogger.kt | 6 + .../formatter/DefaultLoggerFormatter.kt | 8 + .../api/logger/formatter/LoggerFormatter.kt | 7 + .../kutil/kutil/api/manager/ManagedEntry.kt | 14 - .../kigawa/kutil/kutil/api/manager/Manager.kt | 19 - .../kutil/kutil/api/manager/RemoveAble.kt | 47 - .../api/manager/RemovedObjectException.kt | 4 - .../kutil/kutil/api/net/SocketClient.kt | 14 + .../kutil/kutil/api/net/SocketConnection.kt | 9 + .../kutil/kutil/api/net/SocketServer.kt | 15 + .../net/kigawa/kutil/kutil/api/net/Url.kt | 10 + .../net/kigawa/kutil/kutil/api/os/KutilOS.kt | 4 + .../net/kigawa/kutil/kutil/api/os/OSType.kt | 9 + .../kutil/kutil/api/process/KuProcess.kt | 12 + .../kutil/api/process/KuProcessBuilder.kt | 9 + .../kutil/api/reflection/KutilReflect.kt | 51 +- .../kigawa/kutil/kutil/api/str/KutilString.kt | 15 + .../kigawa/kutil/kutil/api/str/StringColor.kt | 99 + .../objectformatter/DefaultObjFormatter.kt | 16 + .../str/objectformatter/ObjectFormatter.kt | 5 + .../kutil/kutil/api/string/KutilString.java | 127 -- .../kutil/kutil/api/string/StringColor.java | 105 - .../kutil/api/validator/AbstractValidator.kt | 18 + .../kutil/api/validator/EmptyValidator.kt | 8 + .../kutil/kutil/api/validator/Validator.kt | 6 + .../api/validator/str/AbstractStrValidator.kt | 8 + .../kutil/api/validator/str/StrValidator.kt | 11 + .../kigawa/kutil/kutil/api/KutilArray.js.kt | 7 + .../kigawa/kutil/kutil/api/KutilFile.js.kt | 9 + .../kutil/kutil/api/KutilPlatform.js.kt | 12 + .../net/kigawa/kutil/kutil/api/Paths.js.kt | 13 + .../kutil/kutil/api/SignalHandler.js.kt | 7 + .../kutil/api/concurrent/PCoroutines.js.kt | 10 + .../kigawa/kutil/kutil/api/io/DefaultIo.js.kt | 7 + .../kutil/kutil/api/io/IoException.js.kt | 4 + .../kutil/kutil/api/io/fs/KuDirectory.js.kt | 10 + .../kigawa/kutil/kutil/api/io/fs/KuFile.js.kt | 4 + .../kigawa/kutil/kutil/api/io/fs/KuPath.js.kt | 56 + .../api/logger/JsDefaultLoggerHandler.kt | 21 + .../kutil/kutil/api/logger/LogRecord.js.kt | 7 + .../kutil/kutil/api/logger/PKuLogger.js.kt | 6 + .../formatter/DefaultLoggerFormatter.js.kt | 10 + .../kutil/kutil/api/net/SocketClient.js.kt | 20 + .../kutil/api/net/SocketConnection.js.kt | 19 + .../kutil/kutil/api/net/SocketServer.js.kt | 21 + .../net/kigawa/kutil/kutil/api/net/Url.js.kt | 9 + .../kigawa/kutil/kutil/api/os/KutilOS.js.kt | 4 + .../kutil/api/process/KuProcessBuilder.js.kt | 16 + .../kutil/api/reflection/KutilReflect.js.kt | 4 + .../kutil/kutil/api/str/KutilString.js.kt | 19 + .../kigawa/kutil/kutil/api/KutilArray.jvm.kt | 28 + .../kigawa/kutil/kutil/api/KutilFile.jvm.kt | 37 + .../kutil/kutil/api/KutilPlatform.jvm.kt | 6 + .../net/kigawa/kutil/kutil/api/Paths.jvm.kt | 12 + .../kutil/kutil/api/SignalHandler.jvm.kt | 12 + .../kutil/api/concurrent/PCoroutines.jvm.kt | 9 + .../kutil/kutil/api/io/DefaultIo.jvm.kt | 24 + .../kutil/kutil/api/io/IoException.jvm.kt | 8 + .../net/kigawa/kutil/kutil/api/io/IoFunc.kt | 18 + .../kutil/kutil/api/io/ReaderStreamIo.kt | 32 + .../kutil/kutil/api/io/WriterStreamIo.kt | 36 + .../kutil/kutil/api/io/fs/KuDirectory.jvm.kt | 18 + .../kutil/kutil/api/io/fs/KuFile.jvm.kt | 12 + .../kigawa/kutil/kutil/api/io/fs/Path.jvm.kt | 56 + .../net/kigawa/kutil/kutil/api/logger/Func.kt | 12 + .../api/logger/JvmDefaultLoggerHandler.kt | 30 + .../kutil/api/logger/KFileFormatter.java | 24 + .../kutil/kutil/api/logger/LogRecord.jvm.kt | 13 + .../kutil/kutil/api/logger/PKuLogger.jvm.kt | 6 + .../formatter/DefaultLoggerFormatter.jvm.kt | 17 + .../logger/formatter/LoggerFormatterBridge.kt | 17 + .../kutil/kutil/api/net/SocketClient.jvm.kt | 27 + .../kutil/api/net/SocketConnection.jvm.kt | 84 + .../kutil/kutil/api/net/SocketServer.kt | 65 + .../net/kigawa/kutil/kutil/api/net/Url.kt | 29 + .../kigawa/kutil/kutil/api/os/KutilOS.jvm.kt | 72 + .../kutil/kutil/api/process/JvmProcess.kt | 54 + .../kutil/api/process/KuProcessBuilder.jvm.kt | 24 + .../kutil/api/reflection/KutilReflect.jvm.kt | 54 + .../kutil/kutil/api/str/KutilString.jvm.kt | 116 + .../kutil/api/reflection/KutilReflectTest.kt | 10 + buildSrc/build.gradle.kts | 2 +- ...wa.kutil.kutil.java-conventions.gradle.kts | 75 +- gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63375 bytes kotlin-js-store/yarn.lock | 1995 +++++++++++++++++ kutil/build.gradle.kts | 63 + settings.gradle.kts | 1 + 164 files changed, 4233 insertions(+), 1681 deletions(-) create mode 100644 .github/workflows/test_on_push.yml create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Func.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Kutil.java create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Kutil.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.java create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.java create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilPlatform.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Option.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/OptionStore.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Paths.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/PlatFormInstance.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/SignalHandler.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Version.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/AsyncExecutor.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Box.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/CoroutineException.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/CoroutineLaunchException.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Coroutines.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/ExecuteTask.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/PCoroutines.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/ResultTask.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/SyncQueue.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/SyncVal.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Task.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Var.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/debug/KutilDebug.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/err/ErrorHandler.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/err/KutilErr.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/err/StreamErrorHandler.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/file/FileExtension.java create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/file/FileExtension.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/ThrowRunnable.java delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/ThrowSupplier.java delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/ThrowTriConsumer.java delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/TriConsumer.java delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/interfaces/LoggerInterface.java create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/ChannelReaderIo.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/ChannelWriterIo.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/DefaultIo.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/FunctionWriterIo.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/Io.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/IoException.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/KuCloseable.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/KutilIo.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/NotDirectoryException.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/ReaderIo.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/SuspendCloseable.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/WriterIo.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuDirectory.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuFile.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuPath.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/ConcurrentMap.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/ConcurrentSet.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/Func.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/GenerateMap.java delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KCollectionStream.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KList.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KListImpl.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KListStream.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/DirLocalerResource.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/LocaleData.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/Localer.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/LocalerResource.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/LocalerResources.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/KuLogger.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/LogLevel.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/LoggerHandler.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/LoggerRecord.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/PKuLogger.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/DefaultLoggerFormatter.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/LoggerFormatter.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/ManagedEntry.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/Manager.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/RemoveAble.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/RemovedObjectException.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketClient.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketConnection.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketServer.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/Url.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/os/KutilOS.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/os/OSType.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcess.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcessBuilder.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/KutilString.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/StringColor.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/objectformatter/DefaultObjFormatter.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/objectformatter/ObjectFormatter.kt delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/string/KutilString.java delete mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/string/StringColor.java create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/AbstractValidator.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/EmptyValidator.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/Validator.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/str/AbstractStrValidator.kt create mode 100644 api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/str/StrValidator.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/KutilPlatform.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/Paths.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/SignalHandler.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/PCoroutines.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/DefaultIo.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/IoException.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuDirectory.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuFile.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuPath.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/JsDefaultLoggerHandler.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/LogRecord.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/PKuLogger.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/DefaultLoggerFormatter.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketClient.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketConnection.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketServer.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/Url.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/os/KutilOS.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcessBuilder.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflect.js.kt create mode 100644 api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/str/KutilString.js.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/KutilPlatform.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/Paths.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/SignalHandler.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/PCoroutines.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/DefaultIo.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/IoException.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/IoFunc.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/ReaderStreamIo.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/WriterStreamIo.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuDirectory.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuFile.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/Path.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/Func.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/JvmDefaultLoggerHandler.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/KFileFormatter.java create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/LogRecord.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/PKuLogger.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/DefaultLoggerFormatter.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/LoggerFormatterBridge.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketClient.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketConnection.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketServer.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/Url.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/os/KutilOS.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/process/JvmProcess.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcessBuilder.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflect.jvm.kt create mode 100644 api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/str/KutilString.jvm.kt create mode 100644 api/src/jvmTest/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflectTest.kt create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 kotlin-js-store/yarn.lock create mode 100644 kutil/build.gradle.kts diff --git a/.github/workflows/deploy_maven_central.yml b/.github/workflows/deploy_maven_central.yml index 5d780c4..dbd1030 100644 --- a/.github/workflows/deploy_maven_central.yml +++ b/.github/workflows/deploy_maven_central.yml @@ -16,17 +16,26 @@ jobs: - name: Set up Java uses: actions/setup-java@v3 with: - java-version: '11' + java-version: '17' distribution: 'temurin' + - name: Make gradlew executable + run: chmod +x ./gradlew - name: Validate Gradle wrapper - uses: gradle/wrapper-validation-action@ccb4328a959376b642e027874838f60f8e596de3 + uses: gradle/wrapper-validation-action@v1 + - name: Restore gradle.properties + env: + GPG_PRIVATE_KEY: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} + GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} + run: | + echo "$GPG_PRIVATE_KEY" | base64 -d > kutil/sec.pem + echo "signing.keyId=ED76201E" >> ./gradle.properties + echo "signing.password=${GPG_PASSPHRASE}" >> ./gradle.properties + echo "signing.secretKeyRingFile=sec.pem" >> ./gradle.properties - name: Publish package - uses: gradle/gradle-build-action@749f47bda3e44aa060e82d7b3ef7e40d953bd629 + uses: gradle/gradle-build-action@v2 with: arguments: publish env: MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }} -# gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} -# MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} #### diff --git a/.github/workflows/test_on_push.yml b/.github/workflows/test_on_push.yml new file mode 100644 index 0000000..bdeea3a --- /dev/null +++ b/.github/workflows/test_on_push.yml @@ -0,0 +1,29 @@ +name: run test + +on: + push: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up Java + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + - name: Make gradlew executable + run: chmod +x ./gradlew + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v1 + - name: run test + uses: gradle/gradle-build-action@v2 + with: + arguments: allTests + env: + MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }} +#### diff --git a/.gitignore b/.gitignore index d5121c1..d2296a7 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,6 @@ out/ *.ctxt # Package Files # -*.jar *.war *.nar *.ear @@ -127,4 +126,4 @@ run/ /.idea/ /log1/ /log/ -/api/build/ +/*/build/ diff --git a/README.md b/README.md index ade46bd..2ad836f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## About -* javaのutility +* kotlinのutility ## Use @@ -11,7 +11,7 @@ net.kigawa.kutil kutil - 2.2.1 + 3.0.0 ...... @@ -19,12 +19,12 @@ ## Requirement -* java +* kotlin ## Author * kigawa - * kigawa.8390@gmail.com + * contact@kigawa.net # Making diff --git a/api/build.gradle.kts b/api/build.gradle.kts index f27b0ef..c4d5f94 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -3,4 +3,5 @@ plugins { } dependencies { -} + commonMainImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Func.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Func.kt new file mode 100644 index 0000000..1602f37 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Func.kt @@ -0,0 +1,10 @@ +package net.kigawa.kutil.kutil.api + +import kotlinx.coroutines.channels.Channel + + +suspend inline fun Channel.forEach(func: (T) -> Unit) { + for (item in this) { + func(item) + } +} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Kutil.java b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Kutil.java deleted file mode 100644 index c14441b..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Kutil.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.kigawa.kutil.kutil.api; - -/** - * utilities for java - */ -@SuppressWarnings("unused") -public class Kutil { - -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Kutil.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Kutil.kt new file mode 100644 index 0000000..898ea92 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Kutil.kt @@ -0,0 +1,56 @@ +@file:Suppress("unused") + +package net.kigawa.kutil.kutil.api + +import net.kigawa.kutil.kutil.api.io.KuCloseable +import net.kigawa.kutil.kutil.api.io.SuspendCloseable +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + +@Suppress("unused") +object Kutil { + fun fillStr(src: String, size: Int, fillChar: Char = ' '): String { + val sb = StringBuilder(size) + for (i in 0 until size) { + sb.append(src.getOrNull(i) ?: fillChar) + } + return sb.toString() + } + +} + +@OptIn(ExperimentalContracts::class) +inline fun T.tryCatch( + block: (self: T) -> R, +): R { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + try { + return block(this) + } catch (e: Throwable) { + throw e + } finally { + close() + } +} + +@OptIn(ExperimentalContracts::class) +suspend inline fun T.tryCatchSuspend( + block: (self: T) -> R, +): R { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + try { + return block(this) + } catch (e: Throwable) { + throw e + } finally { + when (this) { + is SuspendCloseable -> suspendClose() + else -> close() + } + } +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.java b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.java deleted file mode 100644 index 812dc88..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.kigawa.kutil.kutil.api; - -import java.util.*; -import java.util.stream.*; - -/** - * utilities about array - */ -@SuppressWarnings("unused") -public class KutilArray -{ - - /** - * test obj contain in array - * - * @param array array to test - * @param obj obj to test - * @param source class type - * @param test class type - * @return return true when contain - */ - public static boolean contain(S[] array, T obj) - { - return Arrays.asList(array).contains(obj); - } - - /** - * creat set from array - * - * @param ts base array - * @param class type - * @return created set - */ - public static Set toSet(T[] ts) - { - return Arrays.stream(ts).collect(Collectors.toSet()); - } - -} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.kt new file mode 100644 index 0000000..2dad4e0 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.kt @@ -0,0 +1,7 @@ +package net.kigawa.kutil.kutil.api + +/** + * utilities about array + */ +@Suppress("unused", "EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect object KutilArray diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.java b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.java deleted file mode 100644 index c540950..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.kigawa.kutil.kutil.api; - -import java.io.File; -import java.nio.file.Paths; - -/** - * utilities about file - */ -@SuppressWarnings("unused") -public class KutilFile { - - /** - * get child file from current - * - * @param path child file names - * @return child file - */ - public static File getRelativeFile(String... path) { - return getFile(Paths.get("").toAbsolutePath().toFile(), path); - } - - /** - * get child file - * - * @param parent parent file - * @param path child file names - * @return child file - */ - public static File getFile(File parent, String... path) { - File file = parent; - for (String name : path) { - file = new File(file, name); - } - return file; - } - - /** - * get current file as absolute - * - * @return current dir - */ - public static File getAbsolutFile() { - return Paths.get("").toAbsolutePath().toFile(); - } -} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.kt new file mode 100644 index 0000000..620700e --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.kt @@ -0,0 +1,9 @@ +package net.kigawa.kutil.kutil.api + +/** + * utilities about file + */ +@Suppress("unused", "EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect object KutilFile { + +} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilPlatform.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilPlatform.kt new file mode 100644 index 0000000..424190c --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/KutilPlatform.kt @@ -0,0 +1,7 @@ +package net.kigawa.kutil.kutil.api + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect object KutilPlatform { + fun getSystemProperty(name: String): String + fun getEnv(name: String): String? +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Option.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Option.kt new file mode 100644 index 0000000..1820708 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Option.kt @@ -0,0 +1,10 @@ +package net.kigawa.kutil.kutil.api + + @Suppress("unused") +interface Option { + val name: String + val optName: String + val shortName: String? + val description: String + val defaultValue: String +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/OptionStore.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/OptionStore.kt new file mode 100644 index 0000000..5fee200 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/OptionStore.kt @@ -0,0 +1,16 @@ +package net.kigawa.kutil.kutil.api + +@Suppress("unused") +class OptionStore { + private val options = mutableMapOf() + + fun add(option: Option, value: String) { + options[option] = value + } + + + fun get(option: Option): String = options[option] + ?: KutilPlatform.getEnv(option.name) + ?: option.defaultValue + +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Paths.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Paths.kt new file mode 100644 index 0000000..c314e97 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Paths.kt @@ -0,0 +1,11 @@ +package net.kigawa.kutil.kutil.api + +import net.kigawa.kutil.kutil.api.io.fs.KuPath + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect enum class Paths { + JAVA + ; + + val path: KuPath +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/PlatFormInstance.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/PlatFormInstance.kt new file mode 100644 index 0000000..c5adfb1 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/PlatFormInstance.kt @@ -0,0 +1,6 @@ +package net.kigawa.kutil.kutil.api + +@Suppress("unused") +data class PlatFormInstance( + val exitProcess: (Int) -> Nothing, +) \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/SignalHandler.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/SignalHandler.kt new file mode 100644 index 0000000..4f235d3 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/SignalHandler.kt @@ -0,0 +1,6 @@ +package net.kigawa.kutil.kutil.api + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect object SignalHandler { + fun shutdownHook(hook: () -> Unit) +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Version.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Version.kt new file mode 100644 index 0000000..dd04fb9 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/Version.kt @@ -0,0 +1,45 @@ +package net.kigawa.kutil.kutil.api + +@Suppress("unused") +class Version( + private val strVersion: String, +) { + fun isAfter(before: Version): Boolean { + val ownIntVer = intVersion() + before.intVersion().forEachIndexed { index, value -> + val own = ownIntVer.getOrNull(index) ?: return false + if (own == value) return@forEachIndexed + return own > value + } + return false + } + + fun intVersion(): List { + val result = mutableListOf() + var section = "" + strVersion.forEach { + if (it.code in 48..57) { + section += it + return@forEach + } + if (section == "") return@forEach + result.add(section.toInt()) + section = "" + } + if (section != "") result.add(section.toInt()) + return result + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as Version + + return strVersion == other.strVersion + } + + override fun hashCode(): Int { + return strVersion.hashCode() + } +} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/AsyncExecutor.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/AsyncExecutor.kt deleted file mode 100644 index e29a971..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/AsyncExecutor.kt +++ /dev/null @@ -1,106 +0,0 @@ -@file:Suppress("unused") - -package net.kigawa.kutil.kutil.api.concurrent - -import net.kigawa.kutil.kutil.api.err.ErrorHandler -import net.kigawa.kutil.kutil.api.err.StreamErrorHandler -import net.kigawa.kutil.kutil.api.list.KList -import net.kigawa.kutil.kutil.api.manager.RemoveAble -import java.util.* -import java.util.concurrent.* - -class AsyncExecutor( - var executor: ExecutorService = Executors.newCachedThreadPool(), - var timeOutMilli: Long = 1000, - var errorHandler: ErrorHandler = StreamErrorHandler(Throwable::class.java), -): AutoCloseable, RemoveAble(null) { - private val tasks = KList.create>() - private val queues = mutableMapOf>>() - - fun submit(task: Runnable, result: T): ResultTask { - return executeFuture(FutureTask(task, result)) - } - - fun submit(task: Runnable): Task { - return submit(task, null) - } - - fun isTerminated(): Boolean { - return executor.isTerminated - } - - fun awaitTermination(timeout: Long, unit: TimeUnit): Boolean { - return executor.awaitTermination(timeout, unit) - } - - fun awaitTermination(): Boolean { - return awaitTermination(timeOutMilli, TimeUnit.MILLISECONDS) - } - - fun submit(callable: Callable): ResultTask { - return executeFuture(FutureTask(callable)) - } - - fun waitTask() { - tasks.forEach(ExecuteTask<*>::waitTask) - } - - fun execute(runnable: Runnable): Task { - return submit(runnable) - } - - private fun executeFuture(futureTask: FutureTask): ExecuteTask { - return ExecuteTask(this, futureTask) - .apply(tasks::add) - .apply {registerRemoveTask {tasks.remove(this)}} - .apply(executor::execute) - } - - fun submitQueue(lock: Any, callable: Callable): ResultTask { - val executeTask = ExecuteTask(this, FutureTask(callable)) - - synchronized(queues) { - var queue = queues[lock] - if (queue == null) { - queue = LinkedList() - queue.add(executeTask) - queues[lock] = queue - runQueue(lock, queue) - } else queue.add(executeTask) - } - - return executeTask - } - - private fun runQueue(key: Any, queue: Queue>) { - execute { - while (true) { - val task = synchronized(queues) { - val futureTask = queue.poll() - if (futureTask == null) { - queues.remove(key) - return@execute - } - futureTask - } - task.run() - try { - task.get() - } catch (e: ExecutionException) { - e.cause?.apply(errorHandler::catch) ?: errorHandler.catch(e) - } - } - } - } - - override fun close() { - if (removed.useSelf { - if (it) return@useSelf true - set(true) - false - }) return - - executor.shutdown() - awaitTermination() - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Box.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Box.kt deleted file mode 100644 index df19d7e..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Box.kt +++ /dev/null @@ -1,14 +0,0 @@ -@file:Suppress("unused") - -package net.kigawa.kutil.kutil.api.concurrent - -class Box(item: T, private val clone: (T)->T): Var(item) { - - override fun get(): T { - return useValue(clone) - } - - fun clone(): Box { - return Box(get(), clone) - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/CoroutineException.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/CoroutineException.kt new file mode 100644 index 0000000..bb08809 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/CoroutineException.kt @@ -0,0 +1,7 @@ +package net.kigawa.kutil.kutil.api.concurrent + +import kotlinx.coroutines.CoroutineScope + +open class CoroutineException(message: String?, coroutineContext: CoroutineScope, cause: Throwable?) : + RuntimeException("$message | context: $coroutineContext", cause) { +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/CoroutineLaunchException.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/CoroutineLaunchException.kt new file mode 100644 index 0000000..95d6307 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/CoroutineLaunchException.kt @@ -0,0 +1,8 @@ +package net.kigawa.kutil.kutil.api.concurrent + +import kotlinx.coroutines.CoroutineScope +import net.kigawa.kutil.kutil.api.concurrent.CoroutineException + +class CoroutineLaunchException(message: String?, coroutineContext: CoroutineScope, cause: Throwable?) : + CoroutineException(message, coroutineContext, cause) { +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Coroutines.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Coroutines.kt new file mode 100644 index 0000000..be9ae93 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Coroutines.kt @@ -0,0 +1,80 @@ +@file:Suppress("unused", "MemberVisibilityCanBePrivate") + +package net.kigawa.kutil.kutil.api.concurrent + +import kotlinx.coroutines.* +import net.kigawa.kutil.kutil.api.logger.KuLogger +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext + +class Coroutines( + private val logger: KuLogger = KuLogger.defaultLogger, + val mainContext: CoroutineDispatcher = defaultMainContext, + val ioContext: CoroutineDispatcher = defaultIoContext, +) { + companion object { + var defaultCoroutines = Coroutines() + val defaultMainContext: CoroutineDispatcher = Dispatchers.Main + val defaultIoContext: CoroutineDispatcher = PCoroutines.defaultIoContext + val defaultDefaultScope: CoroutineScope + get() = CoroutineScope(defaultMainContext) + val defaultIoScope: CoroutineScope + get() = CoroutineScope(defaultIoContext) + } + + val defaultScope + get() = CoroutineScope(mainContext) + val ioScope + get() = CoroutineScope(ioContext) + + fun launchMain( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + block: suspend CoroutineScope.() -> Unit, + ) = launchDef(defaultScope, context, start, block) + + fun asyncMain( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + block: suspend CoroutineScope.() -> T, + ) = defaultScope.async(context, start, block) + + suspend fun withContext( + block: suspend CoroutineScope.() -> T, + ) = withContext(mainContext, block) + + fun launchIo( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + block: suspend CoroutineScope.() -> Unit, + ) = launchDef(ioScope, context, start, block) + + fun asyncIo( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + block: suspend CoroutineScope.() -> T, + ) = ioScope.async(context, start, block) + + suspend fun withContextIo( + block: suspend CoroutineScope.() -> T, + ) = withContext(ioContext, block) + + private fun launchDef( + scope: CoroutineScope, + context: CoroutineContext, + start: CoroutineStart, + block: suspend CoroutineScope.() -> Unit, + ): Job { + return scope.launch(context, start) { + try { + block() + } catch (e: Exception) { + if (e is CancellationException) return@launch + logger.warning("exception in coroutine") + logger.warning(scope.toString()) + logger.warning(e.message ?: e.toString()) + throw CoroutineLaunchException("exception in coroutine", scope, e) + } + } + } +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/ExecuteTask.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/ExecuteTask.kt deleted file mode 100644 index 2be1a25..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/ExecuteTask.kt +++ /dev/null @@ -1,58 +0,0 @@ -@file:Suppress("unused") - -package net.kigawa.kutil.kutil.api.concurrent - -import net.kigawa.kutil.kutil.api.manager.RemoveAble -import java.util.concurrent.* - -class ExecuteTask( - private val executor: AsyncExecutor, - private val futureTask: FutureTask, -): RemoveAble(executor), ResultTask, Runnable { - - constructor(executor: AsyncExecutor, callable: Callable): this(executor, FutureTask(callable)) - - override fun waitTask(timeoutMilli: Long) { - if (isDone) return - try { - get(timeoutMilli) - } catch (e: ExecutionException) { - e.cause?.also(executor.errorHandler::catch) ?: executor.errorHandler.catch(e) - } - } - - override fun waitTask() { - waitTask(executor.timeOutMilli) - } - - override fun cancel(mayInterruptIfRunning: Boolean): Boolean { - return futureTask.cancel(mayInterruptIfRunning) - } - - override fun isCancelled(): Boolean { - return futureTask.isCancelled - } - - override fun isDone(): Boolean { - return futureTask.isDone - } - - override fun get(timeoutMilli: Long): T { - return get(timeoutMilli, TimeUnit.MILLISECONDS) - } - - override fun get(): T { - return get(executor.timeOutMilli) - } - - override fun get(timeout: Long, unit: TimeUnit): T { - return futureTask.get(timeout, unit) - } - - override fun run() { - if (isDone) return - - futureTask.run() - remove() - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/PCoroutines.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/PCoroutines.kt new file mode 100644 index 0000000..094c328 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/PCoroutines.kt @@ -0,0 +1,7 @@ +package net.kigawa.kutil.kutil.api.concurrent + +import kotlinx.coroutines.CoroutineDispatcher + +internal expect object PCoroutines { + val defaultIoContext: CoroutineDispatcher +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/ResultTask.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/ResultTask.kt deleted file mode 100644 index 3bc8056..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/ResultTask.kt +++ /dev/null @@ -1,11 +0,0 @@ -package net.kigawa.kutil.kutil.api.concurrent - -import java.util.concurrent.Future -import java.util.concurrent.TimeUnit - -interface ResultTask: Task, Future { - fun get(timeoutMilli: Long): T - override fun get(): T - override fun get(timeout: Long, unit: TimeUnit): T - -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/SyncQueue.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/SyncQueue.kt new file mode 100644 index 0000000..c19e65b --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/SyncQueue.kt @@ -0,0 +1,23 @@ +package net.kigawa.kutil.kutil.api.concurrent + +import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.Deferred +import kotlinx.coroutines.channels.Channel +import net.kigawa.kutil.kutil.api.forEach + +open class SyncQueue( + protected val coroutines: Coroutines = Coroutines.defaultCoroutines, +) { + private val tasks = Channel>() + + init { + coroutines.launchMain { + tasks.forEach { + it.start() + } + } + } + + suspend fun runTask(task: suspend () -> R) = + tasks.send(coroutines.asyncMain(start = CoroutineStart.LAZY) { task() }) +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/SyncVal.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/SyncVal.kt new file mode 100644 index 0000000..baf60c1 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/SyncVal.kt @@ -0,0 +1,8 @@ +package net.kigawa.kutil.kutil.api.concurrent + +class SyncVal( + private val value: T, + coroutines: Coroutines = Coroutines.defaultCoroutines, +) : SyncQueue(coroutines) { + suspend fun useValue(task: suspend (T) -> R) = runTask { task(value) } +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Task.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Task.kt deleted file mode 100644 index ec08b4f..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Task.kt +++ /dev/null @@ -1,9 +0,0 @@ -package net.kigawa.kutil.kutil.api.concurrent - -interface Task { - fun waitTask(timeoutMilli: Long) - fun waitTask() - fun cancel(mayInterruptIfRunning: Boolean): Boolean - fun isCancelled(): Boolean - fun isDone(): Boolean -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Var.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Var.kt deleted file mode 100644 index 65acae7..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/Var.kt +++ /dev/null @@ -1,32 +0,0 @@ -@file:Suppress("unused") - -package net.kigawa.kutil.kutil.api.concurrent - -open class Var( - protected var value: T, -) { - @Synchronized - fun set(value: T) { - this.value = value - } - - @Synchronized - fun useSelf(task: Var. (T)->R): R { - return task(value) - } - - @Synchronized - fun useValue(task: (T)->R): R { - return task(value) - } - - @Synchronized - fun modify(task: (T)->T) { - value = task(value) - } - - @Synchronized - open fun get(): T { - return value - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/debug/KutilDebug.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/debug/KutilDebug.kt deleted file mode 100644 index 73efa7a..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/debug/KutilDebug.kt +++ /dev/null @@ -1,32 +0,0 @@ -@file:Suppress("unused") - -package net.kigawa.kutil.kutil.api.debug - -object KutilDebug { - @JvmStatic - var debug: Boolean = true - - @JvmStatic - fun debug(message: Any?) = debug(message.toString(), 1, 1) - - @JvmStatic - fun debug() = debug(null, 1, 1) - - @JvmStatic - fun debug(message: String?) = debug(message, 1, 1) - - @JvmStatic - fun debug(message: Any?, size: Int) = debug(message.toString(), 1, size) - - @JvmStatic - fun debug(message: String?, traceSize: Int) = debug(message, 1, traceSize) - - @JvmStatic - fun debug(message: String?, traceOffset: Int, traceSize: Int) { - if (!debug) return - Thread.currentThread().stackTrace.drop(traceOffset + 2).take(traceSize).forEach { - println(" |$it") - } - message?.let {println(it)} - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/dependency/Dependencies.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/dependency/Dependencies.kt index 6fd1c85..0d5c390 100644 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/dependency/Dependencies.kt +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/dependency/Dependencies.kt @@ -1,16 +1,14 @@ package net.kigawa.kutil.kutil.api.dependency -import java.util.* - @Suppress("unused") class DependencyStack( private val stack: List, ) { - constructor(): this(mutableListOf()) - + constructor() : this(mutableListOf()) + fun add(dependency: T): DependencyStack { if (stack.contains(dependency)) throw DependencyCirculationException("unit has bean circular reference", dependency) - val list = LinkedList(stack) + val list = stack.toMutableList() list.add(dependency) return DependencyStack(stack) } diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/diff/KutilDiff.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/diff/KutilDiff.kt index cf896d2..f9ca821 100644 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/diff/KutilDiff.kt +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/diff/KutilDiff.kt @@ -3,9 +3,8 @@ package net.kigawa.kutil.kutil.api.diff object KutilDiff { - - @JvmStatic - fun getDiff(oldIterable: Iterable, newIterable: Iterable): Diff> { + + fun getIterableDiff(oldIterable: Iterable, newIterable: Iterable): Diff> { return Diff( newIterable.filter { !oldIterable.contains(it) diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/err/ErrorHandler.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/err/ErrorHandler.kt deleted file mode 100644 index 4030ee9..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/err/ErrorHandler.kt +++ /dev/null @@ -1,16 +0,0 @@ -package net.kigawa.kutil.kutil.api.err - -interface ErrorHandler { - fun tryCatch(eClass: Class, task: ()->R) { - try { - task() - } catch (e: Throwable) { - @Suppress("UNCHECKED_CAST") - if (eClass.isInstance(e)) catch(e as T) - else throw e - } - } - - fun tryCatch(task: ()->R) - fun catch(e: T) -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/err/KutilErr.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/err/KutilErr.kt deleted file mode 100644 index 58dfd99..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/err/KutilErr.kt +++ /dev/null @@ -1 +0,0 @@ -package net.kigawa.kutil.kutil.api.err diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/err/StreamErrorHandler.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/err/StreamErrorHandler.kt deleted file mode 100644 index 42e195b..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/err/StreamErrorHandler.kt +++ /dev/null @@ -1,16 +0,0 @@ -package net.kigawa.kutil.kutil.api.err - -import java.io.PrintStream - -class StreamErrorHandler( - private val errorClass: Class, - var out: PrintStream = System.out, -): ErrorHandler { - override fun catch(e: T) { - e.printStackTrace(out) - } - - override fun tryCatch(task: ()->R) { - return tryCatch(errorClass, task) - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/file/FileExtension.java b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/file/FileExtension.java deleted file mode 100644 index 93247ad..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/file/FileExtension.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.kigawa.kutil.kutil.api.file; - -/** - * 拡張子の管理のためのクラス - * to manage file extension - */ -@SuppressWarnings("unused") -public enum FileExtension -{ - LOG("log"), - /** - * @deprecated - */ - @Deprecated - log("log"); - - private final String extension; - - FileExtension(String extension) { - this.extension = extension; - } - - /** - * 拡張子の取得 - * get extension - * - * @return extension - */ - public String getExtension() { - return "." + extension; - } - - /** - * 拡張子を追加して返す - * add extension and return - * - * @param name file name - * @return added file name - */ - public String addExtension(String name) { - return name + getExtension(); - } - - /** - * 拡張子を追加する - * add extension - * - * @param stringBuffer file name - * @return added string buffer - */ - public StringBuffer addExtension(StringBuffer stringBuffer) { - return stringBuffer.append(".").append(extension); - } -} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/file/FileExtension.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/file/FileExtension.kt new file mode 100644 index 0000000..86438e0 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/file/FileExtension.kt @@ -0,0 +1,46 @@ +package net.kigawa.kutil.kutil.api.file; + +/** + * 拡張子の管理のためのクラス + * to manage file extension + */ +@Suppress("unused", "MemberVisibilityCanBePrivate") +enum class FileExtension( + private val extension: String, +) { + LOG("log"), + ; + + + /** + * 拡張子の取得 + * get extension + * + * @return extension + */ + fun getExtension(): String { + return ".$extension"; + } + + /** + * 拡張子を追加して返す + * add extension and return + * + * @param name file name + * @return added file name + */ + fun addExtension(name: String): String { + return name + getExtension(); + } + + /** + * 拡張子を追加する + * add extension + * + * @param sb file name + * @return added string buffer + */ + fun addExtension(sb: StringBuilder): StringBuilder { + return sb.append(".").append(extension); + } +} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/ThrowRunnable.java b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/ThrowRunnable.java deleted file mode 100644 index 7d56815..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/ThrowRunnable.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.kigawa.kutil.kutil.api.function; - -/** - * 例外を投げれる引数と返り値のない関数 - * function with no argument and no return values that can throw exception - */ -@SuppressWarnings("unused") -public interface ThrowRunnable { - void run() throws Exception; -} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/ThrowSupplier.java b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/ThrowSupplier.java deleted file mode 100644 index 98c2f07..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/ThrowSupplier.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.kigawa.kutil.kutil.api.function; - -/** - * 結果のサプライヤを表します - * Represents a supplier of results. - */ -@SuppressWarnings("unused") -public interface ThrowSupplier -{ - T get() throws Exception; -} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/ThrowTriConsumer.java b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/ThrowTriConsumer.java deleted file mode 100644 index 8203f08..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/ThrowTriConsumer.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.kigawa.kutil.kutil.api.function; - - -/** - * 例外を投げれる3つの引数と返り値のない関数 - * function with three arguments and no return values that can throw exception - */ -@SuppressWarnings("unused") -public interface ThrowTriConsumer { - void accept(T t, U u, V v) throws Exception; -} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/TriConsumer.java b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/TriConsumer.java deleted file mode 100644 index 933d7aa..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/function/TriConsumer.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.kigawa.kutil.kutil.api.function; - -/** - * 3つの引数と返り値のない関数 - * function with three arguments and no return values - */ -@SuppressWarnings("unused") -public interface TriConsumer { - void accept(T t, U u, V v); -} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/interfaces/LoggerInterface.java b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/interfaces/LoggerInterface.java deleted file mode 100644 index 7593802..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/interfaces/LoggerInterface.java +++ /dev/null @@ -1,65 +0,0 @@ -package net.kigawa.kutil.kutil.api.interfaces; - -/** - * create pass through logger - */ -@SuppressWarnings("unused") -public interface LoggerInterface { - default String finePass(String str) { - fine(str); - return str; - } - - void fine(Object... o); - - default String warningPass(String str) { - warning(str); - return str; - } - - void warning(Object... o); - - default String severPass(String str) { - severe(str); - return str; - } - - void severe(Object... o); - - default String infoPass(String str) { - info(str); - return str; - } - - void info(Object... o); - - default String allPass(String str) { - all(str); - return str; - } - - void all(Object... o); - - void finer(Object... o); - - default String finerPass(String str) { - fine(str); - return str; - } - - void finest(Object... o); - - default String finestPass(String str) { - fine(str); - return str; - } - - /** - * @param message log - * @deprecated - */ - @Deprecated - default void logger(String message) { - fine(message); - } -} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/ChannelReaderIo.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/ChannelReaderIo.kt new file mode 100644 index 0000000..37ffe28 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/ChannelReaderIo.kt @@ -0,0 +1,18 @@ +package net.kigawa.kutil.kutil.api.io + +import kotlinx.coroutines.channels.Channel +import net.kigawa.kutil.kutil.api.forEach + +open class ChannelReaderIo( + protected val channel: Channel, +) : ReaderIo { + + override suspend fun read(): T { + return channel.receive() + } + + override suspend fun forEach(block: suspend (T) -> Unit) { + channel.forEach { block(it) } + } + +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/ChannelWriterIo.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/ChannelWriterIo.kt new file mode 100644 index 0000000..b08cc02 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/ChannelWriterIo.kt @@ -0,0 +1,11 @@ +package net.kigawa.kutil.kutil.api.io + +import kotlinx.coroutines.channels.Channel + +open class ChannelWriterIo( + protected val channel: Channel, +) : WriterIo { + override suspend fun writeLine(value: T) { + channel.send(value) + } +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/DefaultIo.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/DefaultIo.kt new file mode 100644 index 0000000..21e94fa --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/DefaultIo.kt @@ -0,0 +1,7 @@ +package net.kigawa.kutil.kutil.api.io + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect object DefaultIo { + val error: WriterIo + val out: WriterIo +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/FunctionWriterIo.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/FunctionWriterIo.kt new file mode 100644 index 0000000..6d58d09 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/FunctionWriterIo.kt @@ -0,0 +1,9 @@ +package net.kigawa.kutil.kutil.api.io + +class FunctionWriterIo( + private val func: (T)->Unit +): WriterIo { + override suspend fun writeLine(value: T) { + func(value) + } +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/Io.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/Io.kt new file mode 100644 index 0000000..056066b --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/Io.kt @@ -0,0 +1,3 @@ +package net.kigawa.kutil.kutil.api.io + +interface Io \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/IoException.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/IoException.kt new file mode 100644 index 0000000..235e59c --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/IoException.kt @@ -0,0 +1,4 @@ +package net.kigawa.kutil.kutil.api.io + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect open class IoException(message: String?) diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/KuCloseable.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/KuCloseable.kt new file mode 100644 index 0000000..a53dbc9 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/KuCloseable.kt @@ -0,0 +1,6 @@ +package net.kigawa.kutil.kutil.api.io + +@OptIn(ExperimentalStdlibApi::class) +interface KuCloseable : AutoCloseable { + override fun close() +} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/KutilIo.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/KutilIo.kt new file mode 100644 index 0000000..8ab53a7 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/KutilIo.kt @@ -0,0 +1,18 @@ +package net.kigawa.kutil.kutil.api.io + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.launch +import kotlin.coroutines.CoroutineContext + +class KutilIo { +} + + +inline fun Channel.dispatchForEach(coroutineContext: CoroutineContext, crossinline func: (T) -> Unit) { + CoroutineScope(coroutineContext).launch { + for (item in this@dispatchForEach) { + func(item) + } + } +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/NotDirectoryException.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/NotDirectoryException.kt new file mode 100644 index 0000000..2a74793 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/NotDirectoryException.kt @@ -0,0 +1,3 @@ +package net.kigawa.kutil.kutil.api.io + +class NotDirectoryException(message: String?) : IoException(message) \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/ReaderIo.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/ReaderIo.kt new file mode 100644 index 0000000..f3be2e2 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/ReaderIo.kt @@ -0,0 +1,6 @@ +package net.kigawa.kutil.kutil.api.io + +interface ReaderIo : Io { + suspend fun read(): T + suspend fun forEach(block: suspend (T) -> Unit) +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/SuspendCloseable.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/SuspendCloseable.kt new file mode 100644 index 0000000..733276a --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/SuspendCloseable.kt @@ -0,0 +1,5 @@ +package net.kigawa.kutil.kutil.api.io + +interface SuspendCloseable { + suspend fun suspendClose() +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/WriterIo.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/WriterIo.kt new file mode 100644 index 0000000..517b432 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/WriterIo.kt @@ -0,0 +1,5 @@ +package net.kigawa.kutil.kutil.api.io + +interface WriterIo : Io { + suspend fun writeLine(value: T) +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuDirectory.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuDirectory.kt new file mode 100644 index 0000000..cf3209c --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuDirectory.kt @@ -0,0 +1,6 @@ +package net.kigawa.kutil.kutil.api.io.fs + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect class KuDirectory { + fun toPath(): KuPath +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuFile.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuFile.kt new file mode 100644 index 0000000..a387c28 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuFile.kt @@ -0,0 +1,4 @@ +package net.kigawa.kutil.kutil.api.io.fs + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect class KuFile \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuPath.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuPath.kt new file mode 100644 index 0000000..86d7b1a --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuPath.kt @@ -0,0 +1,20 @@ +package net.kigawa.kutil.kutil.api.io.fs + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect class KuPath( + strPath: String, +) { + companion object { + val separator: String + } + + fun join(child: String): KuPath + fun join(child: KuPath): KuPath + fun strPath(): String + fun toAbsolute(): KuPath + fun parent(): KuPath + fun createDirOrGet(): KuDirectory + fun toFile(): KuFile + fun isExists(): Boolean + fun removeIfExists() +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/ConcurrentMap.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/ConcurrentMap.kt deleted file mode 100644 index dfddda8..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/ConcurrentMap.kt +++ /dev/null @@ -1,74 +0,0 @@ -@file:Suppress("unused") - -package net.kigawa.kutil.kutil.api.list - -import net.kigawa.kutil.kutil.api.concurrent.Box - -open class ConcurrentMap(map: Map): MutableMap { - constructor(): this(mutableMapOf()) - - private val listBox = Box(map.toMutableMap()) {HashMap(it)} - - @Synchronized - private fun modify(task: (MutableMap)->R): R { - return listBox.useValue(task) - } - - fun toMutableMap(): MutableMap { - return listBox.get() - } - - override val entries: MutableSet> - get() = toMutableMap().entries - override val keys: MutableSet - get() = toMutableMap().keys - - override val size: Int - get() = toMutableMap().size - override val values: MutableCollection - get() = toMutableMap().values - - override fun clear() { - return modify { - it.clear() - } - } - - override fun get(key: K): V? { - return toMutableMap().get(key) - } - - override fun containsValue(value: V): Boolean { - return toMutableMap().containsValue(value) - } - - override fun containsKey(key: K): Boolean { - return toMutableMap().containsKey(key) - } - - override fun isEmpty(): Boolean { - return toMutableMap().isEmpty() - } - - override fun remove(key: K): V? { - return modify { - it.remove(key) - } - } - - override fun putAll(from: Map) { - return modify { - it.putAll(from) - } - } - - override fun put(key: K, value: V): V? { - return modify { - it.put(key, value) - } - } - - override fun toString(): String { - return "ConcurrentMap(entries=$entries)" - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/ConcurrentSet.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/ConcurrentSet.kt deleted file mode 100644 index 4076d6a..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/ConcurrentSet.kt +++ /dev/null @@ -1,75 +0,0 @@ -package net.kigawa.kutil.kutil.api.list - -import net.kigawa.kutil.kutil.api.concurrent.Box - -open class ConcurrentSet(collection: Collection): MutableSet { - constructor(): this(mutableListOf()) - - private val listBox = Box(collection.toMutableSet()) {HashSet(it)} - - @Synchronized - private fun modifyList(task: (MutableSet)->R): R { - return listBox.useValue(task) - } - - fun toMutableSet(): MutableSet { - return listBox.get() - } - - override fun add(element: T): Boolean { - return modifyList { - it.add(element) - } - } - - override fun remove(element: T): Boolean { - return modifyList { - it.remove(element) - } - } - - override val size: Int - get() = toMutableSet().size - - override fun clear() { - return modifyList { - it.clear() - } - } - - override fun addAll(elements: Collection): Boolean { - return modifyList { - it.addAll(elements) - } - } - - override fun isEmpty(): Boolean { - return toMutableSet().isEmpty() - } - - override fun iterator(): MutableIterator { - return toMutableSet().iterator() - } - - override fun retainAll(elements: Collection): Boolean { - return toMutableSet().retainAll(elements) - } - - override fun removeAll(elements: Collection): Boolean { - return modifyList { - it.removeAll(elements) - } - } - - override fun containsAll(elements: Collection): Boolean { - return toMutableSet().containsAll(elements) - } - - override fun contains(element: T): Boolean { - return toMutableSet().contains(element) - } - - override fun toString(): String { - return "ConcurrentList(${listBox.get()})" - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/Func.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/Func.kt new file mode 100644 index 0000000..f790b8d --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/Func.kt @@ -0,0 +1,18 @@ +package net.kigawa.kutil.kutil.api.list + + +@Suppress("unused") +fun Collection.containsIf(filter: (E) -> Boolean): Boolean { + forEach { + if (filter(it)) return true + } + return false +} + +@Suppress("unused") +fun Collection.firstOrNullMap(filter: (E) -> R?): R? { + forEach { + return filter.invoke(it) ?: return@forEach + } + return null +} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/GenerateMap.java b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/GenerateMap.java deleted file mode 100644 index 5f0627b..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/GenerateMap.java +++ /dev/null @@ -1,177 +0,0 @@ -package net.kigawa.kutil.kutil.api.list; - -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.function.Function; - -/** - * map that need to create new instance when there is no instance - * - * @param key - * @param value - */ -@SuppressWarnings("unused") -public class GenerateMap implements Map -{ - private final Map map; - private final Function newInstance; - - /** - * @param newInstance new instance function - */ - public GenerateMap(Function newInstance) - { - this(newInstance, null); - } - - /** - * @param newInstance new instance function - * @param map default values or non values when null - */ - public GenerateMap(Function newInstance, Map map) - { - this.newInstance = newInstance; - if (map == null) - this.map = new HashMap<>(); - else - this.map = new HashMap<>(map); - } - - /** - * @return size - */ - @Override - public int size() - { - return map.size(); - } - - /** - * @return return true when empty - */ - @Override - public boolean isEmpty() - { - return map.isEmpty(); - } - - /** - * @param key key - * @return return true when key is contained in keys - */ - @Override - public boolean containsKey(Object key) - { - return map.containsKey(key); - } - - /** - * @param value value - * @return return true when value is contained in values - */ - @Override - public boolean containsValue(Object value) - { - return map.containsValue(value); - } - - /** - * @param key key - * @return return value that linked by key - */ - @Override - public V get(Object key) - { - K safeKey; - try { - //noinspection unchecked - safeKey = (K) key; - } catch (ClassCastException e) { - return null; - } - - var obj = map.get(key); - if (obj == null) { - try { - obj = newInstance.apply(safeKey); - map.put(safeKey, obj); - } catch (ClassCastException e) { - return null; - } - } - return obj; - } - - /** - * @param key key - * @param value value - * @return put in the value and link key - */ - @Override - public V put(K key, V value) - { - return map.put(key, value); - } - - /** - * @param key key - * @return remove by key - */ - @Override - public V remove(Object key) - { - return map.remove(key); - } - - /** - * @param m map that to add - */ - @Override - public void putAll(@NotNull Map m) - { - map.putAll(m); - } - - /** - * clear all - */ - @Override - public void clear() - { - map.clear(); - } - - /** - * @return set that from keys - */ - @NotNull - @Override - public Set keySet() - { - return map.keySet(); - } - - /** - * @return collection from values - */ - @NotNull - @Override - public Collection values() - { - return map.values(); - } - - /** - * @return entry set from own - */ - @NotNull - @Override - public Set> entrySet() - { - return map.entrySet(); - } -} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KCollectionStream.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KCollectionStream.kt deleted file mode 100644 index 2131172..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KCollectionStream.kt +++ /dev/null @@ -1,6 +0,0 @@ -package net.kigawa.kutil.kutil.api.list - -interface KCollectionStream: Collection { - fun modifyList(task: (MutableList)->R): R - fun toMutableList(): MutableList -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KList.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KList.kt deleted file mode 100644 index 081ea40..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KList.kt +++ /dev/null @@ -1,66 +0,0 @@ -package net.kigawa.kutil.kutil.api.list - -import java.util.* - -interface KList: MutableList, KListStream { - companion object { - @JvmStatic - fun create() = KListImpl(LinkedList()) - - @JvmStatic - fun create(iterable: Iterable) = KListImpl(LinkedList(iterable.toList())) - } - - override val size: Int - get() = toMutableList().size - - override fun lastIndexOf(element: T): Int { - return toMutableList().lastIndexOf(element) - } - - override fun indexOf(element: T): Int { - return toMutableList().indexOf(element) - } - - override fun containsAll(elements: Collection): Boolean { - return toMutableList().containsAll(elements) - } - - override fun contains(element: T): Boolean { - return toMutableList().contains(element) - } - - override fun get(index: Int): T { - return toMutableList()[index] - } - - override fun isEmpty(): Boolean { - return toMutableList().isEmpty() - } - - override fun iterator(): MutableIterator { - return toMutableList().iterator() - } - - override fun listIterator(): MutableListIterator { - return toMutableList().listIterator() - } - - override fun listIterator(index: Int): MutableListIterator { - return toMutableList().listIterator(index) - } - - override fun removeAt(index: Int): T { - return toMutableList().removeAt(index) - } - - override fun subList(fromIndex: Int, toIndex: Int): MutableList { - return toMutableList().subList(fromIndex, toIndex) - } - - override fun retainAll(elements: Collection): Boolean { - return toMutableList().retainAll(elements) - } - - fun clone(): KList -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KListImpl.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KListImpl.kt deleted file mode 100644 index bdf3f09..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KListImpl.kt +++ /dev/null @@ -1,82 +0,0 @@ -@file:Suppress("unused") - -package net.kigawa.kutil.kutil.api.list - -import net.kigawa.kutil.kutil.api.concurrent.Box - -class KListImpl(list: MutableList): KList { - constructor(): this(mutableListOf()) - constructor(initialCapacity: Int): this(ArrayList(initialCapacity)) - constructor(iterable: Iterable): this(iterable.toMutableList()) - - private val listBox = Box(list) {ArrayList(it)} - - @Synchronized - override fun modifyList(task: (MutableList)->R): R { - return listBox.useValue(task) - } - - override fun toMutableList(): MutableList { - return listBox.get() - } - - override fun add(element: T): Boolean { - return modifyList { - it.add(element) - } - } - - override fun remove(element: T): Boolean { - return modifyList { - it.remove(element) - } - } - - override fun clone(): KList { - return KList.create(this) - } - - override fun clear() { - return modifyList { - it.clear() - } - } - - override fun addAll(elements: Collection): Boolean { - return modifyList { - it.addAll(elements) - } - } - - override fun addAll(index: Int, elements: Collection): Boolean { - return modifyList { - it.addAll(index, elements) - } - } - - override fun add(index: Int, element: T) { - return modifyList { - it.add(index, element) - } - } - - override fun set(index: Int, element: T): T { - return modifyList { - it.set(index, element) - } - } - - override fun removeAll(elements: Collection): Boolean { - return modifyList { - it.removeAll(elements) - } - } - - override fun toString(): String { - return "ConcurrentList(${toMutableList()})" - } - - override fun toKList(): KList { - return KList.create(this) - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KListStream.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KListStream.kt deleted file mode 100644 index 980bb57..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KListStream.kt +++ /dev/null @@ -1,73 +0,0 @@ -package net.kigawa.kutil.kutil.api.list - -interface KListStream: List, KCollectionStream { - fun toKList(): KList - - /** - * Returns 1st *element* from the list. - * - * Throws an [IndexOutOfBoundsException] if the size of this list is less than 1. - */ - fun component1(): T { - return get(0) - } - - /** - * Returns 2nd *element* from the list. - * - * Throws an [IndexOutOfBoundsException] if the size of this list is less than 2. - */ - fun component2(): T { - return get(1) - } - - /** - * Returns 3rd *element* from the list. - * - * Throws an [IndexOutOfBoundsException] if the size of this list is less than 3. - */ - fun component3(): T { - return get(2) - } - - /** - * Returns 4th *element* from the list. - * - * Throws an [IndexOutOfBoundsException] if the size of this list is less than 4. - */ - fun component4(): T { - return get(3) - } - - /** - * Returns 5th *element* from the list. - * - * Throws an [IndexOutOfBoundsException] if the size of this list is less than 5. - */ - fun component5(): T { - return get(4) - } - - fun forEach(action: (T)->Unit) { - toKList().forEach(action) - } - - /** - * Returns a list with elements in reversed order. - */ - fun reversed(): KList { - val list = toKList() - list.reverse() - return list - } - - fun map(transform: (T)->R): KList { - return mapTo(KListImpl(this.size), transform) - } - - fun > mapTo(destination: C, transform: (T)->R): C { - for (item in this) - destination.add(transform(item)) - return destination - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KutilList.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KutilList.kt index 288b122..800a074 100644 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KutilList.kt +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/list/KutilList.kt @@ -3,22 +3,7 @@ package net.kigawa.kutil.kutil.api.list object KutilList { - @JvmStatic fun connectList(vararg list: List): List { return list.flatMap {it} } } - -fun Collection.contains(filter: (E)->Boolean): Boolean { - forEach { - if (filter(it)) return true - } - return false -} - -fun Collection.firstOrNullMap(filter: (E)->R?): R? { - forEach { - return filter.invoke(it) ?: return@forEach - } - return null -} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/DirLocalerResource.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/DirLocalerResource.kt deleted file mode 100644 index 411731f..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/DirLocalerResource.kt +++ /dev/null @@ -1,51 +0,0 @@ -@file:Suppress("unused") - -package net.kigawa.kutil.kutil.api.locale - -import java.io.File -import java.io.FileFilter -import java.util.* - -class DirLocalerResource(private val dir: File) : LocalerResource { - private val locales = mutableSetOf() - private val changed = mutableSetOf() - - init { - load() - } - - fun load(): Properties { - val properties = Properties() - dir - .listFiles(FileFilter { it.name.endsWith(".properties") }) - ?.forEach { file -> - val language = file.name.replace(".properties", "") - - file.inputStream().use(properties::load) - properties.forEach { - LocaleData(language, it.key.toString(), it.value.toString()) - .also(locales::add) - } - } - return properties - } - - fun save() { - load() - } - - fun reload() { - save() - load() - } - - override fun getLocales(key: String?, language: String?): List { - return locales - .filter { it.key == key } - .filter { it.language == language } - } - - override fun setLocale(localeData: LocaleData): Boolean { - TODO("Not yet implemented") - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/LocaleData.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/LocaleData.kt deleted file mode 100644 index 022574f..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/LocaleData.kt +++ /dev/null @@ -1,23 +0,0 @@ -package net.kigawa.kutil.kutil.api.locale - -data class LocaleData( - val language: String, - val key: String, - val message: String, -) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is LocaleData) return false - - if (language != other.language) return false - if (key != other.key) return false - return message == other.message - } - - override fun hashCode(): Int { - var result = language.hashCode() - result = 31 * result + key.hashCode() - result = 31 * result + message.hashCode() - return result - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/Localer.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/Localer.kt deleted file mode 100644 index b9d59c7..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/Localer.kt +++ /dev/null @@ -1,22 +0,0 @@ -@file:Suppress("unused") - -package net.kigawa.kutil.kutil.api.locale - -import java.util.* - -class Localer(private var defaultLanguage: String, private var localerResource: LocalerResources) { - fun getLocaleData(key: String, locale: String) = localerResource.getLocaleData(key, locale) - fun getLocaleData(key: String) = getLocaleData(key, Locale.getDefault().language) - fun getDefaultLocaleData(key: String) = getLocaleData(key, defaultLanguage) - - fun use(key: String) = use(key, null) - fun use(key: String, defaultMessage: String?): String { - defaultMessage?.let {on(defaultLanguage, key, it)} - return getLocaleData(key)?.message ?: getDefaultLocaleData(key)?.message ?: defaultMessage ?: "message not found" - } - - fun on(language: String, key: String, message: String): Localer { - localerResource.setData(LocaleData(language, key, message)) - return this - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/LocalerResource.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/LocalerResource.kt deleted file mode 100644 index 7c58bf7..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/LocalerResource.kt +++ /dev/null @@ -1,10 +0,0 @@ -package net.kigawa.kutil.kutil.api.locale - -interface LocalerResource { - fun getLocales(key: String? = null, language: String? = null): List - fun getLocale(key: String, language: String): LocaleData? { - return getLocales(key, language).firstOrNull() - } - - fun setLocale(localeData: LocaleData): Boolean -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/LocalerResources.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/LocalerResources.kt deleted file mode 100644 index 65e6620..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/locale/LocalerResources.kt +++ /dev/null @@ -1,27 +0,0 @@ -@file:Suppress("unused") - -package net.kigawa.kutil.kutil.api.locale - -import net.kigawa.kutil.kutil.api.list.KList -import net.kigawa.kutil.kutil.api.list.firstOrNullMap - -class LocalerResources(vararg resource: LocalerResource) { - private val resources = KList.create(resource.toMutableSet()) - - fun getLocales(key: String? = null, language: String? = null): Set { - return resources - .reversed() - .flatMap {it.getLocales(key, language)} - .toMutableSet() - } - - fun getLocaleData(key: String, language: String): LocaleData? { - return resources - .firstOrNullMap {it.getLocale(key, language)} - } - - fun setData(localeData: LocaleData): Boolean { - return resources - .firstOrNull {it.setLocale(localeData)} == null - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/KuLogger.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/KuLogger.kt new file mode 100644 index 0000000..cc783aa --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/KuLogger.kt @@ -0,0 +1,15 @@ +package net.kigawa.kutil.kutil.api.logger + +@Suppress("MemberVisibilityCanBePrivate", "unused") +class KuLogger( + private val loggerHandler: LoggerHandler, +) { + companion object { + var defaultHandler = PKuLogger.defaultHandler + var defaultLogger: KuLogger = KuLogger(defaultHandler) + } + + fun info(message: Any) = loggerHandler.log(LogLevel.INFO, message) + fun fine(message: Any) = loggerHandler.log(LogLevel.FINE, message) + fun warning(message: Any) = loggerHandler.log(LogLevel.WARNING, message) +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/LogLevel.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/LogLevel.kt new file mode 100644 index 0000000..5c406cb --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/LogLevel.kt @@ -0,0 +1,5 @@ +package net.kigawa.kutil.kutil.api.logger + +enum class LogLevel { + WARNING, INFO, FINE +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/LoggerHandler.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/LoggerHandler.kt new file mode 100644 index 0000000..bdd7ff2 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/LoggerHandler.kt @@ -0,0 +1,8 @@ +package net.kigawa.kutil.kutil.api.logger + +import net.kigawa.kutil.kutil.api.logger.formatter.LoggerFormatter + +interface LoggerHandler { + fun log(level: LogLevel, message: Any) + fun setFormatter(loggerFormatter: LoggerFormatter) +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/LoggerRecord.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/LoggerRecord.kt new file mode 100644 index 0000000..063e4cb --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/LoggerRecord.kt @@ -0,0 +1,7 @@ +package net.kigawa.kutil.kutil.api.logger + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect class LoggerRecord { + val level: LogLevel + val message: Any +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/PKuLogger.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/PKuLogger.kt new file mode 100644 index 0000000..4a63185 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/PKuLogger.kt @@ -0,0 +1,6 @@ +package net.kigawa.kutil.kutil.api.logger + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +internal expect object PKuLogger { + val defaultHandler: LoggerHandler +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/DefaultLoggerFormatter.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/DefaultLoggerFormatter.kt new file mode 100644 index 0000000..86fed73 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/DefaultLoggerFormatter.kt @@ -0,0 +1,8 @@ +package net.kigawa.kutil.kutil.api.logger.formatter + +import net.kigawa.kutil.kutil.api.logger.LoggerRecord + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect class DefaultLoggerFormatter : LoggerFormatter { + override fun format(logRecord: LoggerRecord): Any +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/LoggerFormatter.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/LoggerFormatter.kt new file mode 100644 index 0000000..2051c9f --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/LoggerFormatter.kt @@ -0,0 +1,7 @@ +package net.kigawa.kutil.kutil.api.logger.formatter + +import net.kigawa.kutil.kutil.api.logger.LoggerRecord + +interface LoggerFormatter { + fun format(logRecord: LoggerRecord): Any +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/ManagedEntry.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/ManagedEntry.kt deleted file mode 100644 index 9afa9aa..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/ManagedEntry.kt +++ /dev/null @@ -1,14 +0,0 @@ -package net.kigawa.kutil.kutil.api.manager - -abstract class ManagedEntry, PARENT: RemoveAble?>( - @Suppress("MemberVisibilityCanBePrivate") - protected val manager: Manager, - override val parentField: PARENT, -): RemoveAble(parentField) { - - override fun remove() { - super.remove() - @Suppress("UNCHECKED_CAST") - manager.remove(this as SELF) - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/Manager.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/Manager.kt deleted file mode 100644 index 8a12c8b..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/Manager.kt +++ /dev/null @@ -1,19 +0,0 @@ -package net.kigawa.kutil.kutil.api.manager - -import net.kigawa.kutil.kutil.api.list.ConcurrentSet - -abstract class Manager> { - @Suppress("MemberVisibilityCanBePrivate") - protected val entries = ConcurrentSet() - open fun add(entry: T) { - entries.add(entry) - } - - open fun remove(entry: T) { - entries.remove(entry) - } - - fun getEntries(): MutableList { - return entries.toMutableList() - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/RemoveAble.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/RemoveAble.kt deleted file mode 100644 index df6e0a6..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/RemoveAble.kt +++ /dev/null @@ -1,47 +0,0 @@ -@file:Suppress("unused") - -package net.kigawa.kutil.kutil.api.manager - -import net.kigawa.kutil.kutil.api.concurrent.Var -import net.kigawa.kutil.kutil.api.list.KList - -@Suppress("MemberVisibilityCanBePrivate") -abstract class RemoveAble( - parent: RemoveAble?, -) { - private val removeTask = KList.create() - open val parentField = parent - private val registeredTask = parent?.registerRemoveTask(::remove) - protected val removed = Var(false) - fun isRemoved(): Boolean { - return removed.get() - } - - fun registerRemoveTask(runnable: Runnable): Runnable { - removed.useValue { - if (it) throw RemovedObjectException("this object is already removed") - removeTask.add(runnable) - } - return runnable - } - - fun unregisterRemoveTask(runnable: Runnable) { - removed.useValue { - if (it) throw RemovedObjectException("this object is already removed") - removeTask.remove(runnable) - } - } - - open fun remove() { - if (removed.useSelf { - if (it) return@useSelf true - set(true) - false - }) return - - registeredTask?.let {parentField?.unregisterRemoveTask(it)} - removeTask.forEach { - it.run() - } - } -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/RemovedObjectException.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/RemovedObjectException.kt deleted file mode 100644 index 25fd8c3..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/manager/RemovedObjectException.kt +++ /dev/null @@ -1,4 +0,0 @@ -package net.kigawa.kutil.kutil.api.manager - -class RemovedObjectException(message: String): RuntimeException(message) { -} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketClient.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketClient.kt new file mode 100644 index 0000000..a31a39c --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketClient.kt @@ -0,0 +1,14 @@ +package net.kigawa.kutil.kutil.api.net + +import net.kigawa.kutil.kutil.api.concurrent.Coroutines +import net.kigawa.kutil.kutil.api.io.fs.KuPath +import net.kigawa.kutil.kutil.api.io.SuspendCloseable +import net.kigawa.kutil.kutil.api.logger.KuLogger + +expect class SocketClient( + path: KuPath, + logger: KuLogger, + coroutines: Coroutines, +) : SuspendCloseable { + fun connect(): SocketConnection +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketConnection.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketConnection.kt new file mode 100644 index 0000000..dae12b1 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketConnection.kt @@ -0,0 +1,9 @@ +package net.kigawa.kutil.kutil.api.net + +import kotlinx.coroutines.channels.Channel +import net.kigawa.kutil.kutil.api.io.SuspendCloseable + +expect class SocketConnection : SuspendCloseable { + fun reader(): Channel + fun writer(): Channel +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketServer.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketServer.kt new file mode 100644 index 0000000..731303c --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketServer.kt @@ -0,0 +1,15 @@ +package net.kigawa.kutil.kutil.api.net + +import kotlinx.coroutines.channels.Channel +import net.kigawa.kutil.kutil.api.concurrent.Coroutines +import net.kigawa.kutil.kutil.api.io.SuspendCloseable +import net.kigawa.kutil.kutil.api.io.fs.KuPath +import net.kigawa.kutil.kutil.api.logger.KuLogger + +expect class SocketServer( + path: KuPath, + logger: KuLogger?, + coroutines: Coroutines, +) : SuspendCloseable { + fun bind(): Channel +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/Url.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/Url.kt new file mode 100644 index 0000000..e5e4ea5 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/net/Url.kt @@ -0,0 +1,10 @@ +package net.kigawa.kutil.kutil.api.net + +import net.kigawa.kutil.kutil.api.io.fs.KuPath + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect class Url( + strUrl: String, +) { + suspend fun download(to: KuPath) +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/os/KutilOS.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/os/KutilOS.kt new file mode 100644 index 0000000..a557b71 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/os/KutilOS.kt @@ -0,0 +1,4 @@ +package net.kigawa.kutil.kutil.api.os + +@Suppress("unused", "EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect object KutilOS \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/os/OSType.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/os/OSType.kt new file mode 100644 index 0000000..b6116ba --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/os/OSType.kt @@ -0,0 +1,9 @@ +package net.kigawa.kutil.kutil.api.os + +enum class OSType { + WINDOWS, + MAC, + LINUX, + UBUNTU, + OTHER +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcess.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcess.kt new file mode 100644 index 0000000..63b916a --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcess.kt @@ -0,0 +1,12 @@ +package net.kigawa.kutil.kutil.api.process + +import net.kigawa.kutil.kutil.api.io.ReaderIo +import net.kigawa.kutil.kutil.api.io.SuspendCloseable +import net.kigawa.kutil.kutil.api.io.WriterIo + +interface KuProcess : SuspendCloseable { + fun reader(): ReaderIo + fun errReader(): ReaderIo + fun writer(): WriterIo + suspend fun waitFor() +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcessBuilder.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcessBuilder.kt new file mode 100644 index 0000000..ea05b69 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcessBuilder.kt @@ -0,0 +1,9 @@ +package net.kigawa.kutil.kutil.api.process + +import net.kigawa.kutil.kutil.api.io.fs.KuDirectory + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect class KuProcessBuilder(vararg args: String) { + fun start(): KuProcess + fun workDir(directory: KuDirectory?): KuProcessBuilder +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflect.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflect.kt index 97828c4..ce7cec1 100644 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflect.kt +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflect.kt @@ -2,53 +2,6 @@ package net.kigawa.kutil.kutil.api.reflection -import java.lang.reflect.* -object KutilReflect { - @JvmStatic - fun getAllExitFields(clazz: Class<*>): List { - return getAllParentClasses(clazz) - .flatMap {it.declaredFields.asList()} - } - - @JvmStatic - fun getAllExitMethod(clazz: Class<*>): List { - return getAllParentClasses(clazz) - .flatMap {it.declaredMethods.asList()} - } - - @JvmStatic - fun getAllExitAnnotation(clazz: Class<*>, annotationClass: Class): MutableList { - val list = mutableListOf() - getAllParentClasses(clazz).forEach { - val annotation = it.getAnnotation(annotationClass) ?: return@forEach - list.add(annotation) - } - return list - } - - @JvmStatic - fun getAllParentClasses(clazz: Class<*>): MutableList> { - val list = mutableListOf(clazz) - clazz.superclass?.let {list.addAll(getAllParentClasses(clazz.superclass))} - clazz.interfaces.forEach { - list.addAll(getAllParentClasses(it)) - } - return list - } - - @JvmStatic - fun isStatic(member: Member): Boolean { - return Modifier.isStatic(member.modifiers) - } - - @JvmStatic - fun isFinal(member: Member): Boolean { - return Modifier.isFinal(member.modifiers) - } - - @JvmStatic - fun instanceOf(clazz: Class<*>, superClass: Class<*>): Boolean { - return getAllParentClasses(clazz).contains(superClass) - } -} +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect object KutilReflect diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/KutilString.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/KutilString.kt new file mode 100644 index 0000000..f3897fa --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/KutilString.kt @@ -0,0 +1,15 @@ +package net.kigawa.kutil.kutil.api.str + +/** + * utilities about string + */ +@Suppress("unused", "EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +expect object KutilString { + /** + * check is int + * + * @param str to test + * @return return true when str is int + */ + fun isInt(str: String): Boolean +} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/StringColor.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/StringColor.kt new file mode 100644 index 0000000..586fbee --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/StringColor.kt @@ -0,0 +1,99 @@ +package net.kigawa.kutil.kutil.api.str + +/** + * to use colors + */ +@Suppress("unused") +enum class StringColor(private val color: String) { + //Color end string, color reset + RESET("\u001b[0m"), + + // Regular Colors. Normal color, no bold, background color etc. + BLACK("\u001b[0;30m"), // BLACK + RED("\u001b[0;31m"), // RED + GREEN("\u001b[0;32m"), // GREEN + YELLOW("\u001b[0;33m"), // YELLOW + BLUE("\u001b[0;34m"), // BLUE + MAGENTA("\u001b[0;35m"), // MAGENTA + CYAN("\u001b[0;36m"), // CYAN + WHITE("\u001b[0;37m"), // WHITE + + // Bold + BLACK_BOLD("\u001b[1;30m"), // BLACK + RED_BOLD("\u001b[1;31m"), // RED + GREEN_BOLD("\u001b[1;32m"), // GREEN + YELLOW_BOLD("\u001b[1;33m"), // YELLOW + BLUE_BOLD("\u001b[1;34m"), // BLUE + MAGENTA_BOLD("\u001b[1;35m"), // MAGENTA + CYAN_BOLD("\u001b[1;36m"), // CYAN + WHITE_BOLD("\u001b[1;37m"), // WHITE + + // Underline + BLACK_UNDERLINED("\u001b[4;30m"), // BLACK + RED_UNDERLINED("\u001b[4;31m"), // RED + GREEN_UNDERLINED("\u001b[4;32m"), // GREEN + YELLOW_UNDERLINED("\u001b[4;33m"), // YELLOW + BLUE_UNDERLINED("\u001b[4;34m"), // BLUE + MAGENTA_UNDERLINED("\u001b[4;35m"), // MAGENTA + CYAN_UNDERLINED("\u001b[4;36m"), // CYAN + WHITE_UNDERLINED("\u001b[4;37m"), // WHITE + + // Background + BLACK_BACKGROUND("\u001b[40m"), // BLACK + RED_BACKGROUND("\u001b[41m"), // RED + GREEN_BACKGROUND("\u001b[42m"), // GREEN + YELLOW_BACKGROUND("\u001b[43m"), // YELLOW + BLUE_BACKGROUND("\u001b[44m"), // BLUE + MAGENTA_BACKGROUND("\u001b[45m"), // MAGENTA + CYAN_BACKGROUND("\u001b[46m"), // CYAN + WHITE_BACKGROUND("\u001b[47m"), // WHITE + + // High Intensity + BLACK_BRIGHT("\u001b[0;90m"), // BLACK + RED_BRIGHT("\u001b[0;91m"), // RED + GREEN_BRIGHT("\u001b[0;92m"), // GREEN + YELLOW_BRIGHT("\u001b[0;93m"), // YELLOW + BLUE_BRIGHT("\u001b[0;94m"), // BLUE + MAGENTA_BRIGHT("\u001b[0;95m"), // MAGENTA + CYAN_BRIGHT("\u001b[0;96m"), // CYAN + WHITE_BRIGHT("\u001b[0;97m"), // WHITE + + // Bold High Intensity + BLACK_BOLD_BRIGHT("\u001b[1;90m"), // BLACK + RED_BOLD_BRIGHT("\u001b[1;91m"), // RED + GREEN_BOLD_BRIGHT("\u001b[1;92m"), // GREEN + YELLOW_BOLD_BRIGHT("\u001b[1;93m"), // YELLOW + BLUE_BOLD_BRIGHT("\u001b[1;94m"), // BLUE + MAGENTA_BOLD_BRIGHT("\u001b[1;95m"), // MAGENTA + CYAN_BOLD_BRIGHT("\u001b[1;96m"), // CYAN + WHITE_BOLD_BRIGHT("\u001b[1;97m"), // WHITE + + // High Intensity backgrounds + BLACK_BACKGROUND_BRIGHT("\u001b[0;100m"), // BLACK + RED_BACKGROUND_BRIGHT("\u001b[0;101m"), // RED + GREEN_BACKGROUND_BRIGHT("\u001b[0;102m"), // GREEN + YELLOW_BACKGROUND_BRIGHT("\u001b[0;103m"), // YELLOW + BLUE_BACKGROUND_BRIGHT("\u001b[0;104m"), // BLUE + MAGENTA_BACKGROUND_BRIGHT("\u001b[0;105m"), // MAGENTA + CYAN_BACKGROUND_BRIGHT("\u001b[0;106m"), // CYAN + WHITE_BACKGROUND_BRIGHT("\u001b[0;107m"); + + /** + * get color str + * + * @return str + */ + override fun toString(): String { + return color + } + + /** + * use color + * + * @param str string + * @return colored str + */ + fun use(str: String): String { + return color + str + RESET + } +} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/objectformatter/DefaultObjFormatter.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/objectformatter/DefaultObjFormatter.kt new file mode 100644 index 0000000..5935079 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/objectformatter/DefaultObjFormatter.kt @@ -0,0 +1,16 @@ +package net.kigawa.kutil.kutil.api.str.objectformatter + +class DefaultObjFormatter : ObjectFormatter { + override fun format(obj: Any?): String { + return when (obj) { + is String -> obj + is Array<*> -> obj.joinToString( + separator = ", ", + prefix = "Array[", + postfix = "]", + transform = { format(obj) } + ) + else -> obj.toString() + } + } +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/objectformatter/ObjectFormatter.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/objectformatter/ObjectFormatter.kt new file mode 100644 index 0000000..aa83137 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/str/objectformatter/ObjectFormatter.kt @@ -0,0 +1,5 @@ +package net.kigawa.kutil.kutil.api.str.objectformatter + +interface ObjectFormatter { + fun format(obj: Any?): String +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/string/KutilString.java b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/string/KutilString.java deleted file mode 100644 index 06c18cf..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/string/KutilString.java +++ /dev/null @@ -1,127 +0,0 @@ -package net.kigawa.kutil.kutil.api.string; - -import java.util.*; -import java.util.function.*; - -/** - * utilities about string - */ -@SuppressWarnings("unused") -public class KutilString { - - /** - * check is int - * - * @param str to test - * @return return true when str is int - */ - public static boolean isInt(String str) { - return str.matches("[+-]?\\d*(\\.\\d+)?"); - } - - /** - * insert symbol between string array - * - * @param sb base string buffer - * @param symbol string symbol - * @param strings base string array - * @return append string buffer - */ - public static StringBuffer insertSymbol(StringBuffer sb, String symbol, String[] strings) { - return insertSymbol(sb, symbol, Arrays.stream(strings).iterator()); - } - - /** - * insert symbol between string Iterable - * - * @param sb base string buffer - * @param symbol string symbol - * @param stringIterable base string iterable - * @return append string buffer - */ - public static StringBuffer insertSymbol(StringBuffer sb, String symbol, Iterable stringIterable) { - return insertSymbol(sb, symbol, stringIterable.iterator()); - } - - /** - * insert symbol between string iterator - * - * @param sb base string buffer - * @param symbol string symbol - * @param iterator base string iterator - * @return append string buffer - */ - public static StringBuffer insertSymbol(StringBuffer sb, String symbol, Iterator iterator) { - return insertSymbol(sb, symbol, iterator, s -> s); - } - - /** - * insert symbol between string that created by function - * - * @param sb base string buffer - * @param symbol string symbol - * @param array base array - * @param function to create function - * @param array type - * @return append string buffer - */ - public static StringBuffer insertSymbol(StringBuffer sb, String symbol, T[] array, Function function) { - return insertSymbol(sb, symbol, Arrays.stream(array).iterator(), function); - } - - /** - * insert symbol between string that created by function - * - * @param sb base string buffer - * @param symbol string symbol - * @param iterable base iterable - * @param function to create function - * @param iterable type - * @return append string buffer - */ - public static StringBuffer insertSymbol(StringBuffer sb, String symbol, Iterable iterable, Function function) { - return insertSymbol(sb, symbol, iterable.iterator(), function); - } - - /** - * insert symbol between string that created by function - * - * @param sb base string buffer - * @param symbol string symbol - * @param iterator base iterator - * @param function to create function - * @param iterator type - * @return append string buffer - */ - public static StringBuffer insertSymbol(StringBuffer sb, String symbol, Iterator iterator, Function function) { - while (iterator.hasNext()) { - sb.append(function.apply(iterator.next())); - if (iterator.hasNext()) sb.append(symbol); - } - return sb; - } - - /** - * insert symbol between string that created by function - * - * @param symbol string symbol - * @param stringIterable base string iterable - * @return created string - */ - public static String insertSymbol(String symbol, Iterable stringIterable) { - return insertSymbol(new StringBuffer(), symbol, stringIterable.iterator()).toString(); - } - - /** - * @param ts array - * @param insert insert str - * @param array type - * @return str - * @deprecated use insertSymbol() - */ - @Deprecated - public static String connectArray(T[] ts, String insert) { - return insertSymbol(insert, Arrays.asList((String[]) ts)); - } - -} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/string/StringColor.java b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/string/StringColor.java deleted file mode 100644 index b7bed94..0000000 --- a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/string/StringColor.java +++ /dev/null @@ -1,105 +0,0 @@ -package net.kigawa.kutil.kutil.api.string; - -/** - * to use colors - */ -@SuppressWarnings("ALL") -public enum StringColor { - //Color end string, color reset - RESET("\033[0m"), - - // Regular Colors. Normal color, no bold, background color etc. - BLACK("\033[0;30m"), // BLACK - RED("\033[0;31m"), // RED - GREEN("\033[0;32m"), // GREEN - YELLOW("\033[0;33m"), // YELLOW - BLUE("\033[0;34m"), // BLUE - MAGENTA("\033[0;35m"), // MAGENTA - CYAN("\033[0;36m"), // CYAN - WHITE("\033[0;37m"), // WHITE - - // Bold - BLACK_BOLD("\033[1;30m"), // BLACK - RED_BOLD("\033[1;31m"), // RED - GREEN_BOLD("\033[1;32m"), // GREEN - YELLOW_BOLD("\033[1;33m"), // YELLOW - BLUE_BOLD("\033[1;34m"), // BLUE - MAGENTA_BOLD("\033[1;35m"), // MAGENTA - CYAN_BOLD("\033[1;36m"), // CYAN - WHITE_BOLD("\033[1;37m"), // WHITE - - // Underline - BLACK_UNDERLINED("\033[4;30m"), // BLACK - RED_UNDERLINED("\033[4;31m"), // RED - GREEN_UNDERLINED("\033[4;32m"), // GREEN - YELLOW_UNDERLINED("\033[4;33m"), // YELLOW - BLUE_UNDERLINED("\033[4;34m"), // BLUE - MAGENTA_UNDERLINED("\033[4;35m"), // MAGENTA - CYAN_UNDERLINED("\033[4;36m"), // CYAN - WHITE_UNDERLINED("\033[4;37m"), // WHITE - - // Background - BLACK_BACKGROUND("\033[40m"), // BLACK - RED_BACKGROUND("\033[41m"), // RED - GREEN_BACKGROUND("\033[42m"), // GREEN - YELLOW_BACKGROUND("\033[43m"), // YELLOW - BLUE_BACKGROUND("\033[44m"), // BLUE - MAGENTA_BACKGROUND("\033[45m"), // MAGENTA - CYAN_BACKGROUND("\033[46m"), // CYAN - WHITE_BACKGROUND("\033[47m"), // WHITE - - // High Intensity - BLACK_BRIGHT("\033[0;90m"), // BLACK - RED_BRIGHT("\033[0;91m"), // RED - GREEN_BRIGHT("\033[0;92m"), // GREEN - YELLOW_BRIGHT("\033[0;93m"), // YELLOW - BLUE_BRIGHT("\033[0;94m"), // BLUE - MAGENTA_BRIGHT("\033[0;95m"), // MAGENTA - CYAN_BRIGHT("\033[0;96m"), // CYAN - WHITE_BRIGHT("\033[0;97m"), // WHITE - - // Bold High Intensity - BLACK_BOLD_BRIGHT("\033[1;90m"), // BLACK - RED_BOLD_BRIGHT("\033[1;91m"), // RED - GREEN_BOLD_BRIGHT("\033[1;92m"), // GREEN - YELLOW_BOLD_BRIGHT("\033[1;93m"), // YELLOW - BLUE_BOLD_BRIGHT("\033[1;94m"), // BLUE - MAGENTA_BOLD_BRIGHT("\033[1;95m"), // MAGENTA - CYAN_BOLD_BRIGHT("\033[1;96m"), // CYAN - WHITE_BOLD_BRIGHT("\033[1;97m"), // WHITE - - // High Intensity backgrounds - BLACK_BACKGROUND_BRIGHT("\033[0;100m"), // BLACK - RED_BACKGROUND_BRIGHT("\033[0;101m"), // RED - GREEN_BACKGROUND_BRIGHT("\033[0;102m"), // GREEN - YELLOW_BACKGROUND_BRIGHT("\033[0;103m"), // YELLOW - BLUE_BACKGROUND_BRIGHT("\033[0;104m"), // BLUE - MAGENTA_BACKGROUND_BRIGHT("\033[0;105m"), // MAGENTA - CYAN_BACKGROUND_BRIGHT("\033[0;106m"), // CYAN - WHITE_BACKGROUND_BRIGHT("\033[0;107m"); - private final String color; - - StringColor(String color) { - this.color = color; - } - - /** - * get color str - * - * @return str - */ - @Override - public String toString() { - return color; - } - - /** - * use color - * - * @param str string - * @return colored str - */ - public String use(String str) { - return color + str + RESET; - } -} diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/AbstractValidator.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/AbstractValidator.kt new file mode 100644 index 0000000..0ec9395 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/AbstractValidator.kt @@ -0,0 +1,18 @@ +package net.kigawa.kutil.kutil.api.validator + +import net.kigawa.kutil.kutil.api.validator.str.StrValidator + +abstract class AbstractValidator( + private val parent: Validator +) : Validator { + final override fun validate(value: ORIGINAL): TO { + val from = parent.validate(value) + return validateTask(from) + } + + abstract fun validateTask(from: FROM): TO + + fun str(): StrValidator { + return StrValidator(this) + } +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/EmptyValidator.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/EmptyValidator.kt new file mode 100644 index 0000000..cdf772c --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/EmptyValidator.kt @@ -0,0 +1,8 @@ +package net.kigawa.kutil.kutil.api.validator + +@Suppress("unused") +class EmptyValidator : Validator { + override fun validate(value: T): T { + return value + } +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/Validator.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/Validator.kt new file mode 100644 index 0000000..4334e9d --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/Validator.kt @@ -0,0 +1,6 @@ +package net.kigawa.kutil.kutil.api.validator + +interface Validator { + fun validate(value: ORIGINAL): TO + +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/str/AbstractStrValidator.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/str/AbstractStrValidator.kt new file mode 100644 index 0000000..c9fdbf8 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/str/AbstractStrValidator.kt @@ -0,0 +1,8 @@ +package net.kigawa.kutil.kutil.api.validator.str + +import net.kigawa.kutil.kutil.api.validator.AbstractValidator +import net.kigawa.kutil.kutil.api.validator.Validator + +abstract class AbstractStrValidator(parent: Validator) : + AbstractValidator(parent) { +} \ No newline at end of file diff --git a/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/str/StrValidator.kt b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/str/StrValidator.kt new file mode 100644 index 0000000..67b9718 --- /dev/null +++ b/api/src/commonMain/kotlin/net/kigawa/kutil/kutil/api/validator/str/StrValidator.kt @@ -0,0 +1,11 @@ +package net.kigawa.kutil.kutil.api.validator.str + +import net.kigawa.kutil.kutil.api.validator.Validator + +class StrValidator(parent: Validator) : + AbstractStrValidator(parent) { + + override fun validateTask(from: FROM): String { + return from.toString() + } +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.js.kt new file mode 100644 index 0000000..708ce3e --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.js.kt @@ -0,0 +1,7 @@ +package net.kigawa.kutil.kutil.api + +/** + * utilities about array + */ +@Suppress("unused", "EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +actual object KutilArray \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.js.kt new file mode 100644 index 0000000..fd2b74e --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.js.kt @@ -0,0 +1,9 @@ +package net.kigawa.kutil.kutil.api + +/** + * utilities about file + */ +@Suppress("unused", "EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +actual object KutilFile { + +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/KutilPlatform.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/KutilPlatform.js.kt new file mode 100644 index 0000000..09c0e2e --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/KutilPlatform.js.kt @@ -0,0 +1,12 @@ +package net.kigawa.kutil.kutil.api + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +actual object KutilPlatform { + actual fun getSystemProperty(name: String): String { + TODO("Not yet implemented") + } + + actual fun getEnv(name: String): String? { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/Paths.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/Paths.js.kt new file mode 100644 index 0000000..0721f1b --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/Paths.js.kt @@ -0,0 +1,13 @@ +package net.kigawa.kutil.kutil.api + +import net.kigawa.kutil.kutil.api.io.fs.KuPath + +@Suppress("unused") +actual enum class Paths { + JAVA + ; + + actual val path: KuPath + get() = TODO("Not yet implemented") + +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/SignalHandler.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/SignalHandler.js.kt new file mode 100644 index 0000000..c2ecf8f --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/SignalHandler.js.kt @@ -0,0 +1,7 @@ +package net.kigawa.kutil.kutil.api + +@Suppress("unused") +actual object SignalHandler { + actual fun shutdownHook(hook: () -> Unit) { + } +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/PCoroutines.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/PCoroutines.js.kt new file mode 100644 index 0000000..dc00daf --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/PCoroutines.js.kt @@ -0,0 +1,10 @@ +package net.kigawa.kutil.kutil.api.concurrent + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +internal actual object PCoroutines { + actual val defaultIoContext: CoroutineDispatcher + get() = Dispatchers.Main +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/DefaultIo.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/DefaultIo.js.kt new file mode 100644 index 0000000..49373d6 --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/DefaultIo.js.kt @@ -0,0 +1,7 @@ +package net.kigawa.kutil.kutil.api.io + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +actual object DefaultIo { + actual val error: WriterIo = FunctionWriterIo { console.error(it) } + actual val out: WriterIo = FunctionWriterIo { console.log(it) } +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/IoException.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/IoException.js.kt new file mode 100644 index 0000000..e0b2671 --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/IoException.js.kt @@ -0,0 +1,4 @@ +package net.kigawa.kutil.kutil.api.io + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +actual open class IoException actual constructor(message: String?) : Exception(message) \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuDirectory.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuDirectory.js.kt new file mode 100644 index 0000000..c0916c5 --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuDirectory.js.kt @@ -0,0 +1,10 @@ +package net.kigawa.kutil.kutil.api.io.fs + +@Suppress( "unused") +actual class KuDirectory( + private val path: KuPath, +) { + actual fun toPath(): KuPath { + return path + } +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuFile.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuFile.js.kt new file mode 100644 index 0000000..6ea3079 --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuFile.js.kt @@ -0,0 +1,4 @@ +package net.kigawa.kutil.kutil.api.io.fs + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +actual class KuFile \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuPath.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuPath.js.kt new file mode 100644 index 0000000..137128c --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuPath.js.kt @@ -0,0 +1,56 @@ +package net.kigawa.kutil.kutil.api.io.fs + +import net.kigawa.kutil.kutil.api.list.KutilList + +@Suppress("unused") +actual class KuPath actual constructor(strPath: String) { + actual companion object { + actual val separator: String = "/" + fun listToPathStr(list: List, isRoot: Boolean): String { + val prefix = if (isRoot) separator else "" + return list + .joinToString(separator = separator, prefix = prefix) + } + } + + private val path: List = strPath.split(separator) + private val isRoot = strPath.startsWith(separator) + + actual fun join(child: String): KuPath { + return KutilList.connectList(path, child.split(separator)) + .let { listToPathStr(it, isRoot) } + .let { KuPath(it) } + } + + actual fun join(child: KuPath): KuPath { + TODO("Not yet implemented") + } + + actual fun strPath(): String { + TODO("Not yet implemented") + } + + actual fun toAbsolute(): KuPath { + TODO("Not yet implemented") + } + + actual fun parent(): KuPath { + TODO("Not yet implemented") + } + + actual fun createDirOrGet(): KuDirectory { + TODO("Not yet implemented") + } + + actual fun toFile(): KuFile { + TODO("Not yet implemented") + } + + actual fun isExists(): Boolean { + TODO("Not yet implemented") + } + + actual fun removeIfExists() { + } + +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/JsDefaultLoggerHandler.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/JsDefaultLoggerHandler.kt new file mode 100644 index 0000000..2153c25 --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/JsDefaultLoggerHandler.kt @@ -0,0 +1,21 @@ +package net.kigawa.kutil.kutil.api.logger + +import net.kigawa.kutil.kutil.api.logger.formatter.DefaultLoggerFormatter +import net.kigawa.kutil.kutil.api.logger.formatter.LoggerFormatter + +internal object JsDefaultLoggerHandler : LoggerHandler { + private var formatter: LoggerFormatter = DefaultLoggerFormatter() + + override fun log(level: LogLevel, message: Any) { + val formattedMsg = formatter.format(LoggerRecord(level, message)) + when (level) { + LogLevel.WARNING -> console.warn(formattedMsg) + LogLevel.INFO -> console.info(formattedMsg) + LogLevel.FINE -> console.log(formattedMsg) + } + } + + override fun setFormatter(loggerFormatter: LoggerFormatter) { + formatter = loggerFormatter + } +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/LogRecord.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/LogRecord.js.kt new file mode 100644 index 0000000..84d0c0e --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/LogRecord.js.kt @@ -0,0 +1,7 @@ +package net.kigawa.kutil.kutil.api.logger + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +actual class LoggerRecord( + actual val level: LogLevel, + actual val message: Any, +) \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/PKuLogger.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/PKuLogger.js.kt new file mode 100644 index 0000000..62547b1 --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/PKuLogger.js.kt @@ -0,0 +1,6 @@ +package net.kigawa.kutil.kutil.api.logger + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +internal actual object PKuLogger { + actual val defaultHandler: LoggerHandler = JsDefaultLoggerHandler +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/DefaultLoggerFormatter.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/DefaultLoggerFormatter.js.kt new file mode 100644 index 0000000..d6d6e1a --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/DefaultLoggerFormatter.js.kt @@ -0,0 +1,10 @@ +package net.kigawa.kutil.kutil.api.logger.formatter + +import net.kigawa.kutil.kutil.api.logger.LoggerRecord + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +actual class DefaultLoggerFormatter : LoggerFormatter { + actual override fun format(logRecord: LoggerRecord): Any { + return logRecord.message + } +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketClient.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketClient.js.kt new file mode 100644 index 0000000..3786d61 --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketClient.js.kt @@ -0,0 +1,20 @@ +package net.kigawa.kutil.kutil.api.net + +import net.kigawa.kutil.kutil.api.concurrent.Coroutines +import net.kigawa.kutil.kutil.api.io.SuspendCloseable +import net.kigawa.kutil.kutil.api.io.fs.KuPath +import net.kigawa.kutil.kutil.api.logger.KuLogger + +@Suppress("unused") +actual class SocketClient actual constructor( + path: KuPath, logger: KuLogger, + coroutines: Coroutines, +) : SuspendCloseable { + actual fun connect(): SocketConnection { + TODO("Not yet implemented") + } + + override suspend fun suspendClose() { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketConnection.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketConnection.js.kt new file mode 100644 index 0000000..32cbf03 --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketConnection.js.kt @@ -0,0 +1,19 @@ +package net.kigawa.kutil.kutil.api.net + +import kotlinx.coroutines.channels.Channel +import net.kigawa.kutil.kutil.api.io.SuspendCloseable + +@Suppress("unused") +actual class SocketConnection : SuspendCloseable { + actual fun reader(): Channel { + TODO("Not yet implemented") + } + + actual fun writer(): Channel { + TODO("Not yet implemented") + } + + override suspend fun suspendClose() { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketServer.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketServer.js.kt new file mode 100644 index 0000000..9cf3752 --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketServer.js.kt @@ -0,0 +1,21 @@ +package net.kigawa.kutil.kutil.api.net + +import kotlinx.coroutines.channels.Channel +import net.kigawa.kutil.kutil.api.concurrent.Coroutines +import net.kigawa.kutil.kutil.api.io.SuspendCloseable +import net.kigawa.kutil.kutil.api.io.fs.KuPath +import net.kigawa.kutil.kutil.api.logger.KuLogger + +@Suppress("unused") +actual class SocketServer actual constructor( + path: KuPath, logger: KuLogger?, + coroutines: Coroutines, +) : SuspendCloseable { + actual fun bind(): Channel { + TODO("Not yet implemented") + } + + override suspend fun suspendClose() { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/Url.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/Url.js.kt new file mode 100644 index 0000000..b65b753 --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/net/Url.js.kt @@ -0,0 +1,9 @@ +package net.kigawa.kutil.kutil.api.net + +import net.kigawa.kutil.kutil.api.io.fs.KuPath + +@Suppress("unused") +actual class Url actual constructor(strUrl: String) { + actual suspend fun download(to: KuPath) { + } +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/os/KutilOS.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/os/KutilOS.js.kt new file mode 100644 index 0000000..917ef3a --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/os/KutilOS.js.kt @@ -0,0 +1,4 @@ +package net.kigawa.kutil.kutil.api.os + +@Suppress("unused", "EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +actual object KutilOS \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcessBuilder.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcessBuilder.js.kt new file mode 100644 index 0000000..862c544 --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcessBuilder.js.kt @@ -0,0 +1,16 @@ +package net.kigawa.kutil.kutil.api.process + +import net.kigawa.kutil.kutil.api.io.fs.KuDirectory + +actual class KuProcessBuilder actual constructor(vararg args: String) { + actual fun start(): KuProcess { + TODO("Not yet implemented") + } + + @Suppress("unused") + actual fun workDir( + directory: KuDirectory?, + ): KuProcessBuilder { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflect.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflect.js.kt new file mode 100644 index 0000000..2f3b717 --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflect.js.kt @@ -0,0 +1,4 @@ +package net.kigawa.kutil.kutil.api.reflection + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +actual object KutilReflect \ No newline at end of file diff --git a/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/str/KutilString.js.kt b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/str/KutilString.js.kt new file mode 100644 index 0000000..479bf7c --- /dev/null +++ b/api/src/jsMain/kotlin/net/kigawa/kutil/kutil/api/str/KutilString.js.kt @@ -0,0 +1,19 @@ +package net.kigawa.kutil.kutil.api.str + +/** + * utilities about string + */ +@Suppress("unused", "EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +actual object KutilString { + /** + * check is int + * + * @param str to test + * @return return true when str is int + */ + actual fun isInt(str: String): Boolean { + return str.matches("[+-]?\\d*(\\.\\d+)?".toRegex()) + } + + +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.jvm.kt new file mode 100644 index 0000000..4a24487 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/KutilArray.jvm.kt @@ -0,0 +1,28 @@ +package net.kigawa.kutil.kutil.api + +@Suppress("unused") +actual object KutilArray { + /** + * test obj contain in array + * + * @param array array to test + * @param obj obj to test + * @param source class type + * @param test class type + * @return return true when contain + */ + fun contain(array: Array, obj: T): Boolean { + return array.contains(obj) + } + + /** + * creat set from array + * + * @param ts base array + * @param class type + * @return created set + */ + fun toSet(ts: Array): Set { + return ts.toSet() + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.jvm.kt new file mode 100644 index 0000000..953562e --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/KutilFile.jvm.kt @@ -0,0 +1,37 @@ +package net.kigawa.kutil.kutil.api + +@Suppress("unused") +actual object KutilFile { + /** + * get child file from current + * + * @param path child file names + * @return child file + */ + fun getRelativeFile(vararg path: String): java.io.File { + return getFile(java.nio.file.Paths.get("").toAbsolutePath().toFile(), *path) + } + + /** + * get child file + * + * @param parent parent file + * @param path child file names + * @return child file + */ + fun getFile(parent: java.io.File, vararg path: String): java.io.File { + var file: java.io.File = parent + for (name in path) { + file = java.io.File(file, name) + } + return file + } + + val absolutFile: java.io.File + /** + * get current file as absolute + * + * @return current dir + */ + get() = java.nio.file.Paths.get("").toAbsolutePath().toFile() +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/KutilPlatform.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/KutilPlatform.jvm.kt new file mode 100644 index 0000000..695698f --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/KutilPlatform.jvm.kt @@ -0,0 +1,6 @@ +package net.kigawa.kutil.kutil.api + +actual object KutilPlatform { + actual fun getSystemProperty(name: String): String = System.getProperty(name) + actual fun getEnv(name: String): String? = System.getenv(name) +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/Paths.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/Paths.jvm.kt new file mode 100644 index 0000000..9077b4d --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/Paths.jvm.kt @@ -0,0 +1,12 @@ +package net.kigawa.kutil.kutil.api + +import net.kigawa.kutil.kutil.api.io.fs.KuPath + +@Suppress("unused") +actual enum class Paths( + actual val path: KuPath, +) { + JAVA(KuPath(System.getProperty("java.home")).join("bin/java")) + ; + +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/SignalHandler.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/SignalHandler.jvm.kt new file mode 100644 index 0000000..52d67a8 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/SignalHandler.jvm.kt @@ -0,0 +1,12 @@ +package net.kigawa.kutil.kutil.api + +import kotlin.concurrent.thread + +@Suppress("unused") +actual object SignalHandler { + actual fun shutdownHook(hook: () -> Unit) { + Runtime.getRuntime().addShutdownHook(thread(start = false) { + hook() + }) + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/PCoroutines.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/PCoroutines.jvm.kt new file mode 100644 index 0000000..1f56495 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/concurrent/PCoroutines.jvm.kt @@ -0,0 +1,9 @@ +package net.kigawa.kutil.kutil.api.concurrent + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +internal actual object PCoroutines { + actual val defaultIoContext: CoroutineDispatcher + get() = Dispatchers.IO +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/DefaultIo.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/DefaultIo.jvm.kt new file mode 100644 index 0000000..e465429 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/DefaultIo.jvm.kt @@ -0,0 +1,24 @@ +package net.kigawa.kutil.kutil.api.io + +import kotlinx.coroutines.channels.Channel +import net.kigawa.kutil.kutil.api.concurrent.Coroutines + +actual object DefaultIo { + actual val error: WriterIo + actual val out: WriterIo + + init { + val infoChannel = Channel() + val errorChannel = Channel() + + out = ChannelWriterIo(infoChannel) + error = ChannelWriterIo(errorChannel) + + infoChannel.dispatchForEach(Coroutines.defaultIoContext) { + println(it) + } + errorChannel.dispatchForEach(Coroutines.defaultIoContext) { + System.err.println(it) + } + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/IoException.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/IoException.jvm.kt new file mode 100644 index 0000000..b641daf --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/IoException.jvm.kt @@ -0,0 +1,8 @@ +package net.kigawa.kutil.kutil.api.io + +import java.io.IOException + +@Suppress("unused") +actual open class IoException actual constructor(message: String?) : IOException(message) { + constructor(exception: IOException) : this(exception.message) +} diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/IoFunc.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/IoFunc.kt new file mode 100644 index 0000000..7422d9d --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/IoFunc.kt @@ -0,0 +1,18 @@ +package net.kigawa.kutil.kutil.api.io + +import kotlinx.coroutines.withContext +import net.kigawa.kutil.kutil.api.concurrent.Coroutines +import java.io.BufferedReader +import kotlin.coroutines.CoroutineContext + +suspend inline fun BufferedReader.forEachLineSuspend( + context: CoroutineContext = Coroutines.defaultIoContext, + block: (String) -> Unit, +) { + while (true) { + val line: String = withContext(context) { + readLine() + } ?: return + block(line) + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/ReaderStreamIo.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/ReaderStreamIo.kt new file mode 100644 index 0000000..b37eb6b --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/ReaderStreamIo.kt @@ -0,0 +1,32 @@ +package net.kigawa.kutil.kutil.api.io + +import kotlinx.coroutines.channels.Channel +import net.kigawa.kutil.kutil.api.concurrent.Coroutines +import java.io.BufferedReader + +class ReaderStreamIo( + coroutines: Coroutines, + private val reader: BufferedReader, + private val onClose: (suspend () -> Unit)? = null, +) : ChannelReaderIo(Channel()), SuspendCloseable { + init { + coroutines.launchIo { + try { + reader.forEachLineSuspend { + channel.send(it) + } + } finally { + suspendClose() + } + } + } + + override suspend fun suspendClose() { + try { + reader.run { close() } + } finally { + channel.close() + onClose?.invoke() + } + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/WriterStreamIo.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/WriterStreamIo.kt new file mode 100644 index 0000000..a043f45 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/WriterStreamIo.kt @@ -0,0 +1,36 @@ +package net.kigawa.mcsm.util.io + +import kotlinx.coroutines.channels.Channel +import net.kigawa.kutil.kutil.api.concurrent.Coroutines +import net.kigawa.kutil.kutil.api.io.ChannelWriterIo +import net.kigawa.kutil.kutil.api.io.SuspendCloseable +import java.io.BufferedWriter + +class WriterStreamIo( + coroutines: Coroutines, + private val writer: BufferedWriter, + private val onClose: (suspend () -> Unit)? = null, +) : ChannelWriterIo(Channel()), SuspendCloseable { + init { + coroutines.launchIo { + try { + for (line in channel) { + writer.write(line) + writer.newLine() + writer.flush() + } + } finally { + suspendClose() + } + } + } + + override suspend fun suspendClose() { + try { + channel.close() + writer.run { close() } + } finally { + onClose?.invoke() + } + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuDirectory.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuDirectory.jvm.kt new file mode 100644 index 0000000..52725b4 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuDirectory.jvm.kt @@ -0,0 +1,18 @@ +package net.kigawa.kutil.kutil.api.io.fs + +import net.kigawa.kutil.kutil.api.io.NotDirectoryException +import java.io.File + +@Suppress("unused") +actual class KuDirectory( + val nativeDirectory: File, +) { + init { + if (!nativeDirectory.isDirectory) + throw NotDirectoryException("$nativeDirectory is not directory") + } + + actual fun toPath(): KuPath { + return KuPath(nativeDirectory.path) + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuFile.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuFile.jvm.kt new file mode 100644 index 0000000..edf50e5 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/KuFile.jvm.kt @@ -0,0 +1,12 @@ +package net.kigawa.kutil.kutil.api.io.fs + +import java.io.File + +@Suppress("unused") +actual class KuFile( + val nativeFile: File, +) { + fun remove() { + nativeFile.delete() + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/Path.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/Path.jvm.kt new file mode 100644 index 0000000..5701730 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/io/fs/Path.jvm.kt @@ -0,0 +1,56 @@ +package net.kigawa.kutil.kutil.api.io.fs + +import java.io.File +import java.nio.file.Files +import java.nio.file.Path +import kotlin.io.path.* + +@Suppress("unused") +actual class KuPath( + private val path: Path, +) { + actual companion object { + actual val separator: String + get() = File.separator + } + + actual constructor(strPath: String) : this(Path(strPath)) + + actual fun join(child: String): KuPath { + return KuPath(path.resolve(child)) + } + + actual fun join(child: KuPath): KuPath { + return KuPath(path.resolve(child.path)) + } + + actual fun toAbsolute(): KuPath { + return KuPath(path.toAbsolutePath()) + } + + actual fun strPath(): String { + return path.pathString + } + + fun javaPath() = path + actual fun parent(): KuPath { + return KuPath(path.parent) + } + + actual fun createDirOrGet(): KuDirectory { + if (!path.isDirectory()) Files.createDirectory(path) + return KuDirectory(path.toFile()) + } + + actual fun toFile(): KuFile { + return KuFile(path.toFile()) + } + + actual fun isExists(): Boolean { + return path.exists() + } + + actual fun removeIfExists() { + path.deleteIfExists() + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/Func.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/Func.kt new file mode 100644 index 0000000..59d65bd --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/Func.kt @@ -0,0 +1,12 @@ +package net.kigawa.kutil.kutil.api.logger + +import java.util.logging.Level + + +fun LogLevel.javaLevel(): Level? { + return Level.parse(this.name) +} + +fun Level.logLevel(): LogLevel = LogLevel.entries.first { + it.name.lowercase() == this.name.lowercase() +} diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/JvmDefaultLoggerHandler.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/JvmDefaultLoggerHandler.kt new file mode 100644 index 0000000..9d053d8 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/JvmDefaultLoggerHandler.kt @@ -0,0 +1,30 @@ +package net.kigawa.kutil.kutil.api.logger + +import net.kigawa.kutil.kutil.api.logger.formatter.DefaultLoggerFormatter +import net.kigawa.kutil.kutil.api.logger.formatter.LoggerFormatter +import net.kigawa.kutil.kutil.api.logger.formatter.LoggerFormatterBridge +import net.kigawa.kutil.kutil.api.str.objectformatter.DefaultObjFormatter +import java.util.logging.ConsoleHandler +import java.util.logging.Logger + +internal object JvmDefaultLoggerHandler : LoggerHandler { + private val logger = Logger.getLogger("") + private val objectFormatter = DefaultObjFormatter() + + init { + val consoleHandler = ConsoleHandler() + consoleHandler.formatter = LoggerFormatterBridge(DefaultLoggerFormatter()) + logger.addHandler(consoleHandler) + } + + override fun log(level: LogLevel, message: Any) { + logger.log(level.javaLevel(), objectFormatter.format(message)) + } + + override fun setFormatter(loggerFormatter: LoggerFormatter) { + val formatter = LoggerFormatterBridge(loggerFormatter) + logger.handlers.forEach { + it.formatter = formatter + } + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/KFileFormatter.java b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/KFileFormatter.java new file mode 100644 index 0000000..e33564a --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/KFileFormatter.java @@ -0,0 +1,24 @@ +package net.kigawa.kutil.kutil.api.logger; + +import java.util.Calendar; +import java.util.logging.LogRecord; + +public class KFileFormatter extends java.util.logging.Formatter +{ + private final Calendar calendar = Calendar.getInstance(); + + @Override + public String format(LogRecord record) + { + StringBuffer sb = new StringBuffer(); + calendar.setTimeInMillis(record.getMillis()); + sb + .append(calendar.get(Calendar.MONTH)).append("-").append(calendar.get(Calendar.DAY_OF_MONTH)) + .append("-").append(calendar.get(Calendar.HOUR_OF_DAY)).append("-") + .append(calendar.get(Calendar.MINUTE)).append("-").append(calendar.get(Calendar.SECOND)) + .append("[").append(record.getLevel().getName()).append("] ") + .append("|") + .append(record.getMessage()).append("\n"); + return sb.toString(); + } +} diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/LogRecord.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/LogRecord.jvm.kt new file mode 100644 index 0000000..02fcc77 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/LogRecord.jvm.kt @@ -0,0 +1,13 @@ +package net.kigawa.kutil.kutil.api.logger + +import java.util.logging.LogRecord + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +actual class LoggerRecord( + val logRecord: LogRecord, +) { + actual val level: LogLevel + get() = logRecord.level.logLevel() + actual val message: Any + get() = logRecord.message +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/PKuLogger.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/PKuLogger.jvm.kt new file mode 100644 index 0000000..3e4ad4d --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/PKuLogger.jvm.kt @@ -0,0 +1,6 @@ +package net.kigawa.kutil.kutil.api.logger + +@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") +internal actual object PKuLogger { + actual val defaultHandler: LoggerHandler = JvmDefaultLoggerHandler +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/DefaultLoggerFormatter.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/DefaultLoggerFormatter.jvm.kt new file mode 100644 index 0000000..2bed636 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/DefaultLoggerFormatter.jvm.kt @@ -0,0 +1,17 @@ +package net.kigawa.kutil.kutil.api.logger.formatter + +import net.kigawa.kutil.kutil.api.logger.LoggerRecord +import net.kigawa.kutil.kutil.api.str.objectformatter.DefaultObjFormatter +import java.time.Instant +import java.time.ZoneId +import java.time.format.DateTimeFormatter + +actual class DefaultLoggerFormatter : LoggerFormatter { + private val datetimeFormatter = DateTimeFormatter.ofPattern("yy-MM-dd|HH-ss") + private val objectFormatter = DefaultObjFormatter() + actual override fun format(logRecord: LoggerRecord): Any { + val datetime = Instant.ofEpochMilli(logRecord.logRecord.millis).atZone(ZoneId.systemDefault()) + val datetimeStr = datetime.format(datetimeFormatter) + return "$datetimeStr[${logRecord.level.name}]|${objectFormatter.format(logRecord.message)}\n" + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/LoggerFormatterBridge.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/LoggerFormatterBridge.kt new file mode 100644 index 0000000..9099026 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/logger/formatter/LoggerFormatterBridge.kt @@ -0,0 +1,17 @@ +package net.kigawa.kutil.kutil.api.logger.formatter + +import net.kigawa.kutil.kutil.api.logger.LoggerRecord +import net.kigawa.kutil.kutil.api.str.objectformatter.DefaultObjFormatter +import net.kigawa.kutil.kutil.api.str.objectformatter.ObjectFormatter +import java.util.logging.Formatter +import java.util.logging.LogRecord + +class LoggerFormatterBridge( + private val loggerFormatter: LoggerFormatter, + private val objectFormatter: ObjectFormatter = DefaultObjFormatter(), +) : Formatter() { + override fun format(record: LogRecord): String = objectFormatter.format( + loggerFormatter.format(LoggerRecord(record)) + ) + +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketClient.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketClient.jvm.kt new file mode 100644 index 0000000..27a6799 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketClient.jvm.kt @@ -0,0 +1,27 @@ +package net.kigawa.kutil.kutil.api.net + +import net.kigawa.kutil.kutil.api.concurrent.Coroutines +import net.kigawa.kutil.kutil.api.io.SuspendCloseable +import net.kigawa.kutil.kutil.api.io.fs.KuPath +import net.kigawa.kutil.kutil.api.logger.KuLogger +import java.net.UnixDomainSocketAddress +import java.nio.channels.SocketChannel + +@Suppress("unused") +actual class SocketClient actual constructor( + path: KuPath, + private val logger: KuLogger, + private val coroutines: Coroutines, +) : SuspendCloseable { + private val socketAddress = UnixDomainSocketAddress.of(path.javaPath()) + private val socketChannel = SocketChannel.open(socketAddress) + actual fun connect(): SocketConnection { + return SocketConnection(socketChannel, logger, coroutines) + } + + override suspend fun suspendClose() { + coroutines.withContextIo { + socketChannel.close() + } + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketConnection.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketConnection.jvm.kt new file mode 100644 index 0000000..3c51bc4 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketConnection.jvm.kt @@ -0,0 +1,84 @@ +package net.kigawa.kutil.kutil.api.net + +import kotlinx.coroutines.cancelAndJoin +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import net.kigawa.kutil.kutil.api.concurrent.Coroutines +import net.kigawa.kutil.kutil.api.io.SuspendCloseable +import net.kigawa.kutil.kutil.api.logger.KuLogger +import java.nio.ByteBuffer +import java.nio.channels.ClosedChannelException +import java.nio.channels.SocketChannel +import java.nio.charset.StandardCharsets + +@Suppress("unused") +actual class SocketConnection( + private val socketChannel: SocketChannel, + private val logger: KuLogger?, + private val coroutines: Coroutines, +) : SuspendCloseable { + private val reader = Channel() + private val writer = Channel() + private val readTask = coroutines.launchIo { + try { + while (socketChannel.isConnected && isActive) { + logger?.fine("reading socket..") + @Suppress("CanBeVal") + var buf = ByteBuffer.allocate(1024) + val read = coroutines.withContextIo { + socketChannel.read(buf) + } + logger?.fine("read socket $buf") + if (read <= 0) { + suspendClose() + break + } + + val sb = StringBuilder() + buf.flip() + val str = StandardCharsets.UTF_8.decode(buf).toString() + + logger?.fine("read text '$str'") + + str.forEach { + if (it == '\n') { + reader.send(sb.toString()) + sb.clear() + return@forEach + } + sb.append(it) + } + } + } catch (_: ClosedChannelException) { + } finally { + reader.close() + } + } + private val writerTask = coroutines.launchIo { + socketChannel.use { socketChannel -> + for (str in writer) { + @Suppress("VARIABLE_WITH_REDUNDANT_INITIALIZER") + var buf = ByteBuffer.allocate(1024) + buf = StandardCharsets.UTF_8.encode((str + "\n")) + logger?.fine("write text to socket $str") + socketChannel.write(buf) + } + } + } + + actual fun reader(): Channel { + return reader + } + + actual fun writer(): Channel { + return writer + } + + override suspend fun suspendClose() { + writer.close() + delay(100) + writerTask.cancelAndJoin() + readTask.cancelAndJoin() + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketServer.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketServer.kt new file mode 100644 index 0000000..3dbe4ab --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/SocketServer.kt @@ -0,0 +1,65 @@ +package net.kigawa.kutil.kutil.api.net + +import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.Job +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.isActive +import net.kigawa.kutil.kutil.api.concurrent.Coroutines +import net.kigawa.kutil.kutil.api.io.SuspendCloseable +import net.kigawa.kutil.kutil.api.io.fs.KuPath +import net.kigawa.kutil.kutil.api.logger.KuLogger +import java.net.BindException +import java.net.StandardProtocolFamily +import java.net.UnixDomainSocketAddress +import java.nio.channels.AsynchronousCloseException +import java.nio.channels.ServerSocketChannel + +@Suppress("unused") +actual class SocketServer actual constructor( + path: KuPath, + private val logger: KuLogger?, + private val coroutines: Coroutines, +) : SuspendCloseable { + private val socketAddress = UnixDomainSocketAddress.of(path.javaPath()) + private val conChannel = Channel() + private val serverSocketChannel: ServerSocketChannel + private val bindTask: Job + + init { + if (path.isExists()) path.removeIfExists() + try { + serverSocketChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX).bind(socketAddress) + } catch (e: BindException) { + conChannel.close() + throw e + } + bindTask = coroutines.launchIo(start = CoroutineStart.LAZY) { + try { + while (serverSocketChannel.isOpen && isActive) { + conChannel.send( + SocketConnection(serverSocketChannel.accept(), logger, coroutines) + ) + logger?.fine("client connected") + } + + } catch (_: AsynchronousCloseException) { + } finally { + conChannel.close() + serverSocketChannel.close() + } + } + } + + actual fun bind(): Channel { + bindTask.start() + return conChannel + } + + override suspend fun suspendClose() { + coroutines.withContextIo { + serverSocketChannel.close() + } + + bindTask.join() + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/Url.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/Url.kt new file mode 100644 index 0000000..0c5228b --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/net/Url.kt @@ -0,0 +1,29 @@ +package net.kigawa.kutil.kutil.api.net + +import kotlinx.coroutines.withContext +import net.kigawa.kutil.kutil.api.concurrent.Coroutines +import net.kigawa.kutil.kutil.api.io.fs.KuPath +import java.io.FileOutputStream +import java.net.URI +import java.nio.channels.Channels + +@Suppress("unused") +actual class Url actual constructor( + strUrl: String, +) { + private val nativeUri = URI(strUrl) + actual suspend fun download(to: KuPath) { + withContext(Coroutines.defaultIoContext) { + nativeUri.toURL().openStream().let { + Channels.newChannel(it) + }.use { channel -> + FileOutputStream(to.toFile().nativeFile).use { + it.channel.transferFrom(channel, 0, Long.MAX_VALUE) + } + } + } + + } + + +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/os/KutilOS.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/os/KutilOS.jvm.kt new file mode 100644 index 0000000..e013f3c --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/os/KutilOS.jvm.kt @@ -0,0 +1,72 @@ +package net.kigawa.kutil.kutil.api.os + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import net.kigawa.kutil.kutil.api.KutilPlatform +import net.kigawa.kutil.kutil.api.io.DefaultIo +import net.kigawa.kutil.kutil.api.Version +import net.kigawa.kutil.kutil.api.process.KuProcessBuilder + +@Suppress("MemberVisibilityCanBePrivate", "unused") +actual object KutilOS { + private val OS_NAME = KutilPlatform.getSystemProperty("os.name") + val OS_TYPE = getOsType() + val OS_VERSION = getVersion() + + private fun getOsType(): OSType { + if (OS_NAME.lowercase().startsWith("win")) return OSType.WINDOWS + if (OS_NAME.lowercase().startsWith("mac")) return OSType.MAC + if (OS_NAME.lowercase().startsWith("linux")) { + return getLinuxType() + } + return OSType.OTHER + } + + private fun getVersion(): Version? { + return when (OS_TYPE) { + OSType.LINUX -> { + val process = KuProcessBuilder("lsb_release", "-i").start() + CoroutineScope(Dispatchers.IO).launch { + process.errReader().forEach { + DefaultIo.error.writeLine(it) + } + } + + val strVersion = runBlocking { + process + .reader() + .read() + }.split(":") + .getOrNull(1) + ?.trim() + ?: return null + + return Version(strVersion) + } + + else -> null + } + } + + private fun getLinuxType(): OSType { + val process = KuProcessBuilder("lsb_release", "-i").start() + CoroutineScope(Dispatchers.IO).launch { + process.errReader().forEach { + DefaultIo.error.writeLine(it) + } + } + val id = runBlocking { + process + .reader() + .read() + }.split(":") + .getOrNull(1) + ?.trim() + ?: return OSType.LINUX + + if (id.lowercase() == "ubuntu") return OSType.UBUNTU + return OSType.LINUX + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/process/JvmProcess.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/process/JvmProcess.kt new file mode 100644 index 0000000..899b87a --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/process/JvmProcess.kt @@ -0,0 +1,54 @@ +package net.kigawa.kutil.kutil.api.process + +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.withContext +import net.kigawa.kutil.kutil.api.concurrent.Coroutines +import net.kigawa.kutil.kutil.api.io.ReaderIo +import net.kigawa.kutil.kutil.api.io.WriterIo +import net.kigawa.kutil.kutil.api.io.ReaderStreamIo +import net.kigawa.mcsm.util.io.WriterStreamIo + +class JvmProcess( + private val process: Process, + private val coroutines: Coroutines = Coroutines.defaultCoroutines, +) : KuProcess { + private val isClosed = MutableStateFlow(false) + private val writer = WriterStreamIo(coroutines, process.outputWriter()) { + if (!isClosed.value) return@WriterStreamIo suspendClose() + try { + process.destroy() + } finally { + reader.suspendClose() + } + } + private val reader = ReaderStreamIo(coroutines, process.inputReader()) { + if (!isClosed.value) return@ReaderStreamIo suspendClose() + errReader.suspendClose() + } + private val errReader = ReaderStreamIo(coroutines, process.errorReader()) { + if (!isClosed.value) return@ReaderStreamIo suspendClose() + } + + override fun reader(): ReaderIo { + return reader + } + + override fun errReader(): ReaderIo { + return errReader + } + + override suspend fun waitFor() { + withContext(coroutines.ioContext) { + process.waitFor() + } + } + + override suspend fun suspendClose() { + if (!isClosed.compareAndSet(expect = false, update = true)) return + writer.suspendClose() + } + + override fun writer(): WriterIo { + return writer + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcessBuilder.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcessBuilder.jvm.kt new file mode 100644 index 0000000..f1617a8 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/process/KuProcessBuilder.jvm.kt @@ -0,0 +1,24 @@ +package net.kigawa.kutil.kutil.api.process + +import net.kigawa.kutil.kutil.api.io.IoException +import net.kigawa.kutil.kutil.api.io.fs.KuDirectory + +import java.io.IOException + +@Suppress("unused") +actual class KuProcessBuilder actual constructor(vararg args: String) { + private val processBuilder = ProcessBuilder(*args) + + actual fun start(): KuProcess { + try { + return JvmProcess(processBuilder.start()) + } catch (e: IOException) { + throw IoException(e) + } + } + + actual fun workDir(directory: KuDirectory?): KuProcessBuilder { + processBuilder.directory(directory?.nativeDirectory) + return this + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflect.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflect.jvm.kt new file mode 100644 index 0000000..21342b1 --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflect.jvm.kt @@ -0,0 +1,54 @@ +package net.kigawa.kutil.kutil.api.reflection + +import java.lang.reflect.Field +import java.lang.reflect.Member +import java.lang.reflect.Method +import java.lang.reflect.Modifier + +@Suppress("unused") +actual object KutilReflect { + @JvmStatic + fun getAllExitFields(clazz: Class<*>): List { + return getAllParentClasses(clazz) + .flatMap {it.declaredFields.asList()} + } + + @JvmStatic + fun getAllExitMethod(clazz: Class<*>): List { + return getAllParentClasses(clazz) + .flatMap {it.declaredMethods.asList()} + } + + @JvmStatic + fun getAllExitAnnotation(clazz: Class<*>, annotationClass: Class): MutableList { + val list = mutableListOf() + getAllParentClasses(clazz).forEach { + val annotation = it.getAnnotation(annotationClass) ?: return@forEach + list.add(annotation) + } + return list + } + @JvmStatic + fun getAllParentClasses(clazz: Class<*>): MutableList> { + val list = mutableListOf(clazz) + clazz.superclass?.let {list.addAll(getAllParentClasses(clazz.superclass))} + clazz.interfaces.forEach { + list.addAll(getAllParentClasses(it)) + } + return list + } + @JvmStatic + fun isStatic(member: Member): Boolean { + return Modifier.isStatic(member.modifiers) + } + + @JvmStatic + fun isFinal(member: Member): Boolean { + return Modifier.isFinal(member.modifiers) + } + + @JvmStatic + fun instanceOf(clazz: Class<*>, superClass: Class<*>): Boolean { + return getAllParentClasses(clazz).contains(superClass) + } +} \ No newline at end of file diff --git a/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/str/KutilString.jvm.kt b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/str/KutilString.jvm.kt new file mode 100644 index 0000000..a26123a --- /dev/null +++ b/api/src/jvmMain/kotlin/net/kigawa/kutil/kutil/api/str/KutilString.jvm.kt @@ -0,0 +1,116 @@ +package net.kigawa.kutil.kutil.api.str + +import java.util.* +import java.util.function.Function + +@Suppress("unused") +actual object KutilString { + + /** + * insert symbol between string array + * + * @param sb base string buffer + * @param symbol string symbol + * @param strings base string array + * @return append string buffer + */ + fun insertSymbol(sb: StringBuffer, symbol: String?, strings: Array?): StringBuffer { + return insertSymbol(sb, symbol, Arrays.stream(strings).iterator()) + } + + /** + * insert symbol between string Iterable + * + * @param sb base string buffer + * @param symbol string symbol + * @param stringIterable base string iterable + * @return append string buffer + */ + fun insertSymbol( + sb: StringBuffer, symbol: String?, stringIterable: Iterable, + ): StringBuffer { + return insertSymbol(sb, symbol, stringIterable.iterator()) + } + + /** + * insert symbol between string iterator + * + * @param sb base string buffer + * @param symbol string symbol + * @param iterator base string iterator + * @return append string buffer + */ + fun insertSymbol(sb: StringBuffer, symbol: String?, iterator: Iterator): StringBuffer { + return insertSymbol(sb, symbol, iterator) { s: String? -> s } + } + + /** + * insert symbol between string that created by function + * + * @param sb base string buffer + * @param symbol string symbol + * @param array base array + * @param function to create function + * @param array type + * @return append string buffer + */ + fun insertSymbol( + sb: StringBuffer, symbol: String?, array: Array?, function: Function, + ): StringBuffer { + return insertSymbol(sb, symbol, Arrays.stream(array).iterator(), function) + } + + /** + * insert symbol between string that created by function + * + * @param sb base string buffer + * @param symbol string symbol + * @param iterable base iterable + * @param function to create function + * @param iterable type + * @return append string buffer + */ + fun insertSymbol( + sb: StringBuffer, symbol: String?, iterable: Iterable, + function: Function, + ): StringBuffer { + return insertSymbol(sb, symbol, iterable.iterator(), function) + } + + /** + * insert symbol between string that created by function + * + * @param sb base string buffer + * @param symbol string symbol + * @param iterator base iterator + * @param function to create function + * @param iterator type + * @return append string buffer + */ + fun insertSymbol( + sb: StringBuffer, symbol: String?, iterator: Iterator, + function: Function, + ): StringBuffer { + while (iterator.hasNext()) { + sb.append(function.apply(iterator.next())) + if (iterator.hasNext()) sb.append(symbol) + } + return sb + } + + /** + * insert symbol between string that created by function + * + * @param symbol string symbol + * @param stringIterable base string iterable + * @return created string + */ + fun insertSymbol(symbol: String?, stringIterable: Iterable): String { + return insertSymbol(StringBuffer(), symbol, stringIterable.iterator()).toString() + } + + actual fun isInt(str: String): Boolean { + return str.matches("[+-]?\\d*(\\.\\d+)?".toRegex()) + } + +} \ No newline at end of file diff --git a/api/src/jvmTest/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflectTest.kt b/api/src/jvmTest/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflectTest.kt new file mode 100644 index 0000000..e81081a --- /dev/null +++ b/api/src/jvmTest/kotlin/net/kigawa/kutil/kutil/api/reflection/KutilReflectTest.kt @@ -0,0 +1,10 @@ +package net.kigawa.kutil.kutil.api.reflection + +import kotlin.test.Test + +class KutilReflectTest { + @Test + fun getAllParentClasses() { + KutilReflect.getAllParentClasses(javaClass) + } +} \ No newline at end of file diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 47055e2..41c4515 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -7,7 +7,7 @@ plugins { `kotlin-dsl` } dependencies{ - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20") } repositories { diff --git a/buildSrc/src/main/kotlin/net.kigawa.kutil.kutil.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/net.kigawa.kutil.kutil.java-conventions.gradle.kts index 88fc85e..2dac4f2 100644 --- a/buildSrc/src/main/kotlin/net.kigawa.kutil.kutil.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/net.kigawa.kutil.kutil.java-conventions.gradle.kts @@ -2,18 +2,15 @@ * This file was generated by the Gradle 'init' task. */ import dependencies.ProjectConfig -import java.net.URI +import org.jetbrains.kotlin.gradle.dsl.KotlinCompile plugins { kotlin("multiplatform") - `maven-publish` } repositories { mavenLocal() - maven { - url = uri("https://repo.maven.apache.org/maven2/") - } + mavenCentral() maven { url = uri("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") @@ -21,6 +18,8 @@ repositories { } dependencies { + commonMainImplementation("org.jetbrains.kotlin:kotlin-stdlib") + commonTestImplementation(kotlin("test-common")) } version = ProjectConfig.VERSION @@ -28,52 +27,38 @@ group = ProjectConfig.GROUP kotlin { - jvm { + jvm("jvm") { + } + js("js") { + browser {} + nodejs { } + } + + sourceSets { + val jvmMain by getting { + dependencies { + implementation(kotlin("test-junit5")) + } + + } + val jvmTest by getting + val commonMain by getting + val commonTest by getting } } -publishing { - publications { - create("mavenJava") { - pom { - description.set("utilities for java") - url.set("https://github.com/kigawa01/kutil-java/") - properties.set( - mapOf( - ) - ) - licenses { - license { - name.set("MIT License") - url.set("http://www.opensource.org/licenses/mit-license.php") - } - } - developers { - developer { - id.set("net.kigawa") - name.set("kigawa") - email.set("contact@kigawa.net") - } - } - scm { - connection.set("scm:git:https://github.com/kigawa01/kutil-java.git") - developerConnection.set("scm:git:https://github.com/kigawa01/kutil-java.git") - url.set("https://github.com/kigawa01/kutil-java") - } - } +tasks { + withType { + kotlinOptions { + jvmTarget = "${JavaVersion.VERSION_17}" } } - - repositories { - maven { - name = "OSSRH" - url = URI("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") - credentials { - username = System.getenv("MAVEN_USERNAME") - password = System.getenv("MAVEN_PASSWORD") - } + withType> { + kotlinOptions { + freeCompilerArgs += "-Xexpect-actual-classes" } } -} + +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..033e24c4cdf41af1ab109bc7f253b2b887023340 GIT binary patch literal 63375 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≫L+crb^Bz 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.0.0": + version "20.11.30" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.30.tgz#9c33467fc23167a347e73834f788f4b9f399d66f" + integrity sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw== + dependencies: + undici-types "~5.26.4" + +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.11.5": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" + integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== + +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== + +"@webassemblyjs/helper-buffer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" + integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== + +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== + +"@webassemblyjs/helper-wasm-section@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" + integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.12.1" + +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.11.5": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" + integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-opt" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/wast-printer" "1.12.1" + +"@webassemblyjs/wasm-gen@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" + integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" + integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.11.5": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" + integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" + integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^2.1.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.1.1.tgz#3b2f852e91dac6e3b85fb2a314fb8bef46d94646" + integrity sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw== + +"@webpack-cli/info@^2.0.1": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.2.tgz#cc3fbf22efeb88ff62310cf885c5b09f44ae0fdd" + integrity sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A== + +"@webpack-cli/serve@^2.0.3": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.5.tgz#325db42395cd49fe6c14057f9a900e427df8810e" + integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abab@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== + +accepts@~1.3.4: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-assertions@^1.7.6: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.7.1, acorn@^8.8.2: + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +binary-extensions@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== + +body-parser@^1.19.0: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserslist@^4.14.5: + version "4.23.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" + integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== + dependencies: + caniuse-lite "^1.0.30001587" + electron-to-chromium "^1.4.668" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001587: + version "1.0.30001600" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz#93a3ee17a35aa6a9f0c6ef1b2ab49507d1ab9079" + integrity sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ== + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chokidar@^3.5.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.14: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +commander@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +connect@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg== + +date-format@^4.0.14: + version "4.0.14" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.14.tgz#7a8e584434fb169a521c8b7aa481f355810d9400" + integrity sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4.3.4, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2, debug@~4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +dom-serialize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ== + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.668: + version "1.4.715" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.715.tgz#bb16bcf2a3537962fccfa746b5c98c5f7404ff46" + integrity sha512-XzWNH4ZSa9BwVUQSDorPWAUQ5WGuYz7zJUNpNif40zFCiCl20t8zgylmreNmn26h5kiyw2lg7RfTmeMBsDklqg== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +engine.io-parser@~5.2.1: + version "5.2.2" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.2.2.tgz#37b48e2d23116919a3453738c5720455e64e1c49" + integrity sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw== + +engine.io@~6.5.2: + version "6.5.4" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.5.4.tgz#6822debf324e781add2254e912f8568508850cdc" + integrity sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.2.1" + ws "~8.11.0" + +enhanced-resolve@^5.13.0: + version "5.16.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz#65ec88778083056cb32487faa9aef82ed0864787" + integrity sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA== + +envinfo@^7.7.3: + version "7.11.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.1.tgz#2ffef77591057081b0129a8fd8cf6118da1b94e1" + integrity sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg== + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-module-lexer@^1.2.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.4.2.tgz#ba1a62255ff9b41023aaf9bd08c016a5f1a3fef3" + integrity sha512-7nOqkomXZEaxUDJw21XZNtRk739QvrPSoZoRtbsEfcii00vdzZUh6zh1CQwHhrib8MdEtJfv5rJiGeb4KuV/vw== + +escalade@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastest-levenshtein@^1.0.12: + version "1.0.16" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.2.7: + version "3.3.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" + integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== + +follow-redirects@^1.0.0: + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== + +format-util@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" + integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3, glob@^7.1.7: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.10, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +hasown@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +interpret@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" + integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.13.0: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +isbinaryfile@^4.0.8: + version "4.0.10" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + +karma-chrome-launcher@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz#eb9c95024f2d6dfbb3748d3415ac9b381906b9a9" + integrity sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q== + dependencies: + which "^1.2.1" + +karma-mocha@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-2.0.1.tgz#4b0254a18dfee71bdbe6188d9a6861bf86b0cd7d" + integrity sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ== + dependencies: + minimist "^1.2.3" + +karma-sourcemap-loader@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.4.0.tgz#b01d73f8f688f533bcc8f5d273d43458e13b5488" + integrity sha512-xCRL3/pmhAYF3I6qOrcn0uhbQevitc2DERMPH82FMnG+4WReoGcGFZb1pURf2a5apyrOHRdvD+O6K7NljqKHyA== + dependencies: + graceful-fs "^4.2.10" + +karma-webpack@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0.tgz#2a2c7b80163fe7ffd1010f83f5507f95ef39f840" + integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA== + dependencies: + glob "^7.1.3" + minimatch "^3.0.4" + webpack-merge "^4.1.5" + +karma@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.2.tgz#a983f874cee6f35990c4b2dcc3d274653714de8e" + integrity sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ== + dependencies: + "@colors/colors" "1.5.0" + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.5.1" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.4.1" + mime "^2.5.2" + minimatch "^3.0.4" + mkdirp "^0.5.5" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^4.4.1" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.30" + yargs "^16.1.1" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash@^4.17.15, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log4js@^6.4.1: + version "6.9.1" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.9.1.tgz#aba5a3ff4e7872ae34f8b4c533706753709e38b6" + integrity sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g== + dependencies: + date-format "^4.0.14" + debug "^4.3.4" + flatted "^3.2.7" + rfdc "^1.3.0" + streamroller "^3.1.5" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.3, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mkdirp@^0.5.5: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mocha@10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== + dependencies: + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +object-assign@^4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" + integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== + dependencies: + resolve "^1.20.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.20.0: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +rfdc@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.1.tgz#2b6d4df52dffe8bb346992a10ea9451f24373a8f" + integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^3.1.1, schema-utils@^3.1.2: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serialize-javascript@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== + dependencies: + randombytes "^2.1.0" + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +socket.io-adapter@~2.5.2: + version "2.5.4" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz#4fdb1358667f6d68f25343353bd99bd11ee41006" + integrity sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg== + dependencies: + debug "~4.3.4" + ws "~8.11.0" + +socket.io-parser@~4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.4.tgz#c806966cf7270601e47469ddeec30fbdfda44c83" + integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + +socket.io@^4.4.1: + version "4.7.5" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.7.5.tgz#56eb2d976aef9d1445f373a62d781a41c7add8f8" + integrity sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + cors "~2.8.5" + debug "~4.3.2" + engine.io "~6.5.2" + socket.io-adapter "~2.5.2" + socket.io-parser "~4.2.4" + +source-map-js@^1.0.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== + +source-map-loader@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-4.0.1.tgz#72f00d05f5d1f90f80974eda781cbd7107c125f2" + integrity sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA== + dependencies: + abab "^2.0.6" + iconv-lite "^0.6.3" + source-map-js "^1.0.2" + +source-map-support@0.5.21, source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +streamroller@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.1.5.tgz#1263182329a45def1ffaef58d31b15d13d2ee7ff" + integrity sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw== + dependencies: + date-format "^4.0.14" + debug "^4.3.4" + fs-extra "^8.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@8.1.1, supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.3.7: + version "5.3.10" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" + integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== + dependencies: + "@jridgewell/trace-mapping" "^0.3.20" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.26.0" + +terser@^5.26.0: + version "5.29.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.29.2.tgz#c17d573ce1da1b30f21a877bffd5655dd86fdb35" + integrity sha512-ZiGkhUBIM+7LwkNjXYJq8svgkd+QK3UUr0wJqY4MieaezBSAIPgbSPZyIx0idM6XWK5CMzSWa8MJIzmRcB8Caw== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + +tmp@^0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" + integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typescript@5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + +ua-parser-js@^0.7.30: + version "0.7.37" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.37.tgz#e464e66dac2d33a7a1251d7d7a99d6157ec27832" + integrity sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +vary@^1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== + +watchpack@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.1.tgz#29308f2cac150fa8e4c92f90e0ec954a9fed7fff" + integrity sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +webpack-cli@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.0.tgz#abc4b1f44b50250f2632d8b8b536cfe2f6257891" + integrity sha512-a7KRJnCxejFoDpYTOwzm5o21ZXMaNqtRlvS183XzGDUPRdVEzJNImcQokqYZ8BNTnk9DkKiuWxw75+DCCoZ26w== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^2.1.0" + "@webpack-cli/info" "^2.0.1" + "@webpack-cli/serve" "^2.0.3" + colorette "^2.0.14" + commander "^10.0.1" + cross-spawn "^7.0.3" + envinfo "^7.7.3" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^3.1.1" + rechoir "^0.8.0" + webpack-merge "^5.7.3" + +webpack-merge@^4.1.5: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== + dependencies: + lodash "^4.17.15" + +webpack-merge@^5.7.3: + version "5.10.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177" + integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA== + dependencies: + clone-deep "^4.0.1" + flat "^5.0.2" + wildcard "^2.0.0" + +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@5.82.0: + version "5.82.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.82.0.tgz#3c0d074dec79401db026b4ba0fb23d6333f88e7d" + integrity sha512-iGNA2fHhnDcV1bONdUu554eZx+XeldsaeQ8T67H6KKHl2nUSwX8Zm7cmzOA46ox/X1ARxf7Bjv8wQ/HsB5fxBg== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" + acorn "^8.7.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.13.0" + es-module-lexer "^1.2.1" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.2" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.7" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +which@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wildcard@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== + +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@~8.11.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" + integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0, yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/kutil/build.gradle.kts b/kutil/build.gradle.kts new file mode 100644 index 0000000..6d72944 --- /dev/null +++ b/kutil/build.gradle.kts @@ -0,0 +1,63 @@ +import java.net.URI + +plugins { + `maven-publish` + signing + id("net.kigawa.kutil.kutil.java-conventions") + id("org.jetbrains.dokka") version "1.9.10" +} + +dependencies { + commonMainImplementation(project(":api")) +} + +publishing { + publications { + withType { + artifactId = if (name == "kotlinMultiplatform") artifactId + else "$artifactId-$name" + + pom { + name.set("kutil") + description.set("utilities for kotlin") + url.set("https://github.com/kigawa01/kutil-java/") + properties.set( + mapOf( + ) + ) + licenses { + license { + name.set("MIT License") + url.set("http://www.opensource.org/licenses/mit-license.php") + } + } + developers { + developer { + id.set("net.kigawa") + name.set("kigawa") + email.set("contact@kigawa.net") + } + } + scm { + connection.set("scm:git:https://github.com/kigawa01/kutil-java.git") + developerConnection.set("scm:git:https://github.com/kigawa01/kutil-java.git") + url.set("https://github.com/kigawa01/kutil-java") + } + } + } + } + + repositories { + maven { + name = "OSSRH" + url = URI("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") + credentials { + username = System.getenv("MAVEN_USERNAME") + password = System.getenv("MAVEN_PASSWORD") + } + } + } +} +signing { + sign(publishing.publications) +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 162fe96..77059af 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,4 +4,5 @@ rootProject.name = "kutil" include("api") +include("kutil") //include("impl")