gitextract_qe2hhq1p/ ├── .dockerignore ├── .editorconfig ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.en.yml │ │ ├── bug_report.zh.yml │ │ ├── config.yml │ │ ├── feature_request.en.yml │ │ └── feature_request.zh.yml │ ├── actions/ │ │ ├── docker-buildx-push/ │ │ │ └── action.yaml │ │ └── setup-env/ │ │ └── action.yaml │ ├── pull_request_template.md │ └── workflows/ │ ├── halo.yaml │ ├── openapi-check.yaml │ ├── packages-preview-release.yaml │ ├── release-ui-packages.yaml │ └── stale-issues.yaml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── OWNERS ├── README.md ├── SECURITY.md ├── api/ │ ├── build.gradle │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── run/ │ │ └── halo/ │ │ └── app/ │ │ ├── content/ │ │ │ ├── ContentWrapper.java │ │ │ ├── ExcerptGenerator.java │ │ │ ├── PatchUtils.java │ │ │ ├── PostContentService.java │ │ │ └── comment/ │ │ │ └── CommentSubject.java │ │ ├── core/ │ │ │ ├── attachment/ │ │ │ │ ├── ThumbnailProvider.java │ │ │ │ └── ThumbnailSize.java │ │ │ ├── endpoint/ │ │ │ │ └── WebSocketEndpoint.java │ │ │ ├── extension/ │ │ │ │ ├── AnnotationSetting.java │ │ │ │ ├── AuthProvider.java │ │ │ │ ├── Counter.java │ │ │ │ ├── Device.java │ │ │ │ ├── Menu.java │ │ │ │ ├── MenuItem.java │ │ │ │ ├── Plugin.java │ │ │ │ ├── RememberMeToken.java │ │ │ │ ├── ReverseProxy.java │ │ │ │ ├── Role.java │ │ │ │ ├── RoleBinding.java │ │ │ │ ├── Setting.java │ │ │ │ ├── Theme.java │ │ │ │ ├── User.java │ │ │ │ ├── UserConnection.java │ │ │ │ ├── attachment/ │ │ │ │ │ ├── Attachment.java │ │ │ │ │ ├── Constant.java │ │ │ │ │ ├── Group.java │ │ │ │ │ ├── Policy.java │ │ │ │ │ ├── PolicyTemplate.java │ │ │ │ │ └── endpoint/ │ │ │ │ │ ├── AttachmentHandler.java │ │ │ │ │ ├── DeleteOption.java │ │ │ │ │ ├── SimpleFilePart.java │ │ │ │ │ └── UploadOption.java │ │ │ │ ├── content/ │ │ │ │ │ ├── Category.java │ │ │ │ │ ├── Comment.java │ │ │ │ │ ├── Constant.java │ │ │ │ │ ├── Post.java │ │ │ │ │ ├── Reply.java │ │ │ │ │ ├── SinglePage.java │ │ │ │ │ ├── Snapshot.java │ │ │ │ │ └── Tag.java │ │ │ │ ├── endpoint/ │ │ │ │ │ ├── CustomEndpoint.java │ │ │ │ │ └── SortResolver.java │ │ │ │ ├── notification/ │ │ │ │ │ ├── Notification.java │ │ │ │ │ ├── NotificationTemplate.java │ │ │ │ │ ├── NotifierDescriptor.java │ │ │ │ │ ├── Reason.java │ │ │ │ │ ├── ReasonType.java │ │ │ │ │ └── Subscription.java │ │ │ │ └── service/ │ │ │ │ └── AttachmentService.java │ │ │ └── user/ │ │ │ └── service/ │ │ │ ├── RoleService.java │ │ │ ├── SignUpData.java │ │ │ ├── UserPostCreatingHandler.java │ │ │ ├── UserPreCreatingHandler.java │ │ │ └── UserService.java │ │ ├── event/ │ │ │ ├── post/ │ │ │ │ ├── PostDeletedEvent.java │ │ │ │ ├── PostEvent.java │ │ │ │ ├── PostPublishedEvent.java │ │ │ │ ├── PostUnpublishedEvent.java │ │ │ │ ├── PostUpdatedEvent.java │ │ │ │ └── PostVisibleChangedEvent.java │ │ │ └── user/ │ │ │ ├── UserConnectionDisconnectedEvent.java │ │ │ ├── UserLoginEvent.java │ │ │ └── UserLogoutEvent.java │ │ ├── extension/ │ │ │ ├── AbstractExtension.java │ │ │ ├── Comparators.java │ │ │ ├── ConfigMap.java │ │ │ ├── DefaultExtensionMatcher.java │ │ │ ├── Extension.java │ │ │ ├── ExtensionClient.java │ │ │ ├── ExtensionMatcher.java │ │ │ ├── ExtensionOperator.java │ │ │ ├── ExtensionUtil.java │ │ │ ├── GVK.java │ │ │ ├── GroupKind.java │ │ │ ├── GroupVersion.java │ │ │ ├── GroupVersionKind.java │ │ │ ├── JsonExtension.java │ │ │ ├── ListOptions.java │ │ │ ├── ListResult.java │ │ │ ├── Metadata.java │ │ │ ├── MetadataOperator.java │ │ │ ├── MetadataUtil.java │ │ │ ├── PageRequest.java │ │ │ ├── PageRequestImpl.java │ │ │ ├── ReactiveExtensionClient.java │ │ │ ├── Ref.java │ │ │ ├── Scheme.java │ │ │ ├── SchemeManager.java │ │ │ ├── Secret.java │ │ │ ├── Unstructured.java │ │ │ ├── Watcher.java │ │ │ ├── WatcherExtensionMatchers.java │ │ │ ├── WatcherPredicates.java │ │ │ ├── controller/ │ │ │ │ ├── Controller.java │ │ │ │ ├── ControllerBuilder.java │ │ │ │ ├── DefaultController.java │ │ │ │ ├── DefaultQueue.java │ │ │ │ ├── ExtensionWatcher.java │ │ │ │ ├── Reconciler.java │ │ │ │ ├── RequestQueue.java │ │ │ │ ├── RequestSynchronizer.java │ │ │ │ ├── RequeueException.java │ │ │ │ └── Synchronizer.java │ │ │ ├── exception/ │ │ │ │ ├── ExtensionException.java │ │ │ │ ├── NotImplementedException.java │ │ │ │ └── SchemeNotFoundException.java │ │ │ ├── index/ │ │ │ │ ├── AbstractValueIndexSpecBuilder.java │ │ │ │ ├── DefaultIndexAttribute.java │ │ │ │ ├── IndexAttribute.java │ │ │ │ ├── IndexAttributeFactory.java │ │ │ │ ├── IndexSpec.java │ │ │ │ ├── IndexSpecBuilder.java │ │ │ │ ├── IndexSpecs.java │ │ │ │ ├── IndexedQueryEngine.java │ │ │ │ ├── KeyComparator.java │ │ │ │ ├── MultiValueBuilder.java │ │ │ │ ├── MultiValueIndexSpec.java │ │ │ │ ├── MultiValueIndexSpecBuilder.java │ │ │ │ ├── SingleValueBuilder.java │ │ │ │ ├── SingleValueIndexSpec.java │ │ │ │ ├── SingleValueIndexSpecBuilder.java │ │ │ │ ├── UnknownKey.java │ │ │ │ ├── ValueIndexSpec.java │ │ │ │ └── query/ │ │ │ │ ├── AllCondition.java │ │ │ │ ├── And.java │ │ │ │ ├── AndCondition.java │ │ │ │ ├── BetweenCondition.java │ │ │ │ ├── Condition.java │ │ │ │ ├── EmptyCondition.java │ │ │ │ ├── EqualCondition.java │ │ │ │ ├── GreaterThanCondition.java │ │ │ │ ├── InCondition.java │ │ │ │ ├── IndexCondition.java │ │ │ │ ├── IsNotNullCondition.java │ │ │ │ ├── IsNullCondition.java │ │ │ │ ├── LabelCondition.java │ │ │ │ ├── LabelEqualsCondition.java │ │ │ │ ├── LabelExistsCondition.java │ │ │ │ ├── LabelInCondition.java │ │ │ │ ├── LabelNotEqualsCondition.java │ │ │ │ ├── LabelNotExistsCondition.java │ │ │ │ ├── LabelNotInCondition.java │ │ │ │ ├── LessThanCondition.java │ │ │ │ ├── NoneCondition.java │ │ │ │ ├── NotBetweenCondition.java │ │ │ │ ├── NotCondition.java │ │ │ │ ├── NotEqualCondition.java │ │ │ │ ├── NotInCondition.java │ │ │ │ ├── OrCondition.java │ │ │ │ ├── Queries.java │ │ │ │ ├── Query.java │ │ │ │ ├── QueryFactory.java │ │ │ │ ├── StringContainsCondition.java │ │ │ │ ├── StringEndsWithCondition.java │ │ │ │ ├── StringNotContainsCondition.java │ │ │ │ ├── StringNotEndsWithCondition.java │ │ │ │ ├── StringNotStartsWithCondition.java │ │ │ │ └── StringStartsWithCondition.java │ │ │ └── router/ │ │ │ ├── IListRequest.java │ │ │ ├── QueryParamBuildUtil.java │ │ │ ├── SortableRequest.java │ │ │ └── selector/ │ │ │ ├── FieldSelector.java │ │ │ ├── FieldSelectorConverter.java │ │ │ ├── LabelSelector.java │ │ │ ├── LabelSelectorConverter.java │ │ │ ├── Operator.java │ │ │ ├── SelectorConverter.java │ │ │ ├── SelectorCriteria.java │ │ │ └── SelectorUtil.java │ │ ├── infra/ │ │ │ ├── AnonymousUserConst.java │ │ │ ├── BackupRootGetter.java │ │ │ ├── Condition.java │ │ │ ├── ConditionList.java │ │ │ ├── ConditionStatus.java │ │ │ ├── ExternalLinkProcessor.java │ │ │ ├── ExternalUrlSupplier.java │ │ │ ├── FileCategoryMatcher.java │ │ │ ├── SystemInfo.java │ │ │ ├── SystemInfoGetter.java │ │ │ ├── SystemSetting.java │ │ │ ├── SystemVersionSupplier.java │ │ │ ├── ValidationUtils.java │ │ │ ├── model/ │ │ │ │ └── License.java │ │ │ └── utils/ │ │ │ ├── FileTypeDetectUtils.java │ │ │ ├── GenericClassUtils.java │ │ │ ├── JsonParseException.java │ │ │ ├── JsonUtils.java │ │ │ └── PathUtils.java │ │ ├── migration/ │ │ │ ├── Backup.java │ │ │ └── Constant.java │ │ ├── notification/ │ │ │ ├── NotificationCenter.java │ │ │ ├── NotificationContext.java │ │ │ ├── NotificationReasonEmitter.java │ │ │ ├── ReactiveNotifier.java │ │ │ ├── ReasonAttributes.java │ │ │ ├── ReasonPayload.java │ │ │ └── UserIdentity.java │ │ ├── plugin/ │ │ │ ├── ApiVersion.java │ │ │ ├── BasePlugin.java │ │ │ ├── PluginConfigUpdatedEvent.java │ │ │ ├── PluginContext.java │ │ │ ├── PluginsRootGetter.java │ │ │ ├── ReactiveSettingFetcher.java │ │ │ ├── SettingFetcher.java │ │ │ ├── SharedEvent.java │ │ │ ├── event/ │ │ │ │ └── PluginStartedEvent.java │ │ │ └── extensionpoint/ │ │ │ └── ExtensionGetter.java │ │ ├── search/ │ │ │ ├── HaloDocument.java │ │ │ ├── HaloDocumentsProvider.java │ │ │ ├── SearchEngine.java │ │ │ ├── SearchOption.java │ │ │ ├── SearchResult.java │ │ │ ├── SearchService.java │ │ │ └── event/ │ │ │ ├── HaloDocumentAddRequestEvent.java │ │ │ ├── HaloDocumentDeleteRequestEvent.java │ │ │ └── HaloDocumentRebuildRequestEvent.java │ │ ├── security/ │ │ │ ├── AdditionalWebFilter.java │ │ │ ├── AfterSecurityWebFilter.java │ │ │ ├── AnonymousAuthenticationSecurityWebFilter.java │ │ │ ├── AuthenticationSecurityWebFilter.java │ │ │ ├── BeforeSecurityWebFilter.java │ │ │ ├── FormLoginSecurityWebFilter.java │ │ │ ├── HttpBasicSecurityWebFilter.java │ │ │ ├── LoginHandlerEnhancer.java │ │ │ ├── OAuth2AuthorizationCodeSecurityWebFilter.java │ │ │ ├── PersonalAccessToken.java │ │ │ ├── authentication/ │ │ │ │ ├── CryptoService.java │ │ │ │ ├── login/ │ │ │ │ │ └── UsernamePasswordAuthenticationManager.java │ │ │ │ └── oauth2/ │ │ │ │ └── HaloOAuth2AuthenticationToken.java │ │ │ └── device/ │ │ │ └── DeviceService.java │ │ └── theme/ │ │ ├── Constant.java │ │ ├── ReactivePostContentHandler.java │ │ ├── ReactiveSinglePageContentHandler.java │ │ ├── TemplateNameResolver.java │ │ ├── dialect/ │ │ │ ├── CommentWidget.java │ │ │ ├── ElementTagPostProcessor.java │ │ │ ├── TemplateFooterProcessor.java │ │ │ └── TemplateHeadProcessor.java │ │ ├── finders/ │ │ │ ├── Finder.java │ │ │ └── vo/ │ │ │ └── ExtensionVoOperator.java │ │ └── router/ │ │ ├── ModelConst.java │ │ ├── PageUrlUtils.java │ │ └── UrlContextListResult.java │ └── test/ │ └── java/ │ └── run/ │ └── halo/ │ └── app/ │ ├── core/ │ │ └── extension/ │ │ ├── content/ │ │ │ └── PostTest.java │ │ └── notification/ │ │ └── SubscriptionTest.java │ ├── extension/ │ │ ├── ExtensionUtilTest.java │ │ ├── FakeExtension.java │ │ ├── ListOptionsTest.java │ │ ├── PageRequestImplTest.java │ │ ├── SecretTest.java │ │ ├── controller/ │ │ │ ├── ControllerBuilderTest.java │ │ │ ├── DefaultControllerTest.java │ │ │ ├── DefaultDelayQueueTest.java │ │ │ ├── DelayedEntryTest.java │ │ │ ├── ExtensionWatcherTest.java │ │ │ └── RequestSynchronizerTest.java │ │ ├── index/ │ │ │ ├── IndexAttributeFactoryTest.java │ │ │ ├── IndexSpecTest.java │ │ │ ├── KeyComparatorTest.java │ │ │ ├── MultiValueBuilderTest.java │ │ │ ├── SingleValueBuilderTest.java │ │ │ ├── UnknownKeyTest.java │ │ │ └── query/ │ │ │ └── QueriesTest.java │ │ ├── indexer/ │ │ │ ├── DefaultIndexEngineTest.java │ │ │ └── LabelIndexImplTest.java │ │ └── router/ │ │ └── selector/ │ │ ├── LabelSelectorTest.java │ │ ├── OperatorTest.java │ │ └── SelectorConverterTest.java │ └── infra/ │ └── utils/ │ ├── GenericClassUtilsTest.java │ ├── JsonUtilsTest.java │ └── PathUtilsTest.java ├── api-docs/ │ └── openapi/ │ └── v3_0/ │ ├── aggregated.json │ ├── apis_console.api_v1alpha1.json │ ├── apis_extension.api_v1alpha1.json │ ├── apis_public.api_v1alpha1.json │ └── apis_uc.api_v1alpha1.json ├── application/ │ ├── build.gradle │ ├── libs/ │ │ ├── thymeleaf-3.1.3.RELEASE.jar │ │ └── thymeleaf-spring6-3.1.3.RELEASE.jar │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── run/ │ │ │ └── halo/ │ │ │ └── app/ │ │ │ ├── Application.java │ │ │ ├── content/ │ │ │ │ ├── AbstractContentService.java │ │ │ │ ├── AbstractEventReconciler.java │ │ │ │ ├── CategoryPostCountUpdater.java │ │ │ │ ├── CategoryService.java │ │ │ │ ├── Content.java │ │ │ │ ├── ContentRequest.java │ │ │ │ ├── ContentUpdateParam.java │ │ │ │ ├── Contributor.java │ │ │ │ ├── ListedPost.java │ │ │ │ ├── ListedSinglePage.java │ │ │ │ ├── ListedSnapshotDto.java │ │ │ │ ├── NotificationReasonConst.java │ │ │ │ ├── PostContentServiceImpl.java │ │ │ │ ├── PostHideFromListStateUpdater.java │ │ │ │ ├── PostQuery.java │ │ │ │ ├── PostRequest.java │ │ │ │ ├── PostService.java │ │ │ │ ├── PostSorter.java │ │ │ │ ├── SinglePageQuery.java │ │ │ │ ├── SinglePageRequest.java │ │ │ │ ├── SinglePageService.java │ │ │ │ ├── SnapshotService.java │ │ │ │ ├── Stats.java │ │ │ │ ├── comment/ │ │ │ │ │ ├── AbstractCommentService.java │ │ │ │ │ ├── CommentEmailOwner.java │ │ │ │ │ ├── CommentNotificationReasonPublisher.java │ │ │ │ │ ├── CommentQuery.java │ │ │ │ │ ├── CommentRequest.java │ │ │ │ │ ├── CommentService.java │ │ │ │ │ ├── CommentServiceImpl.java │ │ │ │ │ ├── CommentStats.java │ │ │ │ │ ├── ListedComment.java │ │ │ │ │ ├── ListedReply.java │ │ │ │ │ ├── OwnerInfo.java │ │ │ │ │ ├── PostCommentSubject.java │ │ │ │ │ ├── ReplyNotificationSubscriptionHelper.java │ │ │ │ │ ├── ReplyQuery.java │ │ │ │ │ ├── ReplyRequest.java │ │ │ │ │ ├── ReplyService.java │ │ │ │ │ ├── ReplyServiceImpl.java │ │ │ │ │ └── SinglePageCommentSubject.java │ │ │ │ ├── impl/ │ │ │ │ │ ├── CategoryServiceImpl.java │ │ │ │ │ ├── PostServiceImpl.java │ │ │ │ │ ├── SinglePageServiceImpl.java │ │ │ │ │ └── SnapshotServiceImpl.java │ │ │ │ ├── permalinks/ │ │ │ │ │ ├── CategoryPermalinkPolicy.java │ │ │ │ │ ├── ExtensionLocator.java │ │ │ │ │ ├── PermalinkPolicy.java │ │ │ │ │ ├── PostPermalinkPolicy.java │ │ │ │ │ └── TagPermalinkPolicy.java │ │ │ │ └── stats/ │ │ │ │ ├── PostStatsUpdater.java │ │ │ │ ├── ReplyEventReconciler.java │ │ │ │ ├── TagPostCountUpdater.java │ │ │ │ ├── VisitedEventReconciler.java │ │ │ │ └── VotedEventReconciler.java │ │ │ ├── core/ │ │ │ │ ├── attachment/ │ │ │ │ │ ├── AttachmentChangedEvent.java │ │ │ │ │ ├── AttachmentLister.java │ │ │ │ │ ├── AttachmentRootGetter.java │ │ │ │ │ ├── PolicyConfigChangeDetector.java │ │ │ │ │ ├── SearchRequest.java │ │ │ │ │ ├── endpoint/ │ │ │ │ │ │ ├── AttachmentEndpoint.java │ │ │ │ │ │ ├── LocalAttachmentUploadHandler.java │ │ │ │ │ │ └── PolicyEndpoint.java │ │ │ │ │ ├── extension/ │ │ │ │ │ │ ├── LocalThumbnail.java │ │ │ │ │ │ └── Thumbnail.java │ │ │ │ │ ├── impl/ │ │ │ │ │ │ ├── AttachmentListerImpl.java │ │ │ │ │ │ └── AttachmentRootGetterImpl.java │ │ │ │ │ ├── reconciler/ │ │ │ │ │ │ ├── AttachmentReconciler.java │ │ │ │ │ │ ├── LocalThumbnailsReconciler.java │ │ │ │ │ │ ├── PolicyReconciler.java │ │ │ │ │ │ └── ThumbnailReconciler.java │ │ │ │ │ └── thumbnail/ │ │ │ │ │ ├── DefaultLocalThumbnailService.java │ │ │ │ │ ├── DefaultThumbnailService.java │ │ │ │ │ ├── LocalThumbnailService.java │ │ │ │ │ ├── ThumbnailImgTagPostProcessor.java │ │ │ │ │ ├── ThumbnailResourceTransformer.java │ │ │ │ │ ├── ThumbnailService.java │ │ │ │ │ └── ThumbnailUtils.java │ │ │ │ ├── counter/ │ │ │ │ │ ├── CounterService.java │ │ │ │ │ ├── CounterServiceImpl.java │ │ │ │ │ └── MeterUtils.java │ │ │ │ ├── endpoint/ │ │ │ │ │ ├── AttachmentHandler.java │ │ │ │ │ ├── WebSocketEndpointManager.java │ │ │ │ │ ├── WebSocketHandlerMapping.java │ │ │ │ │ ├── console/ │ │ │ │ │ │ ├── AttachmentConsoleEndpoint.java │ │ │ │ │ │ ├── AuthProviderEndpoint.java │ │ │ │ │ │ ├── CommentEndpoint.java │ │ │ │ │ │ ├── ConsoleUserEndpoint.java │ │ │ │ │ │ ├── CustomEndpointsBuilder.java │ │ │ │ │ │ ├── PluginEndpoint.java │ │ │ │ │ │ ├── PostEndpoint.java │ │ │ │ │ │ ├── ReplyEndpoint.java │ │ │ │ │ │ ├── SinglePageEndpoint.java │ │ │ │ │ │ ├── StatsEndpoint.java │ │ │ │ │ │ ├── SystemConfigEndpoint.java │ │ │ │ │ │ ├── TagEndpoint.java │ │ │ │ │ │ ├── TrackerEndpoint.java │ │ │ │ │ │ └── UserEndpoint.java │ │ │ │ │ ├── theme/ │ │ │ │ │ │ ├── CategoryQueryEndpoint.java │ │ │ │ │ │ ├── CommentFinderEndpoint.java │ │ │ │ │ │ ├── MenuQueryEndpoint.java │ │ │ │ │ │ ├── PluginQueryEndpoint.java │ │ │ │ │ │ ├── PostPublicQuery.java │ │ │ │ │ │ ├── PostQueryEndpoint.java │ │ │ │ │ │ ├── PublicApiUtils.java │ │ │ │ │ │ ├── SinglePageQueryEndpoint.java │ │ │ │ │ │ ├── SiteStatsQueryEndpoint.java │ │ │ │ │ │ ├── TagQueryEndpoint.java │ │ │ │ │ │ └── ThumbnailEndpoint.java │ │ │ │ │ └── uc/ │ │ │ │ │ ├── AnnotationSettingEndpoint.java │ │ │ │ │ ├── AttachmentUcEndpoint.java │ │ │ │ │ ├── UcPostEndpoint.java │ │ │ │ │ ├── UcSnapshotEndpoint.java │ │ │ │ │ ├── UcUserPreferenceEndpoint.java │ │ │ │ │ └── UserConnectionEndpoint.java │ │ │ │ ├── reconciler/ │ │ │ │ │ ├── AnnotationSettingReconciler.java │ │ │ │ │ ├── AuthProviderReconciler.java │ │ │ │ │ ├── CategoryReconciler.java │ │ │ │ │ ├── CommentReconciler.java │ │ │ │ │ ├── MenuItemReconciler.java │ │ │ │ │ ├── PluginReconciler.java │ │ │ │ │ ├── PostCounterReconciler.java │ │ │ │ │ ├── PostReconciler.java │ │ │ │ │ ├── ReplyReconciler.java │ │ │ │ │ ├── ReverseProxyReconciler.java │ │ │ │ │ ├── RoleReconciler.java │ │ │ │ │ ├── SinglePageReconciler.java │ │ │ │ │ ├── SystemConfigReconciler.java │ │ │ │ │ ├── TagReconciler.java │ │ │ │ │ ├── ThemeReconciler.java │ │ │ │ │ └── UserReconciler.java │ │ │ │ └── user/ │ │ │ │ └── service/ │ │ │ │ ├── DefaultRoleService.java │ │ │ │ ├── EmailPasswordRecoveryService.java │ │ │ │ ├── EmailVerificationService.java │ │ │ │ ├── InMemoryResetTokenRepository.java │ │ │ │ ├── InvalidResetTokenException.java │ │ │ │ ├── PatService.java │ │ │ │ ├── ResetToken.java │ │ │ │ ├── ResetTokenRepository.java │ │ │ │ ├── SettingConfigService.java │ │ │ │ ├── UserConnectionService.java │ │ │ │ ├── UserLoginOrLogoutProcessing.java │ │ │ │ └── impl/ │ │ │ │ ├── DefaultAttachmentService.java │ │ │ │ ├── EmailPasswordRecoveryServiceImpl.java │ │ │ │ ├── EmailVerificationServiceImpl.java │ │ │ │ ├── PatServiceImpl.java │ │ │ │ ├── SettingConfigServiceImpl.java │ │ │ │ ├── UserConnectionServiceImpl.java │ │ │ │ └── UserServiceImpl.java │ │ │ ├── event/ │ │ │ │ ├── post/ │ │ │ │ │ ├── CategoryHiddenStateChangeEvent.java │ │ │ │ │ ├── CommentCreatedEvent.java │ │ │ │ │ ├── CommentUnreadReplyCountChangedEvent.java │ │ │ │ │ ├── DownvotedEvent.java │ │ │ │ │ ├── PostStatsChangedEvent.java │ │ │ │ │ ├── ReplyChangedEvent.java │ │ │ │ │ ├── ReplyCreatedEvent.java │ │ │ │ │ ├── ReplyDeletedEvent.java │ │ │ │ │ ├── ReplyEvent.java │ │ │ │ │ ├── UpvotedEvent.java │ │ │ │ │ ├── VisitedEvent.java │ │ │ │ │ └── VotedEvent.java │ │ │ │ └── user/ │ │ │ │ └── PasswordChangedEvent.java │ │ │ ├── extension/ │ │ │ │ ├── DefaultSchemeManager.java │ │ │ │ ├── DelegateExtensionClient.java │ │ │ │ ├── ExtensionConverter.java │ │ │ │ ├── ExtensionStoreUtil.java │ │ │ │ ├── JSONExtensionConverter.java │ │ │ │ ├── ReactiveExtensionClientImpl.java │ │ │ │ ├── availability/ │ │ │ │ │ └── IndexBuildState.java │ │ │ │ ├── controller/ │ │ │ │ │ └── DefaultControllerManager.java │ │ │ │ ├── event/ │ │ │ │ │ ├── IndexerBuiltEvent.java │ │ │ │ │ ├── SchemeAddedEvent.java │ │ │ │ │ └── SchemeRemovedEvent.java │ │ │ │ ├── exception/ │ │ │ │ │ ├── ExtensionConvertException.java │ │ │ │ │ ├── ExtensionNotFoundException.java │ │ │ │ │ └── SchemaViolationException.java │ │ │ │ ├── gc/ │ │ │ │ │ ├── GcControllerInitializer.java │ │ │ │ │ ├── GcReconciler.java │ │ │ │ │ ├── GcRequest.java │ │ │ │ │ ├── GcSynchronizer.java │ │ │ │ │ └── GcWatcher.java │ │ │ │ ├── index/ │ │ │ │ │ ├── DefaultIndexEngine.java │ │ │ │ │ ├── DefaultIndices.java │ │ │ │ │ ├── DefaultIndicesManager.java │ │ │ │ │ ├── Index.java │ │ │ │ │ ├── IndexEngine.java │ │ │ │ │ ├── Indices.java │ │ │ │ │ ├── IndicesInitializer.java │ │ │ │ │ ├── IndicesManager.java │ │ │ │ │ ├── LabelIndex.java │ │ │ │ │ ├── LabelIndexQuery.java │ │ │ │ │ ├── MultiValueIndex.java │ │ │ │ │ ├── SingleValueIndex.java │ │ │ │ │ ├── StringUnknownKeyConverter.java │ │ │ │ │ ├── TransactionalOperation.java │ │ │ │ │ ├── ValueIndexQuery.java │ │ │ │ │ └── query/ │ │ │ │ │ └── QueryVisitor.java │ │ │ │ ├── indexer/ │ │ │ │ │ └── DefaultIndicesInitializer.java │ │ │ │ ├── router/ │ │ │ │ │ ├── ExtensionCompositeRouterFunction.java │ │ │ │ │ ├── ExtensionCreateHandler.java │ │ │ │ │ ├── ExtensionDeleteHandler.java │ │ │ │ │ ├── ExtensionGetHandler.java │ │ │ │ │ ├── ExtensionListHandler.java │ │ │ │ │ ├── ExtensionPatchHandler.java │ │ │ │ │ ├── ExtensionRouterFunctionFactory.java │ │ │ │ │ ├── ExtensionUpdateHandler.java │ │ │ │ │ └── JsonPatch.java │ │ │ │ └── store/ │ │ │ │ ├── ExtensionStore.java │ │ │ │ ├── ExtensionStoreClient.java │ │ │ │ ├── ExtensionStoreClientJPAImpl.java │ │ │ │ ├── ExtensionStoreRepository.java │ │ │ │ ├── ReactiveExtensionStoreClient.java │ │ │ │ └── ReactiveExtensionStoreClientImpl.java │ │ │ ├── infra/ │ │ │ │ ├── DefaultBackupRootGetter.java │ │ │ │ ├── DefaultExternalLinkProcessor.java │ │ │ │ ├── DefaultInitializationStateGetter.java │ │ │ │ ├── DefaultReactiveUrlDataBufferFetcher.java │ │ │ │ ├── DefaultSystemConfigFetcher.java │ │ │ │ ├── DefaultSystemVersionSupplier.java │ │ │ │ ├── DefaultThemeRootGetter.java │ │ │ │ ├── ExtensionInitializedEvent.java │ │ │ │ ├── ExtensionResourceInitializer.java │ │ │ │ ├── ExternalUrlChangedEvent.java │ │ │ │ ├── InitializationPhase.java │ │ │ │ ├── InitializationStateGetter.java │ │ │ │ ├── ReactiveExtensionPaginatedOperator.java │ │ │ │ ├── ReactiveExtensionPaginatedOperatorImpl.java │ │ │ │ ├── ReactiveUrlDataBufferFetcher.java │ │ │ │ ├── SchemeInitializer.java │ │ │ │ ├── SecureRequestMappingHandlerAdapter.java │ │ │ │ ├── SecureServerRequest.java │ │ │ │ ├── SecureServerWebExchange.java │ │ │ │ ├── SystemConfigChangedEvent.java │ │ │ │ ├── SystemConfigFetcher.java │ │ │ │ ├── SystemConfigFirstExternalUrlSupplier.java │ │ │ │ ├── SystemConfigInitializer.java │ │ │ │ ├── SystemInfoGetterImpl.java │ │ │ │ ├── SystemState.java │ │ │ │ ├── ThemeRootGetter.java │ │ │ │ ├── actuator/ │ │ │ │ │ ├── DatabaseInfoContributor.java │ │ │ │ │ ├── GlobalInfo.java │ │ │ │ │ ├── GlobalInfoEndpoint.java │ │ │ │ │ ├── GlobalInfoService.java │ │ │ │ │ ├── GlobalInfoServiceImpl.java │ │ │ │ │ └── RestartEndpoint.java │ │ │ │ ├── config/ │ │ │ │ │ ├── ExtensionConfiguration.java │ │ │ │ │ ├── HaloConfiguration.java │ │ │ │ │ ├── JacksonAdapterModule.java │ │ │ │ │ ├── R2dbcConfiguration.java │ │ │ │ │ ├── SessionConfiguration.java │ │ │ │ │ ├── SwaggerConfig.java │ │ │ │ │ ├── WebFluxConfig.java │ │ │ │ │ └── WebServerSecurityConfig.java │ │ │ │ ├── exception/ │ │ │ │ │ ├── AccessDeniedException.java │ │ │ │ │ ├── AttachmentAlreadyExistsException.java │ │ │ │ │ ├── DuplicateNameException.java │ │ │ │ │ ├── EmailAlreadyTakenException.java │ │ │ │ │ ├── EmailVerificationFailed.java │ │ │ │ │ ├── Exceptions.java │ │ │ │ │ ├── FileSizeExceededException.java │ │ │ │ │ ├── FileTypeNotAllowedException.java │ │ │ │ │ ├── NotFoundException.java │ │ │ │ │ ├── OAuth2UserAlreadyBoundException.java │ │ │ │ │ ├── PluginAlreadyExistsException.java │ │ │ │ │ ├── PluginDependenciesNotEnabledException.java │ │ │ │ │ ├── PluginDependencyException.java │ │ │ │ │ ├── PluginDependentsNotDisabledException.java │ │ │ │ │ ├── PluginInstallationException.java │ │ │ │ │ ├── PluginRuntimeIncompatibleException.java │ │ │ │ │ ├── RateLimitExceededException.java │ │ │ │ │ ├── RequestBodyValidationException.java │ │ │ │ │ ├── RequestRestrictedException.java │ │ │ │ │ ├── RestrictedNameException.java │ │ │ │ │ ├── ThemeAlreadyExistsException.java │ │ │ │ │ ├── ThemeInstallationException.java │ │ │ │ │ ├── ThemeUninstallException.java │ │ │ │ │ ├── ThemeUpgradeException.java │ │ │ │ │ ├── UnsatisfiedAttributeValueException.java │ │ │ │ │ ├── UserNotFoundException.java │ │ │ │ │ └── handlers/ │ │ │ │ │ ├── HaloErrorConfiguration.java │ │ │ │ │ ├── HaloErrorWebExceptionHandler.java │ │ │ │ │ └── ProblemDetailErrorAttributes.java │ │ │ │ ├── properties/ │ │ │ │ │ ├── AttachmentProperties.java │ │ │ │ │ ├── CacheProperties.java │ │ │ │ │ ├── ExtensionProperties.java │ │ │ │ │ ├── HaloProperties.java │ │ │ │ │ ├── JwtProperties.java │ │ │ │ │ ├── ProxyProperties.java │ │ │ │ │ ├── SecurityProperties.java │ │ │ │ │ ├── ThemeProperties.java │ │ │ │ │ └── UiProperties.java │ │ │ │ ├── ui/ │ │ │ │ │ ├── ProxyFilter.java │ │ │ │ │ ├── WebSocketRequestPredicate.java │ │ │ │ │ ├── WebSocketServerWebExchangeMatcher.java │ │ │ │ │ └── WebSocketUtils.java │ │ │ │ ├── utils/ │ │ │ │ │ ├── Base62Utils.java │ │ │ │ │ ├── FileNameUtils.java │ │ │ │ │ ├── FileUtils.java │ │ │ │ │ ├── HaloUtils.java │ │ │ │ │ ├── IpAddressUtils.java │ │ │ │ │ ├── ReactiveUtils.java │ │ │ │ │ ├── SettingUtils.java │ │ │ │ │ ├── SortUtils.java │ │ │ │ │ ├── SystemConfigUtils.java │ │ │ │ │ ├── VersionUtils.java │ │ │ │ │ └── YamlUnstructuredLoader.java │ │ │ │ └── webfilter/ │ │ │ │ ├── AdditionalWebFilterChainProxy.java │ │ │ │ └── LocaleChangeWebFilter.java │ │ │ ├── migration/ │ │ │ │ ├── BackupFile.java │ │ │ │ ├── BackupReconciler.java │ │ │ │ ├── MigrationEndpoint.java │ │ │ │ ├── MigrationService.java │ │ │ │ └── impl/ │ │ │ │ └── MigrationServiceImpl.java │ │ │ ├── notification/ │ │ │ │ ├── DefaultNotificationCenter.java │ │ │ │ ├── DefaultNotificationReasonEmitter.java │ │ │ │ ├── DefaultNotificationSender.java │ │ │ │ ├── DefaultNotificationService.java │ │ │ │ ├── DefaultNotificationTemplateRender.java │ │ │ │ ├── DefaultNotifierConfigStore.java │ │ │ │ ├── DefaultSubscriberEmailResolver.java │ │ │ │ ├── EmailNotifier.java │ │ │ │ ├── EmailSenderHelper.java │ │ │ │ ├── EmailSenderHelperImpl.java │ │ │ │ ├── LanguageUtils.java │ │ │ │ ├── NotificationSender.java │ │ │ │ ├── NotificationTemplateRender.java │ │ │ │ ├── NotificationTrigger.java │ │ │ │ ├── NotifierConfigStore.java │ │ │ │ ├── ReasonNotificationTemplateSelector.java │ │ │ │ ├── ReasonNotificationTemplateSelectorImpl.java │ │ │ │ ├── RecipientResolver.java │ │ │ │ ├── RecipientResolverImpl.java │ │ │ │ ├── Subscriber.java │ │ │ │ ├── SubscriberEmailResolver.java │ │ │ │ ├── SubscriptionService.java │ │ │ │ ├── SubscriptionServiceImpl.java │ │ │ │ ├── UserNotificationPreference.java │ │ │ │ ├── UserNotificationPreferenceService.java │ │ │ │ ├── UserNotificationPreferenceServiceImpl.java │ │ │ │ ├── UserNotificationQuery.java │ │ │ │ ├── UserNotificationService.java │ │ │ │ └── endpoint/ │ │ │ │ ├── ConsoleNotifierEndpoint.java │ │ │ │ ├── EmailConfigValidationEndpoint.java │ │ │ │ ├── SubscriptionRouter.java │ │ │ │ ├── UserNotificationEndpoint.java │ │ │ │ ├── UserNotificationPreferencesEndpoint.java │ │ │ │ └── UserNotifierEndpoint.java │ │ │ ├── plugin/ │ │ │ │ ├── AggregatedRouterFunction.java │ │ │ │ ├── BuiltInPluginsInitializer.java │ │ │ │ ├── DefaultDevelopmentPluginRepository.java │ │ │ │ ├── DefaultPluginApplicationContextFactory.java │ │ │ │ ├── DefaultPluginGetter.java │ │ │ │ ├── DefaultPluginRouterFunctionRegistry.java │ │ │ │ ├── DefaultReactiveSettingFetcher.java │ │ │ │ ├── DefaultSettingFetcher.java │ │ │ │ ├── DefaultSpringPlugin.java │ │ │ │ ├── DevPluginLoader.java │ │ │ │ ├── HaloPluginManager.java │ │ │ │ ├── HaloSharedEventDelegator.java │ │ │ │ ├── OptionalDependentResolver.java │ │ │ │ ├── PluginApplicationContext.java │ │ │ │ ├── PluginApplicationContextFactory.java │ │ │ │ ├── PluginAutoConfiguration.java │ │ │ │ ├── PluginBeforeStopSyncListener.java │ │ │ │ ├── PluginConst.java │ │ │ │ ├── PluginControllerManager.java │ │ │ │ ├── PluginDevelopmentInitializer.java │ │ │ │ ├── PluginExtensionLoaderUtils.java │ │ │ │ ├── PluginFinder.java │ │ │ │ ├── PluginGetter.java │ │ │ │ ├── PluginNotFoundException.java │ │ │ │ ├── PluginProperties.java │ │ │ │ ├── PluginRequestMappingHandlerMapping.java │ │ │ │ ├── PluginRouterFunctionRegistry.java │ │ │ │ ├── PluginService.java │ │ │ │ ├── PluginServiceImpl.java │ │ │ │ ├── PluginSharedEventDelegator.java │ │ │ │ ├── PluginStartedListener.java │ │ │ │ ├── PluginUtils.java │ │ │ │ ├── PluginsRootGetterImpl.java │ │ │ │ ├── PropertyPluginStatusProvider.java │ │ │ │ ├── SharedApplicationContextFactory.java │ │ │ │ ├── SharedEventDispatcher.java │ │ │ │ ├── SpringComponentsFinder.java │ │ │ │ ├── SpringExtensionFactory.java │ │ │ │ ├── SpringPlugin.java │ │ │ │ ├── SpringPluginFactory.java │ │ │ │ ├── SpringPluginManager.java │ │ │ │ ├── YamlPluginDescriptorFinder.java │ │ │ │ ├── YamlPluginFinder.java │ │ │ │ ├── event/ │ │ │ │ │ ├── HaloPluginBeforeStopEvent.java │ │ │ │ │ ├── HaloPluginStartedEvent.java │ │ │ │ │ ├── HaloPluginStoppedEvent.java │ │ │ │ │ ├── SpringPluginStartedEvent.java │ │ │ │ │ ├── SpringPluginStartingEvent.java │ │ │ │ │ ├── SpringPluginStoppedEvent.java │ │ │ │ │ └── SpringPluginStoppingEvent.java │ │ │ │ ├── extensionpoint/ │ │ │ │ │ ├── AbstractDefinitionGetter.java │ │ │ │ │ ├── DefaultExtensionGetter.java │ │ │ │ │ ├── ExtensionDefinition.java │ │ │ │ │ ├── ExtensionDefinitionGetter.java │ │ │ │ │ ├── ExtensionDefinitionGetterImpl.java │ │ │ │ │ ├── ExtensionPointDefinition.java │ │ │ │ │ ├── ExtensionPointDefinitionGetter.java │ │ │ │ │ └── ExtensionPointDefinitionGetterImpl.java │ │ │ │ └── resources/ │ │ │ │ ├── BundleResourceUtils.java │ │ │ │ ├── ReverseProxyRouterFunctionFactory.java │ │ │ │ └── ReverseProxyRouterFunctionRegistry.java │ │ │ ├── search/ │ │ │ │ ├── HaloDocumentEventsListener.java │ │ │ │ ├── IndexEndpoint.java │ │ │ │ ├── IndicesEndpoint.java │ │ │ │ ├── SearchEngineUnavailableException.java │ │ │ │ ├── SearchServiceImpl.java │ │ │ │ ├── lucene/ │ │ │ │ │ └── LuceneSearchEngine.java │ │ │ │ └── post/ │ │ │ │ ├── PostEventsListener.java │ │ │ │ └── PostHaloDocumentsProvider.java │ │ │ ├── security/ │ │ │ │ ├── AuthProviderService.java │ │ │ │ ├── AuthProviderServiceImpl.java │ │ │ │ ├── CorsConfigurer.java │ │ │ │ ├── CsrfConfigurer.java │ │ │ │ ├── DefaultServerAuthenticationEntryPoint.java │ │ │ │ ├── DefaultSuperAdminInitializer.java │ │ │ │ ├── DefaultUserDetailService.java │ │ │ │ ├── ExceptionSecurityConfigurer.java │ │ │ │ ├── HaloRedirectAuthenticationSuccessHandler.java │ │ │ │ ├── HaloServerRequestCache.java │ │ │ │ ├── HaloUserDetails.java │ │ │ │ ├── InitializeRedirectionWebFilter.java │ │ │ │ ├── ListedAuthProvider.java │ │ │ │ ├── LoginHandlerEnhancerImpl.java │ │ │ │ ├── LogoutSecurityConfigurer.java │ │ │ │ ├── RedirectAccessDeniedHandler.java │ │ │ │ ├── SecurityWebFiltersConfigurer.java │ │ │ │ ├── SuperAdminInitializer.java │ │ │ │ ├── authentication/ │ │ │ │ │ ├── SecurityConfigurer.java │ │ │ │ │ ├── WebExchangeMatchers.java │ │ │ │ │ ├── exception/ │ │ │ │ │ │ ├── TooManyRequestsException.java │ │ │ │ │ │ └── TwoFactorAuthException.java │ │ │ │ │ ├── impl/ │ │ │ │ │ │ └── RsaKeyService.java │ │ │ │ │ ├── login/ │ │ │ │ │ │ ├── HaloUser.java │ │ │ │ │ │ ├── InvalidEncryptedMessageException.java │ │ │ │ │ │ ├── LoginAuthenticationConverter.java │ │ │ │ │ │ ├── LoginSecurityConfigurer.java │ │ │ │ │ │ ├── PublicKeyRouteBuilder.java │ │ │ │ │ │ ├── UsernamePasswordDelegatingAuthenticationManager.java │ │ │ │ │ │ └── UsernamePasswordHandler.java │ │ │ │ │ ├── oauth2/ │ │ │ │ │ │ ├── DefaultOAuth2LoginHandlerEnhancer.java │ │ │ │ │ │ ├── MapOAuth2AuthenticationFilter.java │ │ │ │ │ │ ├── OAuth2AuthenticationTokenCache.java │ │ │ │ │ │ ├── OAuth2LoginHandlerEnhancer.java │ │ │ │ │ │ ├── OAuth2SecurityConfigurer.java │ │ │ │ │ │ └── WebSessionOAuth2AuthenticationTokenCache.java │ │ │ │ │ ├── pat/ │ │ │ │ │ │ ├── PatAuthenticationConverter.java │ │ │ │ │ │ ├── PatAuthenticationManager.java │ │ │ │ │ │ ├── PatEndpoint.java │ │ │ │ │ │ ├── PatSecurityConfigurer.java │ │ │ │ │ │ ├── UserScopedPatHandler.java │ │ │ │ │ │ └── UserScopedPatHandlerImpl.java │ │ │ │ │ ├── rememberme/ │ │ │ │ │ │ ├── CookieSignatureKeyResolver.java │ │ │ │ │ │ ├── DefaultCookieSignatureKeyResolver.java │ │ │ │ │ │ ├── PersistentRememberMeTokenRepository.java │ │ │ │ │ │ ├── PersistentRememberMeTokenRepositoryImpl.java │ │ │ │ │ │ ├── PersistentTokenBasedRememberMeServices.java │ │ │ │ │ │ ├── RememberMeAuthenticationManager.java │ │ │ │ │ │ ├── RememberMeConfigurer.java │ │ │ │ │ │ ├── RememberMeCookieResolver.java │ │ │ │ │ │ ├── RememberMeCookieResolverImpl.java │ │ │ │ │ │ ├── RememberMeRequestCache.java │ │ │ │ │ │ ├── RememberMeServices.java │ │ │ │ │ │ ├── RememberMeTokenRevoker.java │ │ │ │ │ │ ├── RememberTokenCleaner.java │ │ │ │ │ │ ├── TokenBasedRememberMeServices.java │ │ │ │ │ │ └── WebSessionRememberMeRequestCache.java │ │ │ │ │ └── twofactor/ │ │ │ │ │ ├── TotpAuthenticationSuccessHandler.java │ │ │ │ │ ├── TwoFactorAuthEndpoint.java │ │ │ │ │ ├── TwoFactorAuthRequiredException.java │ │ │ │ │ ├── TwoFactorAuthSecurityConfigurer.java │ │ │ │ │ ├── TwoFactorAuthSettings.java │ │ │ │ │ ├── TwoFactorAuthentication.java │ │ │ │ │ ├── TwoFactorAuthenticationEntryPoint.java │ │ │ │ │ ├── TwoFactorUtils.java │ │ │ │ │ └── totp/ │ │ │ │ │ ├── DefaultTotpAuthService.java │ │ │ │ │ ├── TotpAuthService.java │ │ │ │ │ ├── TotpAuthenticationManager.java │ │ │ │ │ ├── TotpAuthenticationToken.java │ │ │ │ │ └── TotpCodeAuthenticationConverter.java │ │ │ │ ├── authorization/ │ │ │ │ │ ├── Attributes.java │ │ │ │ │ ├── AttributesRecord.java │ │ │ │ │ ├── AuthorityUtils.java │ │ │ │ │ ├── AuthorizationExchangeConfigurers.java │ │ │ │ │ ├── AuthorizationRuleResolver.java │ │ │ │ │ ├── AuthorizingVisitor.java │ │ │ │ │ ├── DefaultRuleResolver.java │ │ │ │ │ ├── PolicyRuleList.java │ │ │ │ │ ├── RbacRequestEvaluation.java │ │ │ │ │ ├── RequestInfo.java │ │ │ │ │ ├── RequestInfoAuthorizationManager.java │ │ │ │ │ ├── RequestInfoFactory.java │ │ │ │ │ └── RuleAccumulator.java │ │ │ │ ├── device/ │ │ │ │ │ ├── DeviceCookieResolver.java │ │ │ │ │ ├── DeviceCookieResolverImpl.java │ │ │ │ │ ├── DeviceEndpoint.java │ │ │ │ │ ├── DeviceReconciler.java │ │ │ │ │ ├── DeviceSecurityConfigurer.java │ │ │ │ │ ├── DeviceServiceImpl.java │ │ │ │ │ ├── DeviceSessionFilter.java │ │ │ │ │ ├── NewDeviceLoginEvent.java │ │ │ │ │ └── NewDeviceLoginListener.java │ │ │ │ ├── jackson2/ │ │ │ │ │ ├── HaloOAuth2AuthenticationTokenMixin.java │ │ │ │ │ ├── HaloSecurityJackson2Module.java │ │ │ │ │ ├── HaloUserMixin.java │ │ │ │ │ ├── SwitchUserGrantedAuthorityMixIn.java │ │ │ │ │ └── TwoFactorAuthenticationMixin.java │ │ │ │ ├── preauth/ │ │ │ │ │ ├── DefaultPasswordResetAvailabilityProviders.java │ │ │ │ │ ├── EmailPasswordResetAvailabilityProvider.java │ │ │ │ │ ├── PasswordResetAvailabilityProvider.java │ │ │ │ │ ├── PasswordResetAvailabilityProviders.java │ │ │ │ │ ├── PreAuthEmailPasswordResetEndpoint.java │ │ │ │ │ ├── PreAuthLoginEndpoint.java │ │ │ │ │ ├── PreAuthSignUpEndpoint.java │ │ │ │ │ ├── PreAuthTwoFactorEndpoint.java │ │ │ │ │ └── SystemSetupEndpoint.java │ │ │ │ ├── session/ │ │ │ │ │ ├── InMemoryReactiveIndexedSessionRepository.java │ │ │ │ │ ├── ReactiveIndexedSessionRepository.java │ │ │ │ │ └── SessionInvalidationListener.java │ │ │ │ └── switchuser/ │ │ │ │ └── SwitchUserConfigurer.java │ │ │ └── theme/ │ │ │ ├── CompositeTemplateResolver.java │ │ │ ├── DefaultTemplateEnum.java │ │ │ ├── DefaultTemplateNameResolver.java │ │ │ ├── DefaultViewNameResolver.java │ │ │ ├── HaloViewResolver.java │ │ │ ├── ReactiveSpelVariableExpressionEvaluator.java │ │ │ ├── SiteSettingVariablesAcquirer.java │ │ │ ├── TemplateEngineManager.java │ │ │ ├── ThemeContext.java │ │ │ ├── ThemeContextBasedVariablesAcquirer.java │ │ │ ├── ThemeLinkBuilder.java │ │ │ ├── ThemeLocaleContextResolver.java │ │ │ ├── ThemeResolver.java │ │ │ ├── UserLocaleRequestAttributeWriteFilter.java │ │ │ ├── ViewContextBasedVariablesAcquirer.java │ │ │ ├── ViewNameResolver.java │ │ │ ├── config/ │ │ │ │ ├── ThemeConfiguration.java │ │ │ │ └── ThemeWebFluxConfigurer.java │ │ │ ├── dialect/ │ │ │ │ ├── CommentElementTagProcessor.java │ │ │ │ ├── CommentEnabledVariableProcessor.java │ │ │ │ ├── ContentTemplateHeadProcessor.java │ │ │ │ ├── DefaultFaviconHeadProcessor.java │ │ │ │ ├── DefaultLinkExpressionFactory.java │ │ │ │ ├── DuplicateMetaTagProcessor.java │ │ │ │ ├── EvaluationContextEnhancer.java │ │ │ │ ├── GeneratorMetaProcessor.java │ │ │ │ ├── GlobalHeadInjectionProcessor.java │ │ │ │ ├── GlobalSeoProcessor.java │ │ │ │ ├── HaloExpressionObjectFactory.java │ │ │ │ ├── HaloPostTemplateHandler.java │ │ │ │ ├── HaloProcessorDialect.java │ │ │ │ ├── HaloSpringSecurityDialect.java │ │ │ │ ├── HaloTrackerProcessor.java │ │ │ │ ├── IndexSeoProcessor.java │ │ │ │ ├── InjectionExcluderProcessor.java │ │ │ │ ├── LinkExpressionObjectDialect.java │ │ │ │ ├── SecureTemplateContext.java │ │ │ │ ├── SecureTemplateContextWrapper.java │ │ │ │ ├── SecureTemplateWebContext.java │ │ │ │ ├── TemplateFooterElementTagProcessor.java │ │ │ │ ├── TemplateGlobalHeadProcessor.java │ │ │ │ └── expression/ │ │ │ │ └── Annotations.java │ │ │ ├── endpoint/ │ │ │ │ └── ThemeEndpoint.java │ │ │ ├── engine/ │ │ │ │ ├── DefaultThemeTemplateAvailabilityProvider.java │ │ │ │ ├── HaloTemplateEngine.java │ │ │ │ ├── PluginClassloaderTemplateResolver.java │ │ │ │ └── ThemeTemplateAvailabilityProvider.java │ │ │ ├── finders/ │ │ │ │ ├── CategoryFinder.java │ │ │ │ ├── CommentFinder.java │ │ │ │ ├── CommentPublicQueryService.java │ │ │ │ ├── ContributorFinder.java │ │ │ │ ├── DefaultFinderRegistry.java │ │ │ │ ├── FinderRegistry.java │ │ │ │ ├── MenuFinder.java │ │ │ │ ├── PluginFinder.java │ │ │ │ ├── PostFinder.java │ │ │ │ ├── PostPublicQueryService.java │ │ │ │ ├── SinglePageConversionService.java │ │ │ │ ├── SinglePageFinder.java │ │ │ │ ├── SiteStatsFinder.java │ │ │ │ ├── TagFinder.java │ │ │ │ ├── ThemeFinder.java │ │ │ │ ├── ThumbnailFinder.java │ │ │ │ ├── impl/ │ │ │ │ │ ├── CategoryFinderImpl.java │ │ │ │ │ ├── CommentFinderImpl.java │ │ │ │ │ ├── CommentPublicQueryServiceImpl.java │ │ │ │ │ ├── ContributorFinderImpl.java │ │ │ │ │ ├── MenuFinderImpl.java │ │ │ │ │ ├── PluginFinderImpl.java │ │ │ │ │ ├── PostFinderImpl.java │ │ │ │ │ ├── PostPublicQueryServiceImpl.java │ │ │ │ │ ├── SinglePageConversionServiceImpl.java │ │ │ │ │ ├── SinglePageFinderImpl.java │ │ │ │ │ ├── SiteStatsFinderImpl.java │ │ │ │ │ ├── TagFinderImpl.java │ │ │ │ │ ├── ThemeFinderImpl.java │ │ │ │ │ └── ThumbnailFinderImpl.java │ │ │ │ └── vo/ │ │ │ │ ├── CategoryTreeVo.java │ │ │ │ ├── CategoryVo.java │ │ │ │ ├── CommentStatsVo.java │ │ │ │ ├── CommentVo.java │ │ │ │ ├── CommentWithReplyVo.java │ │ │ │ ├── ContentVo.java │ │ │ │ ├── ContributorVo.java │ │ │ │ ├── ListedPostVo.java │ │ │ │ ├── ListedSinglePageVo.java │ │ │ │ ├── MenuItemVo.java │ │ │ │ ├── MenuVo.java │ │ │ │ ├── NavigationPostVo.java │ │ │ │ ├── PostArchiveVo.java │ │ │ │ ├── PostArchiveYearMonthVo.java │ │ │ │ ├── PostVo.java │ │ │ │ ├── ReplyVo.java │ │ │ │ ├── SinglePageVo.java │ │ │ │ ├── SiteSettingVo.java │ │ │ │ ├── SiteStatsVo.java │ │ │ │ ├── StatsVo.java │ │ │ │ ├── TagVo.java │ │ │ │ ├── ThemeVo.java │ │ │ │ ├── UserVo.java │ │ │ │ └── VisualizableTreeNode.java │ │ │ ├── message/ │ │ │ │ ├── ThemeMessageResolutionUtils.java │ │ │ │ └── ThemeMessageResolver.java │ │ │ ├── router/ │ │ │ │ ├── DefaultQueryPostPredicateResolver.java │ │ │ │ ├── ExtensionPermalinkPatternUpdater.java │ │ │ │ ├── ModelMapUtils.java │ │ │ │ ├── PermalinkRuleChangedEvent.java │ │ │ │ ├── PreviewRouterFunction.java │ │ │ │ ├── ReactiveQueryPostPredicateResolver.java │ │ │ │ ├── SinglePageRoute.java │ │ │ │ ├── ThemeCompositeRouterFunction.java │ │ │ │ ├── TitleVisibilityIdentifyCalculator.java │ │ │ │ └── factories/ │ │ │ │ ├── ArchiveRouteFactory.java │ │ │ │ ├── AuthorPostsRouteFactory.java │ │ │ │ ├── CategoriesRouteFactory.java │ │ │ │ ├── CategoryPostRouteFactory.java │ │ │ │ ├── IndexRouteFactory.java │ │ │ │ ├── PostRouteFactory.java │ │ │ │ ├── RouteFactory.java │ │ │ │ ├── TagPostRouteFactory.java │ │ │ │ └── TagsRouteFactory.java │ │ │ ├── service/ │ │ │ │ ├── ThemeService.java │ │ │ │ ├── ThemeServiceImpl.java │ │ │ │ └── ThemeUtils.java │ │ │ └── utils/ │ │ │ └── PatternUtils.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── spring-devtools.properties │ │ ├── application-dev.yaml │ │ ├── application-doc.yaml │ │ ├── application-mariadb.yaml │ │ ├── application-mysql.yaml │ │ ├── application-postgresql.yaml │ │ ├── application-win.yaml │ │ ├── application.yaml │ │ ├── banner.txt │ │ ├── config/ │ │ │ └── i18n/ │ │ │ ├── messages.properties │ │ │ ├── messages_es.properties │ │ │ └── messages_zh.properties │ │ ├── db/ │ │ │ └── migration/ │ │ │ ├── h2/ │ │ │ │ └── .gitkeep │ │ │ ├── mariadb/ │ │ │ │ └── .gitkeep │ │ │ ├── mysql/ │ │ │ │ └── .gitkeep │ │ │ └── postgresql/ │ │ │ └── .gitkeep │ │ ├── extensions/ │ │ │ ├── attachment-local-policy.yaml │ │ │ ├── authproviders.yaml │ │ │ ├── extension-definitions.yaml │ │ │ ├── extensionpoint-definitions.yaml │ │ │ ├── notification-templates.yaml │ │ │ ├── notification.yaml │ │ │ ├── role-template-actuator.yaml │ │ │ ├── role-template-anonymous.yaml │ │ │ ├── role-template-attachment.yaml │ │ │ ├── role-template-authenticated.yaml │ │ │ ├── role-template-cache.yaml │ │ │ ├── role-template-category.yaml │ │ │ ├── role-template-comment.yaml │ │ │ ├── role-template-configmap.yaml │ │ │ ├── role-template-menu.yaml │ │ │ ├── role-template-migration.yaml │ │ │ ├── role-template-notification.yaml │ │ │ ├── role-template-permissions.yaml │ │ │ ├── role-template-plugin.yaml │ │ │ ├── role-template-post.yaml │ │ │ ├── role-template-role.yaml │ │ │ ├── role-template-setting.yaml │ │ │ ├── role-template-singlepage.yaml │ │ │ ├── role-template-snapshot.yaml │ │ │ ├── role-template-tag.yaml │ │ │ ├── role-template-theme.yaml │ │ │ ├── role-template-uc-attachment.yaml │ │ │ ├── role-template-uc-content.yaml │ │ │ ├── role-template-user.yaml │ │ │ ├── system-configurable-configmap.yaml │ │ │ ├── system-default-role.yaml │ │ │ ├── system-setting.yaml │ │ │ └── user.yaml │ │ ├── initial-data.yaml │ │ ├── schema-h2.sql │ │ ├── schema-mariadb.sql │ │ ├── schema-mysql.sql │ │ ├── schema-postgresql.sql │ │ ├── static/ │ │ │ ├── halo-tracker.js │ │ │ ├── js/ │ │ │ │ └── main.js │ │ │ └── styles/ │ │ │ └── main.css │ │ ├── templates/ │ │ │ ├── challenges/ │ │ │ │ └── two-factor/ │ │ │ │ ├── totp.html │ │ │ │ ├── totp.properties │ │ │ │ ├── totp_en.properties │ │ │ │ ├── totp_es.properties │ │ │ │ └── totp_zh_TW.properties │ │ │ ├── error/ │ │ │ │ └── error.html │ │ │ ├── gateway_fragments/ │ │ │ │ ├── common.html │ │ │ │ ├── common.properties │ │ │ │ ├── common_en.properties │ │ │ │ ├── common_es.properties │ │ │ │ ├── common_zh_TW.properties │ │ │ │ ├── input.html │ │ │ │ ├── layout.html │ │ │ │ ├── login.html │ │ │ │ ├── login.properties │ │ │ │ ├── login_en.properties │ │ │ │ ├── login_es.properties │ │ │ │ ├── login_zh_TW.properties │ │ │ │ ├── logout.html │ │ │ │ ├── logout.properties │ │ │ │ ├── logout_en.properties │ │ │ │ ├── logout_es.properties │ │ │ │ ├── logout_zh_TW.properties │ │ │ │ ├── password_reset_email_reset.html │ │ │ │ ├── password_reset_email_reset.properties │ │ │ │ ├── password_reset_email_reset_en.properties │ │ │ │ ├── password_reset_email_reset_es.properties │ │ │ │ ├── password_reset_email_reset_zh_TW.properties │ │ │ │ ├── password_reset_email_send.html │ │ │ │ ├── password_reset_email_send.properties │ │ │ │ ├── password_reset_email_send_en.properties │ │ │ │ ├── password_reset_email_send_es.properties │ │ │ │ ├── password_reset_email_send_zh_TW.properties │ │ │ │ ├── signup.html │ │ │ │ ├── signup.properties │ │ │ │ ├── signup_en.properties │ │ │ │ ├── signup_es.properties │ │ │ │ ├── signup_zh_TW.properties │ │ │ │ ├── totp.html │ │ │ │ ├── totp.properties │ │ │ │ ├── totp_en.properties │ │ │ │ ├── totp_es.properties │ │ │ │ └── totp_zh_TW.properties │ │ │ ├── login.html │ │ │ ├── login.properties │ │ │ ├── login_en.properties │ │ │ ├── login_es.properties │ │ │ ├── login_local.html │ │ │ ├── login_local.properties │ │ │ ├── login_local_en.properties │ │ │ ├── login_local_es.properties │ │ │ ├── login_local_zh_TW.properties │ │ │ ├── login_zh_TW.properties │ │ │ ├── logout.html │ │ │ ├── logout.properties │ │ │ ├── logout_en.properties │ │ │ ├── logout_es.properties │ │ │ ├── logout_zh_TW.properties │ │ │ ├── password-reset/ │ │ │ │ └── email/ │ │ │ │ ├── reset.html │ │ │ │ ├── reset.properties │ │ │ │ ├── reset_en.properties │ │ │ │ ├── reset_es.properties │ │ │ │ ├── reset_zh_TW.properties │ │ │ │ ├── send.html │ │ │ │ ├── send.properties │ │ │ │ ├── send_en.properties │ │ │ │ ├── send_es.properties │ │ │ │ └── send_zh_TW.properties │ │ │ ├── setup.html │ │ │ ├── setup.properties │ │ │ ├── setup_en.properties │ │ │ ├── setup_es.properties │ │ │ ├── setup_zh_TW.properties │ │ │ ├── signup.html │ │ │ ├── signup.properties │ │ │ ├── signup_en.properties │ │ │ ├── signup_es.properties │ │ │ └── signup_zh_TW.properties │ │ └── thumbnailator.properties │ └── test/ │ ├── java/ │ │ └── run/ │ │ └── halo/ │ │ └── app/ │ │ ├── ApplicationTests.java │ │ ├── PathPrefixPredicateTest.java │ │ ├── XForwardHeaderTest.java │ │ ├── config/ │ │ │ ├── CorsTest.java │ │ │ ├── ExtensionConfigurationTest.java │ │ │ ├── HaloConfigurationTest.java │ │ │ ├── SecurityConfigTest.java │ │ │ ├── ServerCodecTest.java │ │ │ └── WebFluxConfigTest.java │ │ ├── content/ │ │ │ ├── CategoryPostCountUpdaterTest.java │ │ │ ├── ContentRequestTest.java │ │ │ ├── PostIntegrationTests.java │ │ │ ├── TestPost.java │ │ │ ├── comment/ │ │ │ │ ├── CommentEmailOwnerTest.java │ │ │ │ ├── CommentNotificationReasonPublisherTest.java │ │ │ │ ├── CommentRequestTest.java │ │ │ │ ├── CommentServiceImplIntegrationTest.java │ │ │ │ ├── CommentServiceImplTest.java │ │ │ │ ├── PostCommentSubjectTest.java │ │ │ │ ├── ReplyNotificationSubscriptionHelperTest.java │ │ │ │ ├── ReplyServiceImplIntegrationTest.java │ │ │ │ └── SinglePageCommentSubjectTest.java │ │ │ └── permalinks/ │ │ │ ├── CategoryPermalinkPolicyTest.java │ │ │ ├── PostPermalinkPolicyTest.java │ │ │ └── TagPermalinkPolicyTest.java │ │ ├── core/ │ │ │ ├── attachment/ │ │ │ │ ├── PolicyConfigChangeDetectorTest.java │ │ │ │ ├── endpoint/ │ │ │ │ │ ├── LocalAttachmentUploadHandlerTest.java │ │ │ │ │ └── PolicyEndpointTest.java │ │ │ │ ├── impl/ │ │ │ │ │ └── AttachmentRootGetterImplTest.java │ │ │ │ └── thumbnail/ │ │ │ │ ├── DefaultLocalThumbnailServiceTest.java │ │ │ │ ├── DefaultThumbnailServiceTest.java │ │ │ │ ├── ThumbnailImgTagPostProcessorTest.java │ │ │ │ ├── ThumbnailResourceTransformerTest.java │ │ │ │ └── ThumbnailUtilsTest.java │ │ │ ├── counter/ │ │ │ │ └── MeterUtilsTest.java │ │ │ ├── endpoint/ │ │ │ │ ├── WebSocketHandlerMappingTest.java │ │ │ │ ├── console/ │ │ │ │ │ ├── EmailVerificationCodeTest.java │ │ │ │ │ ├── PluginEndpointTest.java │ │ │ │ │ ├── PostEndpointTest.java │ │ │ │ │ ├── SinglePageEndpointTest.java │ │ │ │ │ ├── TagEndpointTest.java │ │ │ │ │ ├── UserEndpointIntegrationTest.java │ │ │ │ │ └── UserEndpointTest.java │ │ │ │ ├── theme/ │ │ │ │ │ ├── CategoryQueryEndpointTest.java │ │ │ │ │ ├── CommentFinderEndpointTest.java │ │ │ │ │ ├── MenuQueryEndpointTest.java │ │ │ │ │ ├── PluginQueryEndpointTest.java │ │ │ │ │ ├── PostQueryEndpointTest.java │ │ │ │ │ ├── PublicApiUtilsTest.java │ │ │ │ │ ├── SinglePageQueryEndpointTest.java │ │ │ │ │ └── ThumbnailEndpointTest.java │ │ │ │ └── uc/ │ │ │ │ ├── AnnotationSettingEndpointTest.java │ │ │ │ └── UcUserPreferenceEndpointTest.java │ │ │ ├── extension/ │ │ │ │ ├── PostTest.java │ │ │ │ ├── RoleBindingTest.java │ │ │ │ ├── SettingTest.java │ │ │ │ ├── TestRole.java │ │ │ │ ├── ThemeTest.java │ │ │ │ └── attachment/ │ │ │ │ └── endpoint/ │ │ │ │ └── AttachmentEndpointTest.java │ │ │ ├── reconciler/ │ │ │ │ ├── CommentReconcilerTest.java │ │ │ │ ├── MenuItemReconcilerTest.java │ │ │ │ ├── PluginReconcilerTest.java │ │ │ │ ├── PostReconcilerTest.java │ │ │ │ ├── ReverseProxyReconcilerTest.java │ │ │ │ ├── SinglePageReconcilerTest.java │ │ │ │ ├── SystemConfigReconcilerTest.java │ │ │ │ ├── TagReconcilerTest.java │ │ │ │ ├── ThemeReconcilerTest.java │ │ │ │ └── UserReconcilerTest.java │ │ │ └── user/ │ │ │ └── service/ │ │ │ ├── DefaultRoleServiceTest.java │ │ │ └── impl/ │ │ │ ├── EmailPasswordRecoveryServiceImplTest.java │ │ │ ├── EmailVerificationServiceImplTest.java │ │ │ └── UserServiceImplTest.java │ │ ├── extension/ │ │ │ ├── AbstractExtensionTest.java │ │ │ ├── ComparatorsTest.java │ │ │ ├── ConfigMapTest.java │ │ │ ├── DefaultSchemeManagerTest.java │ │ │ ├── ExtensionOperatorTest.java │ │ │ ├── ExtensionStoreUtilTest.java │ │ │ ├── FakeExtension.java │ │ │ ├── GroupVersionKindTest.java │ │ │ ├── GroupVersionTest.java │ │ │ ├── JsonExtensionConverterTest.java │ │ │ ├── JsonExtensionTest.java │ │ │ ├── ListResultTest.java │ │ │ ├── MetadataOperatorTest.java │ │ │ ├── ReactiveExtensionClientTest.java │ │ │ ├── RefTest.java │ │ │ ├── SchemeTest.java │ │ │ ├── UnstructuredTest.java │ │ │ ├── gc/ │ │ │ │ ├── GcReconcilerTest.java │ │ │ │ ├── GcSynchronizerTest.java │ │ │ │ └── GcWatcherTest.java │ │ │ ├── index/ │ │ │ │ ├── DefaultIndexEngineTest.java │ │ │ │ ├── DefaultIndicesManagerTest.java │ │ │ │ ├── DefaultIndicesTest.java │ │ │ │ ├── Fake.java │ │ │ │ ├── LabelIndexTest.java │ │ │ │ ├── MultiValueIndexTest.java │ │ │ │ ├── SingleValueIndexTest.java │ │ │ │ └── query/ │ │ │ │ └── QueryVisitorTest.java │ │ │ ├── router/ │ │ │ │ ├── ExtensionCompositeRouterFunctionTest.java │ │ │ │ ├── ExtensionCreateHandlerTest.java │ │ │ │ ├── ExtensionDeleteHandlerTest.java │ │ │ │ ├── ExtensionGetHandlerTest.java │ │ │ │ ├── ExtensionListHandlerTest.java │ │ │ │ ├── ExtensionRouterFunctionFactoryTest.java │ │ │ │ ├── ExtensionUpdateHandlerTest.java │ │ │ │ └── PathPatternGeneratorTest.java │ │ │ └── store/ │ │ │ └── ReactiveExtensionStoreClientImplTest.java │ │ ├── infra/ │ │ │ ├── ConditionListTest.java │ │ │ ├── DefaultBackupRootGetterTest.java │ │ │ ├── DefaultExternalLinkProcessorTest.java │ │ │ ├── DefaultSystemConfigFetcherTest.java │ │ │ ├── DefaultSystemVersionSupplierTest.java │ │ │ ├── ExtensionResourceInitializerTest.java │ │ │ ├── InitializationStateGetterTest.java │ │ │ ├── ReactiveExtensionPaginatedOperatorImplTest.java │ │ │ ├── SystemConfigFirstExternalUrlSupplierTest.java │ │ │ ├── SystemSettingTest.java │ │ │ ├── SystemStateTest.java │ │ │ ├── ValidationUtilsTest.java │ │ │ ├── config/ │ │ │ │ └── SessionConfigurationTest.java │ │ │ ├── exception/ │ │ │ │ └── handlers/ │ │ │ │ └── I18nExceptionTest.java │ │ │ ├── properties/ │ │ │ │ └── HaloPropertiesTest.java │ │ │ └── utils/ │ │ │ ├── Base62UtilsTest.java │ │ │ ├── FileNameUtilsTest.java │ │ │ ├── FileTypeDetectUtilsTest.java │ │ │ ├── FileUtilsTest.java │ │ │ ├── HaloUtilsTest.java │ │ │ ├── IpAddressUtilsTest.java │ │ │ ├── SettingUtilsTest.java │ │ │ ├── SortUtilsTest.java │ │ │ ├── SystemConfigUtilsTest.java │ │ │ ├── VersionUtilsTest.java │ │ │ └── YamlUnstructuredLoaderTest.java │ │ ├── migration/ │ │ │ ├── BackupReconcilerTest.java │ │ │ └── impl/ │ │ │ └── MigrationServiceImplTest.java │ │ ├── notification/ │ │ │ ├── DefaultNotificationCenterTest.java │ │ │ ├── DefaultNotificationReasonEmitterTest.java │ │ │ ├── DefaultNotificationSenderTest.java │ │ │ ├── DefaultNotificationTemplateRenderTest.java │ │ │ ├── DefaultNotifierConfigStoreTest.java │ │ │ ├── DefaultSubscriberEmailResolverTest.java │ │ │ ├── LanguageUtilsTest.java │ │ │ ├── NotificationContextTest.java │ │ │ ├── NotificationTriggerTest.java │ │ │ ├── ReasonNotificationTemplateSelectorImplTest.java │ │ │ ├── ReasonPayloadTest.java │ │ │ ├── RecipientResolverImplTest.java │ │ │ ├── SubscriptionServiceImplTest.java │ │ │ ├── UserIdentityTest.java │ │ │ ├── UserNotificationPreferenceServiceImplTest.java │ │ │ ├── UserNotificationPreferenceTest.java │ │ │ └── endpoint/ │ │ │ ├── SubscriptionRouterTest.java │ │ │ └── UserNotificationPreferencesEndpointTest.java │ │ ├── plugin/ │ │ │ ├── BuiltInPluginsInitializerTest.java │ │ │ ├── DefaultDevelopmentPluginRepositoryTest.java │ │ │ ├── DefaultPluginApplicationContextFactoryTest.java │ │ │ ├── DefaultPluginRouterFunctionRegistryTest.java │ │ │ ├── DefaultSettingFetcherTest.java │ │ │ ├── HaloPluginManagerTest.java │ │ │ ├── OptionalDependentResolverTest.java │ │ │ ├── PluginExtensionLoaderUtilsTest.java │ │ │ ├── PluginRequestMappingHandlerMappingTest.java │ │ │ ├── PluginServiceImplTest.java │ │ │ ├── PluginsRootGetterImplTest.java │ │ │ ├── SharedApplicationContextFactoryTest.java │ │ │ ├── SharedEventDispatcherTest.java │ │ │ ├── SpringComponentsFinderTest.java │ │ │ ├── YamlPluginDescriptorFinderTest.java │ │ │ ├── YamlPluginFinderTest.java │ │ │ ├── extensionpoint/ │ │ │ │ └── DefaultExtensionGetterTest.java │ │ │ └── resources/ │ │ │ ├── BundleResourceUtilsTest.java │ │ │ ├── ReverseProxyRouterFunctionFactoryTest.java │ │ │ └── ReverseProxyRouterFunctionRegistryTest.java │ │ ├── search/ │ │ │ ├── HaloDocumentEventsListenerTest.java │ │ │ ├── IndexEndpointTest.java │ │ │ ├── IndicesEndpointTest.java │ │ │ ├── SearchServiceImplTest.java │ │ │ ├── lucene/ │ │ │ │ ├── LuceneSearchEngineIntegrationTest.java │ │ │ │ └── LuceneSearchEngineTest.java │ │ │ └── post/ │ │ │ ├── PostEventsListenerTest.java │ │ │ └── PostHaloDocumentsProviderTest.java │ │ ├── security/ │ │ │ ├── AuthProviderServiceImplTest.java │ │ │ ├── CsrfSecurityTest.java │ │ │ ├── DefaultServerAuthenticationEntryPointTest.java │ │ │ ├── DefaultSuperAdminInitializerTest.java │ │ │ ├── DefaultUserDetailServiceTest.java │ │ │ ├── HaloServerRequestCacheTest.java │ │ │ ├── InitializeRedirectionWebFilterTest.java │ │ │ ├── ResponseMap.java │ │ │ ├── authentication/ │ │ │ │ ├── WebExchangeMatchersTest.java │ │ │ │ ├── impl/ │ │ │ │ │ └── RsaKeyServiceTest.java │ │ │ │ ├── login/ │ │ │ │ │ ├── LoginAuthenticationConverterTest.java │ │ │ │ │ └── PublicKeyRouteBuilderTest.java │ │ │ │ ├── pat/ │ │ │ │ │ └── PatTest.java │ │ │ │ ├── rememberme/ │ │ │ │ │ ├── PersistentTokenBasedRememberMeServicesTest.java │ │ │ │ │ ├── RememberTokenCleanerTest.java │ │ │ │ │ └── TokenBasedRememberMeServicesTest.java │ │ │ │ └── twofactor/ │ │ │ │ └── TwoFactorAuthSettingsTest.java │ │ │ ├── authorization/ │ │ │ │ ├── AuthorityUtilsTest.java │ │ │ │ ├── AuthorizationTest.java │ │ │ │ ├── DefaultRuleResolverTest.java │ │ │ │ ├── PolicyRuleTest.java │ │ │ │ ├── RbacRequestEvaluationTest.java │ │ │ │ └── RequestInfoResolverTest.java │ │ │ ├── device/ │ │ │ │ └── DeviceServiceImplTest.java │ │ │ ├── jackson2/ │ │ │ │ └── HaloSecurityJacksonModuleTest.java │ │ │ ├── preauth/ │ │ │ │ └── SystemSetupEndpointTest.java │ │ │ ├── session/ │ │ │ │ └── InMemoryReactiveIndexedSessionRepositoryTest.java │ │ │ └── switchuser/ │ │ │ ├── SwitchUserConfigurerTest.java │ │ │ ├── SwitchUserSecurityContextFactory.java │ │ │ └── WithSwitchUser.java │ │ ├── theme/ │ │ │ ├── CompositeTemplateResolverTest.java │ │ │ ├── ReactiveFinderExpressionParserTests.java │ │ │ ├── SiteSettingVariablesAcquirerTest.java │ │ │ ├── ThemeContextTest.java │ │ │ ├── ThemeIntegrationTest.java │ │ │ ├── ThemeLinkBuilderTest.java │ │ │ ├── ThemeLocaleContextResolverTest.java │ │ │ ├── ViewNameResolverTest.java │ │ │ ├── dialect/ │ │ │ │ ├── CommentElementTagProcessorTest.java │ │ │ │ ├── CommentEnabledVariableProcessorTest.java │ │ │ │ ├── ContentTemplateHeadProcessorIntegrationTest.java │ │ │ │ ├── ContentTemplateHeadProcessorTest.java │ │ │ │ ├── DuplicateMetaTagProcessorTest.java │ │ │ │ ├── GeneratorMetaProcessorTest.java │ │ │ │ ├── HaloPostTemplateHandlerTest.java │ │ │ │ ├── HaloProcessorDialectTest.java │ │ │ │ ├── HaloSpringSecurityDialectTest.java │ │ │ │ ├── InjectionExcluderProcessorTest.java │ │ │ │ ├── LinkExpressionObjectDialectTest.java │ │ │ │ └── TemplateFooterElementTagProcessorTest.java │ │ │ ├── endpoint/ │ │ │ │ └── ThemeEndpointTest.java │ │ │ ├── engine/ │ │ │ │ ├── DefaultThemeTemplateAvailabilityProviderTest.java │ │ │ │ └── PluginClassloaderTemplateResolverTest.java │ │ │ ├── finders/ │ │ │ │ ├── FinderRegistryTest.java │ │ │ │ ├── impl/ │ │ │ │ │ ├── CategoryFinderImplTest.java │ │ │ │ │ ├── CommentPublicQueryServiceImplTest.java │ │ │ │ │ ├── CommentPublicQueryServiceIntegrationTest.java │ │ │ │ │ ├── MenuFinderImplTest.java │ │ │ │ │ ├── PluginFinderImplTest.java │ │ │ │ │ ├── PostFinderImplIntegrationTest.java │ │ │ │ │ ├── PostFinderImplTest.java │ │ │ │ │ ├── PostPublicQueryServiceImplTest.java │ │ │ │ │ ├── SinglePageConversionServiceImplTest.java │ │ │ │ │ ├── SinglePageFinderImplTest.java │ │ │ │ │ ├── TagFinderImplTest.java │ │ │ │ │ └── ThumbnailFinderImplTest.java │ │ │ │ └── vo/ │ │ │ │ └── UserVoTest.java │ │ │ ├── message/ │ │ │ │ ├── ThemeMessageResolutionUtilsTest.java │ │ │ │ └── ThemeMessageResolverIntegrationTest.java │ │ │ ├── router/ │ │ │ │ ├── EmptyView.java │ │ │ │ ├── PageUrlUtilsTest.java │ │ │ │ ├── PreviewRouterFunctionTest.java │ │ │ │ ├── ReactiveQueryPostPredicateResolverTest.java │ │ │ │ ├── SinglePageRouteTest.java │ │ │ │ └── factories/ │ │ │ │ ├── ArchiveRouteFactoryTest.java │ │ │ │ ├── AuthorPostsRouteFactoryTest.java │ │ │ │ ├── CategoriesRouteFactoryTest.java │ │ │ │ ├── IndexRouteFactoryTest.java │ │ │ │ ├── PostRouteFactoryTest.java │ │ │ │ ├── RouteFactoryTest.java │ │ │ │ ├── RouteFactoryTestSuite.java │ │ │ │ └── TagPostRouteFactoryTest.java │ │ │ ├── service/ │ │ │ │ └── ThemeServiceImplTest.java │ │ │ └── utils/ │ │ │ └── PatternUtilsTest.java │ │ ├── ui/ │ │ │ ├── WebSocketServerWebExchangeMatcherTest.java │ │ │ └── WebSocketUtilsTest.java │ │ └── webfilter/ │ │ └── LocaleChangeWebFilterTest.java │ └── resources/ │ ├── apiToken.salt │ ├── app.key │ ├── app.pub │ ├── application.yaml │ ├── backups/ │ │ └── backup-for-restoration/ │ │ ├── extensions.data │ │ └── workdir/ │ │ └── fake-file │ ├── categories/ │ │ └── independent-post-count.json │ ├── config/ │ │ └── i18n/ │ │ ├── messages.properties │ │ └── messages_zh.properties │ ├── console/ │ │ ├── assets/ │ │ │ └── fake.txt │ │ └── index.html │ ├── file-type-detect/ │ │ ├── index.html │ │ ├── index.js │ │ ├── other.xlsx │ │ ├── test.docx │ │ └── test.json │ ├── folder-to-zip/ │ │ └── examplefile │ ├── plugin/ │ │ ├── plugin-0.0.1/ │ │ │ ├── extensions/ │ │ │ │ ├── reverseProxy.yaml │ │ │ │ ├── roles.yaml │ │ │ │ ├── setting.yaml │ │ │ │ └── test.yml │ │ │ └── plugin.yaml │ │ ├── plugin-0.0.2/ │ │ │ └── plugin.yaml │ │ ├── plugin-for-finder/ │ │ │ └── META-INF/ │ │ │ └── plugin-components.idx │ │ ├── plugin-for-reverseproxy/ │ │ │ └── static/ │ │ │ └── test.txt │ │ └── plugin.yaml │ ├── presets/ │ │ └── plugins/ │ │ └── fake-plugin.jar │ ├── themes/ │ │ ├── default/ │ │ │ ├── i18n/ │ │ │ │ ├── default.properties │ │ │ │ ├── en.properties │ │ │ │ └── zh.properties │ │ │ ├── templates/ │ │ │ │ ├── index.html │ │ │ │ ├── index.properties │ │ │ │ ├── index_zh.properties │ │ │ │ └── timezone.html │ │ │ └── theme.yaml │ │ ├── invalid-missing-manifest/ │ │ │ ├── i18n/ │ │ │ │ ├── default.properties │ │ │ │ └── en.properties │ │ │ └── templates/ │ │ │ ├── index.html │ │ │ └── timezone.html │ │ └── other/ │ │ ├── i18n/ │ │ │ ├── default.properties │ │ │ └── en.properties │ │ ├── templates/ │ │ │ └── index.html │ │ └── theme.yaml │ └── ui/ │ ├── console.html │ ├── uc.html │ └── ui-assets/ │ └── fake.txt ├── buildSrc/ │ ├── build.gradle │ └── src/ │ └── main/ │ └── groovy/ │ ├── UploadBundleTask.groovy │ └── halo.publish.gradle ├── config/ │ └── checkstyle/ │ └── checkstyle.xml ├── docs/ │ ├── authentication/ │ │ └── README.md │ ├── backup-and-restore.md │ ├── cache/ │ │ └── page.md │ ├── developer-guide/ │ │ ├── custom-endpoint.md │ │ └── plugin-configuration-properties.md │ ├── email-verification/ │ │ └── README.md │ ├── extension-points/ │ │ ├── authentication.md │ │ ├── content.md │ │ └── search-engine.md │ ├── full-text-search/ │ │ └── README.md │ ├── index/ │ │ └── README.md │ ├── notification/ │ │ └── README.md │ └── plugin/ │ ├── shared-event.md │ └── websocket.md ├── e2e/ │ ├── Dockerfile │ ├── Makefile │ ├── README.md │ ├── compose-mysql.yaml │ ├── compose-postgres.yaml │ ├── compose.yaml │ ├── start.sh │ └── testsuite.yaml ├── gradle/ │ ├── libs.versions.toml │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── hack/ │ └── cherry_pick_pull.sh ├── platform/ │ ├── application/ │ │ └── build.gradle │ └── plugin/ │ └── build.gradle ├── settings.gradle └── ui/ ├── .editorconfig ├── .husky/ │ └── pre-commit ├── .npmrc ├── .oxfmtrc.json ├── Makefile ├── build.gradle ├── console-src/ │ ├── App.vue │ ├── components/ │ │ └── snapshots/ │ │ ├── BaseSnapshots.vue │ │ ├── SnapshotContent.vue │ │ ├── SnapshotDiffContent.vue │ │ ├── SnapshotListItem.vue │ │ └── query-keys.ts │ ├── composables/ │ │ ├── use-content-snapshot.ts │ │ ├── use-dashboard-stats.ts │ │ ├── use-entity-extension-points.ts │ │ ├── use-operation-extension-points.ts │ │ ├── use-save-keybinding.ts │ │ └── use-slugify.ts │ ├── layouts/ │ │ ├── BasicLayout.vue │ │ └── BlankLayout.vue │ ├── main.ts │ ├── modules/ │ │ ├── contents/ │ │ │ ├── attachments/ │ │ │ │ ├── AttachmentList.vue │ │ │ │ ├── components/ │ │ │ │ │ ├── AttachmentDetailModal.vue │ │ │ │ │ ├── AttachmentError.vue │ │ │ │ │ ├── AttachmentGroupBadge.vue │ │ │ │ │ ├── AttachmentGroupEditingModal.vue │ │ │ │ │ ├── AttachmentGroupList.vue │ │ │ │ │ ├── AttachmentListItem.vue │ │ │ │ │ ├── AttachmentLoading.vue │ │ │ │ │ ├── AttachmentPoliciesListItem.vue │ │ │ │ │ ├── AttachmentPoliciesModal.vue │ │ │ │ │ ├── AttachmentPolicyBadge.vue │ │ │ │ │ ├── AttachmentPolicyEditingModal.vue │ │ │ │ │ ├── AttachmentSelectorModal.vue │ │ │ │ │ ├── AttachmentUploadArea.vue │ │ │ │ │ ├── AttachmentUploadModal.vue │ │ │ │ │ ├── DisplayNameEditForm.vue │ │ │ │ │ ├── UploadFromUrl.vue │ │ │ │ │ └── selector-providers/ │ │ │ │ │ ├── CoreSelectorProvider.vue │ │ │ │ │ └── components/ │ │ │ │ │ ├── AttachmentSelectorListItem.vue │ │ │ │ │ ├── GroupFilter.vue │ │ │ │ │ └── PolicyFilter.vue │ │ │ │ ├── composables/ │ │ │ │ │ ├── use-attachment-group.ts │ │ │ │ │ ├── use-attachment-policy.ts │ │ │ │ │ └── use-attachment.ts │ │ │ │ └── module.ts │ │ │ ├── comments/ │ │ │ │ ├── CommentList.vue │ │ │ │ ├── components/ │ │ │ │ │ ├── CommentDetailModal.vue │ │ │ │ │ ├── CommentEditor.vue │ │ │ │ │ ├── CommentListItem.vue │ │ │ │ │ ├── DefaultCommentContent.vue │ │ │ │ │ ├── DefaultCommentEditor.vue │ │ │ │ │ ├── OwnerButton.vue │ │ │ │ │ ├── ReplyCreationModal.vue │ │ │ │ │ ├── ReplyDetailModal.vue │ │ │ │ │ ├── ReplyListItem.vue │ │ │ │ │ ├── SubjectQueryCommentList.vue │ │ │ │ │ └── SubjectQueryCommentListModal.vue │ │ │ │ ├── composables/ │ │ │ │ │ ├── use-comment-last-readtime-mutate.ts │ │ │ │ │ ├── use-comments-fetch.ts │ │ │ │ │ ├── use-content-provider-extension-point.ts │ │ │ │ │ └── use-subject-ref.ts │ │ │ │ └── module.ts │ │ │ ├── pages/ │ │ │ │ ├── DeletedSinglePageList.vue │ │ │ │ ├── SinglePageEditor.vue │ │ │ │ ├── SinglePageList.vue │ │ │ │ ├── SinglePageSnapshots.vue │ │ │ │ ├── components/ │ │ │ │ │ ├── SinglePageListItem.vue │ │ │ │ │ ├── SinglePageSettingModal.vue │ │ │ │ │ └── entity-fields/ │ │ │ │ │ ├── ContributorsField.vue │ │ │ │ │ ├── CoverField.vue │ │ │ │ │ ├── PublishStatusField.vue │ │ │ │ │ ├── PublishTimeField.vue │ │ │ │ │ ├── TitleField.vue │ │ │ │ │ └── VisibleField.vue │ │ │ │ ├── composables/ │ │ │ │ │ └── use-page-update-mutate.ts │ │ │ │ └── module.ts │ │ │ └── posts/ │ │ │ ├── DeletedPostList.vue │ │ │ ├── PostEditor.vue │ │ │ ├── PostList.vue │ │ │ ├── PostSnapshots.vue │ │ │ ├── categories/ │ │ │ │ ├── CategoryList.vue │ │ │ │ ├── components/ │ │ │ │ │ ├── CategoryEditingModal.vue │ │ │ │ │ ├── CategoryListItem.vue │ │ │ │ │ └── __tests__/ │ │ │ │ │ └── CategoryEditingModal.spec.ts │ │ │ │ ├── composables/ │ │ │ │ │ └── use-post-category.ts │ │ │ │ └── utils/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index.spec.ts │ │ │ │ └── index.ts │ │ │ ├── components/ │ │ │ │ ├── PostBatchSettingModal.vue │ │ │ │ ├── PostListItem.vue │ │ │ │ ├── PostSettingModal.vue │ │ │ │ ├── __tests__/ │ │ │ │ │ └── PostSettingModal.spec.ts │ │ │ │ └── entity-fields/ │ │ │ │ ├── ContributorsField.vue │ │ │ │ ├── CoverField.vue │ │ │ │ ├── PublishStatusField.vue │ │ │ │ ├── PublishTimeField.vue │ │ │ │ ├── TitleField.vue │ │ │ │ └── VisibleField.vue │ │ │ ├── composables/ │ │ │ │ └── use-post-update-mutate.ts │ │ │ ├── module.ts │ │ │ └── tags/ │ │ │ ├── TagList.vue │ │ │ ├── components/ │ │ │ │ ├── PostTag.vue │ │ │ │ ├── TagEditingModal.vue │ │ │ │ └── TagListItem.vue │ │ │ └── composables/ │ │ │ └── use-post-tag.ts │ │ ├── dashboard/ │ │ │ ├── Dashboard.vue │ │ │ ├── DashboardDesigner.vue │ │ │ ├── components/ │ │ │ │ ├── ActionButton.vue │ │ │ │ ├── WidgetCard.vue │ │ │ │ ├── WidgetConfigFormModal.vue │ │ │ │ ├── WidgetEditableItem.vue │ │ │ │ ├── WidgetHubModal.vue │ │ │ │ └── WidgetViewItem.vue │ │ │ ├── composables/ │ │ │ │ ├── use-dashboard-extension-point.ts │ │ │ │ └── use-dashboard-widgets-fetch.ts │ │ │ ├── module.ts │ │ │ ├── styles/ │ │ │ │ └── dashboard.css │ │ │ └── widgets/ │ │ │ ├── defaults.ts │ │ │ ├── index.ts │ │ │ └── presets/ │ │ │ ├── comments/ │ │ │ │ ├── CommentItem.vue │ │ │ │ ├── CommentStatsWidget.vue │ │ │ │ └── PendingCommentsWidget.vue │ │ │ ├── core/ │ │ │ │ ├── iframe/ │ │ │ │ │ └── IframeWidget.vue │ │ │ │ ├── quick-action/ │ │ │ │ │ ├── QuickActionItem.vue │ │ │ │ │ ├── QuickActionWidget.vue │ │ │ │ │ ├── ThemePreviewItem.vue │ │ │ │ │ └── composables/ │ │ │ │ │ └── use-dashboard-extension-point.ts │ │ │ │ ├── stack/ │ │ │ │ │ ├── StackWidget.vue │ │ │ │ │ ├── StackWidgetConfigModal.vue │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── IndexIndicator.vue │ │ │ │ │ │ ├── WidgetEditableItem.vue │ │ │ │ │ │ └── WidgetViewItem.vue │ │ │ │ │ └── types.ts │ │ │ │ ├── upvotes-stats/ │ │ │ │ │ └── UpvotesStatsWidget.vue │ │ │ │ └── view-stats/ │ │ │ │ └── ViewsStatsWidget.vue │ │ │ ├── posts/ │ │ │ │ ├── PostStatsWidget.vue │ │ │ │ ├── RecentPublishedWidget.vue │ │ │ │ └── components/ │ │ │ │ └── PostListItem.vue │ │ │ ├── single-pages/ │ │ │ │ └── SinglePageStatsWidget.vue │ │ │ └── users/ │ │ │ ├── NotificationWidget.vue │ │ │ └── UserStatsWidget.vue │ │ ├── index.ts │ │ ├── interface/ │ │ │ ├── menus/ │ │ │ │ ├── Menus.vue │ │ │ │ ├── components/ │ │ │ │ │ ├── MenuEditingModal.vue │ │ │ │ │ ├── MenuItemEditingModal.vue │ │ │ │ │ └── MenuList.vue │ │ │ │ ├── module.ts │ │ │ │ └── utils/ │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── index.spec.ts.snap │ │ │ │ │ └── index.spec.ts │ │ │ │ └── index.ts │ │ │ └── themes/ │ │ │ ├── ThemeDetail.vue │ │ │ ├── ThemeSetting.vue │ │ │ ├── components/ │ │ │ │ ├── ThemeListItem.vue │ │ │ │ ├── ThemeListModal.vue │ │ │ │ ├── list-tabs/ │ │ │ │ │ ├── InstalledThemes.vue │ │ │ │ │ ├── LocalUpload.vue │ │ │ │ │ ├── NotInstalledThemes.vue │ │ │ │ │ └── RemoteDownload.vue │ │ │ │ ├── operation/ │ │ │ │ │ ├── MoreOperationItem.vue │ │ │ │ │ └── UninstallOperationItem.vue │ │ │ │ └── preview/ │ │ │ │ ├── ThemePreviewListItem.vue │ │ │ │ └── ThemePreviewModal.vue │ │ │ ├── composables/ │ │ │ │ └── use-theme.ts │ │ │ ├── constants/ │ │ │ │ └── index.ts │ │ │ ├── layouts/ │ │ │ │ └── ThemeLayout.vue │ │ │ ├── module.ts │ │ │ └── types/ │ │ │ └── index.ts │ │ └── system/ │ │ ├── auth-providers/ │ │ │ ├── AuthProviderDetail.vue │ │ │ ├── AuthProviders.vue │ │ │ ├── components/ │ │ │ │ ├── AuthProviderListItem.vue │ │ │ │ └── AuthProvidersSection.vue │ │ │ └── module.ts │ │ ├── backup/ │ │ │ ├── Backups.vue │ │ │ ├── components/ │ │ │ │ └── BackupListItem.vue │ │ │ ├── composables/ │ │ │ │ └── use-backup.ts │ │ │ ├── module.ts │ │ │ └── tabs/ │ │ │ ├── List.vue │ │ │ └── Restore.vue │ │ ├── overview/ │ │ │ ├── Overview.vue │ │ │ ├── components/ │ │ │ │ ├── ExternalUrlForm.vue │ │ │ │ └── ExternalUrlItem.vue │ │ │ └── module.ts │ │ ├── plugins/ │ │ │ ├── PluginDetail.vue │ │ │ ├── PluginExtensionPointSettings.vue │ │ │ ├── PluginList.vue │ │ │ ├── components/ │ │ │ │ ├── PluginConditionsModal.vue │ │ │ │ ├── PluginDetailModal.vue │ │ │ │ ├── PluginInstallationModal.vue │ │ │ │ ├── PluginListItem.vue │ │ │ │ ├── entity-fields/ │ │ │ │ │ ├── AuthorField.vue │ │ │ │ │ ├── LogoField.vue │ │ │ │ │ ├── ReloadField.vue │ │ │ │ │ ├── SwitchField.vue │ │ │ │ │ └── TitleField.vue │ │ │ │ ├── extension-points/ │ │ │ │ │ ├── ExtensionDefinitionListItem.vue │ │ │ │ │ ├── ExtensionDefinitionMultiInstanceView.vue │ │ │ │ │ └── ExtensionDefinitionSingletonView.vue │ │ │ │ ├── installation-tabs/ │ │ │ │ │ ├── LocalUpload.vue │ │ │ │ │ └── RemoteDownload.vue │ │ │ │ └── tabs/ │ │ │ │ ├── Detail.vue │ │ │ │ └── Setting.vue │ │ │ ├── composables/ │ │ │ │ ├── use-extension-definition-fetch.ts │ │ │ │ └── use-plugin.ts │ │ │ ├── constants/ │ │ │ │ └── index.ts │ │ │ ├── module.ts │ │ │ └── types/ │ │ │ └── index.ts │ │ ├── roles/ │ │ │ ├── RoleDetail.vue │ │ │ ├── RoleList.vue │ │ │ ├── components/ │ │ │ │ └── RoleEditingModal.vue │ │ │ └── module.ts │ │ ├── settings/ │ │ │ ├── SystemSettings.vue │ │ │ ├── module.ts │ │ │ └── tabs/ │ │ │ ├── NotificationSetting.vue │ │ │ ├── Notifications.vue │ │ │ └── Setting.vue │ │ ├── tools/ │ │ │ ├── Tools.vue │ │ │ └── module.ts │ │ └── users/ │ │ ├── UserDetail.vue │ │ ├── UserList.vue │ │ ├── components/ │ │ │ ├── GrantPermissionModal.vue │ │ │ ├── RolesView.vue │ │ │ ├── UserCreationModal.vue │ │ │ ├── UserEditingModal.vue │ │ │ ├── UserListItem.vue │ │ │ └── UserPasswordChangeModal.vue │ │ ├── composables/ │ │ │ ├── use-role.ts │ │ │ └── use-user.ts │ │ ├── module.ts │ │ └── tabs/ │ │ └── Detail.vue │ ├── router/ │ │ ├── constant.ts │ │ ├── guards/ │ │ │ ├── auth-check.ts │ │ │ └── permission.ts │ │ ├── index.ts │ │ └── routes.config.ts │ └── stores/ │ └── theme.ts ├── console.html ├── docs/ │ ├── components/ │ │ └── README.md │ ├── custom-formkit-input/ │ │ └── README.md │ ├── extension-points/ │ │ ├── backup.md │ │ ├── comment-content.md │ │ ├── comment-editor.md │ │ ├── comment-subject-ref.md │ │ ├── dashboard.md │ │ ├── default-editor–extension.md │ │ ├── editor.md │ │ ├── entity-listitem-field.md │ │ ├── entity-listitem-operation.md │ │ ├── plugin-installation-tabs.md │ │ ├── plugin-self-tabs.md │ │ └── theme-list-tabs.md │ ├── project-structure/ │ │ └── README.md │ └── routes-generation/ │ └── README.md ├── env.d.ts ├── eslint.config.ts ├── package.json ├── packages/ │ ├── api-client/ │ │ ├── .openapi_config.yaml │ │ ├── README.md │ │ ├── entry/ │ │ │ ├── api-client.ts │ │ │ ├── index.ts │ │ │ └── utils/ │ │ │ ├── index.ts │ │ │ └── paginate.ts │ │ ├── openapitools.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── .gitignore │ │ │ ├── .npmignore │ │ │ ├── .openapi-generator/ │ │ │ │ ├── FILES │ │ │ │ └── VERSION │ │ │ ├── .openapi-generator-ignore │ │ │ ├── api/ │ │ │ │ ├── annotation-setting-v1-alpha-uc-api.ts │ │ │ │ ├── annotation-setting-v1alpha1-api.ts │ │ │ │ ├── attachment-v1alpha1-api.ts │ │ │ │ ├── attachment-v1alpha1-console-api.ts │ │ │ │ ├── attachment-v1alpha1-uc-api.ts │ │ │ │ ├── auth-provider-v1alpha1-api.ts │ │ │ │ ├── auth-provider-v1alpha1-console-api.ts │ │ │ │ ├── backup-v1alpha1-api.ts │ │ │ │ ├── category-v1alpha1-api.ts │ │ │ │ ├── category-v1alpha1-public-api.ts │ │ │ │ ├── comment-v1alpha1-api.ts │ │ │ │ ├── comment-v1alpha1-console-api.ts │ │ │ │ ├── comment-v1alpha1-public-api.ts │ │ │ │ ├── config-map-v1alpha1-api.ts │ │ │ │ ├── counter-v1alpha1-api.ts │ │ │ │ ├── device-v1alpha1-api.ts │ │ │ │ ├── device-v1alpha1-uc-api.ts │ │ │ │ ├── extension-definition-v1alpha1-api.ts │ │ │ │ ├── extension-point-definition-v1alpha1-api.ts │ │ │ │ ├── group-v1alpha1-api.ts │ │ │ │ ├── index-v1alpha1-public-api.ts │ │ │ │ ├── indices-v1alpha1-console-api.ts │ │ │ │ ├── local-thumbnail-v1alpha1-api.ts │ │ │ │ ├── menu-item-v1alpha1-api.ts │ │ │ │ ├── menu-v1alpha1-api.ts │ │ │ │ ├── menu-v1alpha1-public-api.ts │ │ │ │ ├── metrics-v1alpha1-public-api.ts │ │ │ │ ├── migration-v1alpha1-console-api.ts │ │ │ │ ├── notification-template-v1alpha1-api.ts │ │ │ │ ├── notification-v1alpha1-api.ts │ │ │ │ ├── notification-v1alpha1-public-api.ts │ │ │ │ ├── notification-v1alpha1-uc-api.ts │ │ │ │ ├── notifier-descriptor-v1alpha1-api.ts │ │ │ │ ├── notifier-v1alpha1-console-api.ts │ │ │ │ ├── notifier-v1alpha1-uc-api.ts │ │ │ │ ├── personal-access-token-v1alpha1-api.ts │ │ │ │ ├── personal-access-token-v1alpha1-uc-api.ts │ │ │ │ ├── plugin-v1alpha1-api.ts │ │ │ │ ├── plugin-v1alpha1-console-api.ts │ │ │ │ ├── plugin-v1alpha1-public-api.ts │ │ │ │ ├── policy-alpha1-console-api.ts │ │ │ │ ├── policy-template-v1alpha1-api.ts │ │ │ │ ├── policy-v1alpha1-api.ts │ │ │ │ ├── post-v1alpha1-api.ts │ │ │ │ ├── post-v1alpha1-console-api.ts │ │ │ │ ├── post-v1alpha1-public-api.ts │ │ │ │ ├── post-v1alpha1-uc-api.ts │ │ │ │ ├── reason-type-v1alpha1-api.ts │ │ │ │ ├── reason-v1alpha1-api.ts │ │ │ │ ├── remember-me-token-v1alpha1-api.ts │ │ │ │ ├── reply-v1alpha1-api.ts │ │ │ │ ├── reply-v1alpha1-console-api.ts │ │ │ │ ├── reverse-proxy-v1alpha1-api.ts │ │ │ │ ├── role-binding-v1alpha1-api.ts │ │ │ │ ├── role-v1alpha1-api.ts │ │ │ │ ├── secret-v1alpha1-api.ts │ │ │ │ ├── setting-v1alpha1-api.ts │ │ │ │ ├── single-page-v1alpha1-api.ts │ │ │ │ ├── single-page-v1alpha1-console-api.ts │ │ │ │ ├── single-page-v1alpha1-public-api.ts │ │ │ │ ├── snapshot-v1alpha1-api.ts │ │ │ │ ├── snapshot-v1alpha1-uc-api.ts │ │ │ │ ├── subscription-v1alpha1-api.ts │ │ │ │ ├── system-config-v1alpha1-console-api.ts │ │ │ │ ├── system-v1alpha1-console-api.ts │ │ │ │ ├── system-v1alpha1-public-api.ts │ │ │ │ ├── tag-v1alpha1-api.ts │ │ │ │ ├── tag-v1alpha1-console-api.ts │ │ │ │ ├── tag-v1alpha1-public-api.ts │ │ │ │ ├── theme-v1alpha1-api.ts │ │ │ │ ├── theme-v1alpha1-console-api.ts │ │ │ │ ├── thumbnail-v1alpha1-api.ts │ │ │ │ ├── thumbnail-v1alpha1-public-api.ts │ │ │ │ ├── two-factor-auth-v1alpha1-uc-api.ts │ │ │ │ ├── user-connection-v1alpha1-api.ts │ │ │ │ ├── user-connection-v1alpha1-uc-api.ts │ │ │ │ ├── user-preference-v1alpha1-uc-api.ts │ │ │ │ ├── user-v1alpha1-api.ts │ │ │ │ └── user-v1alpha1-console-api.ts │ │ │ ├── api.ts │ │ │ ├── base.ts │ │ │ ├── common.ts │ │ │ ├── configuration.ts │ │ │ ├── git_push.sh │ │ │ ├── index.ts │ │ │ └── models/ │ │ │ ├── add-operation.ts │ │ │ ├── annotation-setting-list.ts │ │ │ ├── annotation-setting-spec.ts │ │ │ ├── annotation-setting.ts │ │ │ ├── attachment-list.ts │ │ │ ├── attachment-spec.ts │ │ │ ├── attachment-status.ts │ │ │ ├── attachment.ts │ │ │ ├── auth-provider-list.ts │ │ │ ├── auth-provider-spec.ts │ │ │ ├── auth-provider.ts │ │ │ ├── author.ts │ │ │ ├── backup-file.ts │ │ │ ├── backup-list.ts │ │ │ ├── backup-spec.ts │ │ │ ├── backup-status.ts │ │ │ ├── backup.ts │ │ │ ├── category-list.ts │ │ │ ├── category-spec.ts │ │ │ ├── category-status.ts │ │ │ ├── category-vo-list.ts │ │ │ ├── category-vo.ts │ │ │ ├── category.ts │ │ │ ├── change-own-password-request.ts │ │ │ ├── change-password-request.ts │ │ │ ├── comment-email-owner.ts │ │ │ ├── comment-list.ts │ │ │ ├── comment-owner.ts │ │ │ ├── comment-request.ts │ │ │ ├── comment-spec.ts │ │ │ ├── comment-stats-vo.ts │ │ │ ├── comment-stats.ts │ │ │ ├── comment-status.ts │ │ │ ├── comment-vo-list.ts │ │ │ ├── comment-vo.ts │ │ │ ├── comment-with-reply-vo-list.ts │ │ │ ├── comment-with-reply-vo.ts │ │ │ ├── comment.ts │ │ │ ├── condition.ts │ │ │ ├── config-map-list.ts │ │ │ ├── config-map-ref.ts │ │ │ ├── config-map.ts │ │ │ ├── content-update-param.ts │ │ │ ├── content-vo.ts │ │ │ ├── content-wrapper.ts │ │ │ ├── content.ts │ │ │ ├── contributor-vo.ts │ │ │ ├── contributor.ts │ │ │ ├── copy-operation.ts │ │ │ ├── counter-list.ts │ │ │ ├── counter-request.ts │ │ │ ├── counter.ts │ │ │ ├── create-user-request.ts │ │ │ ├── custom-templates.ts │ │ │ ├── dashboard-stats.ts │ │ │ ├── detailed-user.ts │ │ │ ├── device-list.ts │ │ │ ├── device-spec.ts │ │ │ ├── device-status.ts │ │ │ ├── device.ts │ │ │ ├── email-config-validation-request.ts │ │ │ ├── email-verify-request.ts │ │ │ ├── excerpt.ts │ │ │ ├── extension-definition-list.ts │ │ │ ├── extension-definition.ts │ │ │ ├── extension-point-definition-list.ts │ │ │ ├── extension-point-definition.ts │ │ │ ├── extension-point-spec.ts │ │ │ ├── extension-spec.ts │ │ │ ├── extension.ts │ │ │ ├── file-reverse-proxy-provider.ts │ │ │ ├── grant-request.ts │ │ │ ├── group-kind.ts │ │ │ ├── group-list.ts │ │ │ ├── group-spec.ts │ │ │ ├── group-status.ts │ │ │ ├── group.ts │ │ │ ├── halo-document.ts │ │ │ ├── index.ts │ │ │ ├── install-from-uri-request.ts │ │ │ ├── interest-reason-subject.ts │ │ │ ├── interest-reason.ts │ │ │ ├── json-patch-inner.ts │ │ │ ├── license.ts │ │ │ ├── list-result-reply-vo.ts │ │ │ ├── listed-auth-provider.ts │ │ │ ├── listed-comment-list.ts │ │ │ ├── listed-comment.ts │ │ │ ├── listed-post-list.ts │ │ │ ├── listed-post-vo-list.ts │ │ │ ├── listed-post-vo.ts │ │ │ ├── listed-post.ts │ │ │ ├── listed-reply-list.ts │ │ │ ├── listed-reply.ts │ │ │ ├── listed-single-page-list.ts │ │ │ ├── listed-single-page-vo-list.ts │ │ │ ├── listed-single-page-vo.ts │ │ │ ├── listed-single-page.ts │ │ │ ├── listed-snapshot-dto.ts │ │ │ ├── listed-snapshot-spec.ts │ │ │ ├── listed-user.ts │ │ │ ├── local-thumbnail-list.ts │ │ │ ├── local-thumbnail-spec.ts │ │ │ ├── local-thumbnail-status.ts │ │ │ ├── local-thumbnail.ts │ │ │ ├── mark-specified-request.ts │ │ │ ├── menu-item-list.ts │ │ │ ├── menu-item-spec.ts │ │ │ ├── menu-item-status.ts │ │ │ ├── menu-item-vo.ts │ │ │ ├── menu-item.ts │ │ │ ├── menu-list.ts │ │ │ ├── menu-spec.ts │ │ │ ├── menu-vo.ts │ │ │ ├── menu.ts │ │ │ ├── metadata.ts │ │ │ ├── move-operation.ts │ │ │ ├── navigation-post-vo.ts │ │ │ ├── notification-list.ts │ │ │ ├── notification-spec.ts │ │ │ ├── notification-template-list.ts │ │ │ ├── notification-template-spec.ts │ │ │ ├── notification-template.ts │ │ │ ├── notification.ts │ │ │ ├── notifier-descriptor-list.ts │ │ │ ├── notifier-descriptor-spec.ts │ │ │ ├── notifier-descriptor.ts │ │ │ ├── notifier-info.ts │ │ │ ├── notifier-setting-ref.ts │ │ │ ├── owner-info.ts │ │ │ ├── password-request.ts │ │ │ ├── pat-spec.ts │ │ │ ├── personal-access-token-list.ts │ │ │ ├── personal-access-token.ts │ │ │ ├── plugin-author.ts │ │ │ ├── plugin-list.ts │ │ │ ├── plugin-running-state-request.ts │ │ │ ├── plugin-spec.ts │ │ │ ├── plugin-status.ts │ │ │ ├── plugin.ts │ │ │ ├── policy-list.ts │ │ │ ├── policy-rule.ts │ │ │ ├── policy-spec.ts │ │ │ ├── policy-template-list.ts │ │ │ ├── policy-template-spec.ts │ │ │ ├── policy-template.ts │ │ │ ├── policy.ts │ │ │ ├── post-list.ts │ │ │ ├── post-request.ts │ │ │ ├── post-spec.ts │ │ │ ├── post-status.ts │ │ │ ├── post-vo.ts │ │ │ ├── post.ts │ │ │ ├── reason-attributes.ts │ │ │ ├── reason-list.ts │ │ │ ├── reason-property.ts │ │ │ ├── reason-selector.ts │ │ │ ├── reason-spec.ts │ │ │ ├── reason-subject.ts │ │ │ ├── reason-type-info.ts │ │ │ ├── reason-type-list.ts │ │ │ ├── reason-type-notifier-collection-request.ts │ │ │ ├── reason-type-notifier-matrix.ts │ │ │ ├── reason-type-notifier-request.ts │ │ │ ├── reason-type-spec.ts │ │ │ ├── reason-type.ts │ │ │ ├── reason.ts │ │ │ ├── ref.ts │ │ │ ├── remember-me-token-list.ts │ │ │ ├── remember-me-token-spec.ts │ │ │ ├── remember-me-token.ts │ │ │ ├── remove-operation.ts │ │ │ ├── replace-operation.ts │ │ │ ├── reply-list.ts │ │ │ ├── reply-request.ts │ │ │ ├── reply-spec.ts │ │ │ ├── reply-status.ts │ │ │ ├── reply-vo-list.ts │ │ │ ├── reply-vo.ts │ │ │ ├── reply.ts │ │ │ ├── reverse-proxy-list.ts │ │ │ ├── reverse-proxy-rule.ts │ │ │ ├── reverse-proxy.ts │ │ │ ├── revert-snapshot-for-post-param.ts │ │ │ ├── revert-snapshot-for-single-param.ts │ │ │ ├── role-binding-list.ts │ │ │ ├── role-binding.ts │ │ │ ├── role-list.ts │ │ │ ├── role-ref.ts │ │ │ ├── role.ts │ │ │ ├── search-option.ts │ │ │ ├── search-result.ts │ │ │ ├── secret-list.ts │ │ │ ├── secret.ts │ │ │ ├── setting-form.ts │ │ │ ├── setting-list.ts │ │ │ ├── setting-ref.ts │ │ │ ├── setting-spec.ts │ │ │ ├── setting.ts │ │ │ ├── setup-request.ts │ │ │ ├── single-page-list.ts │ │ │ ├── single-page-request.ts │ │ │ ├── single-page-spec.ts │ │ │ ├── single-page-status.ts │ │ │ ├── single-page-vo.ts │ │ │ ├── single-page.ts │ │ │ ├── site-stats-vo.ts │ │ │ ├── snap-shot-spec.ts │ │ │ ├── snapshot-list.ts │ │ │ ├── snapshot.ts │ │ │ ├── stats-vo.ts │ │ │ ├── stats.ts │ │ │ ├── subject.ts │ │ │ ├── subscription-list.ts │ │ │ ├── subscription-spec.ts │ │ │ ├── subscription-subscriber.ts │ │ │ ├── subscription.ts │ │ │ ├── tag-list.ts │ │ │ ├── tag-spec.ts │ │ │ ├── tag-status.ts │ │ │ ├── tag-vo-list.ts │ │ │ ├── tag-vo.ts │ │ │ ├── tag.ts │ │ │ ├── template-content.ts │ │ │ ├── template-descriptor.ts │ │ │ ├── test-operation.ts │ │ │ ├── theme-list.ts │ │ │ ├── theme-spec.ts │ │ │ ├── theme-status.ts │ │ │ ├── theme.ts │ │ │ ├── thumbnail-list.ts │ │ │ ├── thumbnail-spec.ts │ │ │ ├── thumbnail.ts │ │ │ ├── totp-auth-link-response.ts │ │ │ ├── totp-request.ts │ │ │ ├── two-factor-auth-settings.ts │ │ │ ├── uc-upload-from-url-request.ts │ │ │ ├── upgrade-from-uri-request.ts │ │ │ ├── upload-from-url-request.ts │ │ │ ├── user-connection-list.ts │ │ │ ├── user-connection-spec.ts │ │ │ ├── user-connection.ts │ │ │ ├── user-device.ts │ │ │ ├── user-endpoint-listed-user-list.ts │ │ │ ├── user-list.ts │ │ │ ├── user-permission.ts │ │ │ ├── user-spec.ts │ │ │ ├── user-status.ts │ │ │ ├── user.ts │ │ │ ├── verify-code-request.ts │ │ │ └── vote-request.ts │ │ ├── tsconfig.json │ │ └── tsdown.config.ts │ ├── components/ │ │ ├── .storybook/ │ │ │ ├── main.ts │ │ │ └── preview.ts │ │ ├── env.d.ts │ │ ├── package.json │ │ ├── postcss.config.cjs │ │ ├── src/ │ │ │ ├── components/ │ │ │ │ ├── alert/ │ │ │ │ │ ├── Alert.stories.ts │ │ │ │ │ ├── Alert.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ └── Alert.spec.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── avatar/ │ │ │ │ │ ├── Avatar.stories.ts │ │ │ │ │ ├── Avatar.vue │ │ │ │ │ ├── AvatarGroup.stories.ts │ │ │ │ │ ├── AvatarGroup.vue │ │ │ │ │ ├── index.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── button/ │ │ │ │ │ ├── Button.stories.ts │ │ │ │ │ ├── Button.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ ├── Button.spec.ts │ │ │ │ │ │ └── __snapshots__/ │ │ │ │ │ │ └── Button.spec.ts.snap │ │ │ │ │ ├── index.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── card/ │ │ │ │ │ ├── Card.stories.ts │ │ │ │ │ ├── Card.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ └── Card.spec.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── description/ │ │ │ │ │ ├── Description.vue │ │ │ │ │ ├── DescriptionItem.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── dialog/ │ │ │ │ │ ├── Dialog.stories.ts │ │ │ │ │ ├── Dialog.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ └── Dialog.spec.ts │ │ │ │ │ ├── dialog-manager.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── dropdown/ │ │ │ │ │ ├── Draopdown.stories.ts │ │ │ │ │ ├── DropdownDivider.vue │ │ │ │ │ ├── DropdownItem.vue │ │ │ │ │ ├── index.ts │ │ │ │ │ └── style.scss │ │ │ │ ├── empty/ │ │ │ │ │ ├── Empty.stories.ts │ │ │ │ │ ├── Empty.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ ├── Empty.spec.ts │ │ │ │ │ │ └── __snapshots__/ │ │ │ │ │ │ └── Empty.spec.ts.snap │ │ │ │ │ └── index.ts │ │ │ │ ├── entity/ │ │ │ │ │ ├── Entity.vue │ │ │ │ │ ├── EntityContainer.vue │ │ │ │ │ ├── EntityField.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ ├── Entity.spec.ts │ │ │ │ │ │ └── EntityField.spec.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── header/ │ │ │ │ │ ├── PageHeader.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── loading/ │ │ │ │ │ ├── Loading.stories.ts │ │ │ │ │ ├── Loading.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── menu/ │ │ │ │ │ ├── Menu.stories.ts │ │ │ │ │ ├── Menu.vue │ │ │ │ │ ├── MenuItem.vue │ │ │ │ │ ├── MenuLabel.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ ├── Menu.spec.tsx │ │ │ │ │ │ ├── MenuLabel.spec.ts │ │ │ │ │ │ └── __snapshots__/ │ │ │ │ │ │ ├── Menu.spec.tsx.snap │ │ │ │ │ │ └── MenuLabel.spec.ts.snap │ │ │ │ │ └── index.ts │ │ │ │ ├── modal/ │ │ │ │ │ ├── Modal.stories.ts │ │ │ │ │ ├── Modal.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ └── Modal.spec.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── pagination/ │ │ │ │ │ ├── Pagination.stories.ts │ │ │ │ │ ├── Pagination.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ └── Pagination.spec.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── space/ │ │ │ │ │ ├── Space.stories.ts │ │ │ │ │ ├── Space.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ └── Space.spec.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── status/ │ │ │ │ │ ├── StatusDot.stories.ts │ │ │ │ │ ├── StatusDot.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ ├── StatusDot.spec.ts │ │ │ │ │ │ └── __snapshots__/ │ │ │ │ │ │ └── StatusDot.spec.ts.snap │ │ │ │ │ ├── index.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── switch/ │ │ │ │ │ ├── Switch.stories.ts │ │ │ │ │ ├── Switch.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ └── Switch.spec.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── tabs/ │ │ │ │ │ ├── TabItem.vue │ │ │ │ │ ├── Tabbar.stories.ts │ │ │ │ │ ├── Tabbar.vue │ │ │ │ │ ├── Tabs.stories.ts │ │ │ │ │ ├── Tabs.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ ├── TabItem.spec.ts │ │ │ │ │ │ ├── Tabbar.spec.ts │ │ │ │ │ │ └── Tabs.spec.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── tag/ │ │ │ │ │ ├── Tag.stories.ts │ │ │ │ │ ├── Tag.story.vue │ │ │ │ │ ├── Tag.vue │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ └── Tag.spec.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── toast/ │ │ │ │ │ ├── Toast.story.vue │ │ │ │ │ ├── Toast.vue │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── toast-manager.ts │ │ │ │ │ └── types.ts │ │ │ │ └── tooltip/ │ │ │ │ ├── index.ts │ │ │ │ └── style.css │ │ │ ├── components.ts │ │ │ ├── icons/ │ │ │ │ └── icons.ts │ │ │ ├── index.ts │ │ │ ├── stories/ │ │ │ │ └── Introduction.mdx │ │ │ └── styles/ │ │ │ └── tailwind.css │ │ ├── tailwind.config.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ ├── tsconfig.vitest.json │ │ └── vite.config.ts │ ├── console-shared/ │ │ ├── README.md │ │ ├── index.js │ │ └── package.json │ ├── editor/ │ │ ├── README.md │ │ ├── docs/ │ │ │ └── extension.md │ │ ├── env.d.ts │ │ ├── package.json │ │ ├── postcss.config.cjs │ │ ├── src/ │ │ │ ├── components/ │ │ │ │ ├── Editor.vue │ │ │ │ ├── EditorHeader.vue │ │ │ │ ├── base/ │ │ │ │ │ ├── DropdownItem.vue │ │ │ │ │ ├── Input.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── block/ │ │ │ │ │ ├── BlockActionButton.vue │ │ │ │ │ ├── BlockActionHorizontalSeparator.vue │ │ │ │ │ ├── BlockActionSeparator.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── bubble/ │ │ │ │ │ ├── BubbleButton.vue │ │ │ │ │ ├── BubbleItem.vue │ │ │ │ │ ├── EditorBubbleMenu.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── common/ │ │ │ │ │ └── ColorPickerDropdown.vue │ │ │ │ ├── drag/ │ │ │ │ │ ├── EditorDragButtonItem.vue │ │ │ │ │ ├── EditorDragHandle.vue │ │ │ │ │ ├── EditorDragMenu.vue │ │ │ │ │ ├── default-drag.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── icon/ │ │ │ │ │ └── MingcuteDelete2Line.vue │ │ │ │ ├── index.ts │ │ │ │ ├── toolbar/ │ │ │ │ │ ├── ToolbarItem.vue │ │ │ │ │ ├── ToolbarSubItem.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── toolbox/ │ │ │ │ │ ├── ToolboxItem.vue │ │ │ │ │ └── index.ts │ │ │ │ └── upload/ │ │ │ │ ├── EditorLinkObtain.vue │ │ │ │ ├── ResourceReplaceButton.vue │ │ │ │ └── index.ts │ │ │ ├── composables/ │ │ │ │ └── use-attachment.ts │ │ │ ├── extensions/ │ │ │ │ ├── align/ │ │ │ │ │ └── index.ts │ │ │ │ ├── audio/ │ │ │ │ │ ├── AudioView.vue │ │ │ │ │ ├── BubbleItemAudioLink.vue │ │ │ │ │ ├── BubbleItemAudioPosition.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── block-position/ │ │ │ │ │ └── index.ts │ │ │ │ ├── blockquote/ │ │ │ │ │ └── index.ts │ │ │ │ ├── bold/ │ │ │ │ │ └── index.ts │ │ │ │ ├── bullet-list/ │ │ │ │ │ └── index.ts │ │ │ │ ├── character-count/ │ │ │ │ │ └── index.ts │ │ │ │ ├── clear-format/ │ │ │ │ │ └── index.ts │ │ │ │ ├── code/ │ │ │ │ │ └── index.ts │ │ │ │ ├── code-block/ │ │ │ │ │ ├── CodeBlockSelect.vue │ │ │ │ │ ├── CodeBlockViewRenderer.vue │ │ │ │ │ ├── code-block.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── color/ │ │ │ │ │ ├── ColorBubbleItem.vue │ │ │ │ │ ├── ColorToolbarItem.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── columns/ │ │ │ │ │ ├── column.ts │ │ │ │ │ ├── columns.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── commands-menu/ │ │ │ │ │ ├── CommandsView.vue │ │ │ │ │ ├── commands.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── details/ │ │ │ │ │ └── index.ts │ │ │ │ ├── document/ │ │ │ │ │ └── index.ts │ │ │ │ ├── drop-cursor/ │ │ │ │ │ └── index.ts │ │ │ │ ├── extensions-kit.ts │ │ │ │ ├── figure/ │ │ │ │ │ ├── FigureCaptionView.vue │ │ │ │ │ ├── figure-caption.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── font-size/ │ │ │ │ │ └── index.ts │ │ │ │ ├── format-brush/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── util.ts │ │ │ │ ├── gallery/ │ │ │ │ │ ├── BubbleItemAddImage.vue │ │ │ │ │ ├── BubbleItemGap.vue │ │ │ │ │ ├── BubbleItemGroupSize.vue │ │ │ │ │ ├── BubbleItemLayout.vue │ │ │ │ │ ├── GalleryView.vue │ │ │ │ │ ├── gallery-bubble.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── useGalleryImages.ts │ │ │ │ ├── gap-cursor/ │ │ │ │ │ ├── gap-cursor-selection.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── hard-break/ │ │ │ │ │ └── index.ts │ │ │ │ ├── heading/ │ │ │ │ │ └── index.ts │ │ │ │ ├── highlight/ │ │ │ │ │ ├── HighlightBubbleItem.vue │ │ │ │ │ ├── HighlightToolbarItem.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── history/ │ │ │ │ │ └── index.ts │ │ │ │ ├── horizontal-rule/ │ │ │ │ │ └── index.ts │ │ │ │ ├── iframe/ │ │ │ │ │ ├── BubbleItemIframeAlign.vue │ │ │ │ │ ├── BubbleItemIframeLink.vue │ │ │ │ │ ├── BubbleItemIframeSize.vue │ │ │ │ │ ├── IframeView.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── image/ │ │ │ │ │ ├── BubbleItemImageAlt.vue │ │ │ │ │ ├── BubbleItemImageHref.vue │ │ │ │ │ ├── BubbleItemImageLink.vue │ │ │ │ │ ├── BubbleItemImagePosition.vue │ │ │ │ │ ├── BubbleItemImageSize.vue │ │ │ │ │ ├── ImageView.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── indent/ │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── italic/ │ │ │ │ │ └── index.ts │ │ │ │ ├── link/ │ │ │ │ │ ├── LinkBubbleButton.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── list-extra/ │ │ │ │ │ └── index.ts │ │ │ │ ├── list-keymap/ │ │ │ │ │ └── index.ts │ │ │ │ ├── node-selected/ │ │ │ │ │ └── index.ts │ │ │ │ ├── ordered-list/ │ │ │ │ │ └── index.ts │ │ │ │ ├── paragraph/ │ │ │ │ │ └── index.ts │ │ │ │ ├── placeholder/ │ │ │ │ │ └── index.ts │ │ │ │ ├── range-selection/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── range-selection.ts │ │ │ │ ├── search-and-replace/ │ │ │ │ │ ├── IconButton.vue │ │ │ │ │ ├── MatchToggleButton.vue │ │ │ │ │ ├── SearchAndReplace.vue │ │ │ │ │ ├── SearchAndReplacePlugin.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── smart-scroll/ │ │ │ │ │ └── index.ts │ │ │ │ ├── strike/ │ │ │ │ │ └── index.ts │ │ │ │ ├── subscript/ │ │ │ │ │ └── index.ts │ │ │ │ ├── superscript/ │ │ │ │ │ └── index.ts │ │ │ │ ├── table/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── table-cell.ts │ │ │ │ │ ├── table-header.ts │ │ │ │ │ ├── table-row.ts │ │ │ │ │ └── util.ts │ │ │ │ ├── task-list/ │ │ │ │ │ └── index.ts │ │ │ │ ├── text/ │ │ │ │ │ ├── BubbleItemTextType.vue │ │ │ │ │ └── index.ts │ │ │ │ ├── text-align/ │ │ │ │ │ └── index.ts │ │ │ │ ├── text-style/ │ │ │ │ │ └── index.ts │ │ │ │ ├── trailing-node/ │ │ │ │ │ └── index.ts │ │ │ │ ├── underline/ │ │ │ │ │ └── index.ts │ │ │ │ ├── upload/ │ │ │ │ │ └── index.ts │ │ │ │ └── video/ │ │ │ │ ├── BubbleItemVideoLink.vue │ │ │ │ ├── BubbleItemVideoPosition.vue │ │ │ │ ├── BubbleItemVideoSize.vue │ │ │ │ ├── VideoView.vue │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── locales/ │ │ │ │ ├── en.json │ │ │ │ ├── es.json │ │ │ │ ├── index.ts │ │ │ │ └── zh-CN.json │ │ │ ├── styles/ │ │ │ │ ├── base.scss │ │ │ │ ├── columns.scss │ │ │ │ ├── details.scss │ │ │ │ ├── draggable.scss │ │ │ │ ├── figure.scss │ │ │ │ ├── format-brush.scss │ │ │ │ ├── gap-cursor.scss │ │ │ │ ├── index.scss │ │ │ │ ├── node-select.scss │ │ │ │ ├── range-selection.scss │ │ │ │ ├── resizer.scss │ │ │ │ ├── search.scss │ │ │ │ ├── table.scss │ │ │ │ └── tailwind.css │ │ │ ├── tiptap/ │ │ │ │ ├── core/ │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── pm/ │ │ │ │ │ └── index.ts │ │ │ │ └── vue-3/ │ │ │ │ └── index.ts │ │ │ ├── types/ │ │ │ │ └── index.ts │ │ │ └── utils/ │ │ │ ├── anchor.ts │ │ │ ├── attachment.ts │ │ │ ├── clipboard.ts │ │ │ ├── delete-node.ts │ │ │ ├── filter-duplicate-extensions.ts │ │ │ ├── index.ts │ │ │ ├── is-allowed-uri.ts │ │ │ ├── is-list-active.ts │ │ │ ├── is-node-empty.ts │ │ │ ├── keyboard.ts │ │ │ └── upload.ts │ │ ├── tailwind.config.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ ├── tsconfig.vitest.json │ │ └── vite.config.ts │ ├── shared/ │ │ ├── env.d.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── events/ │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── plugin/ │ │ │ │ ├── index.ts │ │ │ │ └── types/ │ │ │ │ ├── attachment-selector.ts │ │ │ │ ├── backup.ts │ │ │ │ ├── comment.ts │ │ │ │ ├── dashboard-widget.ts │ │ │ │ ├── editor-provider.ts │ │ │ │ ├── index.ts │ │ │ │ ├── list-entity-field.ts │ │ │ │ ├── list-operation.ts │ │ │ │ ├── plugin-installation-tab.ts │ │ │ │ ├── plugin-tab.ts │ │ │ │ ├── theme-list-tab.ts │ │ │ │ ├── ui-plugin-entry.ts │ │ │ │ ├── ui-plugin-module.ts │ │ │ │ └── user-tab.ts │ │ │ ├── stores/ │ │ │ │ ├── index.ts │ │ │ │ └── types/ │ │ │ │ ├── actuator.ts │ │ │ │ ├── index.ts │ │ │ │ └── slug.ts │ │ │ ├── types/ │ │ │ │ ├── index.ts │ │ │ │ └── menus.ts │ │ │ └── utils/ │ │ │ ├── attachment.ts │ │ │ ├── date.ts │ │ │ ├── id.ts │ │ │ ├── index.ts │ │ │ └── permission.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ └── tsdown.config.ts │ └── ui-plugin-bundler-kit/ │ ├── README.md │ ├── package.json │ ├── src/ │ │ ├── constants/ │ │ │ ├── build.ts │ │ │ ├── externals.ts │ │ │ └── halo-plugin.ts │ │ ├── index.ts │ │ ├── legacy.ts │ │ ├── rsbuild.ts │ │ ├── utils/ │ │ │ └── halo-plugin.ts │ │ └── vite.ts │ ├── tsconfig.json │ └── tsdown.config.ts ├── patches/ │ └── @tiptap__extension-drag-handle@3.17.1.patch ├── pnpm-workspace.yaml ├── postcss.config.cjs ├── scripts/ │ ├── apply_missing_translations.mjs │ ├── find_missing_translations.mjs │ └── fix_translations.mjs ├── src/ │ ├── components/ │ │ ├── alerts/ │ │ │ └── H2WarningAlert.vue │ │ ├── attachment/ │ │ │ ├── AttachmentGridListItem.vue │ │ │ ├── AttachmentImagePreview.vue │ │ │ └── AttachmentPermalinkList.vue │ │ ├── back-to-top/ │ │ │ └── BackToTop.vue │ │ ├── base-app/ │ │ │ └── BaseApp.vue │ │ ├── button/ │ │ │ └── SubmitButton.vue │ │ ├── codemirror/ │ │ │ ├── Codemirror.vue │ │ │ └── supports.ts │ │ ├── common/ │ │ │ └── AppDownloadAlert.vue │ │ ├── dropdown-selector/ │ │ │ └── EditorProviderSelector.vue │ │ ├── editor/ │ │ │ └── DefaultEditor.vue │ │ ├── entity/ │ │ │ └── EntityDropdownItems.vue │ │ ├── entity-fields/ │ │ │ ├── EntityFieldItems.vue │ │ │ └── StatusDotField.vue │ │ ├── filter/ │ │ │ ├── CategoryFilterDropdown.vue │ │ │ ├── FilterCleanButton.vue │ │ │ ├── FilterDropdown.vue │ │ │ ├── FilterTag.vue │ │ │ ├── TagFilterDropdown.vue │ │ │ └── UserFilterDropdown.vue │ │ ├── form/ │ │ │ └── AnnotationsForm.vue │ │ ├── global-search/ │ │ │ └── GlobalSearchModal.vue │ │ ├── icon/ │ │ │ └── AttachmentFileTypeIcon.vue │ │ ├── input/ │ │ │ └── SearchInput.vue │ │ ├── menu/ │ │ │ ├── MenuLoading.vue │ │ │ └── RoutesMenu.tsx │ │ ├── permission/ │ │ │ └── HasPermission.vue │ │ ├── preview/ │ │ │ └── UrlPreviewModal.vue │ │ ├── sticky-block/ │ │ │ └── StickyBlock.vue │ │ ├── upload/ │ │ │ └── UppyUpload.vue │ │ ├── user/ │ │ │ └── PostContributorList.vue │ │ ├── user-avatar/ │ │ │ ├── UserAvatar.vue │ │ │ └── UserAvatarCropper.vue │ │ └── video/ │ │ └── LazyVideo.vue │ ├── composables/ │ │ ├── use-auto-save-content.ts │ │ ├── use-content-cache.ts │ │ ├── use-editor-extension-points.ts │ │ ├── use-role.ts │ │ ├── use-route-menu-generator.ts │ │ ├── use-session-keep-alive.ts │ │ └── use-title.ts │ ├── constants/ │ │ ├── annotations.ts │ │ ├── app.ts │ │ ├── constants.ts │ │ ├── error-types.ts │ │ ├── finalizers.ts │ │ ├── labels.ts │ │ └── regex.ts │ ├── formkit/ │ │ ├── formkit.config.ts │ │ ├── inputs/ │ │ │ ├── array/ │ │ │ │ ├── ArrayFormModal.vue │ │ │ │ ├── ArrayInput.vue │ │ │ │ ├── index.ts │ │ │ │ ├── labels/ │ │ │ │ │ ├── ColorLabel.vue │ │ │ │ │ └── IconifyLabel.vue │ │ │ │ ├── renderers/ │ │ │ │ │ ├── attachment.ts │ │ │ │ │ ├── category-select.ts │ │ │ │ │ ├── checkbox.ts │ │ │ │ │ ├── helpers/ │ │ │ │ │ │ └── findOption.ts │ │ │ │ │ ├── iconify.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── native-select.ts │ │ │ │ │ ├── radio.ts │ │ │ │ │ ├── select.ts │ │ │ │ │ ├── tag-select.ts │ │ │ │ │ ├── toggle.ts │ │ │ │ │ └── types.ts │ │ │ │ └── sections/ │ │ │ │ └── index.ts │ │ │ ├── attachment/ │ │ │ │ ├── AttachmentDropdownItem.vue │ │ │ │ ├── AttachmentInput.vue │ │ │ │ ├── AttachmentPreview.vue │ │ │ │ ├── CustomLinkDropdownItem.vue │ │ │ │ ├── UploadDropdownItem.vue │ │ │ │ ├── feature.ts │ │ │ │ └── index.ts │ │ │ ├── attachment-group-select.ts │ │ │ ├── attachment-input/ │ │ │ │ ├── AttachmentInput.vue │ │ │ │ └── index.ts │ │ │ ├── attachment-policy-select.ts │ │ │ ├── category-checkbox.ts │ │ │ ├── category-select/ │ │ │ │ ├── CategorySelect.vue │ │ │ │ ├── components/ │ │ │ │ │ ├── CategoryListItem.vue │ │ │ │ │ ├── CategoryTag.vue │ │ │ │ │ └── SearchResultListItem.vue │ │ │ │ ├── index.ts │ │ │ │ └── sections/ │ │ │ │ └── index.ts │ │ │ ├── code/ │ │ │ │ ├── CodeInput.vue │ │ │ │ └── index.ts │ │ │ ├── color/ │ │ │ │ ├── ColorInput.vue │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── form.ts │ │ │ ├── group.ts │ │ │ ├── iconify/ │ │ │ │ ├── Collections.vue │ │ │ │ ├── CollectionsView.vue │ │ │ │ ├── Icon.vue │ │ │ │ ├── IconConfirmPanel.vue │ │ │ │ ├── IconifyInput.vue │ │ │ │ ├── IconifyPicker.vue │ │ │ │ ├── Icons.vue │ │ │ │ ├── SearchView.vue │ │ │ │ ├── api.ts │ │ │ │ ├── feature.ts │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── list/ │ │ │ │ ├── AddButton.vue │ │ │ │ ├── features/ │ │ │ │ │ └── lists.ts │ │ │ │ ├── index.ts │ │ │ │ ├── listSection.ts │ │ │ │ └── sections/ │ │ │ │ └── index.ts │ │ │ ├── menu-checkbox.ts │ │ │ ├── menu-item-select.ts │ │ │ ├── menu-radio.ts │ │ │ ├── menu-select.ts │ │ │ ├── password/ │ │ │ │ ├── RevealButton.vue │ │ │ │ └── index.ts │ │ │ ├── post-select.ts │ │ │ ├── repeater/ │ │ │ │ ├── AddButton.vue │ │ │ │ ├── features/ │ │ │ │ │ └── repeats.ts │ │ │ │ ├── index.ts │ │ │ │ ├── repeaterSection.ts │ │ │ │ └── sections/ │ │ │ │ └── index.ts │ │ │ ├── role-select.ts │ │ │ ├── secret/ │ │ │ │ ├── SecretSelect.vue │ │ │ │ ├── components/ │ │ │ │ │ ├── SecretCreationModal.vue │ │ │ │ │ ├── SecretEditModal.vue │ │ │ │ │ ├── SecretForm.vue │ │ │ │ │ ├── SecretListItem.vue │ │ │ │ │ └── SecretListModal.vue │ │ │ │ ├── composables/ │ │ │ │ │ └── use-secrets-fetch.ts │ │ │ │ ├── feature.ts │ │ │ │ ├── index.ts │ │ │ │ ├── sections/ │ │ │ │ │ └── index.ts │ │ │ │ └── types/ │ │ │ │ └── index.ts │ │ │ ├── select/ │ │ │ │ ├── MultipleOverflow.vue │ │ │ │ ├── MultipleOverflowItem.vue │ │ │ │ ├── MultipleSelect.vue │ │ │ │ ├── MultipleSelectItem.vue │ │ │ │ ├── MultipleSelectSearchInput.vue │ │ │ │ ├── MultipleSelectSelector.vue │ │ │ │ ├── SelectContainer.vue │ │ │ │ ├── SelectDropdownContainer.vue │ │ │ │ ├── SelectMain.vue │ │ │ │ ├── SelectOption.vue │ │ │ │ ├── SelectOptionItem.vue │ │ │ │ ├── SelectSearchInput.vue │ │ │ │ ├── SelectSelector.vue │ │ │ │ ├── index.ts │ │ │ │ ├── isFalse.ts │ │ │ │ └── sections/ │ │ │ │ └── index.ts │ │ │ ├── singlePage-select.ts │ │ │ ├── switch/ │ │ │ │ ├── SwitchInput.vue │ │ │ │ ├── feature.ts │ │ │ │ └── index.ts │ │ │ ├── tag-checkbox.ts │ │ │ ├── tag-select/ │ │ │ │ ├── TagSelect.vue │ │ │ │ ├── index.ts │ │ │ │ └── sections/ │ │ │ │ └── index.ts │ │ │ ├── toggle/ │ │ │ │ ├── ToggleInput.vue │ │ │ │ ├── feature.ts │ │ │ │ └── index.ts │ │ │ ├── user-select.ts │ │ │ └── verify-form/ │ │ │ ├── VerificationButton.vue │ │ │ ├── features/ │ │ │ │ └── index.ts │ │ │ └── index.ts │ │ ├── plugins/ │ │ │ ├── auto-scroll-to-errors.ts │ │ │ ├── password-prevent-autocomplete.ts │ │ │ ├── radio-alt.ts │ │ │ ├── required-asterisk.ts │ │ │ └── stop-implicit-submission.ts │ │ ├── theme.ts │ │ └── utils/ │ │ └── focus.ts │ ├── layouts/ │ │ ├── MobileMenu.vue │ │ └── UserProfileBanner.vue │ ├── locales/ │ │ ├── en.json │ │ ├── es.json │ │ ├── index.ts │ │ ├── zh-CN.json │ │ └── zh-TW.json │ ├── router/ │ │ └── process-bar.ts │ ├── setup/ │ │ ├── setupApiClient.ts │ │ ├── setupComponents.ts │ │ ├── setupModules.ts │ │ ├── setupStyles.ts │ │ ├── setupUserPermissions.ts │ │ └── setupVueQuery.ts │ ├── stores/ │ │ ├── plugin.ts │ │ └── role.ts │ ├── styles/ │ │ ├── index.css │ │ └── tailwind.css │ ├── utils/ │ │ ├── __tests__/ │ │ │ └── media-type.spec.ts │ │ ├── cookie.ts │ │ ├── device.ts │ │ ├── image.ts │ │ ├── load-style.ts │ │ ├── media-type.ts │ │ ├── modal.ts │ │ └── role.ts │ ├── views/ │ │ └── exceptions/ │ │ ├── Forbidden.vue │ │ ├── NotFound.vue │ │ ├── __tests__/ │ │ │ └── NotFound.spec.ts │ │ └── components/ │ │ └── Exception.vue │ └── vite/ │ ├── library-external.ts │ └── plugin-dev.ts ├── tailwind.config.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json ├── tsconfig.vitest.json ├── uc-src/ │ ├── App.vue │ ├── layouts/ │ │ └── BasicLayout.vue │ ├── main.ts │ ├── modules/ │ │ ├── contents/ │ │ │ ├── attachments/ │ │ │ │ ├── components/ │ │ │ │ │ ├── AttachmentDetailModal.vue │ │ │ │ │ ├── AttachmentSelectorModal.vue │ │ │ │ │ └── selector-providers/ │ │ │ │ │ ├── AttachmentUploadModal.vue │ │ │ │ │ ├── CoreSelectorProvider.vue │ │ │ │ │ └── components/ │ │ │ │ │ └── AttachmentSelectorListItem.vue │ │ │ │ └── module.ts │ │ │ └── posts/ │ │ │ ├── PostEditor.vue │ │ │ ├── PostList.vue │ │ │ ├── components/ │ │ │ │ ├── PostCreationModal.vue │ │ │ │ ├── PostListItem.vue │ │ │ │ ├── PostSettingEditModal.vue │ │ │ │ └── PostSettingForm.vue │ │ │ ├── composables/ │ │ │ │ ├── use-post-publish-mutate.ts │ │ │ │ └── use-post-update-mutate.ts │ │ │ ├── module.ts │ │ │ └── types/ │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── notifications/ │ │ │ ├── Notifications.vue │ │ │ ├── components/ │ │ │ │ ├── NotificationContent.vue │ │ │ │ └── NotificationListItem.vue │ │ │ └── module.ts │ │ └── profile/ │ │ ├── Profile.vue │ │ ├── components/ │ │ │ ├── EmailVerifyModal.vue │ │ │ ├── PasswordChangeModal.vue │ │ │ ├── PersonalAccessTokenCreationModal.vue │ │ │ ├── PersonalAccessTokenListItem.vue │ │ │ └── ProfileEditingModal.vue │ │ ├── module.ts │ │ └── tabs/ │ │ ├── Authentication.vue │ │ ├── Detail.vue │ │ ├── Devices.vue │ │ ├── NotificationPreferences.vue │ │ ├── PersonalAccessTokens.vue │ │ ├── components/ │ │ │ ├── AuthProviders.vue │ │ │ ├── DeviceDetailModal.vue │ │ │ ├── DeviceListItem.vue │ │ │ ├── PasswordValidationForm.vue │ │ │ ├── TotpConfigureModal.vue │ │ │ ├── TotpDeletionModal.vue │ │ │ ├── TwoFactor.vue │ │ │ ├── TwoFactorDisableModal.vue │ │ │ └── TwoFactorEnableModal.vue │ │ └── composables/ │ │ ├── use-user-agent.ts │ │ └── use-user-device.ts │ └── router/ │ ├── constant.ts │ ├── guards/ │ │ ├── auth-check.ts │ │ └── permission.ts │ ├── index.ts │ └── routes.config.ts ├── uc.html └── vite.config.ts