Repository: Night-stars-1/Han1meViewer Branch: master Commit: cc61b0c58cb2 Files: 553 Total size: 1.8 MB Directory structure: gitextract_rimhsaes/ ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ ├── custom.md │ │ └── feature_request.yml │ ├── PULL_REQUEST_TEMPLATE/ │ │ ├── bug_fix.md │ │ ├── feature_addition.md │ │ └── submit_h_keyframe.md │ ├── dependabot.yml │ └── workflows/ │ ├── ci.yml │ ├── ci_release.yml │ └── pr_check.yml ├── .gitignore ├── .idea/ │ ├── .gitignore │ ├── .name │ ├── AndroidProjectSystem.xml │ ├── appInsightsSettings.xml │ ├── codeStyles/ │ │ ├── Project.xml │ │ └── codeStyleConfig.xml │ ├── compiler.xml │ ├── dbnavigator.xml │ ├── deploymentTargetDropDown.xml │ ├── deploymentTargetSelector.xml │ ├── dictionaries/ │ │ └── wrzg8.xml │ ├── gradle.xml │ ├── inspectionProfiles/ │ │ └── Project_Default.xml │ ├── kotlinc.xml │ ├── ktlint-plugin.xml │ ├── migrations.xml │ ├── misc.xml │ ├── render.experimental.xml │ ├── runConfigurations.xml │ ├── studiobot.xml │ └── vcs.xml ├── LICENSE ├── README.md ├── README_TECH.md ├── app/ │ ├── .gitignore │ ├── build.gradle.kts │ ├── keystore/ │ │ └── Han1meViewerKeystore.jks │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── yenaly/ │ │ └── han1meviewer/ │ │ └── ExampleInstrumentedTest.kt │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── assets/ │ │ │ ├── h_keyframes/ │ │ │ │ ├── 12444.json │ │ │ │ ├── 14463.json │ │ │ │ ├── 21806.json │ │ │ │ ├── 22068.json │ │ │ │ ├── 37176.json │ │ │ │ ├── 37177.json │ │ │ │ ├── 37178.json │ │ │ │ ├── 37179.json │ │ │ │ ├── 37220.json │ │ │ │ ├── 37221.json │ │ │ │ ├── 38387.json │ │ │ │ ├── 38389.json │ │ │ │ ├── 38457.json │ │ │ │ ├── 38461.json │ │ │ │ ├── 39192.json │ │ │ │ ├── 39305.json │ │ │ │ ├── 39306.json │ │ │ │ ├── 39468.json │ │ │ │ ├── 39811.json │ │ │ │ ├── 84717.json │ │ │ │ ├── 84718.json │ │ │ │ ├── 85926.json │ │ │ │ ├── 85927.json │ │ │ │ ├── 87968.json │ │ │ │ ├── 87969.json │ │ │ │ ├── 89087.json │ │ │ │ ├── 89088.json │ │ │ │ └── README.md │ │ │ ├── search_options/ │ │ │ │ ├── brands.json │ │ │ │ ├── duration.json │ │ │ │ ├── genre.json │ │ │ │ ├── sort_option.json │ │ │ │ └── tags.json │ │ │ └── shaders/ │ │ │ ├── Anime4K_AutoDownscalePre_x2.glsl │ │ │ ├── Anime4K_AutoDownscalePre_x4.glsl │ │ │ ├── Anime4K_Clamp_Highlights.glsl │ │ │ ├── Anime4K_Restore_CNN_M.glsl │ │ │ ├── Anime4K_Restore_CNN_S.glsl │ │ │ ├── Anime4K_Restore_CNN_VL.glsl │ │ │ ├── Anime4K_Upscale_CNN_x2_M.glsl │ │ │ ├── Anime4K_Upscale_CNN_x2_S.glsl │ │ │ └── Anime4K_Upscale_CNN_x2_VL.glsl │ │ ├── java/ │ │ │ └── com/ │ │ │ └── yenaly/ │ │ │ └── han1meviewer/ │ │ │ ├── Constants.kt │ │ │ ├── FirebaseConstants.kt │ │ │ ├── HAdvancedSearch.kt │ │ │ ├── HCacheManager.kt │ │ │ ├── HCrashHandler.kt │ │ │ ├── HFileManager.kt │ │ │ ├── HInitializer.kt │ │ │ ├── HanimeApplication.kt │ │ │ ├── HanimeManager.kt │ │ │ ├── HanimeResolution.kt │ │ │ ├── Preferences.kt │ │ │ ├── VideoCoverSize.kt │ │ │ ├── logic/ │ │ │ │ ├── DatabaseRepo.kt │ │ │ │ ├── NetworkRepo.kt │ │ │ │ ├── Parser.kt │ │ │ │ ├── dao/ │ │ │ │ │ ├── DownloadDatabase.kt │ │ │ │ │ ├── HKeyframeDao.kt │ │ │ │ │ ├── HistoryDatabase.kt │ │ │ │ │ ├── MiscellanyDatabase.kt │ │ │ │ │ ├── SearchHistoryDao.kt │ │ │ │ │ ├── WatchHistoryDao.kt │ │ │ │ │ └── download/ │ │ │ │ │ ├── DownloadCategoryDao.kt │ │ │ │ │ ├── HUpdateDao.kt │ │ │ │ │ └── HanimeDownloadDao.kt │ │ │ │ ├── entity/ │ │ │ │ │ ├── HKeyframeEntity.kt │ │ │ │ │ ├── SearchHistoryEntity.kt │ │ │ │ │ ├── WatchHistoryEntity.kt │ │ │ │ │ └── download/ │ │ │ │ │ ├── DownloadCategoryEntity.kt │ │ │ │ │ ├── HUpdateEntity.kt │ │ │ │ │ ├── HanimeCategoryCrossRef.kt │ │ │ │ │ ├── HanimeDownloadEntity.kt │ │ │ │ │ └── VideoWithCategories.kt │ │ │ │ ├── exception/ │ │ │ │ │ ├── CloudFlareBlockedException.kt │ │ │ │ │ ├── HanimeNotFoundException.kt │ │ │ │ │ ├── IPBlockedException.kt │ │ │ │ │ └── ParseException.kt │ │ │ │ ├── model/ │ │ │ │ │ ├── HanimeInfo.kt │ │ │ │ │ ├── HanimePreview.kt │ │ │ │ │ ├── HanimeVideo.kt │ │ │ │ │ ├── HomePage.kt │ │ │ │ │ ├── MultiItemEntity.kt │ │ │ │ │ ├── MyListItems.kt │ │ │ │ │ ├── ParamEnum.kt │ │ │ │ │ ├── Playlists.kt │ │ │ │ │ ├── SearchOption.kt │ │ │ │ │ ├── SearchTag.kt │ │ │ │ │ ├── Subscription.kt │ │ │ │ │ ├── VideoComments.kt │ │ │ │ │ └── github/ │ │ │ │ │ ├── Commit.kt │ │ │ │ │ ├── Latest.kt │ │ │ │ │ ├── Release.kt │ │ │ │ │ └── Workflow.kt │ │ │ │ ├── network/ │ │ │ │ │ ├── GitHubDns.kt │ │ │ │ │ ├── HCookieJar.kt │ │ │ │ │ ├── HDns.kt │ │ │ │ │ ├── HProxySelector.kt │ │ │ │ │ ├── HUpdater.kt │ │ │ │ │ ├── HanimeNetwork.kt │ │ │ │ │ ├── ServiceCreator.kt │ │ │ │ │ ├── interceptor/ │ │ │ │ │ │ ├── SpeedLimitInterceptor.kt │ │ │ │ │ │ ├── SpeedLimitResponseBody.kt │ │ │ │ │ │ └── UserAgentInterceptor.kt │ │ │ │ │ └── service/ │ │ │ │ │ ├── HGitHubService.kt │ │ │ │ │ ├── HanimeBaseService.kt │ │ │ │ │ ├── HanimeCommentService.kt │ │ │ │ │ ├── HanimeMyListService.kt │ │ │ │ │ └── HanimeSubscriptionService.kt │ │ │ │ └── state/ │ │ │ │ ├── DownloadState.kt │ │ │ │ ├── PageLoadingState.kt │ │ │ │ ├── VideoLoadingState.kt │ │ │ │ └── WebsiteState.kt │ │ │ ├── ui/ │ │ │ │ ├── StateLayoutMixin.kt │ │ │ │ ├── activity/ │ │ │ │ │ ├── DownloadActivity.kt │ │ │ │ │ ├── LoginActivity.kt │ │ │ │ │ ├── MainActivity.kt │ │ │ │ │ ├── PreviewActivity.kt │ │ │ │ │ ├── PreviewCommentActivity.kt │ │ │ │ │ ├── SearchActivity.kt │ │ │ │ │ ├── SettingsActivity.kt │ │ │ │ │ ├── SettingsRouter.kt │ │ │ │ │ └── VideoActivity.kt │ │ │ │ ├── adapter/ │ │ │ │ │ ├── AdapterLikeDataBindingPage.kt │ │ │ │ │ ├── BaseSingleDifferAdapter.kt │ │ │ │ │ ├── FixedGridLayoutManager.kt │ │ │ │ │ ├── HKeyframesRvAdapter.kt │ │ │ │ │ ├── HRvItemAdapter.kt │ │ │ │ │ ├── HSearchTagAdapter.kt │ │ │ │ │ ├── HSubscriptionAdapter.kt │ │ │ │ │ ├── HanimeDownloadedRvAdapter.kt │ │ │ │ │ ├── HanimeDownloadingRvAdapter.kt │ │ │ │ │ ├── HanimeMyListVideoAdapter.kt │ │ │ │ │ ├── HanimePreviewNewsRvAdapter.kt │ │ │ │ │ ├── HanimePreviewTourRvAdapter.kt │ │ │ │ │ ├── HanimeSearchHistoryRvAdapter.kt │ │ │ │ │ ├── HanimeUpdateRvAdapter.kt │ │ │ │ │ ├── HanimeUpdatedRvAdapter.kt │ │ │ │ │ ├── HanimeVideoRvAdapter.kt │ │ │ │ │ ├── PlaylistRvAdapter.kt │ │ │ │ │ ├── RvWrapper.kt │ │ │ │ │ ├── SharedHKeyframesRvAdapter.kt │ │ │ │ │ ├── SuperResolutionAdapter.kt │ │ │ │ │ ├── VideoColumnTitleAdapter.kt │ │ │ │ │ ├── VideoCommentRvAdapter.kt │ │ │ │ │ ├── VideoSpeedAdapter.kt │ │ │ │ │ └── WatchHistoryRvAdapter.kt │ │ │ │ ├── fragment/ │ │ │ │ │ ├── IToolbarFragment.kt │ │ │ │ │ ├── LoginNeededFragmentMixin.kt │ │ │ │ │ ├── home/ │ │ │ │ │ │ ├── DownloadFragment.kt │ │ │ │ │ │ ├── HomePageFragment.kt │ │ │ │ │ │ ├── MyFavVideoFragment.kt │ │ │ │ │ │ ├── MyPlaylistFragment.kt │ │ │ │ │ │ ├── MyWatchLaterFragment.kt │ │ │ │ │ │ ├── WatchHistoryFragment.kt │ │ │ │ │ │ └── download/ │ │ │ │ │ │ ├── DownloadedFragment.kt │ │ │ │ │ │ └── DownloadingFragment.kt │ │ │ │ │ ├── search/ │ │ │ │ │ │ ├── HCheckBoxFragment.kt │ │ │ │ │ │ ├── HMultiChoicesDialog.kt │ │ │ │ │ │ ├── HTimePickerDialog.kt │ │ │ │ │ │ └── SearchOptionsPopupFragment.kt │ │ │ │ │ ├── settings/ │ │ │ │ │ │ ├── DownloadSettingsFragment.kt │ │ │ │ │ │ ├── HKeyframeSettingsFragment.kt │ │ │ │ │ │ ├── HKeyframesFragment.kt │ │ │ │ │ │ ├── HomeSettingsFragment.kt │ │ │ │ │ │ ├── NetworkSettingsFragment.kt │ │ │ │ │ │ ├── PlayerSettingsFragment.kt │ │ │ │ │ │ └── SharedHKeyframesFragment.kt │ │ │ │ │ └── video/ │ │ │ │ │ ├── ChildCommentPopupFragment.kt │ │ │ │ │ ├── CommentFragment.kt │ │ │ │ │ └── VideoIntroductionFragment.kt │ │ │ │ ├── popup/ │ │ │ │ │ ├── CoilImageLoader.kt │ │ │ │ │ ├── HTimePickerPopup.kt │ │ │ │ │ └── ReplyPopup.kt │ │ │ │ ├── view/ │ │ │ │ │ ├── BlurTransformation.kt │ │ │ │ │ ├── CenterLinearLayoutManager.kt │ │ │ │ │ ├── CollapsibleTags.kt │ │ │ │ │ ├── HOptionChip.kt │ │ │ │ │ ├── HanimeSearchBar.kt │ │ │ │ │ ├── HorizontalNestedScrollView.kt │ │ │ │ │ ├── LinearSmoothToStartScroller.kt │ │ │ │ │ ├── PlaylistHeader.kt │ │ │ │ │ ├── funcbar/ │ │ │ │ │ │ ├── Hanidapter.kt │ │ │ │ │ │ ├── Hanidock.kt │ │ │ │ │ │ ├── Hanidokitem.kt │ │ │ │ │ │ └── Hanidontroller.kt │ │ │ │ │ ├── pref/ │ │ │ │ │ │ ├── HPrivacyPreference.kt │ │ │ │ │ │ └── MaterialDialogPreference.kt │ │ │ │ │ └── video/ │ │ │ │ │ ├── HJzvdStd.kt │ │ │ │ │ ├── HMediaKernel.kt │ │ │ │ │ ├── HanimeDataSource.kt │ │ │ │ │ └── IMedia.kt │ │ │ │ └── viewmodel/ │ │ │ │ ├── AppViewModel.kt │ │ │ │ ├── CommentViewModel.kt │ │ │ │ ├── DownloadViewModel.kt │ │ │ │ ├── IHCsrfToken.kt │ │ │ │ ├── MainViewModel.kt │ │ │ │ ├── MyListViewModel.kt │ │ │ │ ├── PreviewCommentPrefetcher.kt │ │ │ │ ├── PreviewViewModel.kt │ │ │ │ ├── SearchViewModel.kt │ │ │ │ ├── SettingsViewModel.kt │ │ │ │ ├── VideoViewModel.kt │ │ │ │ └── mylist/ │ │ │ │ ├── FavSubViewModel.kt │ │ │ │ ├── PlaylistSubViewModel.kt │ │ │ │ ├── SubscriptionSubViewModel.kt │ │ │ │ └── WatchLaterSubViewModel.kt │ │ │ ├── util/ │ │ │ │ ├── Adapters.kt │ │ │ │ ├── AlertDialogs.kt │ │ │ │ ├── Animations.kt │ │ │ │ ├── AnimeShaders.kt │ │ │ │ ├── Colors.kt │ │ │ │ ├── Cookies.kt │ │ │ │ ├── Extend.kt │ │ │ │ ├── Files.kt │ │ │ │ ├── Firebases.kt │ │ │ │ ├── GridSpacingDecoration.kt │ │ │ │ ├── HImageMeower.kt │ │ │ │ ├── MediaUtils.kt │ │ │ │ ├── Networks.kt │ │ │ │ ├── Parcels.kt │ │ │ │ ├── Permissions.kt │ │ │ │ ├── Platform.kt │ │ │ │ ├── Preferences.kt │ │ │ │ ├── TextViews.kt │ │ │ │ ├── Versions.kt │ │ │ │ └── Views.kt │ │ │ └── worker/ │ │ │ ├── HUpdateWorker.kt │ │ │ ├── HanimeDownloadManager.kt │ │ │ ├── HanimeDownloadManagerV2.kt │ │ │ ├── HanimeDownloadWorker.kt │ │ │ └── WorkerMixin.kt │ │ └── res/ │ │ ├── anim/ │ │ │ ├── fade_in.xml │ │ │ ├── fade_out.xml │ │ │ ├── slide_in_from_bottom.xml │ │ │ └── slide_out_to_bottom.xml │ │ ├── drawable/ │ │ │ ├── baseline_add_24.xml │ │ │ ├── baseline_add_link_24.xml │ │ │ ├── baseline_advanced_search_24.xml │ │ │ ├── baseline_arrow_forward_ios_24.xml │ │ │ ├── baseline_bug_report_24.xml │ │ │ ├── baseline_data_usage_24.xml │ │ │ ├── baseline_dns_24.xml │ │ │ ├── baseline_edit_24.xml │ │ │ ├── baseline_error_outline_24.xml │ │ │ ├── baseline_format_list_bulleted_24.xml │ │ │ ├── baseline_forum_24.xml │ │ │ ├── baseline_h_24.xml │ │ │ ├── baseline_keyboard_arrow_down_24.xml │ │ │ ├── baseline_keyboard_arrow_up_24.xml │ │ │ ├── baseline_link_24.xml │ │ │ ├── baseline_more_horiz_24.xml │ │ │ ├── baseline_refresh_24.xml │ │ │ ├── baseline_remove_circle_24.xml │ │ │ ├── baseline_simp_to_trad_24.xml │ │ │ ├── baseline_sort_24.xml │ │ │ ├── gradient_black80_transparent_270.xml │ │ │ ├── gradient_black_transparent_90.xml │ │ │ ├── ic_baseline_access_time_24.xml │ │ │ ├── ic_baseline_arrow_back_24.xml │ │ │ ├── ic_baseline_arrow_forward_24.xml │ │ │ ├── ic_baseline_cancel_24.xml │ │ │ ├── ic_baseline_check_circle_24.xml │ │ │ ├── ic_baseline_checklist_24.xml │ │ │ ├── ic_baseline_clear_all_24.xml │ │ │ ├── ic_baseline_close_24.xml │ │ │ ├── ic_baseline_comment_24.xml │ │ │ ├── ic_baseline_delete_24.xml │ │ │ ├── ic_baseline_download_24.xml │ │ │ ├── ic_baseline_favorite_24.xml │ │ │ ├── ic_baseline_favorite_border_24.xml │ │ │ ├── ic_baseline_help_24.xml │ │ │ ├── ic_baseline_history_24.xml │ │ │ ├── ic_baseline_home_24.xml │ │ │ ├── ic_baseline_info_24.xml │ │ │ ├── ic_baseline_language_24.xml │ │ │ ├── ic_baseline_list_24.xml │ │ │ ├── ic_baseline_menu_24.xml │ │ │ ├── ic_baseline_more_time_24.xml │ │ │ ├── ic_baseline_newspaper_24.xml │ │ │ ├── ic_baseline_pause_24.xml │ │ │ ├── ic_baseline_pause_24_tintwhite.xml │ │ │ ├── ic_baseline_play_arrow_24.xml │ │ │ ├── ic_baseline_play_arrow_24_tintwhite.xml │ │ │ ├── ic_baseline_play_circle_outline_24.xml │ │ │ ├── ic_baseline_reply_24.xml │ │ │ ├── ic_baseline_search_24.xml │ │ │ ├── ic_baseline_send_24.xml │ │ │ ├── ic_baseline_settings_24.xml │ │ │ ├── ic_baseline_share_24.xml │ │ │ ├── ic_baseline_tag_24.xml │ │ │ ├── ic_baseline_thumb_down_alt_24.xml │ │ │ ├── ic_baseline_thumb_down_off_alt_24.xml │ │ │ ├── ic_baseline_thumb_up_alt_24.xml │ │ │ ├── ic_baseline_thumb_up_off_alt_24.xml │ │ │ ├── ic_baseline_update_24.xml │ │ │ ├── ic_baseline_watch_later_24.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── ic_outline_watch_later_24.xml │ │ │ ├── line_divider.xml │ │ │ ├── menu_24px.xml │ │ │ ├── open_in_new_24px.xml │ │ │ ├── outline_home_24.xml │ │ │ ├── pause_circle_24px.xml │ │ │ ├── pip_24px.xml │ │ │ ├── play_circle_24px.xml │ │ │ ├── scaled_added_time.xml │ │ │ ├── screenshot_frame_2_24px.xml │ │ │ ├── search_bar.xml │ │ │ ├── shape_download_func_bar.xml │ │ │ ├── shape_preview_button_left.xml │ │ │ ├── shape_preview_button_right.xml │ │ │ ├── shape_reply_show_bottom_dialog.xml │ │ │ ├── shape_tag_selector.xml │ │ │ ├── shape_title_mask.xml │ │ │ ├── shape_title_mask_black.xml │ │ │ └── translated_border.xml │ │ ├── drawable-v24/ │ │ │ └── ic_launcher_foreground.xml │ │ ├── layout/ │ │ │ ├── activity_download.xml │ │ │ ├── activity_login.xml │ │ │ ├── activity_main.xml │ │ │ ├── activity_preview.xml │ │ │ ├── activity_preview_comment.xml │ │ │ ├── activity_search.xml │ │ │ ├── activity_settings.xml │ │ │ ├── activity_video.xml │ │ │ ├── base_column_title.xml │ │ │ ├── dialog_apply_deep_links.xml │ │ │ ├── dialog_login.xml │ │ │ ├── dialog_modify_h_keyframe.xml │ │ │ ├── dialog_modify_h_keyframes.xml │ │ │ ├── dialog_playlist_modify_edit_text.xml │ │ │ ├── dialog_proxy.xml │ │ │ ├── fragment_comment.xml │ │ │ ├── fragment_h_keyframes.xml │ │ │ ├── fragment_home_page.xml │ │ │ ├── fragment_list_only.xml │ │ │ ├── fragment_page_list.xml │ │ │ ├── fragment_playlist.xml │ │ │ ├── fragment_tab_view_pager_only.xml │ │ │ ├── fragment_tag_selector.xml │ │ │ ├── fragment_video_introduction.xml │ │ │ ├── item_h_keyframe.xml │ │ │ ├── item_h_keyframes.xml │ │ │ ├── item_h_subscription.xml │ │ │ ├── item_hanidock.xml │ │ │ ├── item_hanime_downloaded.xml │ │ │ ├── item_hanime_downloading.xml │ │ │ ├── item_hanime_preview_news.xml │ │ │ ├── item_hanime_preview_news_pic.xml │ │ │ ├── item_hanime_preview_news_v2.xml │ │ │ ├── item_hanime_updated.xml │ │ │ ├── item_hanime_updating.xml │ │ │ ├── item_hanime_video.xml │ │ │ ├── item_hanime_video_simplified.xml │ │ │ ├── item_playlist.xml │ │ │ ├── item_preview_tour_simplified.xml │ │ │ ├── item_rv_wrapper.xml │ │ │ ├── item_search_history.xml │ │ │ ├── item_shared_h_keyframes.xml │ │ │ ├── item_tag_chip.xml │ │ │ ├── item_tag_chip_group.xml │ │ │ ├── item_video_column_title.xml │ │ │ ├── item_video_comment.xml │ │ │ ├── item_video_introduction.xml │ │ │ ├── item_video_tag_chip.xml │ │ │ ├── item_watch_history.xml │ │ │ ├── jz_layout_speed.xml │ │ │ ├── layout_collapsible_tag.xml │ │ │ ├── layout_empty_view.xml │ │ │ ├── layout_hanidock.xml │ │ │ ├── layout_hanime_search_bar.xml │ │ │ ├── layout_header_h_keyframes.xml │ │ │ ├── layout_jzvd_with_speed.xml │ │ │ ├── layout_playlist_header.xml │ │ │ ├── layout_playlist_header_v2.xml │ │ │ ├── layout_rv_scrollbars.xml │ │ │ ├── nav_header_ability.xml │ │ │ ├── pop_up_ext_h_time_picker.xml │ │ │ ├── pop_up_fragment_child_comment.xml │ │ │ ├── pop_up_fragment_search_options.xml │ │ │ ├── pop_up_hanime_search_tag.xml │ │ │ ├── pop_up_hanime_time_picker.xml │ │ │ └── pop_up_reply.xml │ │ ├── layout-sw600dp/ │ │ │ ├── activity_main.xml │ │ │ └── fragment_home_page.xml │ │ ├── menu/ │ │ │ ├── menu_downloaded_toolbar.xml │ │ │ ├── menu_downloading_toolbar.xml │ │ │ ├── menu_h_keyframes_toolbar.xml │ │ │ ├── menu_main_bnv.xml │ │ │ ├── menu_main_nv.xml │ │ │ ├── menu_main_rail_nv.xml │ │ │ ├── menu_main_toolbar.xml │ │ │ ├── menu_my_list_toolbar.xml │ │ │ ├── menu_playlist_toolbar.xml │ │ │ ├── menu_preview_toolbar.xml │ │ │ ├── menu_search_toolbar.xml │ │ │ └── menu_watch_history_toolbar.xml │ │ ├── mipmap-anydpi-v26/ │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── navigation/ │ │ │ ├── nav_main.xml │ │ │ └── nav_settings.xml │ │ ├── values/ │ │ │ ├── arrays.xml │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── ids.xml │ │ │ ├── strings.xml │ │ │ └── themes.xml │ │ ├── values-en/ │ │ │ └── strings.xml │ │ ├── values-night/ │ │ │ └── themes.xml │ │ ├── values-zh-rCN/ │ │ │ └── strings.xml │ │ └── xml/ │ │ ├── backup_rules.xml │ │ ├── data_extraction_rules.xml │ │ ├── file_paths.xml │ │ ├── locales_config.xml │ │ ├── settings_download.xml │ │ ├── settings_h_keyframe.xml │ │ ├── settings_home.xml │ │ ├── settings_network.xml │ │ └── settings_player.xml │ └── test/ │ └── java/ │ └── com/ │ └── yenaly/ │ └── han1meviewer/ │ └── ExampleUnitTest.kt ├── build.gradle.kts ├── buildSrc/ │ ├── build.gradle.kts │ └── src/ │ └── main/ │ └── java/ │ └── Config.kt ├── gradle/ │ ├── libs.versions.toml │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── yenaly_libs/ ├── .gitignore ├── build.gradle.kts ├── consumer-rules.pro ├── proguard-rules.pro └── src/ ├── androidTest/ │ └── java/ │ └── com/ │ └── yenaly/ │ └── yenaly_libs/ │ └── ExampleInstrumentedTest.kt ├── main/ │ ├── AndroidManifest.xml │ ├── java/ │ │ └── com/ │ │ └── yenaly/ │ │ └── yenaly_libs/ │ │ ├── ActivityManager.kt │ │ ├── SingletonHolder.kt │ │ ├── base/ │ │ │ ├── IViewBinding.kt │ │ │ ├── YenalyActivity.kt │ │ │ ├── YenalyApplication.kt │ │ │ ├── YenalyBottomSheetDialogFragment.kt │ │ │ ├── YenalyCrashHandler.kt │ │ │ ├── YenalyFragment.kt │ │ │ ├── YenalyInitializer.kt │ │ │ ├── YenalyViewModel.kt │ │ │ ├── dialog/ │ │ │ │ └── YenalyCrashDialogActivity.kt │ │ │ ├── frame/ │ │ │ │ ├── FrameActivity.kt │ │ │ │ └── FrameFragment.kt │ │ │ ├── preference/ │ │ │ │ ├── LongClickablePreference.kt │ │ │ │ ├── LongClickableSwitchPreference.kt │ │ │ │ └── MaterialSwitchPreference.kt │ │ │ ├── settings/ │ │ │ │ ├── YenalySettingsActivity.kt │ │ │ │ └── YenalySettingsFragment.kt │ │ │ └── view/ │ │ │ ├── NestedScrollableHost.kt │ │ │ └── RecyclerViewAtViewPager2.kt │ │ └── utils/ │ │ ├── ActivityResultUtil.kt │ │ ├── AppUtil.kt │ │ ├── ArrayUtil.kt │ │ ├── Base64Util.kt │ │ ├── ClipboardUtil.kt │ │ ├── ContextUtil.kt │ │ ├── DeviceUtil.kt │ │ ├── FileUtil.kt │ │ ├── ImageUtil.kt │ │ ├── LanguageHelper.kt │ │ ├── LogUtil.kt │ │ ├── OrientationManager.kt │ │ ├── ResourceUtil.kt │ │ ├── ShareUtil.kt │ │ ├── SharedPreferencesUtil.kt │ │ ├── SingleFlowLaunch.kt │ │ ├── SnackBarUtil.kt │ │ ├── SystemStatusUtil.kt │ │ ├── TextUtil.kt │ │ ├── ToastUtil.kt │ │ ├── UnicodeUtil.kt │ │ ├── UriUtil.kt │ │ ├── _AesUtil.kt │ │ ├── _GsonUtil.kt │ │ ├── _IntentUtil.kt │ │ ├── _LazyUtil.kt │ │ ├── span/ │ │ │ ├── SpannedTextGenerator.kt │ │ │ ├── YenalyImageSpan.kt │ │ │ └── YenalyQuoteSpan.kt │ │ └── view/ │ │ ├── AppBarLayoutStateChangeListener.kt │ │ ├── BottomNavViewMediator.kt │ │ ├── BottomNavViewUtil.kt │ │ ├── BottomNavigationViewMediator.kt │ │ ├── ClickUtil.kt │ │ ├── EditTextUtil.kt │ │ ├── SimpleBottomNavViewMediator.kt │ │ ├── SimpleFragmentStateAdapter.kt │ │ ├── TabLayoutUtil.kt │ │ ├── ViewPagerUtil.kt │ │ ├── ViewUtil.kt │ │ └── YenalyHideBottomViewOnScrollBehavior.kt │ └── res/ │ ├── anim/ │ │ ├── yenaly_bottom_to_top_in.xml │ │ ├── yenaly_bottom_to_top_out.xml │ │ ├── yenaly_top_to_bottom_in.xml │ │ └── yenaly_top_to_bottom_out.xml │ ├── layout/ │ │ ├── yenaly_activity_crash_dialog.xml │ │ ├── yenaly_activity_settings.xml │ │ ├── yenaly_dialog_loading.xml │ │ └── yenaly_preference_switch_widget.xml │ ├── values/ │ │ ├── ids.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── xml/ │ └── http_network_config.xml └── test/ └── java/ └── com/ └── yenaly/ └── yenaly_libs/ └── UtilUnitTest.kt ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.yml ================================================ name: 🐞 問題回報 description: 回報在 Han1meViewer 中出現的問題 labels: [bug] body: - type: textarea id: actual-behavior attributes: label: 實際行為 description: 請簡短解釋實際發生的事 placeholder: | Example: "我打開 Han1meViewer 發生了..." validations: required: true - type: textarea id: expected-behavior attributes: label: 預期行為 description: 請簡短解釋你應該發生的事 placeholder: | Example: "我應該要..." validations: required: true - type: input id: version attributes: label: Han1meViewer version description: 你的**Han1meViewer**版本 placeholder: | Example: "v0.14.0" validations: required: true - type: input id: android-version attributes: label: Android version description: 你的**Android**版本 placeholder: | Example: "Android 13" validations: required: true - type: input id: device attributes: label: Device description: 你的設備型號 placeholder: | Example: "Google Pixel 5" validations: required: true - type: textarea id: other-details attributes: label: 其他 placeholder: | 其他詳細的說明 ================================================ FILE: .github/ISSUE_TEMPLATE/custom.md ================================================ --- name: 自定義問題 about: 描述此問題的目的 title: '' labels: '' assignees: '' --- ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.yml ================================================ name: ⭐ 功能請求 description: 建議一個功能來改善 Han1meViewer labels: [ good idea | 好主意 ] body: - type: textarea id: feature-description attributes: label: 描述您建議的功能 description: 如何改進 Han1meViewer? placeholder: | Example: "我想要bla bla bla..." validations: required: true - type: textarea id: other-details attributes: label: 其他你想講的 description: 比如哪些軟體有您所說的類似功能,我方便偷過來 placeholder: | 其他補充資訊 ================================================ FILE: .github/PULL_REQUEST_TEMPLATE/bug_fix.md ================================================ --- name: "Bug 修復" about: "用於提交 Bug 修復的拉取請求" title: "[BUGFIX] <簡短描述>" labels: "bug" assignees: "" --- ### 描述 ### 修復方法 ================================================ FILE: .github/PULL_REQUEST_TEMPLATE/feature_addition.md ================================================ --- name: "新功能添加" about: "用於提交新功能的拉取請求" title: "[FEATURE] <簡短描述>" labels: "good idea | 好主意" assignees: "" --- ### 功能描述 ================================================ FILE: .github/PULL_REQUEST_TEMPLATE/submit_h_keyframe.md ================================================ --- name: "提交關鍵H幀" about: "分享你的關鍵H幀" title: "[HKeyframe] <簡短描述>" labels: "𝐇Keyframe" assignees: "" --- ### 關鍵H幀描述 ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: - package-ecosystem: gradle directory: "/" # Location of package manifests schedule: interval: weekly ================================================ FILE: .github/workflows/ci.yml ================================================ name: CI on: push: branches: [ "master" ] paths-ignore: - "**.md" workflow_dispatch: permissions: contents: write actions: write jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up JDK 21 uses: actions/setup-java@v4 with: java-version: '21' distribution: 'temurin' cache: gradle - name: Load Google Services File env: DATA: ${{ secrets.HA1_GOOGLE_SERVICES_JSON_BASE64 }} run: echo $DATA | base64 -di > app/google-services.json - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build and sign APK with Gradle run: ./gradlew assembleRelease env: HA1_KEYSTORE_PASSWORD: ${{ secrets.HA1_KEYSTORE_PASSWORD }} HA1_GITHUB_TOKEN: ${{ secrets.HA1_GITHUB_TOKEN }} HA1_VERSION_SOURCE: 'ci' - name: Upload Artifacts(arm32) uses: actions/upload-artifact@v4 with: path: app/build/outputs/apk/release/Han1meViewer-v*_armeabi-v7a.apk name: Han1meViewer-ci-${{ github.sha }}-armeabi-v7a - name: Upload Artifacts(arm64) uses: actions/upload-artifact@v4 with: path: app/build/outputs/apk/release/Han1meViewer-v*_arm64-v8a.apk name: Han1meViewer-ci-${{ github.sha }}-arm64-v8a - name: Upload Artifacts(universal) uses: actions/upload-artifact@v4 with: path: app/build/outputs/apk/release/Han1meViewer-v*_universal.apk name: Han1meViewer-ci-${{ github.sha }}-universal ================================================ FILE: .github/workflows/ci_release.yml ================================================ name: CI on: push: tags: - "v*.*.*" permissions: contents: write actions: write jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up JDK 21 uses: actions/setup-java@v4 with: java-version: '21' distribution: 'temurin' cache: gradle - name: Load Google Services File env: DATA: ${{ secrets.HA1_GOOGLE_SERVICES_JSON_BASE64 }} run: echo $DATA | base64 -di > app/google-services.json - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build and sign APK with Gradle run: | ./gradlew assembleRelease echo "VERSION_CODE=$(find app/build/outputs/apk/release -name '*arm64-v8a.apk' | head -n 1 | grep -oP '(?<=release\+)\d+(?=_arm64-v8a)')" >> $GITHUB_ENV env: HA1_KEYSTORE_PASSWORD: ${{ secrets.HA1_KEYSTORE_PASSWORD }} HA1_GITHUB_TOKEN: ${{ secrets.HA1_GITHUB_TOKEN }} HA1_VERSION_SOURCE: 'release' - name: Create release uses: softprops/action-gh-release@v2.0.4 with: name: Han1meViewer ${{ github.ref_name }}+${{ env.VERSION_CODE }} files: app/build/outputs/apk/release/Han1meViewer-v*.apk changelog: name: Generate Changelog runs-on: windows-latest needs: build steps: - name: Checkout uses: actions/checkout@v4.1.1 with: fetch-depth: 0 fetch-tags: true - name: Generate Changelog id: generate_changelog uses: Night-stars-1/changelog-generator-action@main - name: Update Changelog uses: softprops/action-gh-release@v2.0.4 with: body: ${{ steps.generate_changelog.outputs.changelog }} make_latest: true ================================================ FILE: .github/workflows/pr_check.yml ================================================ name: Pull Request Check on: pull_request: branches: [ "master" ] paths-ignore: - "**.md" jobs: check: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up JDK 21 uses: actions/setup-java@v4 with: java-version: '21' distribution: 'temurin' cache: gradle - name: Load Google Services File env: DATA: ${{ secrets.HA1_GOOGLE_SERVICES_JSON_BASE64 }} run: echo $DATA | base64 -di > app/google-services.json - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build run: ./gradlew build ================================================ FILE: .gitignore ================================================ *.iml .gradle /local.properties /.idea/caches /.idea/libraries /.idea/modules.xml /.idea/workspace.xml /.idea/navEditor.xml /.idea/assetWizardSettings.xml .DS_Store /build /captures .externalNativeBuild .cxx local.properties ================================================ FILE: .idea/.gitignore ================================================ # Default ignored files /shelf/ /workspace.xml ================================================ FILE: .idea/.name ================================================ Han1meViewer ================================================ FILE: .idea/AndroidProjectSystem.xml ================================================ ================================================ FILE: .idea/appInsightsSettings.xml ================================================ ================================================ FILE: .idea/codeStyles/Project.xml ================================================ ================================================ FILE: .idea/codeStyles/codeStyleConfig.xml ================================================ ================================================ FILE: .idea/compiler.xml ================================================ ================================================ FILE: .idea/dbnavigator.xml ================================================ ================================================ FILE: .idea/deploymentTargetDropDown.xml ================================================ ================================================ FILE: .idea/deploymentTargetSelector.xml ================================================ ================================================ FILE: .idea/dictionaries/wrzg8.xml ================================================ ================================================ FILE: .idea/gradle.xml ================================================ ================================================ FILE: .idea/inspectionProfiles/Project_Default.xml ================================================ ================================================ FILE: .idea/kotlinc.xml ================================================ ================================================ FILE: .idea/ktlint-plugin.xml ================================================ DISABLED false ================================================ FILE: .idea/migrations.xml ================================================ ================================================ FILE: .idea/misc.xml ================================================ ================================================ FILE: .idea/render.experimental.xml ================================================ ================================================ FILE: .idea/runConfigurations.xml ================================================ ================================================ FILE: .idea/studiobot.xml ================================================ ================================================ FILE: .idea/vcs.xml ================================================ ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS Copyright 2021 Yenaly Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ # Han1meViewer ![Han1meViewer](https://socialify.git.ci/YenalyLiew/Han1meViewer/image?description=1&font=KoHo&forks=1&issues=1&language=1&logo=https%3A%2F%2Fgithub.com%2FYenalyLiew%2FHan1meViewer%2Fblob%2Fmaster%2Ficon%2Ficon_han1me_viewer-rurires.png%3Fraw%3Dtrue&name=1&owner=1&pattern=Plus&pulls=1&stargazers=1&theme=Dark) Han1meViewer 是一个使用 Kotlin 开发的第三方动漫浏览器,旨在为用户提供流畅、美观且高效的动画内容浏览体验。支持多种自定义与扩展,适合二次元爱好者和开发者共同完善。 ## 功能特点 - **Anime4K超分**:集成 Anime4K 技术,提供高清晰度的动画画质。 - **动画内容浏览**:快速、流畅地浏览、搜索和筛选动漫资源。 - **多主题支持**:支持深色与浅色主题,个性化你的观影体验。 - **收藏与历史记录**:一键收藏喜欢的动画,随时查看观影历史。 - **高性能**:基于 Kotlin,界面响应快,占用资源少。 - **开源自由**:欢迎二次开发与贡献,持续优化功能。 - **画中画**:支持画中画模式,边看边做其他事情。 - **垂直视频适配**:优化垂直视频播放体验,适合手机用户。 ## 安装与运行 1. 克隆本仓库到本地: ```bash git clone https://github.com/Night-stars-1/Han1meViewer.git ``` 2. 使用 Android Studio 或其他支持 Kotlin 的 IDE 打开项目。 3. 配置依赖并编译运行到你的 Android 设备。 ## 项目结构 - `app/` 主程序源码 - `res/` 资源文件(图片、布局等) - `gradle/` 构建相关配置 - `README.md` 项目说明 - 其他相关代码和配置文件 ## 贡献指南 欢迎任何形式的贡献!你可以通过以下方式参与项目: - 提交 Issue 报告 bug 或建议新功能 - Fork 并提交 Pull Request - 优化文档与翻译 ## 特别鸣谢 - 感谢所有参与本项目的开发者和贡献者 - [Han1meViewer(YenalyLiew)](https://github.com/YenalyLiew/Han1meViewer) 原项目 - [Anime4K](https://github.com/bloc97/Anime4K) Anime4K超分辨率 - [mpv-android](https://github.com/abdallahmehiz/mpv-android) MPV 播放器内核 - [mpv-android](https://github.com/mpv-android/mpv-android) MPV 播放器内核 ## License 本项目采用 Apache-2.0 开源许可证,详见 [LICENSE](LICENSE) 文件。 ================================================ FILE: README_TECH.md ================================================ # Han1meViewer 技术相关 > 抄是程序员进步的阶梯。 ## 概括 本软件使用 MVVM 架构,Material 3 视觉风格,Jetpack 不用问肯定用,但未使用 Compose(有一说一不用 Compose 写 xml 真是写到吐)。网络请求使用 Retrofit,图片加载使用 Coil,视频播放使用 Jiaozi,Json 解析使用 Serialization,部分弹窗使用的 Xpopup。未使用 LiveData,全部改用功能更强大的 Flow。 ## 受众人群 这篇文章主要给谁看的呢?一是那些刚学习 Android 的同学,想看看本项目是怎么写的,或者对其中某个功能很感兴趣,想学习一下并且快速集成于自己的 App 中;二是普通开发者感兴趣来捧个场,能学到东西更好,写的不对的来发 discussion 拷打我。 ## 功能解析 ### 断点续传下载 #### 你可以学到 1. WorkManager 使用,如何在 WorkManager 中对下载任务进行基础管理? 2. RecyclerView 使用,DiffUtil 使用,如何充分利用 `payload` 参数对某个特定的控件进行刷新? 3. Room 使用,如何通过数据库实现回调? #### 关键文件 - [HanimeDownloadWorker.kt](app/src/main/java/com/yenaly/han1meviewer/worker/HanimeDownloadWorker.kt) - 关键作业类 - [HanimeDownloadEntity.kt](app/src/main/java/com/yenaly/han1meviewer/logic/entity/HanimeDownloadEntity.kt) - 下载 实体类 - [HanimeDownloadDao.kt](app/src/main/java/com/yenaly/han1meviewer/logic/dao/HanimeDownloadDao.kt) - 下载 Dao 类 - [DownloadDatabase.kt](app/src/main/java/com/yenaly/han1meviewer/logic/dao/DownloadDatabase.kt) - 下载 数据库类 - [HanimeDownloadingRvAdapter.kt](app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HanimeDownloadingRvAdapter.kt) - 下载界面的 RecyclerView Adapter #### 解释 你可能问我你就这几个文件就实现了?我接口呢,没接口你怎么回调的? **先去看**我写的 [小白如何快速实现简单的可保存状态断点续传后台下载?一个 Jetpack 库搞定一切!](https://juejin.cn/post/7278929337067225149),看完再看下面。 但是不要照搬,使用前要注意这么几点: 1. 你所下载的东西是否可以断点续传?对于视频类 App 来说,视频基本都是可以断点续传的,毕竟要播放嘛!所以我在实现下载的时候不必考虑那么多。 2. 是否要对每个下载任务进行很粒度的操作?不是说不行,但可能实现起来有点麻烦。 3. 一次性下载数目是否很多?如果使用上述文章的做法去下载极多文件可能会对手机性能造成一定压力,一会细说。 为什么说下载数目过多会造成一定压力? 聚焦于 [HanimeDownloadWorker.kt](app/src/main/java/com/yenaly/han1meviewer/worker/HanimeDownloadWorker.kt) 第 180 行左右: ```kotlin const val RESPONSE_INTERVAL = 500L if (System.currentTimeMillis() - delayTime > RESPONSE_INTERVAL) { val progress = entity.downloadedLength * 100 / entity.length setProgress(workDataOf(PROGRESS to progress.toInt())) setForeground(createForegroundInfo(progress.toInt())) DatabaseRepo.HanimeDownload.update(entity) delayTime = System.currentTimeMillis() } ``` 我在 App 里设置的是 500 ms 一更新,相当于 `2 次数据库更新操作/s/job`,加上通过 Flow/LiveData 回调,当数据库检测到数据更新,会立即返回全新的、拥有最新数据的列表,相当于又有 `回调 2 次/s/job`。如果一次性下载极多个文件,并且调低了 `RESPONSE_INTERVAL`,可能会对数据库造成一定负担。这个时候这种方法就不太好用了。 配置好了 RecyclerView,那刷新闪烁问题该如何解决?我在原文章中提供的方法并不好: ```kotlin rv.itemAnimator?.changeDuration = 0 ``` 这句代码只是解决了表面问题,实际上背后还是接着“闪”。因为即使是通过了 DiffUtil 进行了差分刷新,但还仍是全局更新,这只是自我欺骗罢了。不信你可以试试 `holder.binding.pbProgress.setProgress(item.progress, true)` 能不能正常出现动态效果。那怎么实现,`isDownloading` 字段发生修改,就单独对暂停按钮修改;`downloadedLength` 字段发生修改,就单独对进度条修改?这时候就需要 `payload` 出场了。 与 `payload` 相关的文章真的挺多,StackOverflow 甚至 掘金 上不少介绍这个的文章,自己去搜一搜马上就能看懂,我就不赘述了。关键就是 `DiffUtil.ItemCallback` 中的 `getChangePayload` 方法和 `onBindViewHolder` 中的 `payloads` 参数。 **先去看** `payload` 使用相关文章,再看下面。 但我发现,很多人确实介绍了这种方法,但鲜少有人去介绍如何高效率实现一次性去处理多个字段。你可能想到了 `List` 或 `IntArray`,通过遍历对应去处理每一种情况。这样的话,时间复杂度和空间复杂度都是 `O(n)`,`n` 是你需要监听的数目;再聪明点也可以想到使用 `Set`,在 `onBindViewHolder` 中分别查询 set 中是否含有某个情况来对应处理,这时候时间复杂度降到了 `O(1)`。如果在刷新不频繁的情况下,这样做确实没什么不妥,但是高强度下,每次 new 一个数据结构确实是一个小负担,那应该怎么样做呢? 这时候可以选择简单的 Bitmap 数据结构。你可能刚听说,但它确实很常见,你在使用 `Intent#addFlags` 打开新 Activity 的时候,大概率会接触到这种数据结构。我们可以利用一个仅 4 个字节的 32-bit 整数值去实现查找 (`find`)、判空 (`isEmpty`)、添加 (`add`) 的功能(我们只需要这些功能,而且不同情况数量大概率不超过 32 个)。 聚焦于 [HanimeDownloadingRvAdapter.kt](app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HanimeDownloadingRvAdapter.kt) > 注意:我使用了 BRVAH 作为 RecyclerView 的代替,所以具体方法和 RecyclerView 不一定一致,但使用方法基本一致。 ```kotlin companion object { private const val DOWNLOADING = 1 // 0000 0001 private const val PAUSE = 1 shl 1 // 0000 0010 val COMPARATOR = object : DiffUtil.ItemCallback() { override fun areContentsTheSame( oldItem: HanimeDownloadEntity, newItem: HanimeDownloadEntity, ): Boolean { return oldItem == newItem } override fun areItemsTheSame( oldItem: HanimeDownloadEntity, newItem: HanimeDownloadEntity, ): Boolean { return oldItem.id == newItem.id } override fun getChangePayload( oldItem: HanimeDownloadEntity, newItem: HanimeDownloadEntity, ): Any { // 假设当前只有 progress 和原来不一样 var bitset = 0 // bitset == 0000 0000 if (oldItem.progress != newItem.progress || oldItem.downloadedLength != newItem.downloadedLength) bitset = bitset or DOWNLOADING // bitset == 0000 0001 if (oldItem.isDownloading != newItem.isDownloading) bitset = bitset or PAUSE // 不经过这里 return bitset // return 0000 0001 } } } ``` ```kotlin override fun onBindViewHolder( holder: DataBindingHolder, position: Int, item: HanimeDownloadEntity?, payloads: List, ) { // 如果 payloads 列表为空,或者为 0000 0000,说明不需要修改 if (payloads.isEmpty() || payloads.first() == 0) return super.onBindViewHolder(holder, position, item, payloads) item.notNull() val bitset = payloads.first() as Int // 0000 0001 & 0000 0001 = 0000 0001 != 0000 0000 // 对进度相关控件进行修改 if (bitset and DOWNLOADING != 0) { holder.binding.tvSize.text = spannable { item.downloadedLength.formatFileSize().text() " | ".span { color(Color.RED) } item.length.formatFileSize().span { style(Typeface.BOLD) } } holder.binding.tvProgress.text = "${item.progress}%" holder.binding.pbProgress.setProgress(item.progress, true) } // 0000 0001 & 0000 0010 = 0000 0000 == 0000 0000 // 不经过下面 if (bitset and PAUSE != 0) { holder.binding.btnStart.handleStartButton(item.isDownloading) } } ``` 就这样实现了效率比较高的差分刷新。 ### CI 更新渠道 #### 你可以学到 #### 关键文件 #### 解释 当你的软件拓展性比较高,但受限于题材内容或者单纯懒,不方便自建服务器去读取这些拓展文件。但你又希望能让用户通过其他渠道实时的获取到更新(比如好心人上传了拓展文件,我合并到主分支之后,几分钟后用户就可以获得更新,而不用我自己做包),但又不是所有人需要这些拓展功能(要是人家不愿用你那功能,又一会一个 Release,用户也会烦;你自己一会发一个包你也会烦)。所以能不能给用户提供两种渠道?一个是稳定更新渠道,自己发版本;另一个是开发版,GitHub 自动构建,保证最新功能(最新拓展功能立即集成)但不保证稳定性。 答案是肯定的。其实我之前也不知道怎么做,但是 @NekoOuO 给我发了 [Foolbar/EhViewer](https://github.com/FooIbar/EhViewer/) 的做法,我想都没想就抄过来了。但没人详细教怎么做,我今天就来讲讲。 **先去看** GitHub CI 基础用法。 谷歌、掘金上全是教程。你先去查一查用法然后配置一下,刚开始的要求不多,你上传 commit 之后,GitHub CI 开始工作并成功 Build,就算入门了,先不用管 Build 之后干什么或者别的。如果你操作非常顺利,再看以下步骤。 待更... ### 共享关键H帧 #### 你可以学到 1. 如何充分利用 Kotlin 的集合操作函数,将一个个单独的 JSON 文件进行排序、分类甚至扁平化? 相关函数:`groupBy`、`flatMap`、`sortedWith` `=>` `compareBy`、`thenBy` #### 关键文件 - [HKeyframes 文件夹](app/src/main/assets/h_keyframes) - 存放所有共享关键H帧 - [DatabaseRepo.kt](app/src/main/java/com/yenaly/han1meviewer/logic/DatabaseRepo.kt) - 处理共享关键H帧 - [SharedHKeyframesRvAdapter.kt](app/src/main/java/com/yenaly/han1meviewer/ui/adapter/SharedHKeyframesRvAdapter.kt) - 界面 Adapter - [HKeyframeEntity.kt](app/src/main/java/com/yenaly/han1meviewer/logic/entity/HKeyframeEntity.kt) - 相关实体类 #### 解释 很多人看到 [HKeyframes 文件夹](app/src/main/assets/h_keyframes) 先笑了,所有 JSON 文件都放一块,作者是个傻宝吧,这都不知道分文件夹来分类? 你以为我没想到吗?首先分文件夹为什么不太行: 1. 分文件夹无法一次性读取到对应影片的关键H帧。比如你正在看 `videoCode` 为 `114514` 的影片,我不分文件夹直接读取文件夹下的对应文件即可,不需要遍历各个文件夹去寻找,相当于 List 和 Map 的区别。 2. 假设分文件夹后,在根目录创建 JSON 来写好哪个文件夹包含哪些影片的代号,也不是不行,但是会增加其他想提供共享H帧的人的负担。 主要还是历史遗留问题,我懒得改了😄。Kotlin 这么多集合操作函数,分个组排个序不轻轻松松? 我现在给你一个关键H帧的 JSON,你来考虑考虑怎么转化为以下格式: 格式: ``` - 系列 1 - 系列 1 第一集 - 系列 1 第二集 - 系列 1 第三集 - 系列 2 - 系列 2 第一集 - 系列 2 第二集 ``` 随机一段关键H帧: > 你要注意,该网站的 `videoCode` 不是按照顺序排列的,第一集和第二集中间可能会夹带一个其他系列的影片。 ```json { "videoCode": "114514", "group": "系列 2", "title": "系列 2 第二集", "episode": 2, "author": "Bekki Chen", "keyframes": [ { "position": 482500, "prompt": null }, { "position": 500500, "prompt": null }, { "position": 556000, "prompt": null }, { "position": 777300, "prompt": null } ] } ``` 你可能想用 Map 分类,但是 RecyclerView 可是传不了 Map 的,那怎么才能扁平化成一个 List,并且能实现 RecyclerView 多布局呢?如果是两种截然不同的两个数据去实现 RecyclerView 多布局,不得不依靠接口,比如说本 App 中共享关键H帧界面中数据不一样的标题和内容。 聚焦于 [HKeyframeEntity.kt](app/src/main/java/com/yenaly/han1meviewer/logic/entity/HKeyframeEntity.kt) ```kotlin interface MultiItemEntity { val itemType: Int } interface HKeyframeType : MultiItemEntity { companion object { const val H_KEYFRAME = 0 const val HEADER = 1 } } ``` 然后 HKeyframeEntity 和 HKeyframeHeader 我就不多说了,把正确的 `itemType` override 给对应的 `itemType` 字段就好。 现在问题是怎么读取那些共享关键H帧并将其扁平化? 聚焦于 [DatabaseRepo.kt](app/src/main/java/com/yenaly/han1meviewer/logic/DatabaseRepo.kt) ```kotlin @OptIn(ExperimentalSerializationApi::class) fun loadAllShared(): Flow> = flow { val res = applicationContext.assets.let { assets -> // assets.list 方法获取到文件夹所有文件的 List assets.list("h_keyframes")?.asSequence() // 将其转化为一个序列 ?.filter { it.endsWith(".json") } // 把其中结尾为 json 的挑出来 ?.mapNotNull { fileName -> // 将 文件名 映射 为 文件,再通过 文件 转化为 实体 try { // assets.open 方法打开文件 assets.open("h_keyframes/$fileName").use { inputStream -> Json.decodeFromStream(inputStream) } } catch (e: Exception) { // 出现问题返回 null e.printStackTrace() null } } ?.sortedWith( compareBy { it.group }.thenBy { it.episode } ) // 排序,先以 group 进行排序,然后对 episode 进行排序 ?.groupBy { it.group ?: "???" } // 分组,以 group 为 key,以 group 下的所有影片的列表为 value 建立 Map,若 group 为 null,加入组 ??? 里 ?.flatMap { (group, entities) -> // 提供两个参数,分别为 key 和 value listOf(HKeyframeHeader(title = group, attached = entities)) + entities } // 关键:扁平化,group 与 entities 由主从关系变为并列关系 .orEmpty() // 若 list 为 null,返回一个长度为 0 的空列表 } emit(res) } ``` 然后在对应 RecyclerView 中设置好 `itemType`,再分 `itemType` 配置相关函数就可以了。 具体查看 [SharedHKeyframesRvAdapter.kt](app/src/main/java/com/yenaly/han1meviewer/ui/adapter/SharedHKeyframesRvAdapter.kt) ================================================ FILE: app/.gitignore ================================================ /build /keystore/ha1_keystore_password.txt /ha1_github_token.txt ================================================ FILE: app/build.gradle.kts ================================================ @file:Suppress("UnstableApiUsage") import Config.Version.createVersion import Config.Version.source import Config.isRelease import Config.lastCommitSha import com.android.build.gradle.internal.api.BaseVariantOutputImpl plugins { alias(libs.plugins.com.android.application) alias(libs.plugins.org.jetbrains.kotlin.android) alias(libs.plugins.org.jetbrains.kotlin.plugin.parcelize) alias(libs.plugins.org.jetbrains.kotlin.plugin.serialization) alias(libs.plugins.com.google.devtools.ksp) alias(libs.plugins.com.google.gms.google.services) alias(libs.plugins.com.google.firebase.crashlytics) alias(libs.plugins.com.google.firebase.firebase.pref) // alias(libs.plugins.compose.compiler) } android { compileSdk = property("compile.sdk")?.toString()?.toIntOrNull() val commitSha = if (isRelease) lastCommitSha else "b8eace8" // 方便调试 // 先 Github Secrets 再读取环境变量,若没有则读取本地文件 val signPwd = System.getenv("HA1_KEYSTORE_PASSWORD") ?: File( projectDir, "keystore/ha1_keystore_password.txt" ).checkIfExists()?.readText().orEmpty() val githubToken = System.getenv("HA1_GITHUB_TOKEN") ?: File( projectDir, "ha1_github_token.txt" ).checkIfExists()?.readText().orEmpty() val signConfig = if (isRelease) signingConfigs.create("release") { storeFile = File(projectDir, "keystore/Han1meViewerKeystore.jks").checkIfExists() storePassword = signPwd keyAlias = "night_star" keyPassword = signPwd enableV3Signing = true enableV4Signing = true } else null defaultConfig { applicationId = "com.yenaly.han1meviewer" minSdk = property("min.sdk")?.toString()?.toIntOrNull() targetSdk = property("target.sdk")?.toString()?.toIntOrNull() val (code, name) = createVersion(major = 0, minor = 18, patch = 0) versionCode = code versionName = name testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" buildConfigField("String", "COMMIT_SHA", "\"$commitSha\"") buildConfigField("String", "VERSION_NAME", "\"${versionName}\"") buildConfigField("int", "VERSION_CODE", "$versionCode") buildConfigField("String", "HA1_GITHUB_TOKEN", "\"${githubToken}\"") buildConfigField("String", "HA1_VERSION_SOURCE", "\"${source}\"") } splits { abi { isEnable = true reset() include("armeabi-v7a", "arm64-v8a") isUniversalApk = true } } buildTypes { release { isMinifyEnabled = true signingConfig = signConfig proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } debug { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) applicationIdSuffix = ".debug" } } applicationVariants.all { outputs.forEach { output -> val outputImpl = output as BaseVariantOutputImpl val abi = outputImpl.filters.find { it.filterType == "ABI" }?.identifier outputImpl.outputFileName = if (abi != null) { "Han1meViewer-v${defaultConfig.versionName}_$abi.apk" } else { "Han1meViewer-v${defaultConfig.versionName}_universal.apk" } } } buildFeatures { //noinspection DataBindingWithoutKapt dataBinding = true buildConfig = true // compose = true } compileOptions { isCoreLibraryDesugaringEnabled = true sourceCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_21 } kotlinOptions { jvmTarget = JavaVersion.VERSION_21.toString() freeCompilerArgs = listOf("-opt-in=kotlin.RequiresOptIn", "-Xjvm-default=all-compatibility") } lint { disable += setOf("EnsureInitializerMetadata") } namespace = "com.yenaly.han1meviewer" } dependencies { implementation(project(":yenaly_libs")) // android related implementation(libs.bundles.android.base) implementation(libs.bundles.android.jetpack) implementation(libs.palette) // implementation(platform(libs.compose.compose.bom)) // androidTestImplementation(platform(libs.compose.compose.bom)) // implementation(libs.compose.material3) // implementation(libs.androidx.activity.compose) // implementation(libs.compose.ui.graphics) // implementation(libs.compose.ui.ui.tooling.preview) // debugImplementation(libs.compose.ui.ui.tooling) // datetime implementation(libs.datetime) // parse implementation(libs.serialization.json) implementation(libs.jsoup) // network implementation(libs.retrofit) implementation(libs.converter.serialization) // pic implementation(libs.coil) // popup implementation(libs.xpopup) implementation(libs.xpopup.ext) // video implementation(libs.jiaozi.video.player) implementation(libs.media3.exoplayer) implementation(libs.media3.exoplayer.hls) // view implementation(libs.refresh.layout.kernel) implementation(libs.refresh.header.material) implementation(libs.refresh.footer.classics) implementation(libs.multitype) implementation(libs.base.recyclerview.adapter.helper4) implementation(libs.expandable.textview) implementation(libs.spannable.x) implementation(libs.about) implementation(libs.statelayout) implementation(libs.circular.reveal.switch) // firebase implementation(platform(libs.firebase.bom)) implementation(libs.firebase.analytics) implementation(libs.firebase.crashlytics) implementation(libs.firebase.perf) implementation(libs.firebase.config) // mpv implementation(libs.mpv.lib) ksp(libs.room.compiler) coreLibraryDesugaring(libs.desugar.jdk.libs) testImplementation(libs.junit) androidTestImplementation(libs.test.junit) androidTestImplementation(libs.test.espresso.core) // debugImplementation(libs.leak.canary) } /** * This function is used to check if a file exists and is a file. */ fun File.checkIfExists(): File? = if (exists() && isFile) this else null ================================================ FILE: app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle.kts. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile -keepattributes SourceFile, LineNumberTable -keepnames class * extends android.app.Activity -keepnames class * extends androidx.fragment.app.Fragment -keep class * extends cn.jzvd.** { *; } -keep class com.google.android.gms.** { *; } -keep interface com.google.android.gms.** { *; } -keep,allowoptimization class is.xyz.mpv.** { public protected *; } ================================================ FILE: app/src/androidTest/java/com/yenaly/han1meviewer/ExampleInstrumentedTest.kt ================================================ package com.yenaly.han1meviewer import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 import org.junit.Test import org.junit.runner.RunWith import org.junit.Assert.* /** * Instrumented test, which will execute on an Android device. * * See [testing documentation](http://d.android.com/tools/testing). */ @RunWith(AndroidJUnit4::class) class ExampleInstrumentedTest { @Test fun useAppContext() { // Context of the app under test. val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.yenaly.han1meviewer", appContext.packageName) } } ================================================ FILE: app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: app/src/main/assets/h_keyframes/12444.json ================================================ { "videoCode": "12444", "group": "思春期SEX", "title": "思春期SEX#1", "episode": 1, "author": "NeKoOuO", "keyframes": [ { "position": 482500, "prompt": null }, { "position": 545000, "prompt": null }, { "position": 832000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/14463.json ================================================ { "videoCode": "14463", "group": "思春期SEX", "title": "思春期SEX#3", "episode": 3, "author": "NeKoOuO", "keyframes": [ { "position": 311500, "prompt": null }, { "position": 432500, "prompt": null }, { "position": 824000, "prompt": null }, { "position": 861300, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/21806.json ================================================ { "videoCode": "21806", "group": "思春期SEX", "title": "思春期SEX#4", "episode": 4, "author": "NeKoOuO", "keyframes": [ { "position": 481000, "prompt": null }, { "position": 657700, "prompt": null }, { "position": 742700, "prompt": null }, { "position": 813000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/22068.json ================================================ { "videoCode": "22068", "group": "思春期SEX", "title": "思春期SEX#2", "episode": 2, "author": "NeKoOuO", "keyframes": [ { "position": 324000, "prompt": null }, { "position": 602000, "prompt": null }, { "position": 734000, "prompt": null }, { "position": 816000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/37176.json ================================================ { "videoCode": "37176", "group": "援助交配", "title": "援助交配#1", "episode": 1, "author": "NeKoOuO", "keyframes": [ { "position": 363600, "prompt": null }, { "position": 633000, "prompt": null }, { "position": 796000, "prompt": null }, { "position": 881700, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/37177.json ================================================ { "videoCode": "37177", "group": "援助交配", "title": "援助交配#2", "episode": 2, "author": "NeKoOuO", "keyframes": [ { "position": 376000, "prompt": null }, { "position": 420000, "prompt": null }, { "position": 600000, "prompt": null }, { "position": 774000, "prompt": null }, { "position": 800000, "prompt": null }, { "position": 840000, "prompt": null }, { "position": 856500, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/37178.json ================================================ { "videoCode": "37178", "group": "援助交配", "title": "援助交配#3", "episode": 3, "author": "NeKoOuO", "keyframes": [ { "position": 239000, "prompt": null }, { "position": 307000, "prompt": null }, { "position": 439000, "prompt": null }, { "position": 641000, "prompt": null }, { "position": 820000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/37179.json ================================================ { "videoCode": "37179", "group": "援助交配", "title": "援助交配#4", "episode": 4, "author": "NeKoOuO", "keyframes": [ { "position": 36000, "prompt": null }, { "position": 480000, "prompt": null }, { "position": 570000, "prompt": null }, { "position": 655000, "prompt": null }, { "position": 800000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/37220.json ================================================ { "videoCode": "37220", "group": "今泉家似乎變成辣妹的聚會所", "title": "今泉家似乎變成辣妹的聚會所#1", "episode": 1, "author": "NeKoOuO", "keyframes": [ { "position": 265000, "prompt": null }, { "position": 403000, "prompt": null }, { "position": 493000, "prompt": null }, { "position": 540000, "prompt": null }, { "position": 604000, "prompt": null }, { "position": 725000, "prompt": null }, { "position": 769000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/37221.json ================================================ { "videoCode": "37221", "group": "今泉家似乎變成辣妹的聚會所", "title": "今泉家似乎變成辣妹的聚會所#2", "episode": 2, "author": "NeKoOuO", "keyframes": [ { "position": 278500, "prompt": null }, { "position": 403000, "prompt": null }, { "position": 510000, "prompt": null }, { "position": 627000, "prompt": null }, { "position": 836000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/38387.json ================================================ { "videoCode": "38387", "group": "援助交配", "title": "援助交配#5", "episode": 5, "author": "NeKoOuO", "keyframes": [ { "position": 335000, "prompt": null }, { "position": 652000, "prompt": null }, { "position": 817000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/38389.json ================================================ { "videoCode": "38389", "group": "闇憑村", "title": "闇憑村#1", "episode": 1, "author": "NeKoOuO", "keyframes": [ { "position": 290700, "prompt": null }, { "position": 428000, "prompt": null }, { "position": 510000, "prompt": null }, { "position": 592000, "prompt": null }, { "position": 798000, "prompt": null }, { "position": 934500, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/38457.json ================================================ { "videoCode": "38457", "group": "闇憑村", "title": "闇憑村#2", "episode": 2, "author": "NeKoOuO", "keyframes": [ { "position": 345300, "prompt": null }, { "position": 458000, "prompt": null }, { "position": 502500, "prompt": null }, { "position": 507500, "prompt": null }, { "position": 549000, "prompt": null }, { "position": 562000, "prompt": null }, { "position": 574000, "prompt": null }, { "position": 686000, "prompt": null }, { "position": 779500, "prompt": null }, { "position": 868000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/38461.json ================================================ { "videoCode": "38461", "group": "援助交配", "title": "援助交配#6", "episode": 6, "author": "NeKoOuO", "keyframes": [ { "position": 86000, "prompt": null }, { "position": 638000, "prompt": null }, { "position": 755000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/39192.json ================================================ { "videoCode": "39192", "group": "援助交配", "title": "援助交配#7", "episode": 7, "author": "NeKoOuO", "keyframes": [ { "position": 260000, "prompt": null }, { "position": 413500, "prompt": null }, { "position": 520000, "prompt": null }, { "position": 564000, "prompt": null }, { "position": 656000, "prompt": null }, { "position": 802000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/39305.json ================================================ { "videoCode": "39305", "group": "到了異世界就拿出性本事", "title": "到了異世界就拿出性本事#1", "episode": 1, "author": "NeKoOuO", "keyframes": [ { "position": 387500, "prompt": null }, { "position": 457000, "prompt": null }, { "position": 712500, "prompt": null }, { "position": 829500, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/39306.json ================================================ { "videoCode": "39306", "group": "到了異世界就拿出性本事", "title": "到了異世界就拿出性本事#2", "episode": 2, "author": "NeKoOuO", "keyframes": [ { "position": 254000, "prompt": null }, { "position": 405000, "prompt": null }, { "position": 502000, "prompt": null }, { "position": 740500, "prompt": null }, { "position": 914000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/39468.json ================================================ { "videoCode": "39468", "group": "援助交配", "title": "援助交配#8", "episode": 8, "author": "NeKoOuO", "keyframes": [ { "position": 223000, "prompt": null }, { "position": 324000, "prompt": null }, { "position": 608000, "prompt": null }, { "position": 848000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/39811.json ================================================ { "videoCode": "39811", "group": "今泉家似乎變成辣妹的聚會所", "title": "今泉家似乎變成辣妹的聚會所#4", "episode": 4, "author": "NeKoOuO", "keyframes": [ { "position": 175000, "prompt": null }, { "position": 425000, "prompt": null }, { "position": 629000, "prompt": null }, { "position": 825000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/84717.json ================================================ { "videoCode": "84717", "group": "初戀時間", "title": "初戀時間#1", "episode": 1, "author": "NeKoOuO", "keyframes": [ { "position": 72000, "prompt": null }, { "position": 427270, "prompt": null }, { "position": 499500, "prompt": null }, { "position": 650000, "prompt": null }, { "position": 840500, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/84718.json ================================================ { "videoCode": "84718", "group": "初戀時間", "title": "初戀時間#2", "episode": 2, "author": "NeKoOuO", "keyframes": [ { "position": 462000, "prompt": null }, { "position": 576500, "prompt": null }, { "position": 588000, "prompt": null }, { "position": 678500, "prompt": null }, { "position": 823430, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/85926.json ================================================ { "videoCode": "85926", "group": "初戀時間", "title": "初戀時間#3", "episode": 3, "author": "NeKoOuO", "keyframes": [ { "position": 438000, "prompt": null }, { "position": 602500, "prompt": null }, { "position": 822500, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/85927.json ================================================ { "videoCode": "85927", "group": "初戀時間", "title": "初戀時間#4", "episode": 4, "author": "NeKoOuO", "keyframes": [ { "position": 376000, "prompt": null }, { "position": 474950, "prompt": null }, { "position": 633500, "prompt": null }, { "position": 715000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/87968.json ================================================ { "videoCode": "87968", "group": "到了異世界就拿出性本事", "title": "到了異世界就拿出性本事#3", "episode": 3, "author": "NeKoOuO", "keyframes": [ { "position": 229500, "prompt": null }, { "position": 445500, "prompt": null }, { "position": 637200, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/87969.json ================================================ { "videoCode": "87969", "group": "到了異世界就拿出性本事", "title": "到了異世界就拿出性本事#4", "episode": 4, "author": "NeKoOuO", "keyframes": [ { "position": 474500, "prompt": null }, { "position": 791000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/89087.json ================================================ { "videoCode": "89087", "group": "初戀時間", "title": "初戀時間#5", "episode": 5, "author": "NeKoOuO", "keyframes": [ { "position": 482500, "prompt": null }, { "position": 500500, "prompt": null }, { "position": 556000, "prompt": null }, { "position": 777300, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/89088.json ================================================ { "videoCode": "89088", "group": "初戀時間", "title": "初戀時間#6", "episode": 6, "author": "NeKoOuO", "keyframes": [ { "position": 304000, "prompt": null }, { "position": 387000, "prompt": null }, { "position": 546000, "prompt": null }, { "position": 644000, "prompt": null }, { "position": 710000, "prompt": null }, { "position": 808000, "prompt": null } ] } ================================================ FILE: app/src/main/assets/h_keyframes/README.md ================================================ # 关键H帧 ## 何为关键H帧? 就是影片到达「**顶点**」的那一刻。 还在因为不能和影片内「顶点」同步,而不停地记着「顶点」的时刻然后看进度条卡时间同步吗? 现在你可能不需要了。如果你开启了该功能(默认开启),并且在影片内**手动标记**每一个关键H帧,它会在 5-30s 前在屏幕**左上角**倒计时提醒(可调整)。在 0-1s 时,会精确到一位小数,方便你更好的控制时间。 此外,还提供了**共享关键H帧集**。这些关键H帧是内置于软件里的,来源于贡献者在 GitHub 上的补充。目前是随着版本更新(或 CI 实时更新)来更新共享关键H帧集,暂时不考虑服务器在线共享之类的(太危险)。 [共享关键库位置](./) ## 须知 1. 中字候补(生肉,字幕未上传)时**不要**上传,因为出字幕后可能会与未出字幕前**有一定的时间差**,导致时间不准。 2. 每一个关键H帧的`prompt`尽可能短,因为太长会影响观看。 3. 两个关键H帧必须**间隔 5s 及以上**! ## 怎么共享关键H帧? > 注意:共享关键H帧是无法在程序内部修改的,只可读。 ### Fork & Clone 先把我项目 Fork 了,然后从你项目里 Clone 到本地。 fork 仓库步骤: 1. 登录GitHub账号,进入要fork的仓库页面。 2. 点击右上角的“Fork”按钮。 3. 等待一段时间后,就可以在个人的GitHub仓库中看到已经fork过来的仓库。 clone 仓库步骤: 1. 在要clone的仓库页面上找到“clone with HTTPS”或“clone with SSH”按钮,并复制HTTPS或SSH地址。 2. 在本地打开终端(或命令行界面),进入要存放仓库的文件夹。 3. 输入命令 `git clone <复制的仓库地址>`,其中`<复制的仓库地址>`替换为刚才复制的地址。 4. 等待一段时间后,就可以在本地文件夹中看到已经克隆过来的仓库。 以上步骤完成后,就可以在本地使用这个仓库了。 ### 创建文件 在该 md 文件所处的文件夹下创建一个 JSON 文件,命名为 `<影片代号>.json`。 该影片代号从哪里来呢?举个例子,你所看的番,网址是`https://hanime1.me/watch?v=37453` ,它的代号就是`v=`后面的`37453`。如果你想共享该影片的关键H帧,你需要创建名为`37453.json`的文件。 ### 了解并编写 JSON 结构 以代号为`84711`的影片为例(内容我乱填的),就按这个格式写: ```json { "videoCode": "84711", "group": "aaa", "title": "abc", "episode": 1, "author": "yenaly", "keyframes": [ { "position": 1000000, "prompt": "abc" }, { "position": 2000000, "prompt": null } ] } ``` 介绍一下每一个键值是干什么的: > 注意-1:`author`为`null`时代表个人本地储存的,不为空才代表是共享的。所以不允许 JSON 文件里出现`null`的`author`。 > > 注意-2:编写前务必查询当前已上传的关键H帧是否存在。假设有一人已上传 AAA 的第一集,group 名为`aaa`,title 为`aaa-01`,你也要按照他的方式进行修改,不要自行更改 group 名为`AAA`。如果你觉得你的命名更准确、更优质,也可以选择将其所有当前系列的group名和title名一起修改。 | 键 | 值类型 | 作用 | | --------- | ----------------- | ------------------------------------------------------------ | | videoCode | string (not null) | 影片代号,用于识别影片 | | group | string (nullable) | 影片系列名称,用于影片分组,为 null 代表无系列 | | title | string (not null) | 影片标题,看得清晰些 | | episode | number | 影片集数,如果无系列请填 0 | | author | string (not null) | 关键H帧作者,也就是你,**而不是**影片作者! | | keyframes | array | 关键H帧列表 | | position | number | 「顶点」位置,怎么获取下面说,两个 position 必须间隔 5s 及以上 | | prompt | string (nullable) | 「顶点」提示,最好少于五个字,或 null | #### 怎么获取「顶点」位置? 首先要打开关键H帧功能,然后进入该影片全屏界面,在「顶点」处暂停,长按选单栏的`🥵`按钮,会弹出一个窗口,例如: > ...... > > 当前时刻:1830ms 此时,`1830`就是你所需要填写的`position`数值。同时,你也可以在此时保存到你的个人本地关键H帧中。 ### Commit & Push 将代码提交到本地仓库和推送到远程仓库的步骤如下: commit 到本地仓库: 1. 在本地文件夹中找到要修改的代码文件。 2. 对代码进行修改、添加或删除。 3. 使用命令 `git add <文件名>` 将修改后的文件添加到暂存区,也可以使用 `git add .` 将所有修改后的文件添加到暂存区。 4. 使用命令 `git commit -m "<提交信息>"` 提交暂存区的文件到本地仓库,其中 `<提交信息>` 是本次提交的说明。 push 到远程仓库: 1. 使用命令 `git push origin <分支名>` 将当前分支推送到远程仓库,其中 `<分支名>` 是要推送的分支名称。例如,如果要将当前分支推送到远程主机的 master 分支,可以输入 `git push origin master`。 以上步骤完成后,就可以将代码从本地仓库推送到远程仓库了。 > 注意,提交信息的格式为:`[HKeyframe] 添加/修改/删除 <影片名称>` > > 简繁都行,英文也行。 > > 例如:`[HKeyframe] 添加 初恋时间系列` ### Pull Request 从我本体的 Pull Request 里提交合并请求,如果没什么大问题就合并了。 以下是Pull Request的步骤: 1. 确认分支:首先,确保你已经在本地仓库中创建了一个新的分支,并且在该分支上进行了修改。 2. 创建远程分支:将本地分支推送到远程仓库中,可以使用 `git push -u origin <分支名>` 命令,其中 `<分支名>` 是当前分支的名称。 3. 打开 GitHub 页面:在浏览器中打开目标仓库的页面,并切换到要合并的分支。 4. 创建 Pull Request:在页面上找到 “New Pull Request” 按钮,点击后会出现一个新的页面,其中包含了你推送的分支和目标仓库的信息。 5. 填写 Pull Request 信息:在新页面中,可以填写一些关于 Pull Request 的信息,例如标题、描述、标签等。这些信息可以帮助其他人更好地理解你提交的代码修改。 6. 提交 Pull Request:最后,点击 “Create Pull Request” 按钮提交 Pull Request。 7. 等待审核:一旦提交了 Pull Request,等我审核你的修改。如果审核通过,你的修改将合并到目标仓库中。 ================================================ FILE: app/src/main/assets/search_options/brands.json ================================================ [ { "name": "妄想実現めでぃあ", "search_key": "妄想実現めでぃあ" }, { "name": "メリー・ジェーン", "search_key": "メリー・ジェーン" }, { "name": "ピンクパイナップル", "search_key": "ピンクパイナップル" }, { "name": "ばにぃうぉ~か~", "search_key": "ばにぃうぉ~か~" }, { "name": "Queen Bee", "search_key": "Queen Bee" }, { "name": "PoRO", "search_key": "PoRO" }, { "name": "せるふぃっしゅ", "search_key": "せるふぃっしゅ" }, { "name": "鈴木みら乃", "search_key": "鈴木みら乃" }, { "name": "ショーテン", "search_key": "ショーテン" }, { "name": "GOLD BEAR", "search_key": "GOLD BEAR" }, { "name": "ZIZ", "search_key": "ZIZ" }, { "name": "EDGE", "search_key": "EDGE" }, { "name": "Collaboration Works", "search_key": "Collaboration Works" }, { "name": "BOOTLEG", "search_key": "BOOTLEG" }, { "name": "BOMB!CUTE!BOMB!", "search_key": "BOMB!CUTE!BOMB!" }, { "name": "nur", "search_key": "nur" }, { "name": "あんてきぬすっ", "search_key": "あんてきぬすっ" }, { "name": "魔人", "search_key": "魔人" }, { "name": "ルネ", "search_key": "ルネ" }, { "name": "Princess Sugar", "search_key": "Princess Sugar" }, { "name": "パシュミナ", "search_key": "パシュミナ" }, { "name": "WHITE BEAR", "search_key": "WHITE BEAR" }, { "name": "AniMan", "search_key": "AniMan" }, { "name": "chippai", "search_key": "chippai" }, { "name": "トップマーシャル", "search_key": "トップマーシャル" }, { "name": "erozuki", "search_key": "erozuki" }, { "name": "サークルトリビュート", "search_key": "サークルトリビュート" }, { "name": "spermation", "search_key": "spermation" }, { "name": "Milky", "search_key": "Milky" }, { "name": "King Bee", "search_key": "King Bee" }, { "name": "PashminaA", "search_key": "PashminaA" }, { "name": "じゅうしぃまんご~", "search_key": "じゅうしぃまんご~" }, { "name": "Hills", "search_key": "Hills" }, { "name": "妄想専科", "search_key": "妄想専科" }, { "name": "ディスカバリー", "search_key": "ディスカバリ���" }, { "name": "ひまじん", "search_key": "ひまじん" }, { "name": "37℃", "search_key": "37℃" }, { "name": "schoolzone", "search_key": "schoolzone" }, { "name": "GREEN BUNNY", "search_key": "GREEN BUNNY" }, { "name": "バニラ", "search_key": "バニラ" }, { "name": "L.", "search_key": "L." }, { "name": "PIXY", "search_key": "PIXY" }, { "name": "こっとんど~る", "search_key": "こっとんど~る" }, { "name": "ANIMAC", "search_key": "ANIMAC" }, { "name": "Celeb", "search_key": "Celeb" }, { "name": "MOON ROCK", "search_key": "MOON ROCK" }, { "name": "Dream", "search_key": "Dream" }, { "name": "ミンク", "search_key": "ミンク" }, { "name": "オズ・インク", "search_key": "オズ・インク" }, { "name": "サン出版", "search_key": "サン出版" }, { "name": "ポニーキャニオン", "search_key": "ポニーキャニオン" }, { "name": "わるきゅ~れ++", "search_key": "わるきゅ~れ++" }, { "name": "株式会社虎の穴", "search_key": "株式会社虎の穴" }, { "name": "エンゼルフィッシュ", "search_key": "エンゼルフィッシュ" }, { "name": "UNION-CHO", "search_key": "UNION-CHO" }, { "name": "TOHO", "search_key": "TOHO" }, { "name": "ミルクセーキ", "search_key": "ミルクセーキ" }, { "name": "2匹目のどぜう", "search_key": "2匹目のどぜう" }, { "name": "じゅうしぃまんご~", "search_key": "じゅうしぃまんご~" }, { "name": "ツクルノモリ", "search_key": "ツクルノモリ" }, { "name": "サークルトリビュート", "search_key": "サークルトリビュート" }, { "name": "トップマーシャル", "search_key": "トップマーシャル" }, { "name": "彗星社", "search_key": "彗星社" }, { "name": "ナチュラルハイ", "search_key": "ナチュラルハイ" }, { "name": "れもんは~と", "search_key": "れもんは~と" } ] ================================================ FILE: app/src/main/assets/search_options/duration.json ================================================ [ { "lang": { "zh-rCN": "全部", "en": "All", "zh-rTW": "全部" }, "search_key": null }, { "lang": { "zh-rCN": "1分钟+", "en": "1 min+", "zh-rTW": "1分鐘+" }, "search_key": "1 分鐘 +" }, { "lang": { "zh-rCN": "5分钟+", "en": "5 min+", "zh-rTW": "5分鐘+" }, "search_key": "5 分鐘 +" }, { "lang": { "zh-rCN": "10分钟+", "en": "10 min+", "zh-rTW": "10分鐘+" }, "search_key": "10 分鐘 +" }, { "lang": { "zh-rCN": "20分钟+", "en": "20 min+", "zh-rTW": "20分鐘+" }, "search_key": "20 分鐘 +" }, { "lang": { "zh-rCN": "30分钟+", "en": "30 min+", "zh-rTW": "30分鐘+" }, "search_key": "30 分鐘 +" }, { "lang": { "zh-rCN": "60分钟+", "en": "60 min+", "zh-rTW": "60分鐘+" }, "search_key": "60 分鐘 +" }, { "lang": { "zh-rCN": "0-10分钟", "en": "0-10 min", "zh-rTW": "0-10分鐘" }, "search_key": "0 - 10 分鐘" }, { "lang": { "zh-rCN": "0-20分钟", "en": "0-20 min", "zh-rTW": "0-20分鐘" }, "search_key": "0 - 20 分鐘" } ] ================================================ FILE: app/src/main/assets/search_options/genre.json ================================================ [ { "lang": { "zh-rCN": "全部", "en": "All", "zh-rTW": "全部" }, "search_key": "全部" }, { "lang": { "zh-rCN": "里番", "en": "Hentai", "zh-rTW": "裏番" }, "search_key": "裏番" }, { "lang": { "zh-rCN": "泡面番", "en": "Short Anime", "zh-rTW": "泡麵番" }, "search_key": "泡麵番" }, { "lang": { "zh-rCN": "Motion Anime", "en": "Motion Anime", "zh-rTW": "Motion Anime" }, "search_key": "Motion Anime" }, { "lang": { "zh-rCN": "3D动画", "en": "3D Animation", "zh-rTW": "3D動畫" }, "search_key": "3D動畫" }, { "lang": { "zh-rCN": "同人作品", "en": "Doujin", "zh-rTW": "同人作品" }, "search_key": "同人作品" }, { "lang": { "zh-rCN": "MMD", "en": "MMD", "zh-rTW": "MMD" }, "search_key": "MMD" }, { "lang": { "zh-rCN": "Cosplay", "en": "Cosplay", "zh-rTW": "Cosplay" }, "search_key": "Cosplay" } ] ================================================ FILE: app/src/main/assets/search_options/sort_option.json ================================================ [ { "lang": { "zh-rCN": "最新上市", "en": "New Arrival", "zh-rTW": "最新上市" }, "search_key": "最新上市" }, { "lang": { "zh-rCN": "最新上傳", "en": "New Upload", "zh-rTW": "最新上傳" }, "search_key": "最新上傳" }, { "lang": { "zh-rCN": "本日排行", "en": "Daily Ranking", "zh-rTW": "本日排行" }, "search_key": "本日排行" }, { "lang": { "zh-rCN": "本週排行", "en": "Weekly Ranking", "zh-rTW": "本週排行" }, "search_key": "本週排行" }, { "lang": { "zh-rCN": "本月排行", "en": "Monthly Ranking", "zh-rTW": "本月排行" }, "search_key": "本月排行" }, { "lang": { "zh-rCN": "观看次数", "en": "View Count", "zh-rTW": "觀看次數" }, "search_key": "觀看次數" }, { "lang": { "zh-rCN": "点赞比例", "en": "Like Proportion", "zh-rTW": "讚好比例" }, "search_key": "讚好比例" }, { "lang": { "zh-rCN": "时长最长", "en": "longest Duration", "zh-rTW": "時長最長" }, "search_key": "時長最長" }, { "lang": { "zh-rCN": "他们在看", "en": "Trending", "zh-rTW": "他們在看" }, "search_key": "他們在看" } ] ================================================ FILE: app/src/main/assets/search_options/tags.json ================================================ { "video_attributes": [ { "lang": { "zh-rCN": "无码", "en": "Uncensored", "zh-rTW": "無碼" }, "search_key": "無碼" }, { "lang": { "zh-rCN": "AI解码", "en": "AI Decoded", "zh-rTW": "AI解碼" }, "search_key": "AI解碼" }, { "lang": { "zh-rCN": "中文字幕", "en": "Chinese Subtitle", "zh-rTW": "中文字幕" }, "search_key": "中文字幕" }, { "lang": { "zh-rCN": "1080P", "en": "1080P", "zh-rTW": "1080P" }, "search_key": "1080P" }, { "lang": { "zh-rCN": "60FPS", "en": "60FPS", "zh-rTW": "60FPS" }, "search_key": "60FPS" }, { "lang": { "zh-rCN": "ASMR", "en": "ASMR", "zh-rTW": "ASMR" }, "search_key": "ASMR" }, { "lang": { "zh-rCN": "断面图", "en": "Sectional View", "zh-rTW": "斷面圖" }, "search_key": "斷面圖" } ], "character_relationships": [ { "lang": { "zh-rCN": "近亲", "en": "Incest", "zh-rTW": "近親" }, "search_key": "近親" }, { "lang": { "zh-rCN": "姐", "en": "Elder Sister", "zh-rTW": "姐" }, "search_key": "姐" }, { "lang": { "zh-rCN": "妹", "en": "Younger Sister", "zh-rTW": "妹" }, "search_key": "妹" }, { "lang": { "zh-rCN": "母", "en": "Mother", "zh-rTW": "母" }, "search_key": "母" }, { "lang": { "zh-rCN": "女儿", "en": "Daughter", "zh-rTW": "女兒" }, "search_key": "女兒" }, { "lang": { "zh-rCN": "师生", "en": "Teacher Student", "zh-rTW": "師生" }, "search_key": "師生" }, { "lang": { "zh-rCN": "情侣", "en": "Couple", "zh-rTW": "情侶" }, "search_key": "情侶" }, { "lang": { "zh-rCN": "青梅竹马", "en": "Childhood Friend", "zh-rTW": "青梅竹馬" }, "search_key": "青梅竹馬" }, { "lang": { "zh-rCN": "同事", "en": "Colleague", "zh-rTW": "同事" }, "search_key": "同事" } ], "characteristics": [ { "lang": { "zh-rCN": "JK", "zh-rTW": "JK" }, "search_key": "JK" }, { "lang": { "zh-rCN": "处女", "en": "virgin", "zh-rTW": "處女" }, "search_key": "處女" }, { "lang": { "zh-rCN": "御姐", "en": "Royal sister", "zh-rTW": "御姐" }, "search_key": "御姐" }, { "lang": { "zh-rCN": "熟女", "en": "MILF", "zh-rTW": "熟女" }, "search_key": "熟女" }, { "lang": { "zh-rCN": "人妻", "en": "wife", "zh-rTW": "人妻" }, "search_key": "人妻" }, { "lang": { "zh-rCN": "女教师", "en": "female teacher", "zh-rTW": "女教師" }, "search_key": "女教師" }, { "lang": { "zh-rCN": "男教师", "en": "male teacher ", "zh-rTW": "男教師" }, "search_key": "男教師" }, { "lang": { "zh-rCN": "女医生", "en": "female doctor", "zh-rTW": "女醫生" }, "search_key": "女醫生" }, { "lang": { "zh-rCN": "女病人", "en": "female patient", "zh-rTW": "女病人" }, "search_key": "女病人" }, { "lang": { "zh-rCN": "护士", "en": "Nurse", "zh-rTW": "護士" }, "search_key": "護士" }, { "lang": { "zh-rCN": "OL", "zh-rTW": "OL" }, "search_key": "OL" }, { "lang": { "zh-rCN": "女警", "en": "policewoman", "zh-rTW": "女警" }, "search_key": "女警" }, { "lang": { "zh-rCN": "大小姐", "en": "Miss", "zh-rTW": "大小姐" }, "search_key": "大小姐" }, { "lang": { "zh-rCN": "偶像", "en": "idol", "zh-rTW": "偶像" }, "search_key": "偶像" }, { "lang": { "zh-rCN": "女仆", "en": "maid", "zh-rTW": "女僕" }, "search_key": "女僕" }, { "lang": { "zh-rCN": "巫女", "en": "miko", "zh-rTW": "巫女" }, "search_key": "巫女" }, { "lang": { "zh-rCN": "魔女", "en": "Witch", "zh-rTW": "魔女" }, "search_key": "魔女" }, { "lang": { "zh-rCN": "修女", "en": "nun", "zh-rTW": "修女" }, "search_key": "修女" }, { "lang": { "zh-rCN": "风俗娘", "en": "custom girl", "zh-rTW": "風俗娘" }, "search_key": "風俗娘" }, { "lang": { "zh-rCN": "公主", "en": "princess", "zh-rTW": "公主" }, "search_key": "公主" }, { "lang": { "zh-rCN": "女忍者", "en": "female ninja", "zh-rTW": "女忍者" }, "search_key": "女忍者" }, { "lang": { "zh-rCN": "女战士", "en": "female warrior", "zh-rTW": "女戰士" }, "search_key": "女戰士" }, { "lang": { "zh-rCN": "女骑士", "en": "female knight", "zh-rTW": "女騎士" }, "search_key": "女騎士" }, { "lang": { "zh-rCN": "魔法少女", "en": "magical girl", "zh-rTW": "魔法少女" }, "search_key": "魔法少女" }, { "lang": { "zh-rCN": "异种族", "en": "interracial", "zh-rTW": "異種族" }, "search_key": "異種族" }, { "lang": { "zh-rCN": "天使", "en": "Angel", "zh-rTW": "天使" }, "search_key": "天使" }, { "lang": { "zh-rCN": "妖精", "en": "goblin", "zh-rTW": "妖精" }, "search_key": "妖精" }, { "lang": { "zh-rCN": "魔物娘", "en": "monster girl", "zh-rTW": "魔物娘" }, "search_key": "魔物娘" }, { "lang": { "zh-rCN": "魅魔", "en": "succubus", "zh-rTW": "魅魔" }, "search_key": "魅魔" }, { "lang": { "zh-rCN": "吸血鬼", "en": "vampire", "zh-rTW": "吸血鬼" }, "search_key": "吸血鬼" }, { "lang": { "zh-rCN": "女鬼", "en": "ghost woman", "zh-rTW": "女鬼" }, "search_key": "女鬼" }, { "lang": { "zh-rCN": "兽娘", "en": "Beast Girl", "zh-rTW": "獸娘" }, "search_key": "獸娘" }, { "lang": { "zh-rCN": "乳牛", "en": "dairy cow", "zh-rTW": "乳牛" }, "search_key": "乳牛" }, { "lang": { "zh-rCN": "机械娘", "en": "Mechanical girl", "zh-rTW": "機械娘" }, "search_key": "機械娘" }, { "lang": { "zh-rCN": "碧池", "en": "Bitike", "zh-rTW": "碧池" }, "search_key": "碧池" }, { "lang": { "zh-rCN": "痴女", "en": "Slut", "zh-rTW": "痴女" }, "search_key": "痴女" }, { "lang": { "zh-rCN": "雌小鬼", "en": "female imp", "zh-rTW": "雌小鬼" }, "search_key": "雌小鬼" }, { "lang": { "zh-rCN": "不良少女", "en": "bad girl", "zh-rTW": "不良少女" }, "search_key": "不良少女" }, { "lang": { "zh-rCN": "傲娇", "en": "Tsundere", "zh-rTW": "傲嬌" }, "search_key": "傲嬌" }, { "lang": { "zh-rCN": "病娇", "en": "yandere", "zh-rTW": "病嬌" }, "search_key": "病嬌" }, { "lang": { "zh-rCN": "无口", "en": "Mouthless", "zh-rTW": "無口" }, "search_key": "無口" }, { "lang": { "zh-rCN": "无表情", "en": "expressionless", "zh-rTW": "無表情" }, "search_key": "無表情" }, { "lang": { "zh-rCN": "眼神死", "en": "Dead eyes", "zh-rTW": "眼神死" }, "search_key": "眼神死" }, { "lang": { "zh-rCN": "正太", "en": "Shota", "zh-rTW": "正太" }, "search_key": "正太" }, { "lang": { "zh-rCN": "伪娘", "en": "femboy", "zh-rTW": "偽娘" }, "search_key": "偽娘" }, { "lang": { "zh-rCN": "扶他", "en": "Help him", "zh-rTW": "扶他" }, "search_key": "扶他" } ], "appearance_and_figure": [ { "lang": { "zh-rCN": "短发", "zh-rTW": "短髮", "en": "Short Hair" }, "search_key": "短髮" }, { "lang": { "zh-rCN": "马尾", "zh-rTW": "馬尾", "en": "Ponytail" }, "search_key": "馬尾" }, { "lang": { "zh-rCN": "双马尾", "zh-rTW": "雙馬尾", "en": "Twin Tails" }, "search_key": "雙馬尾" }, { "lang": { "zh-rCN": "巨乳", "zh-rTW": "巨乳", "en": "Large Breasts" }, "search_key": "巨乳" }, { "lang": { "zh-rCN": "乳环", "zh-rTW": "乳環", "en": "Nipple Ring" }, "search_key": "乳環" }, { "lang": { "zh-rCN": "舌环", "zh-rTW": "舌環", "en": "Tongue Ring" }, "search_key": "舌環" }, { "lang": { "zh-rCN": "贫乳", "zh-rTW": "貧乳", "en": "Small Breasts" }, "search_key": "貧乳" }, { "lang": { "zh-rCN": "黑皮肤", "zh-rTW": "黑皮膚", "en": "Dark Skin" }, "search_key": "黑皮膚" }, { "lang": { "zh-rCN": "晒痕", "zh-rTW": "曬痕", "en": "Tan Lines" }, "search_key": "曬痕" }, { "lang": { "zh-rCN": "眼镜娘", "zh-rTW": "眼鏡娘", "en": "Girl with Glasses" }, "search_key": "眼鏡娘" }, { "lang": { "zh-rCN": "兽耳", "zh-rTW": "獸耳", "en": "Animal Ears" }, "search_key": "獸耳" }, { "lang": { "zh-rCN": "尖耳朵", "zh-rTW": "尖耳朵", "en": "Pointed Ears" }, "search_key": "尖耳朵" }, { "lang": { "zh-rCN": "异色瞳", "zh-rTW": "異色瞳", "en": "Heterochromia" }, "search_key": "異色瞳" }, { "lang": { "zh-rCN": "美人痣", "zh-rTW": "美人痣", "en": "Beauty Mark" }, "search_key": "美人痣" }, { "lang": { "zh-rCN": "肌肉女", "zh-rTW": "肌肉女", "en": "Muscular Female" }, "search_key": "肌肉女" }, { "lang": { "zh-rCN": "白虎", "zh-rTW": "白虎", "en": "Hairless" }, "search_key": "白虎" }, { "lang": { "zh-rCN": "阴毛", "zh-rTW": "陰毛", "en": "Pubic Hair" }, "search_key": "陰毛" }, { "lang": { "zh-rCN": "腋毛", "zh-rTW": "腋毛", "en": "Armpit Hair" }, "search_key": "腋毛" }, { "lang": { "zh-rCN": "大屌", "zh-rTW": "大屌", "en": "Big Dick" }, "search_key": "大屌" }, { "lang": { "zh-rCN": "水手服", "zh-rTW": "水手服", "en": "Sailor Uniform" }, "search_key": "水手服" }, { "lang": { "zh-rCN": "体操服", "zh-rTW": "體操服", "en": "Gym Uniform" }, "search_key": "體操服" }, { "lang": { "zh-rCN": "泳装", "zh-rTW": "泳裝", "en": "Swimsuit" }, "search_key": "泳裝" }, { "lang": { "zh-rCN": "比基尼", "zh-rTW": "比基尼", "en": "Bikini" }, "search_key": "比基尼" }, { "lang": { "zh-rCN": "死库水", "zh-rTW": "死庫水", "en": "School Swimsuit" }, "search_key": "死庫水" }, { "lang": { "zh-rCN": "和服", "zh-rTW": "和服", "en": "Kimono" }, "search_key": "和服" }, { "lang": { "zh-rCN": "兔女郎", "zh-rTW": "兔女郎", "en": "Bunny Girl" }, "search_key": "兔女郎" }, { "lang": { "zh-rCN": "围裙", "zh-rTW": "圍裙", "en": "Apron" }, "search_key": "圍裙" }, { "lang": { "zh-rCN": "啦啦队", "zh-rTW": "啦啦隊", "en": "Cheerleader" }, "search_key": "啦啦隊" }, { "lang": { "zh-rCN": "丝袜", "zh-rTW": "絲襪", "en": "Stockings" }, "search_key": "絲襪" }, { "lang": { "zh-rCN": "吊袜带", "zh-rTW": "吊襪帶", "en": "Garter Belt" }, "search_key": "吊襪帶" }, { "lang": { "zh-rCN": "热裤", "zh-rTW": "熱褲", "en": "Short Shorts" }, "search_key": "熱褲" }, { "lang": { "zh-rCN": "迷你裙", "zh-rTW": "迷你裙", "en": "Miniskirt" }, "search_key": "迷你裙" }, { "lang": { "zh-rCN": "性感内衣", "zh-rTW": "性感內衣", "en": "Sexy Lingerie" }, "search_key": "性感內衣" }, { "lang": { "zh-rCN": "紧身衣", "zh-rTW": "緊身衣", "en": "Bodysuit" }, "search_key": "緊身衣" }, { "lang": { "zh-rCN": "丁字裤", "zh-rTW": "丁字褲", "en": "Thong" }, "search_key": "丁字褲" }, { "lang": { "zh-rCN": "高跟鞋", "zh-rTW": "高跟鞋", "en": "High Heels" }, "search_key": "高跟鞋" }, { "lang": { "zh-rCN": "婚纱", "zh-rTW": "婚紗", "en": "Wedding Dress" }, "search_key": "婚紗" }, { "lang": { "zh-rCN": "旗袍", "zh-rTW": "旗袍", "en": "Cheongsam" }, "search_key": "旗袍" }, { "lang": { "zh-rCN": "古装", "zh-rTW": "古裝", "en": "Traditional Chinese Clothing" }, "search_key": "古裝" }, { "lang": { "zh-rCN": "哥德萝莉塔", "zh-rTW": "哥德蘿莉塔", "en": "Gothic Lolita" }, "search_key": "哥德蘿莉塔" }, { "lang": { "zh-rCN": "口罩", "zh-rTW": "口罩", "en": "Mask" }, "search_key": "口罩" }, { "lang": { "zh-rCN": "刺青", "zh-rTW": "刺青", "en": "Tattoo" }, "search_key": "刺青" }, { "lang": { "zh-rCN": "淫纹", "zh-rTW": "淫紋", "en": "Lewd Tattoo" }, "search_key": "淫紋" }, { "lang": { "zh-rCN": "身体写字", "zh-rTW": "身體寫字", "en": "Body Writing" }, "search_key": "身體寫字" } ], "story_plot": [ { "lang": { "zh-rCN": "纯爱", "en": "pure love", "zh-rTW": "純愛" }, "search_key": "纯爱" }, { "lang": { "zh-rCN": "恋爱喜剧", "en": "romantic comedy", "zh-rTW": "戀愛喜劇" }, "search_key": "恋爱喜剧" }, { "lang": { "zh-rCN": "后宫", "en": "harem", "zh-rTW": "後宮" }, "search_key": "后宫" }, { "lang": { "zh-rCN": "开大车", "en": "drive big", "zh-rTW": "開大車" }, "search_key": "开大车" }, { "lang": { "zh-rCN": "校园", "en": "campus", "zh-rTW": "校園" }, "search_key": "校园" }, { "lang": { "zh-rCN": "教室", "en": "classroom", "zh-rTW": "教室" }, "search_key": "教室" }, { "lang": { "zh-rCN": "公众场合", "en": "public places", "zh-rTW": "公眾場合" }, "search_key": "公众场合" }, { "lang": { "zh-rCN": "公共厕所", "en": "public toilet", "zh-rTW": "公共廁所" }, "search_key": "公共厕所" }, { "lang": { "zh-rCN": "NTR", "zh-rTW": "NTR" }, "search_key": "NTR" }, { "lang": { "zh-rCN": "精神控制", "en": "mind control", "zh-rTW": "精神控制" }, "search_key": "精神控制" }, { "lang": { "zh-rCN": "药物", "en": "drug", "zh-rTW": "藥物" }, "search_key": "药物" }, { "lang": { "zh-rCN": "痴汉", "en": "Idiot", "zh-rTW": "痴漢" }, "search_key": "痴汉" }, { "lang": { "zh-rCN": "阿嘿颜", "en": "orgasm face", "zh-rTW": "阿嘿顏" }, "search_key": "阿嘿颜" }, { "lang": { "zh-rCN": "精神崩溃", "en": "nervous breakdown", "zh-rTW": "精神崩潰" }, "search_key": "精神崩溃" }, { "lang": { "zh-rCN": "猎奇", "en": "Curiosity", "zh-rTW": "獵奇" }, "search_key": "猎奇" }, { "lang": { "zh-rCN": "BDSM", "zh-rTW": "BDSM" }, "search_key": "BDSM" }, { "lang": { "zh-rCN": "捆绑", "en": "bundle", "zh-rTW": "綑綁" }, "search_key": "捆绑" }, { "lang": { "zh-rCN": "眼罩", "en": "blindfold", "zh-rTW": "眼罩" }, "search_key": "眼罩" }, { "lang": { "zh-rCN": "项圈", "en": "collar", "zh-rTW": "項圈" }, "search_key": "项圈" }, { "lang": { "zh-rCN": "调教", "en": "training", "zh-rTW": "調教" }, "search_key": "调教" }, { "lang": { "zh-rCN": "异物插入", "en": "Foreign body insertion", "zh-rTW": "異物插入" }, "search_key": "异物插入" }, { "lang": { "zh-rCN": "寻欢洞", "en": "glory hole", "zh-rTW": "尋歡洞" }, "search_key": "寻欢洞" }, { "lang": { "zh-rCN": "肉便器", "en": "meat toilet", "zh-rTW": "肉便器" }, "search_key": "肉便器" }, { "lang": { "zh-rCN": "性奴隶", "en": "slave", "zh-rTW": "性奴隸" }, "search_key": "性奴隶" }, { "lang": { "zh-rCN": "胃凸", "en": "Stomach protrusion", "zh-rTW": "胃凸" }, "search_key": "胃凸" }, { "lang": { "zh-rCN": "强制", "en": "forced", "zh-rTW": "強制" }, "search_key": "强制" }, { "lang": { "zh-rCN": "轮奸", "en": "gang rape", "zh-rTW": "輪姦" }, "search_key": "轮奸" }, { "lang": { "zh-rCN": "凌辱", "en": "insult", "zh-rTW": "凌辱" }, "search_key": "凌辱" }, { "lang": { "zh-rCN": "扯头发", "en": "pull hair", "zh-rTW": "扯頭髮" }, "search_key": "扯头发" }, { "lang": { "zh-rCN": "打屁股", "en": "spanking", "zh-rTW": "打屁股" }, "search_key": "打屁股" }, { "lang": { "zh-rCN": "肉棒打脸", "en": "Cock slapping face", "zh-rTW": "肉棒打臉" }, "search_key": "肉棒打脸" }, { "lang": { "zh-rCN": "性暴力", "en": "sexual violence", "zh-rTW": "性暴力" }, "search_key": "性暴力" }, { "lang": { "zh-rCN": "逆强制", "en": "Counter coercion", "zh-rTW": "逆強制" }, "search_key": "逆强制" }, { "lang": { "zh-rCN": "女王样", "en": "Queenlike", "zh-rTW": "女王樣" }, "search_key": "女王样" }, { "lang": { "zh-rCN": "母女丼", "en": "Mother and Daughter Donburi", "zh-rTW": "母女丼" }, "search_key": "母女丼" }, { "lang": { "zh-rCN": "姐妹丼", "en": "Sisters' Donburi", "zh-rTW": "姐妹丼" }, "search_key": "姐妹丼" }, { "lang": { "zh-rCN": "出轨", "en": "Cheating", "zh-rTW": "出軌" }, "search_key": "出轨" }, { "lang": { "zh-rCN": "醉酒", "en": "Drunk", "zh-rTW": "醉酒" }, "search_key": "醉酒" }, { "lang": { "zh-rCN": "摄影", "en": "photography", "zh-rTW": "攝影" }, "search_key": "摄影" }, { "lang": { "zh-rCN": "睡眠奸", "en": "sleep rape", "zh-rTW": "睡眠姦" }, "search_key": "睡眠奸" }, { "lang": { "zh-rCN": "机械奸", "en": "Mechanical rape", "zh-rTW": "機械姦" }, "search_key": "机械奸" }, { "lang": { "zh-rCN": "虫奸", "en": "Insect rape", "zh-rTW": "蟲姦" }, "search_key": "虫奸" }, { "lang": { "zh-rCN": "性转换", "en": "sexual conversion", "zh-rTW": "性轉換" }, "search_key": "性转换" }, { "lang": { "zh-rCN": "百合", "en": "lily", "zh-rTW": "百合" }, "search_key": "百合" }, { "lang": { "zh-rCN": "耽美", "en": "BL", "zh-rTW": "耽美" }, "search_key": "耽美" }, { "lang": { "zh-rCN": "时间停止", "en": "time stop", "zh-rTW": "時間停止" }, "search_key": "时间停止" }, { "lang": { "zh-rCN": "异世界", "en": "Another World", "zh-rTW": "異世界" }, "search_key": "异世界" }, { "lang": { "zh-rCN": "怪兽", "en": "monster", "zh-rTW": "怪獸" }, "search_key": "怪兽" }, { "lang": { "zh-rCN": "哥布林", "en": "Goblin", "zh-rTW": "哥布林" }, "search_key": "哥布林" }, { "lang": { "zh-rCN": "世界末日", "en": "end of the world", "zh-rTW": "世界末日" }, "search_key": "世界末日" } ], "sex_positions": [ { "lang": { "zh-rCN": "手交", "en": "handjob", "zh-rTW": "手交" }, "search_key": "手交" }, { "lang": { "zh-rCN": "指交", "en": "fingering", "zh-rTW": "指交" }, "search_key": "指交" }, { "lang": { "zh-rCN": "乳交", "en": "Titjob", "zh-rTW": "乳交" }, "search_key": "乳交" }, { "lang": { "zh-rCN": "乳头交", "en": "mammary intercourse", "zh-rTW": "乳頭交" }, "search_key": "乳頭交" }, { "lang": { "zh-rCN": "肛交", "en": "anal", "zh-rTW": "肛交" }, "search_key": "肛交" }, { "lang": { "zh-rCN": "双洞齐下", "en": "Double holes", "zh-rTW": "雙洞齊下" }, "search_key": "雙洞齊下" }, { "lang": { "zh-rCN": "脚交", "en": "footjob", "zh-rTW": "腳交" }, "search_key": "腳交" }, { "lang": { "zh-rCN": "素股", "en": "Plain stocks", "zh-rTW": "素股" }, "search_key": "素股" }, { "lang": { "zh-rCN": "拳交", "en": "fisting", "zh-rTW": "拳交" }, "search_key": "拳交" }, { "lang": { "zh-rCN": "3P", "zh-rTW": "3P" }, "search_key": "3P" }, { "lang": { "zh-rCN": "群交", "en": "Group sex", "zh-rTW": "群交" }, "search_key": "群交" }, { "lang": { "zh-rCN": "口交", "en": "oral sex", "zh-rTW": "口交" }, "search_key": "口交" }, { "lang": { "zh-rCN": "深喉咙", "en": "Deep Throat", "zh-rTW": "深喉嚨" }, "search_key": "深喉嚨" }, { "lang": { "zh-rCN": "口爆", "en": "oral sex", "zh-rTW": "口爆" }, "search_key": "口爆" }, { "lang": { "zh-rCN": "吞精", "en": "swallow semen", "zh-rTW": "吞精" }, "search_key": "吞精" }, { "lang": { "zh-rCN": "舔蛋蛋", "en": "Licking balls", "zh-rTW": "舔蛋蛋" }, "search_key": "舔蛋蛋" }, { "lang": { "zh-rCN": "舔穴", "en": "Licking pussy", "zh-rTW": "舔穴" }, "search_key": "舔穴" }, { "lang": { "zh-rCN": "69", "zh-rTW": "69" }, "search_key": "69" }, { "lang": { "zh-rCN": "自慰", "en": "masturbate", "zh-rTW": "自慰" }, "search_key": "自慰" }, { "lang": { "zh-rCN": "腋交", "en": "armpit sex", "zh-rTW": "腋交" }, "search_key": "腋交" }, { "lang": { "zh-rCN": "舔腋下", "en": "lick armpits", "zh-rTW": "舔腋下" }, "search_key": "舔腋下" }, { "lang": { "zh-rCN": "发交", "en": "Send", "zh-rTW": "髮交" }, "search_key": "髮交" }, { "lang": { "zh-rCN": "舔耳朵", "en": "Licking ears", "zh-rTW": "舔耳朵" }, "search_key": "舔耳朵" }, { "lang": { "zh-rCN": "内射", "en": "Creampie", "zh-rTW": "內射" }, "search_key": "內射" }, { "lang": { "zh-rCN": "外射", "en": "ejaculate externally", "zh-rTW": "外射" }, "search_key": "外射" }, { "lang": { "zh-rCN": "颜射", "en": "Facial cumshot", "zh-rTW": "顏射" }, "search_key": "顏射" }, { "lang": { "zh-rCN": "潮吹", "en": "squirt", "zh-rTW": "潮吹" }, "search_key": "潮吹" }, { "lang": { "zh-rCN": "怀孕", "en": "pregnant", "zh-rTW": "懷孕" }, "search_key": "懷孕" }, { "lang": { "zh-rCN": "喷奶", "en": "Squirt", "zh-rTW": "噴奶" }, "search_key": "噴奶" }, { "lang": { "zh-rCN": "放尿", "en": "urinate", "zh-rTW": "放尿" }, "search_key": "放尿" }, { "lang": { "zh-rCN": "排便", "en": "Defecation", "zh-rTW": "排便" }, "search_key": "排便" }, { "lang": { "zh-rCN": "骑乘位", "en": "riding", "zh-rTW": "騎乘位" }, "search_key": "騎乘位" }, { "lang": { "zh-rCN": "背后位", "en": "Behind back", "zh-rTW": "背後位" }, "search_key": "背後位" }, { "lang": { "zh-rCN": "颜面骑乘", "en": "Facesitting", "zh-rTW": "顏面騎乘" }, "search_key": "顏面騎乘" }, { "lang": { "zh-rCN": "火车便当", "en": "train lunch", "zh-rTW": "火車便當" }, "search_key": "火車便當" }, { "lang": { "zh-rCN": "车震", "en": "car shock", "zh-rTW": "車震" }, "search_key": "車震" }, { "lang": { "zh-rCN": "性玩具", "en": "sex toys", "zh-rTW": "性玩具" }, "search_key": "性玩具" }, { "lang": { "zh-rCN": "飞机杯", "en": "airplane cup", "zh-rTW": "飛機杯" }, "search_key": "飛機杯" }, { "lang": { "zh-rCN": "跳蛋", "en": "Vibrator", "zh-rTW": "跳蛋" }, "search_key": "跳蛋" }, { "lang": { "zh-rCN": "毒龙钻", "en": "Poison Dragon Diamond", "zh-rTW": "毒龍鑽" }, "search_key": "毒龍鑽" }, { "lang": { "zh-rCN": "触手", "en": "tentacle", "zh-rTW": "觸手" }, "search_key": "觸手" }, { "lang": { "zh-rCN": "兽交", "en": "bestiality", "zh-rTW": "獸交" }, "search_key": "獸交" }, { "lang": { "zh-rCN": "颈手枷", "en": "pillory", "zh-rTW": "頸手枷" }, "search_key": "頸手枷" }, { "lang": { "zh-rCN": "着衣", "en": "dress", "zh-rTW": "著衣" }, "search_key": "著衣" }, { "lang": { "zh-rCN": "阴道外翻", "en": "vaginal eversion", "zh-rTW": "陰道外翻" }, "search_key": "陰道外翻" }, { "lang": { "zh-rCN": "接吻", "en": "kiss", "zh-rTW": "接吻" }, "search_key": "接吻" }, { "lang": { "zh-rCN": "舌吻", "en": "French kiss", "zh-rTW": "舌吻" }, "search_key": "舌吻" }, { "lang": { "zh-rCN": "POV", "zh-rTW": "POV" }, "search_key": "POV" } ] } ================================================ FILE: app/src/main/assets/shaders/Anime4K_AutoDownscalePre_x2.glsl ================================================ // This is free and unencumbered software released into the public domain. // Anyone is free to copy, modify, publish, use, compile, sell, or // distribute this software, either in source code form or as a compiled // binary, for any purpose, commercial or non-commercial, and by any // means. // In jurisdictions that recognize copyright laws, the author or authors // of this software dedicate any and all copyright interest in the // software to the public domain. We make this dedication for the benefit // of the public at large and to the detriment of our heirs and // successors. We intend this dedication to be an overt act of // relinquishment in perpetuity of all present and future rights to this // software under copyright law. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // For more information, please refer to //!DESC Anime4K-v4.0-AutoDownscalePre-x2 //!HOOK MAIN //!BIND HOOKED //!BIND NATIVE //!WHEN OUTPUT.w NATIVE.w / 2.0 < OUTPUT.h NATIVE.h / 2.0 < * OUTPUT.w NATIVE.w / 1.2 > OUTPUT.h NATIVE.h / 1.2 > * * //!WIDTH OUTPUT.w //!HEIGHT OUTPUT.h vec4 hook() { return HOOKED_tex(HOOKED_pos); } ================================================ FILE: app/src/main/assets/shaders/Anime4K_AutoDownscalePre_x4.glsl ================================================ // This is free and unencumbered software released into the public domain. // Anyone is free to copy, modify, publish, use, compile, sell, or // distribute this software, either in source code form or as a compiled // binary, for any purpose, commercial or non-commercial, and by any // means. // In jurisdictions that recognize copyright laws, the author or authors // of this software dedicate any and all copyright interest in the // software to the public domain. We make this dedication for the benefit // of the public at large and to the detriment of our heirs and // successors. We intend this dedication to be an overt act of // relinquishment in perpetuity of all present and future rights to this // software under copyright law. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // For more information, please refer to //!DESC Anime4K-v3.2-AutoDownscalePre-x4 //!HOOK MAIN //!BIND HOOKED //!BIND NATIVE //!WHEN OUTPUT.w NATIVE.w / 4.0 < OUTPUT.h NATIVE.h / 4.0 < * OUTPUT.w NATIVE.w / 2.4 > OUTPUT.h NATIVE.h / 2.4 > * * //!WIDTH OUTPUT.w 2 / //!HEIGHT OUTPUT.h 2 / vec4 hook() { return HOOKED_tex(HOOKED_pos); } ================================================ FILE: app/src/main/assets/shaders/Anime4K_Clamp_Highlights.glsl ================================================ // MIT License // Copyright (c) 2019-2021 bloc97 // All rights reserved. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //!DESC Anime4K-v4.0-De-Ring-Compute-Statistics //!HOOK MAIN //!BIND HOOKED //!SAVE STATSMAX //!COMPONENTS 1 #define KERNELSIZE 5 //Kernel size, must be an positive odd integer. #define KERNELHALFSIZE 2 //Half of the kernel size without remainder. Must be equal to trunc(KERNELSIZE/2). float get_luma(vec4 rgba) { return dot(vec4(0.299, 0.587, 0.114, 0.0), rgba); } vec4 hook() { float gmax = 0.0; for (int i=0; iRGB matrix has 1 for every row... (which is the case for BT.709) //Otherwise we would need to convert RGB to YUV, modify Y then convert back to RGB. return HOOKED_tex(HOOKED_pos) - (current_luma - new_luma); } ================================================ FILE: app/src/main/assets/shaders/Anime4K_Restore_CNN_M.glsl ================================================ // MIT License // Copyright (c) 2019-2021 bloc97 // All rights reserved. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //!DESC Anime4K-v4.0-Restore-CNN-(M)-Conv-4x3x3x3 //!HOOK MAIN //!BIND MAIN //!SAVE conv2d_tf //!WIDTH MAIN.w //!HEIGHT MAIN.h //!COMPONENTS 4 #define go_0(x_off, y_off) (MAIN_texOff(vec2(x_off, y_off))) vec4 hook() { vec4 result = mat4(-0.09991986, 0.13782342, -0.031251684, -0.06356843, -0.3437488, 0.05450952, 0.34347802, 0.46335372, 0.08607224, 0.044988394, 0.137179, 0.17976908, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, -1.0); result += mat4(-0.024212424, -0.09278509, -0.00040907756, 0.34552294, -0.13254678, 0.113105185, 0.005667946, -0.00036919137, -0.06375679, 0.009184115, 0.115518734, -0.115506776, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 0.0); result += mat4(-0.14101827, 0.023523493, 0.044094566, -0.019271746, -0.44348842, -0.08818877, -0.4026149, -0.21995795, -0.15880394, -0.013732858, -0.020751135, 0.012719151, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 1.0); result += mat4(0.013001821, -0.34503505, 0.39219138, 0.18792126, 0.24760444, -0.016173402, 0.10154511, 0.15453082, -0.058132876, 0.016784398, -0.05808539, -0.11039915, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, -1.0); result += mat4(0.37024534, 0.041440863, -0.3374568, -0.44994286, 0.19555596, 0.20855539, -0.27974075, -0.5372628, 0.21228147, -0.0295346, -0.56700057, 0.030042822, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 0.0); result += mat4(-0.12940632, 0.057526, 0.090682045, -0.06985033, -0.13704006, -0.047685407, 0.44615674, -0.48056605, -0.06166251, -0.01883519, 0.2032237, -0.113287605, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 1.0); result += mat4(0.010856669, -0.35820737, 0.16757219, 0.082619876, -0.03967303, 0.038705572, 0.32652855, -0.012030017, 0.015120559, -0.15314877, 0.23442009, 0.09767922, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, -1.0); result += mat4(-0.046272673, -0.17752305, 0.082018286, -0.2512824, 0.58619463, -0.060903464, -0.022793597, 0.077803515, -0.17025311, 0.05136993, 0.029383298, -0.15475409, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 0.0); result += mat4(-0.11212024, 0.13378005, -0.2027488, 0.08056421, -0.11176219, -0.048429377, -0.08396386, 0.10507829, 0.13326839, 0.0430627, 0.051362377, 0.06482755, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 1.0); result += vec4(-0.061233472, 0.39222646, 0.029704979, 0.02586828); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(M)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_tf //!SAVE conv2d_1_tf //!WIDTH conv2d_tf.w //!HEIGHT conv2d_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.16410656, -0.40521824, 0.13121907, -0.02314597, 0.105412476, -0.060401272, -0.043063477, -0.13933973, 0.12558138, -0.020861467, 0.030370515, 0.13178016, -0.14220351, 0.20736893, 0.003321564, -0.29241714) * go_0(-1.0, -1.0); result += mat4(0.18517321, 0.29162985, -0.26783395, 0.039760686, 0.025527012, -0.067319244, 0.055004176, 0.048916563, 0.12750523, -0.091435954, 0.13818842, 0.36704224, 0.0839921, 0.10186618, -0.17237376, 0.13282418) * go_0(-1.0, 0.0); result += mat4(-0.1657887, 0.0131325135, -0.17222486, 0.091398895, -0.12756164, -0.08437298, -0.29052997, 0.3269337, 0.15870757, -0.013529402, -0.0581753, 0.11802371, 0.07099966, -0.024063632, 0.31834844, -0.11183859) * go_0(-1.0, 1.0); result += mat4(0.46036887, -0.07654623, 0.22923063, 0.17463821, 0.10555414, -0.117430426, 0.12406777, -0.011399492, 0.028316498, 0.13684341, 0.009664087, 0.2022659, 0.04953974, -0.31342217, -0.6103131, -0.13605757) * go_0(0.0, -1.0); result += mat4(0.03406955, -0.39819366, 0.61176, -0.46809456, -0.029321073, 0.46619493, 0.36700186, 0.02288561, 0.11464085, -0.10931452, -0.09154022, 0.07334147, -0.5609916, 0.31826234, -0.011012659, -0.46719545) * go_0(0.0, 0.0); result += mat4(-0.056855045, 0.27037027, -0.09269696, -0.563572, -0.06816116, -0.22986612, 0.08693167, -0.16246101, 0.09954046, -0.05374176, 0.0071916827, -0.1788692, 0.3825241, -0.1609887, 0.055204768, 0.10213068) * go_0(0.0, 1.0); result += mat4(0.0646626, 0.102358796, -0.45055822, 0.20557903, -0.23337309, 0.12633002, -0.19299199, -0.15085731, -0.13473304, 0.053790465, -0.10061193, -0.13393497, -0.04264752, -0.029740738, -0.07865285, 0.20883279) * go_0(1.0, -1.0); result += mat4(0.010471527, -0.033218473, -0.46157447, 0.004866583, 0.23226471, -0.059343327, -0.1439596, 0.13619648, 0.013839963, 0.15930325, 0.043742355, 0.17467323, 0.33772305, 0.40261495, -0.08351293, 0.18129359) * go_0(1.0, 0.0); result += mat4(-0.12493434, -0.1875134, -0.074943796, -0.0031701606, -0.037142616, 0.1667002, 0.16665547, -0.011248127, 0.0071619414, 0.0034872112, 0.120318964, -0.09625579, 0.14917047, -0.16310586, 0.07231737, 0.30447328) * go_0(1.0, 1.0); result += mat4(0.093798615, 0.17074613, -0.08780678, -0.012520207, 0.118534856, 0.027508778, -0.2778478, -0.19509242, -0.34137097, 0.32000312, -0.22027159, 0.337515, 0.16220862, 0.108993016, 0.14070526, 0.12784284) * go_1(-1.0, -1.0); result += mat4(-0.14325632, -0.1467453, -0.27502358, 0.09370837, 0.11821083, -0.012266484, -0.2100548, 0.4707502, -0.06766648, 0.58165014, -0.2512279, -0.33783755, 0.1318925, -0.04346277, 0.15454485, 0.044500057) * go_1(-1.0, 0.0); result += mat4(-0.05683207, 0.0051946463, -0.108000524, 0.10133204, -0.50763863, 0.007308442, 0.8542404, 0.28387356, 0.022709515, 0.294523, -0.3822472, 0.66166407, 0.01404485, 0.031282708, -0.26756814, -0.123147786) * go_1(-1.0, 1.0); result += mat4(-0.36455178, 0.3470555, -0.045303088, -0.03170764, -0.15802494, -0.0019141496, -0.25939587, -0.23875342, 0.130428, 0.03954273, -0.17985536, 0.105145946, 0.15804817, 0.12551713, 0.28371975, -0.085748516) * go_1(0.0, -1.0); result += mat4(0.0060625463, 0.2443924, -0.017692259, -0.20214005, -0.09584515, -0.012805372, -0.13942227, 0.16143198, 0.12942013, 0.41785547, 0.046071563, 0.7030026, 0.10499644, -0.20566013, -0.031321276, 0.27830327) * go_1(0.0, 0.0); result += mat4(-0.081274964, -0.14562319, 0.27200526, -0.20491314, 0.012910989, 0.024201397, 0.04816258, 0.21297328, -0.22015952, -0.44160756, -0.056035373, 0.33824417, -0.31645304, 0.15469243, 0.053187452, -0.20989445) * go_1(0.0, 1.0); result += mat4(-0.046550367, 0.033185404, 0.33337244, 0.12853645, 0.23520172, -0.05909214, 0.0861368, 0.10706329, -0.07058717, -0.11759937, -0.18594047, 0.080006264, -0.055425353, -0.12506317, 0.15729053, -0.0915004) * go_1(1.0, -1.0); result += mat4(0.042516407, 0.14844789, 0.16533111, 0.13502933, -0.0655417, -0.057256397, 0.076713726, -0.23448966, 0.12855926, 0.014219275, 0.051761385, 0.053433083, -0.2446715, -0.4008074, 0.19603717, -0.1796951) * go_1(1.0, 0.0); result += mat4(0.14777803, 0.15524907, 0.043158617, -0.06996876, 0.19210646, -0.2144364, -0.47020787, -0.4207906, -0.18074386, -0.2163903, 0.0030754965, 0.36799973, -0.3837698, -0.0022661497, -0.37276733, -0.28934997) * go_1(1.0, 1.0); result += vec4(-0.018297346, -0.080951825, -0.062163066, -0.08050014); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(M)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_1_tf //!SAVE conv2d_2_tf //!WIDTH conv2d_1_tf.w //!HEIGHT conv2d_1_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.31543177, 0.23095237, -0.06692611, -0.5867763, 0.003622504, 0.17948842, -0.14627707, 0.1745016, -0.052964583, -0.15551159, 0.05644786, -0.012665164, 0.13107763, 0.11369179, -0.09452995, -0.11973403) * go_0(-1.0, -1.0); result += mat4(-0.2694661, -0.115382135, 0.3073268, -0.067228466, -0.25511482, -0.13922207, 0.36758214, -0.18821828, -0.022617863, 0.20333402, -0.11125889, 0.3552245, -0.013346653, -0.099095374, -0.25100616, 0.35521755) * go_0(-1.0, 0.0); result += mat4(0.011012409, -0.13675085, 0.25642, -0.34851208, -0.23184675, 0.18012202, 0.57654136, 0.103173524, -0.16461405, 0.038177088, 0.1234096, 0.013202029, -0.19033363, 0.07469178, -0.017948546, 0.15287702) * go_0(-1.0, 1.0); result += mat4(-0.05340533, 0.23797482, 0.20351392, -0.05333351, -0.12181174, -0.23363493, -0.20696607, 0.109941036, -0.11519453, 0.13842066, -0.10687832, 0.29040006, 0.022218632, 0.031238724, 0.2685182, 0.15300068) * go_0(0.0, -1.0); result += mat4(0.22985318, -0.3103802, -0.22916415, 0.25238806, -0.11690287, -0.1947488, 0.118020535, 0.07814263, -0.06335474, -0.007870727, 0.076106325, 0.094677486, -0.16776285, -0.006570437, -0.29589584, 0.41413507) * go_0(0.0, 0.0); result += mat4(0.43607962, -0.36456433, -0.123776875, -0.16634953, -0.091190875, 0.13035081, 0.28627968, 0.27249968, 0.12356344, -0.008616177, 0.09599816, -0.006144557, -0.23490307, 0.3013123, 0.14153156, 0.21837278) * go_0(0.0, 1.0); result += mat4(0.060364585, 0.37860224, 0.039182413, -0.22805426, -0.089910224, -0.06817697, -0.2684275, -0.12528503, 0.036934495, -0.07826616, 0.06559976, -0.08253646, 0.13489649, 0.06237663, 0.126376, 0.21194184) * go_0(1.0, -1.0); result += mat4(-0.12534817, 0.21225189, -0.27818045, -0.3070443, -0.006957577, -0.025105853, 0.12100924, -0.06916452, 0.23081483, 0.1802756, -0.18995638, 0.16603014, -0.2904096, -0.25292823, -0.21834068, 0.13719653) * go_0(1.0, 0.0); result += mat4(0.017209655, 0.10757137, 0.21414296, -0.30885983, 0.10467716, -0.2184891, 0.100061476, -0.1527528, 0.2100472, -0.25768545, -0.22329919, -0.29153427, -0.06983842, -0.103854865, -0.051384352, 0.14629121) * go_0(1.0, 1.0); result += mat4(0.0059623295, -0.26060802, 0.32115817, 0.021025505, 0.09783085, -0.15865178, 0.1473021, -0.24977303, -0.033508282, 0.17480391, -0.091310136, 0.09870876, 0.10504043, -0.06105686, 0.013493489, -0.11278855) * go_1(-1.0, -1.0); result += mat4(0.14875248, -0.14859414, 0.19377062, -0.17456068, 0.101288855, -0.1113682, -0.48944646, 0.1018565, -0.037392337, 0.08539691, 0.1751306, -0.15428723, -0.059375558, 0.027663672, 0.051804014, -0.049813222) * go_1(-1.0, 0.0); result += mat4(0.118846565, -0.19869871, -0.037388258, 0.08456728, -0.11662527, -0.43818352, -0.093285345, 0.038507205, -0.051991668, 0.21008292, 0.10792365, 0.2020924, 0.057021596, 0.09460527, 0.0016551288, -0.0015957063) * go_1(-1.0, 1.0); result += mat4(0.11062174, -0.2639232, -0.060295466, -0.3217331, -0.050545212, 0.30989558, 0.30906132, 0.030323273, 0.028986752, 0.037429404, 0.20855664, -0.19848943, 0.034687653, -0.09599135, -0.06250494, -0.13215867) * go_1(0.0, -1.0); result += mat4(-0.010391146, 0.07657845, 0.44491258, 0.0435906, 0.0075931503, 0.42632654, 0.47022533, 0.34737435, -0.15452717, -0.14613411, -0.45231065, 0.12094409, 0.0067911847, 0.057501152, 0.09876979, 0.044946447) * go_1(0.0, 0.0); result += mat4(-0.15607435, 0.2293058, -0.09520331, 0.012836732, -0.15282455, 0.26437718, -0.1685477, -0.13211122, -0.055801593, -0.016778728, -0.34478986, -0.23228309, 0.12300962, -0.13235827, -0.13987203, -0.16550972) * go_1(0.0, 1.0); result += mat4(0.13161735, -0.09039346, -0.033475474, -0.23686698, 0.1514885, 0.20977421, 0.031431954, -0.0049226107, 0.090661936, 0.15288061, -0.03316583, 0.09646573, -0.32651708, 0.18825398, -0.15777239, 0.17572704) * go_1(1.0, -1.0); result += mat4(0.112157226, -0.08712878, 0.23453182, 0.1043877, -0.14686783, 0.28682423, -0.086443506, 0.059457052, -0.31530112, -0.2700583, -0.06028952, -0.070416875, 0.18053482, 0.16653341, 0.25215197, 0.061915852) * go_1(1.0, 0.0); result += mat4(-0.20122242, 0.076313145, -0.0988483, 0.094337784, -0.35436687, 0.3762327, -0.07809558, 0.3055848, 0.10425242, -0.17087407, 0.030301496, -0.13911743, 0.01630275, 0.24247427, -0.006474477, 0.03842641) * go_1(1.0, 1.0); result += vec4(-0.008952847, -0.0058945753, -0.08097229, 0.020968592); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(M)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_2_tf //!SAVE conv2d_3_tf //!WIDTH conv2d_2_tf.w //!HEIGHT conv2d_2_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.2237721, -0.0064096362, -0.31808427, 0.73477733, 0.015353088, 0.23983319, 0.14967978, -0.34920225, -0.07456269, 0.093151815, -0.14331086, -0.24586205, -0.14183366, 0.06401045, -0.22044073, 0.29932275) * go_0(-1.0, -1.0); result += mat4(-0.07968509, -0.3349146, 0.16529128, 0.08443499, 0.4095855, -0.17120704, 0.17425705, 0.15298946, 0.2981273, 0.2212369, 0.10392389, -0.28775454, -0.065247655, -0.15255849, 0.13094437, 0.18685219) * go_0(-1.0, 0.0); result += mat4(0.015706737, -0.17755036, 0.2622526, 0.112057306, -0.15876788, -0.38466996, -0.33700845, -0.031711742, -0.023320962, -0.3145249, -0.21223734, -0.1314596, -0.1888095, -0.046370104, 0.09000896, -0.0046378844) * go_0(-1.0, 1.0); result += mat4(-0.31127506, 0.31304324, -0.03965752, 0.03649018, -0.029851055, 0.05801377, 0.00040150844, -0.04422069, 0.18019931, 0.14415511, -0.09845236, 0.21895434, -0.013932474, -0.046454947, -0.3403935, -0.006705289) * go_0(0.0, -1.0); result += mat4(-0.34878647, -0.5129283, 0.060250953, -0.16354133, 0.20644619, 0.08732273, -0.24118888, 0.24455065, 0.24449423, 0.44103387, 0.22455928, 0.25738943, -0.26914698, -0.21309987, 0.08386486, 0.021484816) * go_0(0.0, 0.0); result += mat4(-0.057454903, -0.4121922, 0.022661546, 0.37178272, 0.03331408, 0.05044008, 0.04324371, 0.20727943, 0.2432641, 0.076906696, -0.20858039, 0.012439015, -0.19335061, 0.09217451, 0.1968369, -0.19435833) * go_0(0.0, 1.0); result += mat4(-0.16960496, 0.24616167, 0.37977478, 0.14324574, -0.011531225, -0.11312143, -0.18141079, -0.23843932, 0.0086012175, -0.3564491, -0.12639481, 0.009799298, -0.29120612, 0.23756824, 0.18035695, -0.087133996) * go_0(1.0, -1.0); result += mat4(-0.10081239, 0.29191494, 0.10434693, 0.08970636, 0.008997759, 0.104756236, 0.039641086, 0.02323888, -0.11627765, 0.023693223, -0.30801758, -0.120208986, 0.05086147, 0.18498175, 0.15595439, -0.09877306) * go_0(1.0, 0.0); result += mat4(0.101321675, -0.2929976, 0.38810417, 0.5605376, -0.04073937, 0.030110704, -0.18147062, -0.09833952, 0.01927733, 0.15335669, -0.15384074, -0.110595055, -0.054297395, -0.077522054, 0.07918369, -0.068480626) * go_0(1.0, 1.0); result += mat4(0.23263514, -0.11719232, 0.2903209, -0.007503795, -0.020222448, -0.17790157, -0.15600762, -0.08741775, 0.12529704, 0.25548857, -0.04585447, -0.10255033, 0.18350503, -0.29593533, 0.0868933, 0.027004737) * go_1(-1.0, -1.0); result += mat4(-0.14958654, -0.006238835, -0.2928948, 0.1988557, -0.17057803, 0.12524141, 0.13978264, -0.019280292, 0.05967142, -0.07790818, -0.5893818, -0.022845713, -0.08596779, 0.07875358, -0.03316667, -0.4369282) * go_1(-1.0, 0.0); result += mat4(0.19195688, -0.060883682, -0.25897828, 0.07063324, 0.090833396, 0.003422883, 0.109534174, 0.031180874, -0.05017118, 0.022862168, -0.270113, -0.057831235, 0.53920543, -0.10252776, -0.091807485, 0.004294343) * go_1(-1.0, 1.0); result += mat4(-0.18494242, -0.119284816, 0.3821897, 0.07777979, 0.15568028, -0.2854859, -0.22441281, -0.049155876, -0.15292497, 0.21895619, -0.095677756, 0.15210424, 0.001643022, -0.026176987, 0.048463076, -0.4824009) * go_1(0.0, -1.0); result += mat4(0.007215129, 0.17074333, 0.053930074, -0.027014816, -0.17180431, -0.15163863, -0.0012122132, -0.18934256, -0.08294297, -0.24580221, -0.46552867, -0.27923223, 0.4092668, 0.06288688, -0.1602188, -0.0030876845) * go_1(0.0, 0.0); result += mat4(0.111870885, 0.03317145, 0.14155298, 0.20328505, -0.05104131, 0.13979794, 0.018966835, -0.07238511, 0.05493792, -0.14975783, -0.10293237, -0.21985306, 0.49054706, 0.18288186, -0.26925826, 0.35845932) * go_1(0.0, 1.0); result += mat4(0.3747799, -0.096748486, -0.17139742, 0.25289854, -0.17421168, -0.018461818, 0.09747162, 0.01660535, -0.20580359, 0.56189656, 0.17151354, -0.26347768, 0.28350568, -0.21486014, -0.44330928, -0.008981037) * go_1(1.0, -1.0); result += mat4(0.10169985, -0.18244018, 0.04760736, 0.41017643, -0.09468786, -0.024218475, 0.103733875, -0.22540338, 0.10630112, 0.3677178, -0.104170956, 0.057317447, 0.21764882, 0.0789158, -0.22041337, 0.15065216) * go_1(1.0, 0.0); result += mat4(0.11633995, -0.008195114, -0.14501533, 0.07168025, 0.058413275, 0.055995367, 0.09362145, -0.13827963, 0.13760869, 0.040319785, 0.038895044, 0.2675253, -0.087339684, 0.1412073, -0.17166458, -0.2312994) * go_1(1.0, 1.0); result += vec4(-0.059377354, -0.02055341, 0.07234869, -0.015452986); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(M)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_3_tf //!SAVE conv2d_4_tf //!WIDTH conv2d_3_tf.w //!HEIGHT conv2d_3_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_3_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_3_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.29012984, -0.13150147, 0.31015614, 0.05992291, -0.050289866, 0.14845313, -0.09608898, 0.27913308, 0.060307387, -0.04160452, 0.035932682, -0.08137563, -0.07999419, 0.11818284, -0.27512288, 0.21948813) * go_0(-1.0, -1.0); result += mat4(0.12916058, -0.21759962, -0.33868533, 0.021636661, 0.053470243, 0.1412425, 0.043395396, -0.26751056, -0.01689101, -0.2623835, 0.010809152, 0.062962815, -0.20692012, -0.1677863, -0.23313859, -0.17402615) * go_0(-1.0, 0.0); result += mat4(-0.08204112, -0.23672083, -0.0064437394, -0.13200696, -0.056692924, -0.02708657, 0.12536962, 0.004428919, 0.14137582, 0.15404348, -0.105753876, 0.047957454, 0.15734316, 0.16562423, -0.010160829, -0.06602983) * go_0(-1.0, 1.0); result += mat4(0.025653997, -0.10877775, -0.31258908, 0.18841636, -0.36005193, 0.1816357, -0.34537643, -0.0741087, 0.4663994, 0.0065186517, 0.08109033, 0.2976773, -0.35774228, -0.041366056, -0.37852773, 0.050565656) * go_0(0.0, -1.0); result += mat4(0.04392313, 0.11316681, -0.14421389, 0.17985669, -0.1651274, -0.5656209, -0.124100484, 0.42774054, -0.1153939, 0.16829851, 0.2025612, 0.054007456, -0.06868256, -0.56935954, -0.12227961, 0.17688861) * go_0(0.0, 0.0); result += mat4(0.34041, 0.499, 0.15234196, 0.21353458, -0.2732667, -0.049950935, 0.03550811, -0.21051687, 0.2609023, 0.016438454, -0.29874632, 0.37994128, 0.049288407, -0.31126305, 0.029235512, -0.012256015) * go_0(0.0, 1.0); result += mat4(-0.0046853204, 0.15391374, -0.040689662, 0.20186873, -0.08137621, 0.35905558, 0.23733845, 0.21794793, -0.066420384, 0.029600656, -0.31421044, -0.050773863, -0.06260773, 0.04634221, -0.10948491, -0.045498934) * go_0(1.0, -1.0); result += mat4(-0.082953, -0.025837064, -0.09928303, -0.14300232, 0.275064, 0.07793617, 0.22240888, 0.06637834, -0.4382666, -0.2932182, -0.27243167, -0.14221182, 0.5695728, 0.20719238, 0.5575927, 0.40816882) * go_0(1.0, 0.0); result += mat4(-0.18510929, -0.15052167, 0.25277212, 0.06804461, 0.016387, 0.20310035, 0.2903229, -0.0615877, -0.28987274, -0.11942605, 0.013498961, 0.3184152, 0.29543474, -0.042830903, -0.018111207, -0.13263674) * go_0(1.0, 1.0); result += mat4(0.25749087, 0.0053866603, -0.09391162, -0.06129529, -0.094091184, -0.07419633, 0.0013858611, 0.012000353, -0.062903, -0.0204224, -0.12113313, 0.017942557, -0.073379934, 0.052201986, 0.35864577, 0.023564404) * go_1(-1.0, -1.0); result += mat4(0.100115694, 0.19451359, 0.23252094, 0.19506809, -0.12470779, 0.0027281935, -0.17488572, -0.018721964, -0.15159339, 0.18457152, 0.057712987, -0.08191495, 0.19735703, 0.07326743, -0.28563106, 0.01642815) * go_1(-1.0, 0.0); result += mat4(0.068062514, 0.28356665, 0.07377898, 0.42776972, 0.28725025, -0.13045293, -0.17525704, -0.05885591, -0.16676305, -0.2555945, -0.10078422, -0.053032875, 0.084470876, 0.06460686, 0.13824362, -0.05231353) * go_1(-1.0, 1.0); result += mat4(0.22637829, -0.028969254, 0.1968254, -0.13331996, 0.038017053, -0.008854481, -0.2031639, 0.09237089, -0.3821112, 0.1108527, -0.11029933, -0.24542028, 0.22416145, -0.031492114, -0.19144306, -0.0996271) * go_1(0.0, -1.0); result += mat4(0.10776744, 0.16363445, 0.14656505, -0.3737814, -0.06642015, 0.5616549, -0.008412252, -0.37266847, 0.12506576, -0.15329036, 0.037538245, -0.10810259, 0.01706349, 0.1813702, 0.035651788, -0.012786579) * go_1(0.0, 0.0); result += mat4(-0.4023338, -0.2098614, -0.18285121, -0.02727653, 0.26107362, 0.041306913, -0.036515504, -0.045217298, -0.39958602, -0.21229339, -0.021053292, -0.13427502, 0.36178818, 0.20934913, 0.1500852, 0.2634554) * go_1(0.0, 1.0); result += mat4(0.07794611, -0.25937587, -0.06822529, -0.056336135, 0.094220124, 0.21588847, -0.0455218, -0.10968329, -0.08068449, -0.31366697, 0.07799637, 0.24252681, 0.23963861, 0.13715535, 0.010329345, 0.09094301) * go_1(1.0, -1.0); result += mat4(-0.20975718, -0.12550138, 0.14453574, -0.0020878632, -0.07153068, 0.3249998, -0.056577377, 0.18166828, 0.37204072, 0.17018336, 0.3752895, 0.32178587, 0.2571982, -0.27258632, -0.25971004, -0.40536007) * go_1(1.0, 0.0); result += mat4(-0.3243907, -0.06300621, -0.09398436, -0.19549188, 0.14906861, 0.061537784, -0.055284478, 0.11281728, 0.12964857, 0.09979093, -0.1810159, -0.4104283, 0.05807971, -0.056371246, 0.08072554, 0.18479007) * go_1(1.0, 1.0); result += vec4(-0.048888464, -0.0561434, 0.030690912, -0.030496685); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(M)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_4_tf //!SAVE conv2d_5_tf //!WIDTH conv2d_4_tf.w //!HEIGHT conv2d_4_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_4_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_4_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.15332128, 0.027258258, 0.14900503, -0.15982795, 0.17021236, -0.51046044, -0.15287271, -0.058167327, 0.51826185, -0.34817994, 0.004513167, 0.05395769, 0.1990321, -0.049979225, 0.11391989, -0.16062729) * go_0(-1.0, -1.0); result += mat4(0.033682905, 0.019728886, 0.19931756, 0.17381927, 0.2585768, -0.2124572, -0.014632459, 0.39779893, -0.1146207, -0.2396625, 0.08960277, 0.38345298, 0.25497693, 0.11692859, -0.14207517, 0.12667973) * go_0(-1.0, 0.0); result += mat4(-0.14911255, 0.08910706, 0.16136818, 0.03914566, 0.24204038, -0.03607149, -0.4571109, 0.10802461, -0.0021356856, 0.00885878, 0.22297303, 0.2367231, 0.045177583, 0.11120606, -0.009971904, -0.059262395) * go_0(-1.0, 1.0); result += mat4(0.24565999, -0.2261384, 0.47373205, 0.024613412, -0.10923052, 0.039027315, -0.42707404, -0.3783373, 0.3544573, -0.5468578, -0.27599156, -0.09455918, 0.18760219, -0.19082001, 0.030565469, 0.20589156) * go_0(0.0, -1.0); result += mat4(0.1973198, -0.03433863, 0.059960485, 0.045642868, 0.1819595, -0.14460869, 0.1286175, 0.2067575, -0.042632047, -0.11842967, -0.11224446, -0.18764776, -0.19563004, 0.027425969, 0.24056377, 0.5949649) * go_0(0.0, 0.0); result += mat4(0.055027682, 0.16331595, -0.2608588, 0.12545955, 0.4588985, 0.03642909, 0.22187738, 0.45190734, -0.001210133, -0.057651415, -0.061199043, 0.11935476, -0.049561135, 0.27509886, 0.13778673, -0.124914035) * go_0(0.0, 1.0); result += mat4(-0.02257459, 0.27705106, 0.044165276, -0.26521233, 0.05982374, -0.2824302, 0.3171142, 0.08430561, -0.10155528, 0.16182268, -0.09183147, -0.19447176, 0.3295707, -0.50616395, -0.036964044, 0.23166709) * go_0(1.0, -1.0); result += mat4(-0.0232342, 0.07299799, -0.18038079, -0.13672702, -0.108305976, 0.15024792, -0.19531927, 0.0870979, -0.26488534, 0.19481428, 0.10737945, -0.14573483, -0.33094683, 0.24155116, -0.09850332, 0.2797003) * go_0(1.0, 0.0); result += mat4(-0.24089853, 0.19506595, 0.4799156, -0.058313113, 0.36212957, -0.44844806, 0.23864488, 0.15477742, -0.07795971, -0.0033861927, -0.11216164, 0.033454563, -0.25893036, 0.23793478, -0.15769425, -0.00033481256) * go_0(1.0, 1.0); result += mat4(0.05772507, -0.1640253, -0.13499664, -0.20460358, -0.024399966, 0.14966168, -0.090857334, -0.039677754, 0.00036956606, -0.24236615, -0.053542696, -0.0049544116, 0.026651502, 0.39019194, -0.2742246, -0.061242323) * go_1(-1.0, -1.0); result += mat4(-0.016323274, -0.036179908, 0.029965919, 0.11151491, -0.00016685206, -0.29573023, 0.17996423, -0.20145437, 0.1324275, -0.18442132, -0.24618152, 0.061780427, -0.02770517, 0.28452995, 0.39804098, -0.1174389) * go_1(-1.0, 0.0); result += mat4(-0.025068847, -0.053328387, -0.27053785, 0.26866457, -0.09866204, 0.057677213, 0.01850112, -0.18014707, -0.13319959, -0.14411181, -0.26355243, -0.022209354, -0.05062645, -0.036771543, 0.13294417, -0.18458557) * go_1(-1.0, 1.0); result += mat4(-0.046194963, 0.038230438, -0.08993043, -0.07236354, 0.11031123, -0.16504908, -0.09517036, -0.16459833, -0.5279925, 0.12686682, -0.05726125, 0.055361677, 0.31593755, 0.027328093, 0.001839602, 0.30581662) * go_1(0.0, -1.0); result += mat4(0.08608678, 0.03168437, 0.007713377, -0.26140293, -0.1268983, 0.13395861, -0.069848835, -0.24080403, 0.018839337, -0.049821075, -0.21461345, -0.14168301, -0.0872339, 0.47096667, 0.022512507, 0.14860632) * go_1(0.0, 0.0); result += mat4(0.06293673, 0.22462969, 0.045494985, 0.021673543, 0.18227446, -0.2956555, 0.08010543, -0.01919729, -0.012190269, 0.241983, -0.046537094, -0.40094566, -0.3853647, 0.1081711, -0.16926058, 0.16138376) * go_1(0.0, 1.0); result += mat4(-0.14854589, -0.17625804, -0.10849075, 0.221543, 0.099971965, 0.13901573, 0.29464146, 0.020068526, 0.054358527, -0.10351705, -0.0062914286, 0.24127026, -0.16914125, 0.12729423, -0.18377453, -0.6452375) * go_1(1.0, -1.0); result += mat4(0.12603393, -0.10986093, 0.2314103, 0.16915044, -0.13619255, -0.09349073, 0.20594226, -0.34507084, 0.19077192, 0.052500796, 0.07185645, 0.029082738, -0.015576321, 0.08254907, -0.5501743, -0.38495848) * go_1(1.0, 0.0); result += mat4(0.09300796, -0.079218306, 0.46825135, -0.08735625, 0.06321122, 0.16234867, 0.042932414, -0.013057422, 0.09697148, 0.23457524, 0.19417483, -0.16804664, 0.18379296, 0.17770062, -0.050235, -0.059676602) * go_1(1.0, 1.0); result += vec4(0.011169491, 0.032399546, 0.138099, 0.023857072); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(M)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_5_tf //!SAVE conv2d_6_tf //!WIDTH conv2d_5_tf.w //!HEIGHT conv2d_5_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_5_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_5_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.22753362, -0.08612073, 0.33140692, 0.08699529, -0.18788953, -0.056579117, -0.12905197, -0.06694621, 0.054559365, 0.15031597, -0.13430363, 0.021646025, 0.14884405, -0.0694291, 0.26149413, 0.11270503) * go_0(-1.0, -1.0); result += mat4(0.17876762, -0.09637848, 0.11285323, 0.2004893, 0.1317187, -0.036162686, 0.17958368, -0.069625, 0.28760737, -0.12505141, 0.12760694, 0.047717955, -0.16811855, -0.16340709, 0.13278298, -0.08403954) * go_0(-1.0, 0.0); result += mat4(-0.21917523, 0.079711854, -0.28642535, 0.2822416, 0.03001489, -0.014772918, -0.3487396, 0.10597145, -0.013841082, 0.17034237, 0.10810282, -0.08089695, -0.22184245, -0.59067357, 0.44113398, 0.13045649) * go_0(-1.0, 1.0); result += mat4(-0.29906932, 0.013923749, 0.2031124, -0.11846688, -0.13953634, 0.08003455, -0.10164494, -0.21218559, 0.10563715, 0.31033117, -0.075903505, 0.047310907, -0.37824214, -0.14506383, 0.11866701, -0.21384487) * go_0(0.0, -1.0); result += mat4(-0.1353849, 0.19258606, 0.063908584, -0.2043788, 0.27244982, 0.1665306, -0.29357895, -0.22441709, 0.18514316, -0.17840464, 0.20986097, 0.14351055, -0.057732623, 0.42166704, -0.23182064, -0.4957248) * go_0(0.0, 0.0); result += mat4(-0.34830126, 0.109066755, -0.28285867, -0.048280068, -0.12290918, 0.04291651, -0.047484186, -0.03702595, 0.23047262, 0.09398974, 0.022467108, 0.08271034, 0.3066665, -0.54077, 0.057771873, 0.23194093) * go_0(0.0, 1.0); result += mat4(-0.17731948, -0.3175927, 0.1452728, 0.09396786, -0.16433562, -0.01833653, -0.22345604, -0.04161193, -0.14827462, 0.18544114, -0.15544125, -0.06179007, 0.16989979, -0.20985202, 0.16391534, -0.09447268) * go_0(1.0, -1.0); result += mat4(-0.053878862, -0.21034616, 0.023831524, 0.19772215, 0.31647214, 0.0126534775, -0.19130844, -0.049282108, -0.21446131, 0.067189045, 0.09117449, -0.25548774, 0.12109098, 0.22009392, -0.3924665, -0.13340388) * go_0(1.0, 0.0); result += mat4(-0.16096684, -0.18495405, 0.10410178, 0.0015673033, -0.00183498, -0.044303037, -0.062745355, -0.090802394, 0.043269135, 0.06924481, -0.21367405, -0.14619029, 0.11555763, -0.20292862, 0.5799557, 0.14739846) * go_0(1.0, 1.0); result += mat4(-0.21030277, -0.09578802, 0.013482288, -0.21484336, 0.12995781, 0.40431052, -0.3347856, -0.18183486, 0.15550353, -0.04402301, 0.4603779, 0.14874357, -0.07694621, -0.053523075, -0.19607326, -0.10850742) * go_1(-1.0, -1.0); result += mat4(-0.2347211, 0.2697403, -0.0634794, -0.17925987, 0.17231455, 0.24999185, -0.5208536, -0.10491828, -0.233575, 0.52950364, 0.0038063182, -0.1380038, 0.022935199, 0.19369157, 0.14586553, 0.1938704) * go_1(-1.0, 0.0); result += mat4(-0.10245223, 0.34150192, 0.25862157, -0.20165509, 0.5597771, 0.114510864, -0.122526556, -0.04010975, 0.1704679, -0.23335956, -0.16771887, -0.03783455, -0.056995615, 0.24153493, -0.08082429, -0.24210933) * go_1(-1.0, 1.0); result += mat4(-0.103466526, 0.15278348, -0.30526164, -0.080755696, 0.103505425, 0.15862796, 0.14696524, -0.008358076, -0.09180311, -0.12505089, 0.28052542, -0.13551563, 0.07528779, -0.09636086, -0.10369617, 0.23656134) * go_1(0.0, -1.0); result += mat4(-0.25752836, 0.099439755, -0.30716348, 0.035077725, 0.023509016, 0.23106368, 0.05277125, 0.34910464, 0.088015385, 0.26995596, 0.1390645, -0.40671825, 0.18096298, -0.100688554, 0.5492049, 0.2482101) * go_1(0.0, 0.0); result += mat4(0.41411775, -0.107200556, -0.13813478, 0.13768874, 0.27137747, 0.06313619, -0.08522967, 0.03218302, -0.03166121, -0.3415683, -0.52242, -0.1741813, -0.36956537, 0.179129, -0.09742935, -0.11696616) * go_1(0.0, 1.0); result += mat4(-0.07975504, 0.17964838, 0.37122533, 0.16064765, 0.14309953, 0.29473078, 0.0926391, -0.22333665, 0.34612748, -0.3387473, 0.0077308523, -0.07239449, 0.18522519, -0.21297298, 0.11493978, 0.16117814) * go_1(1.0, -1.0); result += mat4(-0.17402779, 0.10023144, 0.11712206, 0.031971734, 0.18713303, 0.08736295, 0.013007052, -0.06943139, -0.20102951, -0.010721135, -0.2562522, 0.34877458, -0.13732676, -0.40258047, 0.25824392, 0.15720639) * go_1(1.0, 0.0); result += mat4(0.044494305, 0.3296108, 0.0017603852, 0.09362289, 0.38839245, 0.40015858, -0.13395199, -0.044521853, -0.56266373, 0.251378, 0.5005789, -0.13106057, -0.18491416, -0.046887, 0.067797676, -0.14694957) * go_1(1.0, 1.0); result += vec4(0.013687534, -0.08185164, -0.04755438, 0.290178); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(M)-Conv-3x1x1x56 //!HOOK MAIN //!BIND MAIN //!BIND conv2d_tf //!BIND conv2d_1_tf //!BIND conv2d_2_tf //!BIND conv2d_3_tf //!BIND conv2d_4_tf //!BIND conv2d_5_tf //!BIND conv2d_6_tf //!SAVE MAIN //!WIDTH conv2d_tf.w //!HEIGHT conv2d_tf.h #define g_0 (max((conv2d_tf_tex(conv2d_tf_pos)), 0.0)) #define g_1 (max(-(conv2d_tf_tex(conv2d_tf_pos)), 0.0)) #define g_2 (max((conv2d_1_tf_tex(conv2d_1_tf_pos)), 0.0)) #define g_3 (max(-(conv2d_1_tf_tex(conv2d_1_tf_pos)), 0.0)) #define g_4 (max((conv2d_2_tf_tex(conv2d_2_tf_pos)), 0.0)) #define g_5 (max(-(conv2d_2_tf_tex(conv2d_2_tf_pos)), 0.0)) #define g_6 (max((conv2d_3_tf_tex(conv2d_3_tf_pos)), 0.0)) #define g_7 (max(-(conv2d_3_tf_tex(conv2d_3_tf_pos)), 0.0)) #define g_8 (max((conv2d_4_tf_tex(conv2d_4_tf_pos)), 0.0)) #define g_9 (max(-(conv2d_4_tf_tex(conv2d_4_tf_pos)), 0.0)) #define g_10 (max((conv2d_5_tf_tex(conv2d_5_tf_pos)), 0.0)) #define g_11 (max(-(conv2d_5_tf_tex(conv2d_5_tf_pos)), 0.0)) #define g_12 (max((conv2d_6_tf_tex(conv2d_6_tf_pos)), 0.0)) #define g_13 (max(-(conv2d_6_tf_tex(conv2d_6_tf_pos)), 0.0)) vec4 hook() { vec4 result = mat4(-0.08837163, -0.065234736, -0.034704313, 0.0, 0.021405501, 0.013663729, 0.019249594, 0.0, 0.05328863, 0.03580334, 0.046457592, 0.0, -0.12216048, 0.022547891, 0.016400825, 0.0) * g_0; result += mat4(0.061996464, 0.05631466, 0.06808407, 0.0, -0.005013109, -0.0044589997, -0.032367796, 0.0, 0.016481603, 0.13721058, 0.14924648, 0.0, 0.020035887, -0.07250003, -0.08034037, 0.0) * g_1; result += mat4(0.24078514, 0.081361525, 0.053420708, 0.0, -0.009353794, -0.051077116, -0.058007747, 0.0, -0.14071098, 0.01035966, 0.005308949, 0.0, -0.1489842, -0.06711817, -0.05552926, 0.0) * g_2; result += mat4(-0.13002375, 0.012733757, 0.017821986, 0.0, 0.17767483, 0.20204604, 0.1751779, 0.0, 0.12804912, 0.07381453, 0.05655911, 0.0, 0.17044514, 0.07301451, 0.06523978, 0.0) * g_3; result += mat4(-0.1170986, -0.05130371, -0.027939914, 0.0, -0.16645707, -0.121526904, -0.09471366, 0.0, -0.04143118, 0.026693767, 0.034615446, 0.0, -0.084318705, -0.064990036, -0.054324172, 0.0) * g_4; result += mat4(0.12094524, 0.09518409, 0.07387219, 0.0, 0.062216382, 0.053228356, 0.031372335, 0.0, 0.072797105, 0.026258165, 0.009804673, 0.0, 0.120719045, 0.073281154, 0.056623302, 0.0) * g_5; result += mat4(-0.11141495, -0.11566289, -0.10398725, 0.0, -0.0651895, -0.06820691, -0.054204144, 0.0, -0.032746475, -0.008849683, -0.007610222, 0.0, -0.024655705, -0.048778858, -0.041144755, 0.0) * g_6; result += mat4(0.058090195, 0.07538767, 0.059722915, 0.0, 0.044788487, 0.04212742, 0.027502589, 0.0, 0.04892866, 0.015416752, 0.008312418, 0.0, -0.011864114, -0.0074752793, -0.0060824654, 0.0) * g_7; result += mat4(0.043446552, 0.061971307, 0.05758086, 0.0, -0.06379154, -0.053758245, -0.047204215, 0.0, 0.016307736, 0.03423424, 0.030179083, 0.0, 0.041445345, 0.03843772, 0.033059113, 0.0) * g_8; result += mat4(-0.003803544, 0.0008906116, -0.00059585314, 0.0, 0.102071285, 0.11485224, 0.10007254, 0.0, -0.074306004, -0.08803551, -0.07972321, 0.0, -0.030704215, -0.021514274, -0.009049376, 0.0) * g_9; result += mat4(0.0066058086, 0.0011408008, 0.0016199006, 0.0, -0.03916473, -0.042929266, -0.04018418, 0.0, -0.03153446, -0.039413508, -0.034767237, 0.0, 0.113516055, 0.12577052, 0.113335624, 0.0) * g_10; result += mat4(0.02655948, 0.041905303, 0.03861737, 0.0, 0.048471425, 0.049788587, 0.050447535, 0.0, 0.12092813, 0.13564217, 0.12613249, 0.0, -0.0023508538, 0.0012828974, 0.0028730957, 0.0) * g_11; result += mat4(0.0084758485, 0.008800083, 0.008206044, 0.0, -0.056123603, -0.06610845, -0.060320783, 0.0, -0.081793964, -0.101638645, -0.096699014, 0.0, -0.04402356, -0.04177539, -0.03829645, 0.0) * g_12; result += mat4(0.10676299, 0.118409514, 0.10618478, 0.0, -0.05880252, -0.06488367, -0.06432695, 0.0, 0.019221924, 0.017602798, 0.017413978, 0.0, -0.07512528, -0.080483615, -0.066218294, 0.0) * g_13; result += vec4(-0.010478934, -0.008364784, -0.010246552, 0.0); return result + MAIN_tex(MAIN_pos); } ================================================ FILE: app/src/main/assets/shaders/Anime4K_Restore_CNN_S.glsl ================================================ // MIT License // Copyright (c) 2019-2021 bloc97 // All rights reserved. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //!DESC Anime4K-v4.0-Restore-CNN-(S)-Conv-4x3x3x3 //!HOOK MAIN //!BIND MAIN //!SAVE conv2d_tf //!WIDTH MAIN.w //!HEIGHT MAIN.h //!COMPONENTS 4 #define go_0(x_off, y_off) (MAIN_texOff(vec2(x_off, y_off))) vec4 hook() { vec4 result = mat4(-0.19288683, -0.21397883, 0.111997396, -0.04791413, -0.26682988, -0.06144587, -0.03601853, -0.16693151, 0.038494494, -0.16651472, 0.147657, -0.083003886, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, -1.0); result += mat4(-0.14286195, 0.08746566, -0.40107322, 0.12390977, -0.33392772, -0.18703035, -0.21326795, 0.04780781, -0.15155545, -0.0010025925, -0.1554875, -0.10676251, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 0.0); result += mat4(0.28095165, 0.022872915, -0.21342312, -0.29982176, 0.025937587, -0.055012174, -0.33779636, 0.0015666655, 0.076416336, 0.06656033, -0.1557806, 0.1078894, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 1.0); result += mat4(-0.31584853, 0.07527119, 0.30713862, -0.34014285, -0.50103146, -0.07217874, 0.512807, -0.09597398, -0.32097813, -0.051580857, -0.022466356, 0.01148551, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, -1.0); result += mat4(-0.026032459, -0.04193211, 0.37703893, -0.031916667, -0.27421117, 1.0906446, -0.049654085, -0.19814016, 0.07819544, 0.06003738, 0.1405805, -0.0064135445, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 0.0); result += mat4(0.041450135, 0.11319654, -0.23237701, 0.08443178, 0.53344345, 0.30857387, -0.057264958, -0.1575803, 0.2325609, -0.027797326, -0.04544767, -0.18720597, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 1.0); result += mat4(0.2531829, -0.074966915, -0.27800754, -0.3146097, 0.20126024, -0.5380133, -0.15082566, -0.19021043, 0.29951036, 0.17123336, -0.01681872, -0.12574998, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, -1.0); result += mat4(0.25203633, 0.19882993, 0.14906439, 0.13593598, 0.40712556, 0.084902965, 0.42969635, 0.2961132, -0.057267334, -0.030388135, 8.8084314e-05, 0.0210724, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 0.0); result += mat4(-0.13459359, -0.12199573, 0.12591946, 0.24736497, 0.2033463, -0.09388599, -0.094370656, 0.1071285, -0.18479438, -0.066625565, 0.08279283, 0.20130983, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 1.0); result += vec4(-0.011108127, -0.07481861, 0.07640154, 0.4964964); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(S)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_tf //!SAVE conv2d_1_tf //!WIDTH conv2d_tf.w //!HEIGHT conv2d_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.056432575, 0.0028165397, -0.026325442, -0.14802271, 0.16885762, -0.062179096, -0.2332292, 0.17513658, -0.08011296, 0.02947316, 0.014771492, -0.17946689, 0.026012989, -0.09823925, 0.036625937, -0.06924322) * go_0(-1.0, -1.0); result += mat4(-0.13571467, 0.09831142, 0.12911566, 0.06305893, -0.07188695, -0.20161287, 0.3858435, -0.21069056, -0.12294444, -0.1404628, -0.022659872, 0.23008968, 0.10969853, 0.17640765, 0.39796907, 0.20413099) * go_0(-1.0, 0.0); result += mat4(-0.0061665224, 0.055102807, -0.0059629944, -0.021429887, 0.061626043, 0.16898955, -0.21215646, 0.16510476, 0.2238265, 0.19429931, 0.09874656, 0.06828208, -0.122404456, -0.00026717107, -0.28203064, -0.29979932) * go_0(-1.0, 1.0); result += mat4(-0.22735378, 0.14538136, 0.11549746, 0.194148, -0.09841722, -0.0661309, 0.348576, -0.017375294, -0.044078812, 0.1298332, 0.04793373, -0.30687734, 0.08353025, 0.083519086, 0.10766399, 0.31796935) * go_0(0.0, -1.0); result += mat4(0.048365135, -0.17566709, -0.33212858, -0.052667376, -0.26443407, -0.010216014, 0.1573303, 0.05725314, 0.08140953, -0.09664591, 0.076109104, -0.026773714, 0.07732627, 0.10188082, -0.28266954, -0.16230233) * go_0(0.0, 0.0); result += mat4(0.29931107, 0.117944, -0.10414009, 0.12795551, 0.12576093, 0.17082554, -0.15803693, 0.13430743, -0.025801308, -0.10797019, 0.0721032, 0.2825884, -0.11025257, 0.12798019, 0.081827976, -0.050441865) * go_0(0.0, 1.0); result += mat4(-0.11827391, 0.08306765, -0.3430314, 0.07898041, -0.023839617, -0.019507334, 0.23176382, -0.40992323, 0.09411734, 0.38415068, -0.25845516, -0.29984522, 0.1470966, -0.0684779, -0.07071314, -0.026773235) * go_0(1.0, -1.0); result += mat4(0.19091596, 0.082110435, -0.5266589, -0.1744098, -0.015838385, -0.046316292, 0.023171103, -0.03731331, 0.2642396, 0.31824252, -0.041754793, -0.09525519, -0.14696182, 0.052168854, 0.039857205, -0.027555354) * go_0(1.0, 0.0); result += mat4(0.15207373, 0.09845733, 0.0142631065, 0.096375965, 0.06089903, 0.17902578, -0.42391995, 0.22475442, 0.016356342, -0.06277531, -0.12173141, -0.18635495, -0.0013459618, 0.15725887, 0.019310836, 0.20293565) * go_0(1.0, 1.0); result += mat4(-0.18395247, 0.30672902, 0.09034339, 0.1821889, -0.0419004, -0.2169228, -0.14052129, 0.11006559, 0.1709272, 0.51062274, 0.13758625, -0.2242552, -0.030382963, 0.3357568, -0.26491287, 0.02501938) * go_1(-1.0, -1.0); result += mat4(0.040511727, 0.12523083, -0.27318433, 0.08388512, 0.25354835, 0.3404216, -0.2632471, -0.17784123, 0.2732347, 0.4468553, 0.084667034, -0.1856242, 0.034099877, -0.00954992, -0.32751867, -0.062207516) * go_1(-1.0, 0.0); result += mat4(0.17564747, 0.11645554, -0.16362113, 0.105654195, -0.2762563, -0.1413764, 0.23264363, -0.14000498, 0.095402054, 0.0715738, -0.19346157, -0.028285999, 0.009799127, 0.04059529, 0.19688335, 0.1282381) * go_1(-1.0, 1.0); result += mat4(0.23575781, -0.11446148, -0.20504695, 0.035568226, 0.36890212, -0.85968876, -0.18545328, 0.33796397, -0.30916876, -0.10445518, -0.3046253, 0.33271998, -0.06263589, -0.2160114, -0.16383372, -0.31173357) * go_1(0.0, -1.0); result += mat4(0.20469664, 0.4039374, -0.070057206, 0.030353077, 0.39843914, -0.15490077, -0.24476516, 0.38238233, -0.21809858, 0.23496576, -0.051794037, 0.033664484, -0.14411364, -0.2515329, 0.124655396, -0.05818785) * go_1(0.0, 0.0); result += mat4(-0.09065731, -0.16787091, 0.013269188, 0.23687351, -0.41504318, -0.048163068, 0.31760025, -0.33648986, 0.29752317, 0.2926866, 0.14408836, -0.33382463, -0.15873958, -0.121961035, 0.11797893, 0.09000567) * go_1(0.0, 1.0); result += mat4(0.13356976, 0.013763947, 0.012169505, -0.109594524, 0.03417223, 0.7031121, 0.65146804, 0.5250268, -0.50132495, -0.419648, 0.2940041, 0.83051753, -0.17595838, 0.1633008, -0.018587278, 0.079596795) * go_1(1.0, -1.0); result += mat4(0.07570128, -0.1581438, 0.03904949, 0.14890033, -0.054611947, 0.17469402, -0.44252598, 0.036181703, -0.4981031, -0.37507218, -0.18466389, 0.2645845, 0.25189674, -0.025896115, 0.034307647, -0.020462232) * go_1(1.0, 0.0); result += mat4(-0.11645865, 0.02296537, 0.040909223, 0.015069485, 0.062284566, -0.22526766, 0.09241534, -0.32623053, 0.18208642, 0.3954284, 0.2884468, -0.25137675, -0.037232924, -0.10185309, -0.17956531, 0.018966453) * go_1(1.0, 1.0); result += vec4(-0.16371979, -0.024620198, -0.035754893, 0.04176776); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(S)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_1_tf //!SAVE conv2d_2_tf //!WIDTH conv2d_1_tf.w //!HEIGHT conv2d_1_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.01921286, -0.26684764, -0.12663573, 0.31641877, -0.25313398, 0.12264074, 0.58750325, -0.14084283, 0.5837018, -0.042300556, -0.20435576, -0.009954825, 0.060783498, 0.05540401, 0.2205112, -0.06578902) * go_0(-1.0, -1.0); result += mat4(-0.21930243, -0.03774968, 0.22615197, 0.18338196, 0.011201461, -0.271034, 0.00573116, -0.12248194, 0.47990513, 0.2982416, -0.1087603, -0.050099242, -0.07620939, -0.07148229, 0.03691984, -0.16796488) * go_0(-1.0, 0.0); result += mat4(-0.14962853, -0.053769328, 0.02387081, 0.22002189, 0.052237745, -0.26160842, -0.08603077, 0.012542448, 0.08119985, 0.075785555, -0.33437458, -0.43373227, -0.13206963, -0.08759176, -0.03288923, -0.09799959) * go_0(-1.0, 1.0); result += mat4(-0.1305593, -0.5974288, 0.06058367, 0.08406488, 0.013692483, 0.06646377, 0.16469325, 0.08990975, 0.42217395, -0.11289523, -0.06165009, 0.48556912, -0.15702641, -0.19922857, -0.0035429662, -0.0022089656) * go_0(0.0, -1.0); result += mat4(-0.1964807, 0.038099788, 0.21587034, 0.039734077, -0.07063389, 0.11604167, -0.24558097, -0.08900199, -0.7684516, -0.1037487, -0.09380674, 0.33144563, -0.16653742, 0.0028585843, -0.33774406, -0.0528696) * go_0(0.0, 0.0); result += mat4(-0.27298656, -0.05665099, 0.09661685, 0.19780266, 0.1025106, -0.22055034, -0.21218458, -0.040628925, 0.0095010325, 0.13118382, -0.42582452, -0.22197723, 0.21006055, -0.06189587, -0.15285942, -0.09526762) * go_0(0.0, 1.0); result += mat4(-0.14494462, -0.046788953, 0.065877035, 0.09911713, 0.35096622, 0.16682479, 0.028363144, 0.36037162, 0.29413632, 0.28212717, -0.025364442, -0.3406269, 0.047262143, -0.11892685, -0.008032766, 0.29743317) * go_0(1.0, -1.0); result += mat4(-0.15191558, -0.36980554, 0.14555687, 0.0043930537, -0.012661432, 0.15737776, -0.115250416, 0.10324491, 0.24491951, -0.15575431, -0.27802598, 0.21959937, 0.18063772, 0.4455559, -0.09693302, 0.33382267) * go_0(1.0, 0.0); result += mat4(0.2717801, 0.13452889, 0.14105384, 0.16324317, -0.40111846, 0.1154301, -0.0076733204, -0.09697362, 0.44306824, -0.02831414, -0.2153124, -0.12075326, 0.060776163, 0.30347148, -0.0036976219, -0.12070682) * go_0(1.0, 1.0); result += mat4(-0.39780128, -0.29875937, -0.12952097, 0.080333896, 0.07520163, 0.021689568, -0.23121156, -0.038140096, -0.1593877, 0.017156163, -0.06038025, 0.009244022, -0.13917233, 0.30957314, 0.243109, -0.104947075) * go_1(-1.0, -1.0); result += mat4(-0.07965157, 0.06776501, -0.13288979, 0.005851189, -0.08768168, -0.03689969, 0.12034646, 0.22441491, 0.14453568, -0.17648841, -0.3378289, -0.018329712, 0.11722939, -0.34161824, 0.08424494, -0.01400687) * go_1(-1.0, 0.0); result += mat4(0.08153887, 0.07222914, -0.14663404, -0.038526025, -0.07385973, 0.18440577, 0.35890242, 0.17084727, 0.26345527, 0.15280858, -0.007446105, -0.024403179, -0.30336383, -0.22978698, 0.11612946, -0.23614909) * go_1(-1.0, 1.0); result += mat4(-0.07447396, 0.09023449, -0.13798, -0.086943336, -0.30787337, 0.15087669, 0.14418626, -0.03371195, 0.048989657, -0.13075387, -0.13458036, -0.059836224, 0.06495196, 0.269715, 0.3674355, 0.38956037) * go_1(0.0, -1.0); result += mat4(0.34981915, -0.048779126, 0.31717536, 0.38080826, -0.20149232, -0.82969636, -0.10167862, 0.6382858, 0.25976858, 0.4370118, -0.04724865, -0.10014156, 0.19380626, -0.080370255, 0.09578106, -0.035166856) * go_1(0.0, 0.0); result += mat4(-0.026443917, 0.4132611, 0.01822534, 0.12742202, -0.26652107, -0.2996705, 0.30905882, 0.07989903, 0.38249823, 0.21486135, 0.025314959, -0.14717339, -0.13344015, -0.32088286, -0.2833883, -0.30973712) * go_1(0.0, 1.0); result += mat4(0.021517841, 0.006556378, 0.2025686, -0.12044382, -0.38583103, -0.0027515136, -0.06556736, -0.097090125, 0.04676486, -0.11954886, -0.051612873, 0.07831412, -0.18823163, -0.16542958, 0.04245155, 0.6437998) * go_1(1.0, -1.0); result += mat4(-0.39475346, -0.2936861, 0.26768062, -0.28151843, 0.21935691, 0.2101108, -0.15455097, 0.19548604, 0.09188909, -0.020147726, 0.103328265, -0.12574542, -0.34167948, 0.07523185, -0.17669058, 0.62446547) * go_1(1.0, 0.0); result += mat4(-0.37661025, -0.29630858, 0.05451026, 0.1611643, 0.14079669, -0.2170294, -0.038716137, 0.13514164, -0.21235192, -0.07860726, -0.005749412, 0.025625167, -0.13297133, 0.33012658, -0.27434957, -0.18416783) * go_1(1.0, 1.0); result += vec4(-0.0036821906, -0.050239526, -0.01355402, 0.00048220603); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(S)-Conv-3x3x3x8 //!HOOK MAIN //!BIND MAIN //!BIND conv2d_2_tf //!SAVE MAIN //!WIDTH conv2d_2_tf.w //!HEIGHT conv2d_2_tf.h #define go_0(x_off, y_off) (max((conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.15873, 0.17989138, 0.14648493, 0.0, -0.017379675, -0.017363746, -0.019855022, 0.0, 0.009670625, 0.0070157526, 0.0075994316, 0.0, 0.025388412, 0.027231036, 0.024052646, 0.0) * go_0(-1.0, -1.0); result += mat4(0.048195973, 0.041760173, 0.037366055, 0.0, -0.115950756, -0.12887983, -0.12535639, 0.0, 0.032125086, 0.03397254, 0.032950625, 0.0, 0.01223746, 0.020822672, 0.0161561, 0.0) * go_0(-1.0, 0.0); result += mat4(0.0890567, 0.094453335, 0.09014035, 0.0, 0.016081346, 0.017434116, 0.020783134, 0.0, -0.011775135, -0.010094134, -0.018522855, 0.0, 0.072103254, 0.07940666, 0.065876864, 0.0) * go_0(-1.0, 1.0); result += mat4(-0.04841196, -0.06963968, -0.056574684, 0.0, 0.10912542, 0.11813441, 0.10643838, 0.0, -0.013013885, -0.01562045, -0.013802797, 0.0, 0.037505716, 0.04352026, 0.04645123, 0.0) * go_0(0.0, -1.0); result += mat4(-0.3472869, -0.36243078, -0.33530185, 0.0, 0.23654196, 0.2305048, 0.22150646, 0.0, -0.045226905, -0.041799217, -0.042511635, 0.0, -0.10267792, -0.1123385, -0.10845448, 0.0) * go_0(0.0, 0.0); result += mat4(0.011987401, 0.012285043, 0.007813165, 0.0, -0.15911353, -0.17523928, -0.1535267, 0.0, 0.15675929, 0.16531634, 0.15948962, 0.0, -0.09240023, -0.09513292, -0.084187366, 0.0) * go_0(0.0, 1.0); result += mat4(0.069052905, 0.07278333, 0.0756627, 0.0, -0.012180326, -0.018794727, -0.031050753, 0.0, -0.044663202, -0.04362803, -0.038904265, 0.0, -0.008540197, -0.011201734, -0.01556625, 0.0) * go_0(1.0, -1.0); result += mat4(-0.08261173, -0.09042543, -0.07589266, 0.0, 0.043515377, 0.045066774, 0.04037769, 0.0, -0.06262993, -0.07469342, -0.058593787, 0.0, 0.026696987, 0.028740842, 0.037405368, 0.0) * go_0(1.0, 0.0); result += mat4(0.07975598, 0.09597654, 0.08997132, 0.0, -0.07844719, -0.07880916, -0.06835411, 0.0, 0.05668995, 0.050163813, 0.053357534, 0.0, -0.020040333, -0.019867316, -0.01907621, 0.0) * go_0(1.0, 1.0); result += mat4(-0.017078733, -0.017393313, -0.008266595, 0.0, -0.0033478448, -0.0027439648, -0.0042334674, 0.0, -0.06354017, -0.062058125, -0.04652064, 0.0, -0.010787706, -0.0062706997, -0.007573461, 0.0) * go_1(-1.0, -1.0); result += mat4(-0.019895451, -0.016341688, -0.008712399, 0.0, 0.026231976, 0.023955572, 0.0216376, 0.0, -0.061950512, -0.05481285, -0.05261985, 0.0, -0.018804235, -0.016235247, -0.0131616965, 0.0) * go_1(-1.0, 0.0); result += mat4(-0.055628926, -0.063315354, -0.057192408, 0.0, -0.0256364, -0.028660972, -0.02937357, 0.0, -0.017604912, -0.020851422, -0.016070362, 0.0, -0.0870202, -0.0832279, -0.07525406, 0.0) * go_1(-1.0, 1.0); result += mat4(0.062738225, 0.07106593, 0.061644047, 0.0, -0.06068257, -0.06983662, -0.066070385, 0.0, 0.024919355, 0.03227179, 0.028569462, 0.0, -0.07866227, -0.098967604, -0.092128105, 0.0) * go_1(0.0, -1.0); result += mat4(0.040397774, 0.047241107, 0.03962998, 0.0, -0.09112752, -0.10057507, -0.09301817, 0.0, 0.10833967, 0.101835825, 0.10027467, 0.0, 0.27189335, 0.27433604, 0.26781923, 0.0) * go_1(0.0, 0.0); result += mat4(-0.044211388, -0.042373534, -0.03658007, 0.0, 0.113148406, 0.12423258, 0.107804194, 0.0, -0.17081551, -0.18562958, -0.17475435, 0.0, 0.09636739, 0.10763415, 0.093332425, 0.0) * go_1(0.0, 1.0); result += mat4(-0.03798545, -0.047811143, -0.050768293, 0.0, 0.018775463, 0.026812987, 0.03452908, 0.0, 0.0055677597, 0.0039081173, -0.0017878668, 0.0, -0.10728597, -0.12618187, -0.109045394, 0.0) * go_1(1.0, -1.0); result += mat4(0.06359783, 0.064184755, 0.04934199, 0.0, -0.009819327, -0.006616115, -0.007431496, 0.0, 0.025055679, 0.024787048, 0.017360551, 0.0, -0.047140837, -0.061695747, -0.06440822, 0.0) * go_1(1.0, 0.0); result += mat4(0.060199022, 0.06482763, 0.059514645, 0.0, 0.026998974, 0.028776823, 0.024897143, 0.0, 0.17968474, 0.19337215, 0.16760105, 0.0, 0.0075838566, 0.010503482, 0.011993149, 0.0) * go_1(1.0, 1.0); result += vec4(-0.0052927984, -0.0060193934, -0.0048643993, 0.0); return result + MAIN_tex(MAIN_pos); } ================================================ FILE: app/src/main/assets/shaders/Anime4K_Restore_CNN_VL.glsl ================================================ // MIT License // Copyright (c) 2019-2021 bloc97 // All rights reserved. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x3 //!HOOK MAIN //!BIND MAIN //!SAVE conv2d_tf //!WIDTH MAIN.w //!HEIGHT MAIN.h //!COMPONENTS 4 #define go_0(x_off, y_off) (MAIN_texOff(vec2(x_off, y_off))) vec4 hook() { vec4 result = mat4(0.1690102, -0.2560719, 0.39658326, -0.3679659, -0.27616683, -0.35619372, -0.3748396, 0.08430813, -0.29574734, -0.31511316, -0.09773105, 0.13616018, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, -1.0); result += mat4(-0.1326393, -0.259433, 0.025070239, 0.58914864, -0.036478516, 0.30723435, 0.007458902, 0.012962684, 0.2493056, 0.13007334, -0.08448256, -0.38414413, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 0.0); result += mat4(-0.11539356, 0.35253766, 0.26143202, 0.2760807, -0.09371543, -0.028165473, -0.028452158, -0.27050856, 0.06718067, -0.0056619495, -0.17654495, 0.17288211, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 1.0); result += mat4(-0.16145481, -0.3204927, -0.54317135, 0.11830119, 0.49315026, 0.12008072, 0.50857407, -0.30382085, 0.25807253, 0.020755528, 0.29388228, 0.106109895, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, -1.0); result += mat4(-0.22728722, 0.50484747, -0.07904469, 0.33114597, 0.50306976, -0.22760947, 0.14773269, 0.17628263, 0.14788547, -0.08223464, -0.10880935, -0.3151985, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 0.0); result += mat4(0.3414351, 0.057279214, -0.14419858, 0.09761111, -0.11794496, 0.021717256, -0.22750235, 0.13986664, -0.38932344, 0.28996095, 0.3773904, 0.13175532, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 1.0); result += mat4(0.1376552, -0.19587159, -0.35147396, -0.097646296, 0.1686707, -0.14385861, 0.031198, 0.12383533, -0.23089902, 0.08707301, 0.3362293, -0.100579016, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, -1.0); result += mat4(-0.056774966, 0.047585852, -0.36395878, -0.20211312, 0.4077735, 0.12631284, 0.39813092, -0.033365678, 0.2307249, -0.09131807, 0.20823865, 0.31084216, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 0.0); result += mat4(-0.12456089, 0.09755632, 0.31490886, -0.06579996, -0.13386595, 0.07564795, -0.26605195, -0.075180635, -0.11182657, 0.06757017, -0.14351276, -0.16828312, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 1.0); result += vec4(-0.046043985, 0.055581126, -0.08791638, -0.13022089); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x3 //!HOOK MAIN //!BIND MAIN //!SAVE conv2d_tf1 //!WIDTH MAIN.w //!HEIGHT MAIN.h //!COMPONENTS 4 #define go_0(x_off, y_off) (MAIN_texOff(vec2(x_off, y_off))) vec4 hook() { vec4 result = mat4(-0.15485518, -0.29363206, -0.22610365, -0.14291525, -0.45240572, -0.18319772, -0.12209436, 0.15031648, 0.09878383, 0.06711082, 0.25763842, -0.084633484, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, -1.0); result += mat4(-0.10204406, 0.16167697, 0.22371867, -0.37947702, -0.24476196, -0.038824454, 0.060157117, 0.15764871, -0.08072927, -0.2210841, -0.31835055, 0.009979876, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 0.0); result += mat4(0.20506924, 0.21132155, -0.0922578, -0.07430473, 0.14529926, 0.20549752, 0.0077948375, 0.13246094, -0.32353187, 0.21074104, 0.092629515, 0.17590871, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 1.0); result += mat4(0.04125819, -0.44050243, 0.23729716, 0.3218237, 0.12943116, -0.011674174, 0.10390632, 0.027775545, -0.20308031, -0.16904089, -0.2121676, -0.022515794, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, -1.0); result += mat4(0.09664124, 0.20127031, 0.60345304, 0.16697013, 0.23093723, -0.38116834, 0.109695725, 0.0007595324, 0.4092646, 0.009624758, 0.11229678, 0.25326383, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 0.0); result += mat4(0.014879592, 0.19204311, 0.07102085, -0.7312604, 0.34860876, 0.3429918, -0.027331594, 0.27636307, 0.1342437, 0.107820466, -0.12645108, 0.21081445, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 1.0); result += mat4(-0.12687613, -0.09247973, -0.25973785, 0.4350873, -0.18987224, 0.028678741, -0.0903819, -0.63974863, 0.205591, 0.11308998, 0.18458389, -0.4149041, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, -1.0); result += mat4(0.34691808, -0.025498383, 0.3428986, 0.21663484, 0.23404741, -0.1725327, -0.0036315925, -0.13299675, -0.1873967, 0.031331502, -0.08785591, -0.0013278709, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 0.0); result += mat4(-0.35846514, 0.048703704, -0.104165934, 0.16529736, -0.15378916, 0.26030356, -0.07134151, 0.03692383, -0.15807101, -0.18885155, 0.044707954, -0.11444462, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 1.0); result += vec4(-0.0022791293, -0.024132347, -0.57621074, 0.028573977); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_tf //!BIND conv2d_tf1 //!SAVE conv2d_1_tf //!WIDTH conv2d_tf.w //!HEIGHT conv2d_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.010346764, 0.07230188, -0.24734616, -0.09937907, 0.02228549, -0.19550583, -0.019540425, -0.1037373, 0.033996485, -0.075554, -0.20228972, 0.07090153, -0.09194035, -0.058972966, 0.1768268, 0.27517542) * go_0(-1.0, -1.0); result += mat4(0.020078976, 0.12433655, -0.1620775, 0.036401592, 0.079748705, 0.11660013, 0.17917652, -0.017513236, -0.18936846, 0.24478136, -0.45726213, -0.045004416, -0.08295188, 0.067733586, -0.080548316, 0.2744211) * go_0(-1.0, 0.0); result += mat4(0.024916803, 0.27562472, 0.043771956, -0.012240604, 0.0786355, 0.042651594, 0.16049327, -0.14577515, -0.032735053, 0.17658092, 0.16382934, -0.02337374, 0.11551492, 0.056343183, -0.17930213, 0.14259394) * go_0(-1.0, 1.0); result += mat4(0.20010485, 0.06747722, -0.19026905, 0.11013709, 0.13062745, -0.044626113, -0.0062261797, 0.2189639, 0.1403497, -0.022713251, -0.19452858, -0.010305412, -0.06407589, 0.09836748, 0.025805516, 0.23430973) * go_0(0.0, -1.0); result += mat4(-0.14664203, 0.034910418, 0.024714258, -0.066872925, -0.15717538, -0.14179383, -0.14091893, 0.05859166, 0.18919097, -0.18544437, -0.09068573, -0.08615929, -0.051434122, 0.2170678, 0.18409058, -0.17461225) * go_0(0.0, 0.0); result += mat4(-0.11354446, 0.10745854, 0.2682663, 0.05949201, -0.10695986, 0.1407851, -0.03551388, 0.10691649, -0.17148238, -0.38287184, 0.2074456, 0.11828914, 0.048535194, 0.1464864, -0.18169662, -0.14074169) * go_0(0.0, 1.0); result += mat4(0.22160622, -0.1513045, -0.053284165, 0.033202525, 0.15574448, -0.043640967, -0.0093824165, -0.0019965349, -0.097964935, -0.08289824, 0.08239996, 0.07868361, 0.05731752, -0.20441617, -0.013016076, -0.253108) * go_0(1.0, -1.0); result += mat4(-0.031249097, -0.2272863, 0.23573665, 0.03357689, 0.011395065, -0.10885564, -0.06287508, -0.031719524, 0.10331069, 0.17560169, 0.18303394, 0.022961004, -0.17011635, -0.24371737, 0.10678694, -0.3222825) * go_0(1.0, 0.0); result += mat4(-0.1275465, -0.08844758, 0.10994917, -0.00910273, 0.09393154, 0.03894992, 0.14367905, -0.11811715, -0.09077633, -0.015776094, 0.27427456, -0.13283503, 0.18724327, -0.08139094, 0.04933602, -0.051852766) * go_0(1.0, 1.0); result += mat4(-0.06764611, -0.27426586, 0.12045272, 0.09410856, -0.14258035, 0.11802992, -0.09093882, 0.0022018093, 0.4590643, 0.046258576, -0.07827223, 0.448011, -0.103631735, -0.016930219, -0.15421398, 0.11045997) * go_1(-1.0, -1.0); result += mat4(-0.17295076, 0.00151352, 0.14938255, 0.08336512, -0.07496541, -0.07561223, -0.0846474, 0.14979269, -0.09142163, 0.23925088, -0.015199518, -0.37749895, -0.20636298, -0.022585187, -0.20371509, 0.0745308) * go_1(-1.0, 0.0); result += mat4(0.06458832, -0.009722021, -0.123604394, 0.06548835, -0.3039139, -0.022024399, 0.05297587, -0.0626883, 0.23556642, 0.1516464, -0.07004877, -0.1845364, -0.05918428, 0.19158973, -0.14983447, 0.030489758) * go_1(-1.0, 1.0); result += mat4(0.36604697, 0.17516142, -0.10853731, -0.22694224, -0.107650936, 0.23013335, 0.094055794, -0.17047717, -0.3006048, -0.08621717, -0.18815655, -0.03570218, 0.09676118, -0.017718751, 0.059138596, 0.073388465) * go_1(0.0, -1.0); result += mat4(-0.12791575, 0.101956226, 0.13091874, -0.046373338, 0.04955811, -0.04030444, 0.13869923, -0.046699073, -0.42611042, -0.7173929, 0.052184317, 0.6178025, -0.02929954, -0.07638965, -0.15000828, 0.030710017) * go_1(0.0, 0.0); result += mat4(0.057806686, 0.20842272, -0.20148766, 0.006666912, 0.13356528, -0.45265228, -0.07354092, 0.21447696, 0.019552143, -0.13645506, 0.14643854, -0.0071413796, -0.15487236, -0.002250615, 0.30622452, 0.0033902125) * go_1(0.0, 1.0); result += mat4(0.06896002, 0.24397352, -0.06479052, 0.20676947, -0.24259068, 0.055320013, -0.09032122, -0.11222854, -0.08982342, -0.114818625, -0.06399291, -0.3024516, -0.06302166, -0.1925528, 0.03458982, 0.028828239) * go_1(1.0, -1.0); result += mat4(0.09764086, 0.09599894, -0.0073313303, 0.14418933, -0.045712367, 0.12657364, 0.04620374, -0.069778584, 0.30047333, -0.012418192, 0.15516461, -0.18087754, 0.08178273, 0.14262857, -0.01741533, -0.12509112) * go_1(1.0, 0.0); result += mat4(0.04697884, -0.1506804, 0.031823065, 0.13397239, -0.18396698, 0.10681781, -0.29586303, -0.0039136545, 0.17560847, -0.12486726, -0.018646788, -0.20688744, -0.030614454, -0.0527634, 0.23593572, -0.10542146) * go_1(1.0, 1.0); result += mat4(-0.19182229, -0.32615846, 0.26283535, -0.1371942, -0.071202695, 0.12056063, -0.11450658, -0.27711076, -0.42096004, 0.0014352369, 0.1559669, -0.14464542, -0.17973948, 0.079166576, -0.12501791, -0.20623216) * go_2(-1.0, -1.0); result += mat4(0.12469872, 0.32190827, -0.059510354, 0.1393449, -0.12845798, -0.019571869, -0.22630808, -0.14031963, 0.36072046, 0.05858427, 0.19278921, 0.121090546, -0.067538865, -0.018770566, 0.14318037, -0.15561756) * go_2(-1.0, 0.0); result += mat4(0.024663208, 0.21110268, -0.016415706, 0.060093414, -0.03739678, -0.107412934, -0.077527136, 0.30331334, 0.17196326, -0.15512557, -0.09499732, -0.15748607, -0.16680105, -0.015185634, 0.16114107, -0.21288376) * go_2(-1.0, 1.0); result += mat4(-0.17739037, -0.1190967, 0.13191372, -0.2527187, -0.14992718, -0.30511454, 0.19145966, 0.002194003, -0.12888977, 0.19152176, 0.27528167, 0.099714965, 0.12865707, -0.12051514, -0.055013947, 0.26231763) * go_2(0.0, -1.0); result += mat4(0.46433613, -0.11708138, -0.20157282, 0.32022122, 0.079468675, 0.029407484, 0.2559102, -0.15651533, 0.08644574, -0.09747344, -0.07528584, 0.17354868, 0.19167562, -0.17698488, -0.09896657, 0.17093097) * go_2(0.0, 0.0); result += mat4(0.20283653, -0.33680332, 0.2282385, 0.18832158, 0.20866042, 0.00076752366, 0.16471444, -0.21548858, 0.16193539, 0.17141372, 0.03140222, 0.03913644, -0.030161971, 0.00014570929, 0.08993654, -0.064823024) * go_2(0.0, 1.0); result += mat4(-0.3075755, 0.19942546, 0.015526995, -0.120868504, -0.254515, -0.07791228, 0.03271691, 0.11794217, 0.11258601, 0.045204375, -0.061196107, -0.115958795, 0.3861869, 0.048215542, 0.07016682, -0.009975758) * go_2(1.0, -1.0); result += mat4(-0.07623697, 0.16094944, -0.02283455, 0.14112763, -0.051149167, 0.20429814, 0.011314802, 0.18914083, -0.24240434, -0.08784008, -0.16763984, -0.08492233, 0.31062725, -0.11925119, -0.33195966, 0.2060798) * go_2(1.0, 0.0); result += mat4(-0.016709225, -0.14472668, -0.3677625, -0.09832719, 0.030297454, -0.05775362, -0.1401375, 0.08119674, -0.01795042, 0.05183797, -0.24320887, 0.066842034, -0.22245285, -0.02740993, 0.06316751, 0.053399116) * go_2(1.0, 1.0); result += mat4(-0.039214406, -0.08876633, 0.045552462, 0.19226661, 0.1355001, -0.13942362, 0.17398876, 0.2914014, -0.191809, 0.037143208, 0.013333581, -0.16632195, 0.113767646, -0.106692605, 0.1589787, 0.030107044) * go_3(-1.0, -1.0); result += mat4(0.21997562, 0.13855208, -0.05783191, -0.033682413, -0.010961168, 0.10524961, 0.02177416, 0.18289444, 0.043692037, 0.07853899, -0.039936125, -0.1004449, 0.04494073, -0.020680292, 0.17578089, -0.106598996) * go_3(-1.0, 0.0); result += mat4(0.026852835, -0.16037546, 0.11278316, 0.12656097, -0.006857894, -0.03400118, -0.051564034, 0.00085412664, -0.37556714, -0.05279987, 0.029383834, -0.14246808, -0.056380164, -0.002399925, 0.16025752, 0.036324855) * go_3(-1.0, 1.0); result += mat4(0.022709966, 0.046350412, 0.03390721, 0.02810572, -0.14394265, 0.04215361, -0.3206118, 0.15034916, -0.0028448137, 0.1682989, -0.042686664, 0.020543462, -0.2786501, -0.007482015, -0.040313292, -0.20745736) * go_3(0.0, -1.0); result += mat4(0.05417556, 0.18728684, -0.046121832, -0.27939513, 0.05907976, -0.09191223, -0.16625418, -0.26038164, 0.39956605, -0.052594025, -0.0596556, 0.29517552, -0.015181923, -0.0763375, 0.25131205, 0.13038464) * go_3(0.0, 0.0); result += mat4(-0.036903054, -0.0066989153, -0.062650286, 0.05614359, -0.0064960583, 0.028512698, -0.10906273, -0.010047654, 0.23030473, 0.049983572, 0.10439064, 0.26643834, 0.05041243, 0.09185424, -0.32352915, 0.11295159) * go_3(0.0, 1.0); result += mat4(0.09724027, -0.34962535, 0.06586686, 0.016635379, 0.13831381, 0.01707076, -0.04690347, 0.022350075, 0.018352794, 0.022000022, 0.070613205, 0.117735535, -0.025971051, 0.18832101, -0.09643588, -0.08512127) * go_3(1.0, -1.0); result += mat4(-0.17324433, 0.06810613, -0.057295907, -0.05115964, -0.101570815, 0.12491774, 0.08762367, -0.005862404, -0.05342927, -0.031942457, -0.039624047, -0.04298937, -0.1303138, -0.11869282, -0.024832053, 0.070463404) * go_3(1.0, 0.0); result += mat4(-0.010514842, 0.1376259, -0.11750346, -0.03786737, 0.03459249, 0.015408171, -0.031430878, -0.060825355, -0.072958425, -0.0037895301, 0.041686177, -0.12352204, -0.06261361, 0.054514423, -0.34072715, 0.13860728) * go_3(1.0, 1.0); result += vec4(0.018166734, -0.11002478, -0.05554318, -0.0988193); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_tf //!BIND conv2d_tf1 //!SAVE conv2d_1_tf1 //!WIDTH conv2d_tf.w //!HEIGHT conv2d_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.040142782, 0.0288423, 0.07569487, -0.01490842, 0.14402796, -0.13682005, 0.027765118, 0.03907358, 0.07117706, 0.058157545, -0.23862502, -0.057674367, -0.19220531, 0.0147159435, -0.18028538, 0.0963821) * go_0(-1.0, -1.0); result += mat4(-0.1676744, -0.11937339, 0.12137117, 0.07119485, 0.14148116, -0.043578617, -0.029261118, -0.0016938087, -0.057269357, -0.080076694, 0.12193026, 0.07326153, -0.056278303, -0.01630716, -0.03792076, 0.1483611) * go_0(-1.0, 0.0); result += mat4(-0.3021578, 0.011601693, 0.11266048, 0.19086999, -0.0122412145, 0.08431291, 0.11615175, -0.008039614, -0.39987534, 0.07820729, 0.03509667, 0.1963505, -0.08839513, -0.21571854, 0.059425723, -0.06830175) * go_0(-1.0, 1.0); result += mat4(0.23135209, -0.12452708, 0.0943565, 0.0028859286, -0.09836373, 0.10681712, -0.3535964, 0.08457615, 0.045332734, 0.16579892, -0.03809797, -0.021596594, 0.2937497, -0.028294371, 0.046484597, -0.037604347) * go_0(0.0, -1.0); result += mat4(0.072675414, -0.16431206, 0.28952035, 0.0076831076, -0.020242939, 0.029483542, -0.092415355, 0.08673106, 0.12109694, 0.14307201, 0.23134442, 0.11731775, 0.09981601, -0.16968462, 0.037470713, 0.14948717) * go_0(0.0, 0.0); result += mat4(0.0029752052, 0.06526503, 0.1866458, 0.07451277, -0.31836876, 0.17115082, -0.13969697, 0.23844297, -0.03244903, -0.08832665, 0.023691226, -0.18230624, -0.074933805, -0.00044301842, 0.050572682, 0.081511915) * go_0(0.0, 1.0); result += mat4(0.039502528, 0.051221415, -0.13968123, -0.091212444, -0.016925618, 0.15409444, -0.017455677, -0.11653652, 0.03539446, -0.00087720866, -0.12839639, 0.037198763, 0.03674469, -0.26444665, 0.019721227, -0.13013805) * go_0(1.0, -1.0); result += mat4(0.039229527, 0.25667152, 0.0032586441, -0.00718359, 0.1617932, 0.10409968, 0.07182867, -0.09810605, 0.07789241, -0.02014911, 0.025767172, -0.14604759, 0.07175764, 0.32513744, -0.20473222, -0.16266066) * go_0(1.0, 0.0); result += mat4(0.13418433, 0.061813723, -0.13927278, -0.2498272, 0.03468218, 0.29483125, 0.063289374, -0.04726235, 0.1898295, -0.33132064, 0.032045014, 0.02159535, -0.1148363, 0.31306976, 0.06456038, 0.048988886) * go_0(1.0, 1.0); result += mat4(0.07151646, 0.2799246, -0.107190795, -0.16431166, -0.28007045, 0.07206954, 0.06775463, 0.009758042, 0.07032184, -0.20843789, 0.087045245, 0.1360676, -0.25718534, 0.028249472, -0.12614648, 0.009949602) * go_1(-1.0, -1.0); result += mat4(0.020241471, -0.23390484, -0.0083223935, 0.08344701, 0.08222297, 0.12026539, -0.08652223, -0.08228822, -0.039576706, -0.24677879, -0.1157289, 0.2590508, -0.23809408, 0.19911982, -0.116798095, -0.035870325) * go_1(-1.0, 0.0); result += mat4(0.024991842, 0.050509237, -0.024134455, -0.12659028, 0.24089767, 0.122712664, -0.10482493, -0.19403952, -0.19177693, -0.06538376, -0.041478425, 0.32176673, -0.1534002, -0.18680622, 0.06763643, 0.020806564) * go_1(-1.0, 1.0); result += mat4(0.03437814, -0.28067374, 0.2830681, 0.038812317, -0.021698112, -0.120865285, 0.22695538, -0.045419116, -0.030475847, -0.01977341, -0.1265364, -0.3109814, 0.012255813, 0.053917278, -0.018620957, -0.14599285) * go_1(0.0, -1.0); result += mat4(-0.016204128, -0.04093018, 0.054571863, 0.02679643, 0.01756274, -0.057685968, 0.16148666, 0.17370272, -0.11065411, 0.06378157, -0.09331551, 0.22985275, 0.057905316, 0.12323568, 0.07748665, 0.09878629) * go_1(0.0, 0.0); result += mat4(-0.018112244, 0.063234635, -0.013184602, 0.16241394, 0.08877139, 0.02145378, -0.02490027, -0.038920373, 0.13127136, 0.14391647, 0.020553736, 0.14401346, 0.06685973, -0.25398204, 0.10369067, -0.055949755) * go_1(0.0, 1.0); result += mat4(0.07710333, 0.047412727, 0.13813803, 0.18624061, 0.16907091, -0.039532468, 0.06234584, 0.06408178, -0.054543987, -0.045220226, -0.11093376, -0.37399602, 0.20372874, 0.004580967, -0.07742308, 0.017989937) * go_1(1.0, -1.0); result += mat4(0.003485311, -0.08897399, -0.013108594, -0.19473282, -0.27081844, -0.16812073, 0.0052992934, -0.055331517, 0.09446357, 0.019280333, 0.16560757, -0.3230032, 0.043096773, 0.059222896, -0.064184934, -0.059852477) * go_1(1.0, 0.0); result += mat4(0.06794279, -0.034135245, 0.083064295, 0.13506731, 0.13064219, -0.44978833, -0.03513717, 0.08999715, 0.1124541, 0.42208397, -0.0038724816, -0.014332087, -0.13751853, -0.04929869, 0.09134992, -0.17687531) * go_1(1.0, 1.0); result += mat4(0.100909084, -0.0131197255, 0.082274795, -0.2138443, -0.08515947, -0.021058358, 0.10951775, -0.06349191, -0.29129833, -0.029262653, 0.25235432, -0.11748315, 0.121980384, 0.062347785, 0.10916932, -0.15993518) * go_2(-1.0, -1.0); result += mat4(0.28893283, -0.05677308, -0.2641288, -0.058937225, -0.16187571, 0.006647366, -0.063294955, 0.04766719, 0.60601914, -0.07831864, -0.15710756, -0.011491797, 0.15587467, -0.08105375, 0.07847514, -0.2803333) * go_2(-1.0, 0.0); result += mat4(-0.077989794, -0.09871811, -0.3516344, 0.15292728, 0.010889273, 0.0011189661, -0.16118282, -0.018821161, -0.039708678, -0.00060983415, -0.06367813, 0.009148068, 0.03919827, 0.18782744, 0.028040757, -0.10230145) * go_2(-1.0, 1.0); result += mat4(-0.4079609, 0.18640275, -0.12475227, 0.13891742, 0.25121725, 0.16942379, 0.14409852, 0.087600805, 0.045335658, -0.12683709, -0.0077387216, 0.06563413, -0.19857128, 0.106910795, -0.048285246, 0.10768945) * go_2(0.0, -1.0); result += mat4(0.5989075, 0.20941062, -0.20086494, 0.13344856, 0.073034994, 0.22358665, 0.101664364, -0.13463663, 0.18816395, -0.061176624, -0.14712185, 0.027320342, -0.09529667, 0.031148786, -0.28744993, 0.18698911) * go_2(0.0, 0.0); result += mat4(0.14799193, 0.39471942, -0.23340325, -0.4031061, 0.18926248, -0.11091216, 0.118981816, -0.09155061, 0.17049436, 0.19803695, -0.1513267, 0.023817873, 0.0090933135, -0.04134864, 0.060486555, 0.03536634) * go_2(0.0, 1.0); result += mat4(-0.39094314, 0.01779997, 0.12710269, 0.0067333193, -0.31255835, -0.08206612, -0.048528638, 0.369439, -0.19351655, -0.03420455, 0.15831526, -0.052294146, -0.08481741, 0.0787108, 0.1312136, -0.108919285) * go_2(1.0, -1.0); result += mat4(-0.16068119, -0.42190582, 0.19383872, -0.018445708, 0.09803051, -0.020769652, -0.022599563, -0.052448895, -0.20645833, -0.031432863, 0.0025441595, 0.03410379, -0.20268854, 0.04481527, 0.05191063, 0.42317194) * go_2(1.0, 0.0); result += mat4(-0.12786235, -0.23936178, 0.116561726, 0.30756372, -0.09420156, -0.044529166, -0.03585749, 0.1829332, -0.23939075, 0.24030831, 0.019878127, -0.015069802, 0.24300557, -0.22558568, -0.104956664, -0.09393648) * go_2(1.0, 1.0); result += mat4(-0.04607054, 0.012677649, -0.027597688, 0.1618836, 0.29210827, 0.014221155, -0.13591036, -0.06895336, -0.09559534, 0.07956421, -0.11112994, -0.13325493, 0.24562472, 0.11046177, 0.057847694, 0.0016315983) * go_3(-1.0, -1.0); result += mat4(-0.03365951, 0.027391057, 0.09653403, -0.14718771, -0.049631152, -0.06467214, -0.058545876, 0.1424002, -0.06320376, 0.181183, 0.10249362, -0.16052136, 0.3013475, -0.04156266, 0.08862033, 0.06888033) * go_3(-1.0, 0.0); result += mat4(0.10045977, -0.004198456, -0.025856055, 0.05739418, -0.1328637, -0.025975171, 0.06553717, 0.11301186, 0.0704087, -0.083569765, 0.16066101, -0.24453588, 0.25370175, 0.037184533, 0.062386766, -0.20025635) * go_3(-1.0, 1.0); result += mat4(-0.017958941, 0.06417776, -0.1525265, 0.12451173, 0.14567685, -0.0049682115, -0.23973411, -0.0783304, -0.010629432, 0.08055161, 0.2028341, 0.17640644, -0.20445108, -0.055524793, -0.019326134, 0.081288636) * go_3(0.0, -1.0); result += mat4(0.007882519, -0.03722546, 0.053249408, 0.00071846246, -0.07053029, -0.21583866, 0.1415364, -0.19486657, 0.20685542, 0.17660026, -0.32156837, 0.1746825, -0.14957622, -0.09224378, -0.098153435, -0.13054638) * go_3(0.0, 0.0); result += mat4(0.10051427, -0.17398237, 0.09842799, -0.14187703, 0.116901085, -0.1229543, -0.0007776771, -0.20410055, -0.11373484, -0.111150615, -0.1974002, -0.11641459, 0.024105398, 0.24985977, 0.015871854, -0.10724633) * go_3(0.0, 1.0); result += mat4(-0.18081793, 0.1209351, -0.12867971, -0.019415248, 0.062617876, -0.037130393, -0.07803658, -0.22862352, 0.2586428, -0.030090366, -0.11894069, 0.18087515, -0.40921417, 0.070013195, 0.030540073, 0.035120826) * go_3(1.0, -1.0); result += mat4(-0.13185939, 0.12992652, 0.08125049, 0.075331174, 0.064219765, 0.056629725, -0.020012032, -0.0855444, -0.044063166, -0.05396545, -0.028002812, 0.21837157, -0.15206428, -0.12681007, 0.14895032, 0.12339962) * go_3(1.0, 0.0); result += mat4(0.08066341, -0.14773634, -0.0212227, -0.014011867, -0.048505764, 0.075407125, -0.020620076, 0.0003291325, -0.21815202, -0.23136546, 0.10853532, -0.036058456, 0.10952532, -0.052677035, -0.13005799, 0.18398996) * go_3(1.0, 1.0); result += vec4(0.022609137, -0.028548084, 0.024431901, 0.010504478); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_1_tf //!BIND conv2d_1_tf1 //!SAVE conv2d_2_tf //!WIDTH conv2d_1_tf.w //!HEIGHT conv2d_1_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_1_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_1_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.069641694, 0.104958326, 0.14786446, 0.027633663, -0.004279524, -0.020451711, 0.0883571, -0.016224537, 0.13585235, 0.11078269, 0.20198658, -0.042161036, 0.020466218, 0.20994963, 0.20072585, -0.028024657) * go_0(-1.0, -1.0); result += mat4(0.050872434, 0.12874635, 0.1298729, 0.115810685, 0.07087254, 0.09885682, 0.23018982, 0.19187538, 0.10953604, 0.0033836907, -0.13325337, 0.09830315, -0.06528767, 0.05096927, -0.016355392, -0.039334368) * go_0(-1.0, 0.0); result += mat4(0.027010268, 0.018263958, 0.0360758, 0.016791478, 0.2815702, 0.15517488, 0.43415815, 0.044976447, -0.0070842914, -0.12546758, 0.16874593, 0.077622116, 0.02252915, 0.1769774, 0.07181055, -0.15128697) * go_0(-1.0, 1.0); result += mat4(0.057129618, 0.118046716, 0.07237424, -0.07842637, -0.044214778, -0.12886304, 0.08603301, -0.10416606, -0.15852053, 0.3788151, 0.26181692, -0.09092249, 0.31635332, 0.064212754, 0.21923725, 0.07500004) * go_0(0.0, -1.0); result += mat4(-0.16981383, 0.044409662, -0.3717617, -0.031610407, 0.03658662, -0.09459229, -0.09449437, -0.014000666, -0.19656453, 0.03934163, -0.16304104, -0.12761801, -0.06235523, 0.16438273, -0.036933117, -0.095564745) * go_0(0.0, 0.0); result += mat4(0.09725091, 0.034022827, 0.17699842, 0.1079676, -0.13236652, 0.03718181, -0.06968635, -0.23288171, 0.10275666, 0.08464966, -0.37162134, -0.35782215, -0.11023659, 0.2519236, -0.035197742, -0.019324787) * go_0(0.0, 1.0); result += mat4(-0.09968464, 0.01102193, 0.0073735216, 0.011999313, -0.004998707, 0.09518938, 0.045727003, -0.21544908, 0.006879454, -0.06398254, -0.12584935, -0.06759933, -0.0820037, -0.07775104, 0.021957919, -0.122708224) * go_0(1.0, -1.0); result += mat4(-0.08869767, 0.031296413, -0.0034280645, 0.13778855, 0.10073061, -0.08393937, -0.032959275, -0.0500518, 0.010908757, -0.09189417, -0.057760105, 0.17652664, -0.08729078, -0.09639096, -0.25654703, 0.055152636) * go_0(1.0, 0.0); result += mat4(0.0027847723, -0.12885433, 0.038065907, 0.17450769, 0.0864409, 0.04592345, -0.015443841, 0.077010944, 0.08967368, 0.06800111, -0.23636387, 0.35023567, 0.03165923, 0.03132063, 0.17964344, 0.035610788) * go_0(1.0, 1.0); result += mat4(-0.032017227, -0.0022808525, -0.08470573, 0.05332408, -0.14674746, 0.025374275, -0.018281924, 0.041163016, 0.00096549373, 0.014724006, 0.004913065, 0.18494442, 0.034953076, -0.15731992, -0.13792977, 0.08041999) * go_1(-1.0, -1.0); result += mat4(0.08305006, 8.6318905e-05, -0.007895379, 0.02731387, -0.061324496, 0.050034665, 0.22662131, -0.013876427, -0.074468784, -0.008136604, -0.23337875, -0.1742574, 0.011753501, -0.11666686, -0.22541048, -0.14549944) * go_1(-1.0, 0.0); result += mat4(-0.028333234, 0.121047184, 0.06720256, -0.058930036, 0.030258363, 0.07292774, 0.06455556, 0.0019076486, 0.0073987027, 0.17144889, 0.06084024, -0.08762086, -0.114422195, -0.16595861, -0.08706028, -0.10736261) * go_1(-1.0, 1.0); result += mat4(-0.02519315, -0.14611271, 0.0388848, 0.19481422, -0.05970354, -0.08391417, 0.18982239, -0.10447052, 0.15587378, -0.023997072, 0.0781739, 0.2182389, -0.023886079, -0.1422596, -0.13352804, 0.005008043) * go_1(0.0, -1.0); result += mat4(0.08842712, -0.100292705, 0.18925671, 0.12198875, 0.061771665, -0.04473232, 0.025053164, 0.039047796, -0.1672479, -0.08934517, 0.33099812, -0.20269585, -0.21640155, -0.22029749, 0.16539703, -0.2442679) * go_1(0.0, 0.0); result += mat4(-0.16332205, -0.101898365, 0.02919932, -0.11900455, 0.14442924, 0.0916815, 0.037550304, 0.024123482, 0.02042624, 0.033472955, -0.059437107, -0.18735693, -0.013749093, -0.06199881, -0.08685079, 0.04252364) * go_1(0.0, 1.0); result += mat4(-0.09047013, -0.055188328, -0.09106191, -0.048969727, 0.05114009, -0.12753403, 0.07116141, 0.060749624, -0.074034564, -0.21952136, -0.09479503, 0.2753584, -0.014141759, -0.14883812, -0.0673838, -0.012279045) * go_1(1.0, -1.0); result += mat4(0.013816464, -0.0747162, -0.19202435, -0.064403646, 0.34980014, 0.04375546, 0.20264609, 0.006684355, 0.11523799, 0.024674915, -0.08697566, -0.04662527, -0.12743855, -0.39463726, 0.0057380227, 0.01286557) * go_1(1.0, 0.0); result += mat4(-0.08146522, 0.074080914, -0.16856177, -0.183158, 0.19228102, 0.12373886, 0.017574452, -0.01753772, 0.045071773, 0.07725093, 0.023422163, -0.011545186, 0.20751388, -0.10795588, 0.07606346, 0.10282933) * go_1(1.0, 1.0); result += mat4(0.12512013, -0.102208994, -0.09125398, 0.12043188, -0.066011876, 0.08831903, -0.017038671, -0.005541508, -0.049607087, 0.08654939, -0.02037085, 0.26887566, 0.005012545, 0.01869507, -0.013064982, -0.010649147) * go_2(-1.0, -1.0); result += mat4(0.006824864, -0.05071593, -0.20786697, -0.07327317, 0.011382597, 0.030494886, -0.04754353, -0.018284699, 0.01305972, -0.036589053, 0.26637617, 0.021887446, -0.026669119, -0.037982125, -0.063445956, -0.009104248) * go_2(-1.0, 0.0); result += mat4(0.032602567, 0.07094331, 0.052653246, 0.08342047, -0.085082285, -0.14674088, -0.23073354, -0.07915851, 0.0017120204, 0.032407638, -0.039819505, 0.16942178, 0.023192152, -0.0353237, 0.10930186, 0.22939779) * go_2(-1.0, 1.0); result += mat4(0.0010455973, -0.11821993, -0.12639599, 0.12250084, -0.12756817, 0.11478416, -0.1862587, 0.016819192, 0.02110181, -0.25492984, -0.1766048, 0.22188173, -0.21305011, 0.113442205, 0.04599144, -0.15840286) * go_2(0.0, -1.0); result += mat4(-0.15086032, -0.17428935, 0.39080557, 0.07576757, 0.121703945, 0.17944208, -0.003140103, -0.11231332, 0.12102969, 0.15310267, 0.17578171, 0.40631834, -0.21299168, 0.024928993, 0.030104794, 0.020753227) * go_2(0.0, 0.0); result += mat4(-0.098734386, -0.020072265, -0.14308836, -0.08490801, 0.017175158, 0.02250534, 0.04060829, 0.033022214, 0.0046218676, 0.17923212, 0.0112105915, 0.09574084, 0.14819936, -0.14692923, 0.12634254, 0.060762513) * go_2(0.0, 1.0); result += mat4(0.030521613, -0.097913325, -0.016720278, 0.11273997, 0.013019863, -0.06557118, 0.0405774, 0.0915019, 0.022414956, -0.053254984, 0.18639986, 0.07820968, 0.06498986, 0.058922634, -0.02240318, -0.086019725) * go_2(1.0, -1.0); result += mat4(0.2058775, 0.01502064, 0.05847032, 0.007249146, 0.086483665, 0.19420148, 0.03892261, -0.013546935, -0.07980237, 0.04347281, -0.10376214, -0.1366535, 0.05285337, 0.07213318, 0.3642818, -0.11331124) * go_2(1.0, 0.0); result += mat4(-0.025740806, 0.14551482, -0.037410017, -0.17477523, -0.11853099, -0.060820814, -0.102599286, -0.13267937, -0.103053465, -0.014044828, -0.01888072, -0.06499249, 0.22311528, -0.051850274, -0.034120858, 0.044562567) * go_2(1.0, 1.0); result += mat4(-0.21360217, 0.10093803, -0.0016407765, -0.1473997, 0.26524043, 0.02112132, 0.23173104, -0.013157391, 0.05945182, 0.044635538, 0.06031638, -0.21435826, -0.10147484, 0.069090195, 0.09641844, -0.09581093) * go_3(-1.0, -1.0); result += mat4(-0.08576515, -0.122861005, 0.049567085, -0.085854456, 0.23809357, -0.024966082, -0.10294079, 0.046241313, 0.008621132, -0.08323767, 0.20277941, 0.163423, -0.07386535, -0.088738985, 0.05274358, -0.025479877) * go_3(-1.0, 0.0); result += mat4(-0.041135542, -0.008365642, 0.17088248, 0.04025207, 0.13809255, -0.056895368, -0.01582834, 0.07361908, -0.00068995473, -0.09300962, 0.19117641, 0.24832036, -0.06572358, -0.026025, -0.019093119, -0.049720034) * go_3(-1.0, 1.0); result += mat4(0.024900286, 0.11525501, 0.025882801, 0.037742402, 0.36976853, 0.052211333, -0.15143296, 0.1802276, -0.059080046, 0.017990451, 0.026395092, -0.12689115, -0.07705386, 0.1232379, 0.13273561, -0.12521964) * go_3(0.0, -1.0); result += mat4(-0.19788785, 0.044887315, 0.07663442, 0.16688696, -0.2842248, -0.15684547, 0.028387763, 0.0063470444, -0.012245601, -0.038382255, -0.8187406, -0.25245667, 0.23014604, 0.22746666, 0.1594356, 0.16469443) * go_3(0.0, 0.0); result += mat4(-0.12663333, 0.014730006, 0.03765697, 0.15704912, -0.106595434, -0.05317512, -0.081759915, -0.08797109, 0.064620756, -0.06341419, 0.16493447, 0.23102313, 0.068325415, -0.088058695, 0.16885915, 0.036382258) * go_3(0.0, 1.0); result += mat4(0.035389822, -0.11811836, -0.035656307, -0.0680554, 0.1338908, 0.065852076, 0.023307983, 0.0675308, 0.09690683, 0.18170924, 0.09862692, -0.20964378, -0.08601271, -0.20016764, -0.01879598, -0.14629345) * go_3(1.0, -1.0); result += mat4(-0.27183273, 0.013525998, -0.14995874, -0.23938845, -0.26218823, -0.0009874097, -0.13385512, -0.10664239, -0.048931994, 0.039898522, 0.047444753, 0.10934722, 0.10969629, 0.123539805, 0.11692802, 0.14172275) * go_3(1.0, 0.0); result += mat4(-0.1656506, 0.019683002, 0.0221048, 0.12596753, 0.20420644, -0.07930122, 0.04653823, 0.11492255, -0.0050175437, -0.03271697, 0.013389486, 0.034583613, -0.2196601, -0.1615663, -0.013763388, -0.056037936) * go_3(1.0, 1.0); result += vec4(-0.022956269, 0.029688787, -0.070148066, -0.07163476); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_1_tf //!BIND conv2d_1_tf1 //!SAVE conv2d_2_tf1 //!WIDTH conv2d_1_tf.w //!HEIGHT conv2d_1_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_1_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_1_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.15104648, 0.05522861, -0.0654341, -0.053517453, -0.08264124, -0.0062249107, -0.20364265, -0.05015117, -0.18837251, 0.030655831, 0.046844713, -0.20673253, -0.14042036, -0.05655449, 0.13994302, 0.011745607) * go_0(-1.0, -1.0); result += mat4(-0.16517559, 0.1489214, -0.09149559, 0.025003506, -0.124926426, 0.16974348, -0.020857265, 0.08017403, 0.21836148, 0.0025619378, 0.2331612, 0.085599184, -0.030934382, -0.055194855, 0.09527726, -0.10081552) * go_0(-1.0, 0.0); result += mat4(0.041800212, 0.028859638, 0.09395546, 0.05211183, -0.038541477, 0.021495212, 0.04862346, -0.007864793, 0.038407274, -0.13841268, -0.14963801, 0.26470762, 0.16691841, -0.07262008, 0.034374326, -0.14709206) * go_0(-1.0, 1.0); result += mat4(0.00094978884, -0.028974704, -0.0900548, -0.08401967, -0.08935931, -0.043606587, -0.14497143, -0.05226239, -0.21516493, 0.19410603, -0.089924194, -0.04335071, -0.012618276, -0.2671613, 0.020422975, -0.037739716) * go_0(0.0, -1.0); result += mat4(-0.13403237, -0.02524383, -0.03474901, 0.054432765, 0.11946775, 0.107336655, -0.1431715, -0.13370377, 0.015087512, -0.1917613, 0.073493585, 0.2788855, -0.010510839, 0.06891479, -0.06741307, -0.05271205) * go_0(0.0, 0.0); result += mat4(-0.15432046, 0.04021662, -0.16979513, 0.13660534, -0.10518303, -0.10095502, -0.13092068, 0.022805348, -0.16676381, -0.4273298, 0.020867536, 0.3506733, -0.29459694, -0.055828743, -0.069241956, 0.04106382) * go_0(0.0, 1.0); result += mat4(-0.08890133, 0.07549666, -0.040735144, -0.1506932, -0.22227979, -0.0762723, -0.17766447, -0.05741318, -0.21885683, 0.2379157, -0.15525854, -0.07306285, 0.15580738, -0.04394069, -0.19175608, 0.018283797) * go_0(1.0, -1.0); result += mat4(-0.08503275, -0.105500385, -0.114987396, -0.07166016, -0.2147138, 0.09378708, 0.24550334, -0.0834075, -0.033147786, -0.022304727, -0.31062204, 0.027651973, 0.109098755, 0.18889032, 0.1163026, 0.13863255) * go_0(1.0, 0.0); result += mat4(0.15266588, -0.14901319, 0.033916786, 0.09381096, -0.08196443, -0.16194504, 0.035789456, 0.21234898, -0.48724765, 0.2619442, -0.11215393, 0.25061038, 0.022344576, 0.0116525125, 0.111661114, -0.15242295) * go_0(1.0, 1.0); result += mat4(0.020475458, 0.0797404, -0.13576819, 0.009681671, 0.030504882, 0.049232908, 0.022025917, 0.16912088, -0.23914136, -0.084663324, 0.020925451, -0.1023938, 0.035916872, -0.07538111, -0.11470242, 0.15238516) * go_1(-1.0, -1.0); result += mat4(-0.12941381, 0.08509899, -0.029489802, -0.09148447, -0.089406274, -0.116145454, -0.08979843, 0.11908148, 0.15473351, -0.21687616, 0.12607013, -0.08244334, -0.079580925, -0.16613089, -0.09287793, -0.03412643) * go_1(-1.0, 0.0); result += mat4(-0.023578499, 0.07394217, -0.13069086, -0.1060499, -0.07559958, -0.21839201, 0.1090753, 0.0787872, 0.07677037, -0.25998843, 0.20039314, 0.046882212, 0.31871012, -0.3048051, 0.15118991, -0.00518087) * go_1(-1.0, 1.0); result += mat4(-0.15338503, -0.11057532, 0.075839415, -0.18592294, -0.0155324, 0.038140323, -0.10498194, 0.09070477, 0.05108992, -0.047939524, -0.091004305, 0.09649005, -0.10967152, -0.051909525, -0.05314551, 0.09661584) * go_1(0.0, -1.0); result += mat4(-0.14458802, -0.053263694, -0.0010885567, 0.23342133, 0.01918937, 0.12026143, -0.15691495, 0.30480555, -0.08725869, 0.19082253, 0.3594973, 0.016653897, 0.045152336, -0.088590585, 0.0069655925, 0.1392425) * go_1(0.0, 0.0); result += mat4(0.17944881, -0.17950764, 0.13282645, 0.030974053, 0.32233685, 0.18067117, -0.11472813, 0.097301506, -0.047649745, -0.1053861, -0.081039384, 0.035132434, 0.10204545, 0.085582554, -0.13153993, -0.021741152) * go_1(0.0, 1.0); result += mat4(-0.15573682, 0.16409989, -0.22574787, -0.03877603, -0.18285516, 0.11638645, 0.18321282, -0.017770218, 0.18230622, 0.16433364, -0.12795393, -0.03805153, 0.14386104, -0.0891527, -0.056928284, -0.10961495) * go_1(1.0, -1.0); result += mat4(0.257622, 0.052519716, -0.25421762, -0.1887382, -0.083568096, -0.0064690276, -0.029110614, 0.103327505, -0.17006217, 0.2254096, -0.29366904, 0.04302887, -0.10198446, -0.24423616, 0.16781262, -0.005019004) * go_1(1.0, 0.0); result += mat4(0.103393994, -0.059044626, -0.18192382, 0.0990813, -0.26143607, 0.11036474, 0.04788275, -0.096738026, 0.12825653, 0.13631694, -0.077904984, -0.020790676, -0.25118098, 0.122588515, -0.049440473, -0.10758222) * go_1(1.0, 1.0); result += mat4(0.06693113, -0.13647175, 0.131139, 0.13143918, 0.081720434, 0.117537096, 0.15387627, -0.008771362, 0.08513583, 0.023794742, -0.0661625, 0.115793936, 0.0023350024, 0.02215075, -0.0494433, -0.013404977) * go_2(-1.0, -1.0); result += mat4(0.041419264, -0.17622781, 0.028418267, 0.12114493, -0.23587078, 0.08457395, 0.014364018, -0.103271864, -0.051572207, -0.026424447, 0.16755055, -0.10763651, -0.033440586, 0.068594255, -0.050668504, 0.1941505) * go_2(-1.0, 0.0); result += mat4(-0.2780181, 0.037816502, -0.11516711, -0.09822884, 0.13762361, -0.14317706, 0.14350282, 0.000623895, -0.08601606, 0.08118504, 0.15497385, -0.04721711, -0.008936935, -0.014223618, -0.09641698, -0.013884213) * go_2(-1.0, 1.0); result += mat4(0.14349665, -0.03144472, -0.057813704, 0.0667044, 0.09026094, 0.051366236, 0.11139983, -0.015782114, -0.18314016, -0.18774192, 0.0014838242, 0.15759028, 0.062388215, 0.13626057, 0.02576217, -0.06317815) * go_2(0.0, -1.0); result += mat4(0.07151769, 0.14508991, 0.1736844, -0.11487795, -0.07999805, -0.07797908, 0.037923355, -0.059138823, -0.23531209, -0.040207293, -0.068355694, -0.024296658, -0.114820175, 0.19726487, 0.21772414, 0.03659222) * go_2(0.0, 0.0); result += mat4(0.16858695, -0.12135113, 0.009391182, -0.081519485, 0.13340487, 0.07007004, 0.094124354, 0.035519842, -0.3320139, -0.06624027, -0.14716229, -0.09205287, 0.12664132, -0.05655441, 0.0123263765, 0.04641279) * go_2(0.0, 1.0); result += mat4(0.19018422, -0.15428329, -0.009354114, 0.04165953, 0.11024837, -0.107493006, -0.05807292, -0.048029456, 0.24319384, -0.10542357, -0.013699952, 0.06228662, -0.06808749, -0.023227982, 0.16528323, -0.05610251) * go_2(1.0, -1.0); result += mat4(-0.008616222, 0.077674195, -0.08638503, 0.09293109, 0.072474636, 0.05004233, -0.20591061, -0.005301386, -0.15486047, 0.15038474, 0.1262478, 0.021724822, 0.02274613, -0.3088281, -0.08437887, -0.10684698) * go_2(1.0, 0.0); result += mat4(-0.16960032, 0.09365251, -0.030414175, -0.010766254, 0.18181023, 0.12130318, 0.08913089, -0.06070321, 0.05200306, 0.092584535, 0.17694671, 0.033796314, -0.038107123, -0.04335955, -0.049443472, 0.30465958) * go_2(1.0, 1.0); result += mat4(0.07661484, -0.009945252, 0.12866217, -0.07592757, -0.21030053, 0.014371748, -0.072458774, -0.04700072, 0.15534303, 0.2007125, -0.15699059, -0.032897495, 0.08110436, -0.11243608, 0.008632577, -0.10153441) * go_3(-1.0, -1.0); result += mat4(-0.034697928, 0.06928288, -0.2796273, 0.14405379, 0.12248569, 0.036539096, 0.06607706, 0.077684596, -0.16473202, 0.1665916, -0.29977503, 0.21047153, 0.13114224, -0.091579035, -0.045458574, 0.03254245) * go_3(-1.0, 0.0); result += mat4(0.053284872, 0.053366095, -0.26152626, -0.03123967, -0.031794485, 0.17670582, -0.07450994, 0.017521491, -0.040290453, 0.38342363, -0.25021288, -0.014660264, 0.1621895, 0.25041878, -0.12124821, 0.068036206) * go_3(-1.0, 1.0); result += mat4(0.11366693, -0.030863572, -0.07411263, 0.12475283, -0.046070684, -0.09033321, 0.013222701, 0.06798592, -0.32814804, 0.057653826, -0.14082801, -0.00217398, -0.22856179, -0.19058353, -0.20992154, -0.03701372) * go_3(0.0, -1.0); result += mat4(0.20345633, -0.1332355, 0.27152926, -0.13477845, -0.25242096, -0.28281286, 0.31289554, 0.14284514, 0.53362453, -0.46766588, 0.4518293, -0.39291728, -0.3573227, -0.014670052, 0.0051881406, 0.16552156) * go_3(0.0, 0.0); result += mat4(-0.15017267, -0.07792945, -0.204405, 0.13964304, -0.13642666, -0.10228306, 0.03238279, -0.08689329, -0.072262034, -0.0258388, 0.05689183, 0.055701543, -0.19800112, 0.012217054, -0.033292748, -0.047611095) * go_3(0.0, 1.0); result += mat4(-0.014704416, -0.12203891, 0.066083655, -0.1409769, 0.0041513643, -0.087383606, -0.17498164, 0.11327789, -0.25947225, -0.0016027623, 0.08202566, 0.042270098, 0.006429511, -0.26576808, -0.08461341, 0.049376782) * go_3(1.0, -1.0); result += mat4(0.0695189, -0.14753938, 0.09578246, -0.16607563, -0.0105561055, 0.17166016, 0.027422488, -0.14175262, -0.009492696, -0.23449713, 0.018270867, 0.14635146, 0.33451268, 0.030959005, -0.46468422, 0.024256868) * go_3(1.0, 0.0); result += mat4(-0.16865666, -0.00015881563, -0.054488145, -0.06222717, -0.032101758, 0.06485387, -0.0028512608, 0.046645947, 0.017593225, -0.19447896, -0.024742266, 0.03970127, 0.29845607, -0.16168733, 0.035172883, 0.07924657) * go_3(1.0, 1.0); result += vec4(0.103826486, 0.045373913, 0.11565896, -0.06568643); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_2_tf //!BIND conv2d_2_tf1 //!SAVE conv2d_3_tf //!WIDTH conv2d_2_tf.w //!HEIGHT conv2d_2_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_2_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_2_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.1851775, 0.053705044, 0.033816848, -0.018555025, -0.21204336, -0.01706974, 0.088259794, -0.13126148, 0.10729598, -0.043457437, 0.08634712, 0.09220895, 0.062131613, -0.01995871, 0.05181067, 0.18520063) * go_0(-1.0, -1.0); result += mat4(0.1662002, -0.14197104, -0.052809287, 0.025287712, -0.08330898, -0.08998097, -0.15642618, -0.14941245, -0.03481203, 0.061857622, 0.26051775, -0.0005498248, 0.086427025, 0.024108192, -0.12418039, 0.022286376) * go_0(-1.0, 0.0); result += mat4(0.058200672, -0.3073398, 0.17150162, -0.13394679, -0.075118184, -0.14607768, -0.006172172, 0.007731589, -0.21818224, -0.06449433, -0.038958784, 0.037722416, 0.28699976, -0.027563032, 0.23295315, 0.028444216) * go_0(-1.0, 1.0); result += mat4(0.12871371, 0.0064904913, 0.14985761, -0.10923005, 0.17413563, 0.1599109, -0.08457703, 0.108153716, -0.08871187, -0.06661137, 0.2754416, -0.009667768, 0.39819396, 0.12392097, 0.14145902, 0.0019376524) * go_0(0.0, -1.0); result += mat4(0.13893189, 0.12715353, 0.015191678, -0.21003054, -0.030412354, -0.01676613, -0.19799289, -0.006130075, 0.37676954, -0.14475077, -0.2065198, -0.30432892, -0.14944535, -0.09121536, -0.107600585, -0.24462196) * go_0(0.0, 0.0); result += mat4(-0.11653076, -0.0068671284, -0.02249137, -0.17877012, -0.15063138, -0.13514869, 0.107643366, -0.03196477, -0.086422764, 0.3079287, 0.17584166, -0.032449376, -0.06917114, -0.2682637, -0.18978168, -0.037039287) * go_0(0.0, 1.0); result += mat4(0.12014731, -0.030360512, -0.12954475, -0.110275604, -0.077214256, 0.019689744, 0.22149551, -0.002266716, 0.09697784, -0.124532826, -0.16776511, -0.034212478, -0.36935154, 0.016926935, 0.1363609, 0.20415346) * go_0(1.0, -1.0); result += mat4(-0.11199535, -0.001692563, -0.09058429, -0.08437503, 0.092625685, 0.06046257, 0.25509837, -0.011657033, -0.17949764, -0.10718947, -0.1180669, -0.24681842, -0.1747311, 0.0014518246, -0.042863015, 0.06103357) * go_0(1.0, 0.0); result += mat4(0.14979295, -0.037154514, 0.01957725, 0.012282435, 0.09168596, -0.05552286, 0.111671515, 0.0078630615, -0.10319766, -0.06416261, -0.23097566, -0.13931875, 0.2110811, 0.013095802, -0.2306504, -0.025639111) * go_0(1.0, 1.0); result += mat4(-0.10091975, -0.10095426, -0.023449723, -0.022170888, 0.054953706, -0.13049407, 0.08289061, 0.023241632, 0.08735388, -0.0058387457, 0.17897247, 0.011434436, 0.008181139, -0.0034718404, -0.015372735, -0.07657766) * go_1(-1.0, -1.0); result += mat4(-0.023442164, 0.07535702, 0.024391165, -0.050532013, 0.044168636, 0.0062343236, -0.019756999, -0.009695123, 0.10102337, 0.0052776975, -0.14944167, -0.060957722, 0.24367364, -0.08069369, 0.12170072, -0.047048368) * go_1(-1.0, 0.0); result += mat4(-0.18376935, -0.08407229, -0.12943378, 0.0738419, -0.12404976, -0.13367929, 0.11265896, -0.021353, 0.003783386, 0.50088304, 0.14058582, 0.041053623, 0.038247623, -0.014179976, 0.007905778, -0.042492237) * go_1(-1.0, 1.0); result += mat4(-0.046272535, 0.052449115, 0.17190954, -0.004745371, -0.045572635, -0.09292636, 0.36309823, 0.16673928, -0.099154025, -0.109614775, 0.17803112, 0.19907133, -0.14306267, 0.06898593, 0.11493454, 0.06795014) * go_1(0.0, -1.0); result += mat4(0.26181114, -0.044014625, -0.21605036, -0.08646438, 0.21038742, -0.084986, 0.0504626, 0.17514943, -0.25218952, -0.18691514, 0.057650108, 0.08653614, -0.101205684, 0.03176334, 0.18569492, 0.17973189) * go_1(0.0, 0.0); result += mat4(-0.0339215, 0.20112811, -0.12986277, 0.028961731, -0.056813832, 0.04451147, -0.07827432, -0.0860976, 0.096853435, 0.3483546, -0.35758162, -0.11749375, -0.035918653, 0.06140711, -0.08520154, 0.02418808) * go_1(0.0, 1.0); result += mat4(-0.09643022, -0.10491069, 0.0068604187, 0.023679713, 0.096521445, -0.29323488, 0.33353668, 0.112864286, -0.1172182, -0.07233183, 0.06607239, 0.08589609, 0.055790007, 0.14396138, -0.14191268, 0.00034840964) * go_1(1.0, -1.0); result += mat4(0.15357164, -0.038462736, 0.08143956, 0.1744909, 0.40503287, -0.114508316, 0.003937322, 0.2536635, -0.042445306, -0.15622465, 0.09155284, 0.010992155, -0.20646071, 0.022801135, 0.08894491, 0.069300614) * go_1(1.0, 0.0); result += mat4(-0.12663515, 0.023849454, -0.053604446, 0.12082873, -0.247968, -0.020969635, -0.03831894, -0.014617553, 0.22630337, 0.037801865, 0.052950703, 0.04285706, -0.14487264, 0.20786528, -0.08719664, 0.1752347) * go_1(1.0, 1.0); result += mat4(-0.073527604, -0.050752833, 0.051830504, 0.32868716, 0.17474994, 0.016937364, -0.08792601, -0.024481766, -0.022229593, 0.030706186, 0.09213566, -0.076506205, 0.073404044, 0.10368055, -0.175889, -0.08453031) * go_2(-1.0, -1.0); result += mat4(-0.06838216, 0.007698341, 0.063972116, -0.015604406, 0.16135305, 0.18044342, 0.024137018, -0.23326185, 0.13235588, -0.009096587, -0.058368143, -0.077040404, 0.0011419816, -0.09246194, 0.061036937, 0.049564146) * go_2(-1.0, 0.0); result += mat4(0.023225296, -0.00060856267, -0.07775185, 0.016958566, -0.2641349, -0.08263046, -0.15350416, -0.30203494, 0.113956556, -0.010813236, -0.017738314, -0.13689043, -0.10318342, 0.025793184, -0.010336172, 0.09733422) * go_2(-1.0, 1.0); result += mat4(-0.04462596, 0.052866418, -0.34754288, 0.05540498, -0.24492586, -0.32016864, 0.18145293, 0.24873725, 0.32388234, -0.034801524, -0.1347588, -0.07565546, 0.015183539, 0.05059595, 0.08090056, 0.05930932) * go_2(0.0, -1.0); result += mat4(0.045346696, -0.052527856, 0.052270077, 0.13417454, 0.05200045, 0.028119288, 0.005115497, 0.22952151, -0.2158375, 0.12241308, 0.3507457, 0.08616576, 0.07592416, 0.28470486, 0.3432788, 0.24857087) * go_2(0.0, 0.0); result += mat4(0.21311626, 0.052607164, 0.1248861, 0.20193806, 0.045226507, 0.14512901, -0.15103437, -0.17926466, 0.11657411, -0.32711068, -0.16332194, -0.07793982, -0.21802668, 0.5183869, -0.13567342, 0.07823041) * go_2(0.0, 1.0); result += mat4(0.00796368, 0.048073012, -0.14537893, -0.021708772, 0.036246423, 0.1062395, 0.12605369, 0.007073524, -0.1572743, 0.07439501, 0.089162275, -0.0039608316, 0.332032, -0.05461242, -0.17615359, -0.10240517) * go_2(1.0, -1.0); result += mat4(0.20636982, -0.0024615112, -0.10625786, 0.024270926, 0.061810836, -0.13585201, -0.16581286, 0.23549418, 0.01928842, 0.07404979, -0.054449487, 0.04096373, 0.046939734, 0.003980803, 0.02111498, 0.064925276) * go_2(1.0, 0.0); result += mat4(0.10485388, 0.06850885, -0.11292169, 0.16991565, -0.15282536, 0.124175504, -0.050431166, -0.06689582, -0.00059811946, 0.033696912, 0.11055047, 0.033060126, -0.17472714, 0.0048819613, -0.04478706, -0.1344572) * go_2(1.0, 1.0); result += mat4(-0.20473132, 0.056477875, 0.059559986, 0.115130566, -0.058425788, -0.035971727, 0.08334707, -0.096510135, -0.23206294, 0.10635798, -0.21575621, -0.07063254, 0.03877511, -0.107549034, 0.22248401, 0.21702304) * go_3(-1.0, -1.0); result += mat4(-0.02557767, 0.09886609, -0.100499466, 0.16687396, -0.084830604, 0.03150401, -0.049512494, 0.05595696, -0.13193256, -0.08585273, 0.14247662, 0.12290477, -0.07168309, 0.14531752, -0.048359327, 0.27716598) * go_3(-1.0, 0.0); result += mat4(0.13297586, 0.20674329, 0.14469388, 0.08981846, -0.004231366, -0.02819193, 0.15470329, 0.17299837, 0.113062344, -0.22716297, -0.21754944, -0.00083956274, -0.14160508, 0.1808253, 0.11268379, 0.27335623) * go_3(-1.0, 1.0); result += mat4(0.07497518, -0.06799594, -0.018158078, -0.00038999433, -0.15169668, -0.06928238, -0.33672288, -0.105485775, 0.33106267, 0.06698315, 0.019718744, -0.06810211, -0.35186404, -0.29145968, -0.056863394, 0.21498048) * go_3(0.0, -1.0); result += mat4(-0.013215512, -0.24763754, 0.20965266, 0.1068435, -0.13234195, 0.053566497, 0.05061848, -0.28645232, 0.15518288, 0.23247199, 0.017553907, -0.25181335, -0.048030723, -0.06663929, -0.111026704, -0.12663394) * go_3(0.0, 0.0); result += mat4(-0.010501938, -0.17995767, 0.06010859, 0.050185587, 0.108627126, -0.101203434, 0.07558728, 0.060466755, -0.106942676, -0.35854608, 0.16015992, 0.16823332, -0.06543775, -0.37310675, 0.014043972, -0.18328045) * go_3(0.0, 1.0); result += mat4(0.09712849, 0.013983463, 0.07291423, 0.031715546, 0.030862397, 0.045510456, -0.22066842, 0.063464865, 0.11721659, -0.10596602, -0.20611264, 0.052158818, -0.3961766, -0.03781582, 0.17633812, 0.1316111) * go_3(1.0, -1.0); result += mat4(-0.25029674, 0.07153423, -0.35125682, -0.18255402, -0.19569087, 0.00432772, -0.0969035, -0.24648514, -0.0040922165, 0.037500706, -0.038137026, 0.056214277, -0.048258524, 0.03567822, -0.05033007, -0.24696785) * go_3(1.0, 0.0); result += mat4(-0.03465209, -0.012495964, 0.22782089, 0.012034795, 0.2916752, 0.08264436, 0.15387125, -0.1473455, -0.15614432, 0.05536727, -0.027079755, 0.010725311, -0.03325222, -0.089212805, -0.10559839, -0.19647683) * go_3(1.0, 1.0); result += vec4(0.0001705175, -0.031081453, 0.010100773, -0.027214011); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_2_tf //!BIND conv2d_2_tf1 //!SAVE conv2d_3_tf1 //!WIDTH conv2d_2_tf.w //!HEIGHT conv2d_2_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_2_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_2_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.026301445, -0.021575214, 0.22165509, 0.059994068, 0.03341161, 0.1831188, 0.20342293, 0.110160105, 0.03908121, 0.020673111, 0.07239561, 0.038754333, 0.15266368, 0.16526422, 0.062376205, -0.09759537) * go_0(-1.0, -1.0); result += mat4(0.19817191, 0.10267733, 0.17744653, 0.23283184, 0.18810122, 0.2708428, -0.12651879, 0.020756349, 0.039632563, -0.22201295, 0.04873703, 0.09159713, 0.13838065, 0.21169297, 0.30816007, 0.044463675) * go_0(-1.0, 0.0); result += mat4(-0.27859214, 0.07277634, 0.0021458792, 0.0089682285, -0.069680706, 0.090415835, -0.057762265, 0.18703683, -0.03514389, -0.102816254, -0.036509827, 0.038066104, -0.0168311, 0.094478935, 0.04079697, -0.049064912) * go_0(-1.0, 1.0); result += mat4(-0.20913245, -0.110538535, -0.08584027, -0.1222067, 0.05414807, -0.045247085, 0.07351766, -0.002078549, -0.1270987, -0.10164512, -0.1857815, 0.08845066, -0.03743333, -0.098948084, 0.21244387, 0.10441866) * go_0(0.0, -1.0); result += mat4(0.015990427, 0.36396438, -0.24094687, 0.30236533, -0.13271736, 0.06057376, -0.19678196, -0.28577125, -0.25427434, -0.08400598, 0.07284403, -0.18552442, -0.16425897, 0.097259276, -0.32386774, -0.2190484) * go_0(0.0, 0.0); result += mat4(-0.004581924, -0.13954072, -0.122360416, 0.14132866, -0.08529257, -0.013296556, 0.0848472, 0.09336581, 0.10332182, -0.016313016, 0.07103558, 0.032564916, -0.13478759, -0.20207484, 0.12986964, 0.1219679) * go_0(0.0, 1.0); result += mat4(0.09817874, -0.10573357, 0.100535244, 0.19608764, -0.13303067, 0.024192972, -0.030689823, 0.02574889, 0.051233094, 0.03489235, -0.18465245, -0.06943822, -0.031604882, 0.1519888, 0.09348508, 0.09187296) * go_0(1.0, -1.0); result += mat4(-0.21365458, -0.23696984, 0.13097638, -0.09435498, 0.16467983, -0.066370346, 0.1269104, -0.095128186, 0.09954892, 0.12489504, -0.43418056, 0.106512725, -0.17860703, -0.07114084, -0.07630834, -0.26642478) * go_0(1.0, 0.0); result += mat4(-0.009044342, 0.02711196, -0.14873673, 0.015405045, 0.0071443473, -0.025285944, 0.07409282, 0.06338527, 0.0149676185, 0.011741382, -0.2133069, -0.028912885, 0.19420496, 0.039629057, 0.057636812, 0.15214856) * go_0(1.0, 1.0); result += mat4(0.07629928, 0.25540486, -0.050925937, -0.18136702, 0.02261603, 0.22343902, 0.003270321, 0.10735731, -0.12541203, -0.10208828, 0.012832783, 0.2591262, 0.08122926, -0.009837677, 0.10308358, 0.19236866) * go_1(-1.0, -1.0); result += mat4(0.0896358, 0.27571487, 0.04406029, -0.047453407, -0.08587119, 0.16366854, 0.20622262, 0.08347545, -0.3501584, -0.28434548, -0.07592983, 0.09098784, 0.07605388, 0.09677056, 0.0015295541, 0.05102585) * go_1(-1.0, 0.0); result += mat4(0.18255898, 0.18618028, 0.0017002645, -0.013004655, -0.06436534, 0.13967068, 0.063077755, -0.10632303, -0.20803222, -0.028537111, -0.03144366, -0.08555215, 0.05154303, 0.02431626, 0.15246728, -0.013708507) * go_1(-1.0, 1.0); result += mat4(-0.020998938, -0.05026291, 0.03700117, 0.00830308, -0.1949294, 0.0026698054, -0.034649856, 0.19784226, -0.083901435, -0.069783084, -0.1504053, 0.16595264, -0.07480141, 0.16067508, 0.06010996, -0.021359695) * go_1(0.0, -1.0); result += mat4(-0.040828142, -0.20158486, 0.034770954, -0.1894161, 0.11665004, 0.29729164, -0.10584386, 0.13165873, -0.18863006, -0.26719162, -0.047613148, -0.12728356, -0.2033613, 0.10550052, 0.20095508, -0.11275811) * go_1(0.0, 0.0); result += mat4(-0.0785033, -0.1896073, -0.051492307, -0.1694358, 0.1368308, 0.049355216, -0.05707422, 0.079159185, 0.024578957, -0.0923136, 0.089215435, 0.28670043, 0.027932687, 0.06510816, 0.10810999, 0.05990052) * go_1(0.0, 1.0); result += mat4(0.08135192, 0.0001326522, -0.16098668, -0.18663193, -0.10280192, 0.078255914, 0.047648013, 0.08326376, 0.055962667, 0.06302574, -0.080121025, -0.031820554, -0.019117938, 0.12515336, 0.09794088, -0.03276838) * go_1(1.0, -1.0); result += mat4(0.280923, 0.24079335, 0.007883573, 0.06270414, 0.3055441, 0.19291803, -0.16041607, 0.14836526, 0.0013885222, 0.04538063, 0.10742898, -0.064491205, 0.048174977, 4.237692e-05, -0.15194727, 0.024381457) * go_1(1.0, 0.0); result += mat4(-0.0009164131, -0.031949926, 0.0076425644, -0.036870714, -0.0031292974, 0.017726978, -0.20172147, -0.0770472, 0.26379177, 0.108997814, 0.08069395, 0.2126177, 0.012075376, -0.029457828, 0.062730506, -0.15754452) * go_1(1.0, 1.0); result += mat4(0.09167904, -0.2657421, -0.03443356, 0.03315832, -0.015365421, -0.1029612, -0.108251, 0.04261033, -0.097120754, -0.05616668, -0.09275983, 0.024902184, 0.050058514, -0.013761632, 0.07555132, -0.0046676896) * go_2(-1.0, -1.0); result += mat4(-0.10743835, -0.0007361781, -0.042085417, -0.08237517, -0.10094376, -0.24007876, 0.13924706, -0.07526801, 0.01158322, 0.15491122, 0.0069442675, -0.004242352, 0.11429785, 0.02994726, -0.11829945, -0.04108612) * go_2(-1.0, 0.0); result += mat4(0.073622055, -0.064717196, -0.0025231615, 0.13256475, 0.20159899, 0.047977835, -0.10289233, -0.18419135, -0.00888952, 0.059428576, -0.053062655, -0.02730631, 0.14545685, -0.08686949, 0.17454128, 0.035443828) * go_2(-1.0, 1.0); result += mat4(-0.010146019, 0.06712568, 0.12614638, 0.023590917, 0.025756737, 0.06603747, -0.17108095, -0.06179699, 0.027241204, -0.13196802, 0.043475866, -0.0397495, 0.05306092, 0.035672903, 0.047219284, -0.16680142) * go_2(0.0, -1.0); result += mat4(0.079427816, -0.06716479, 0.19028603, -0.19694683, -0.061598092, -0.07471188, 0.21170339, 0.30140215, -0.0023369973, 0.04688297, -0.14154115, 0.19283508, 0.1339858, -0.09116279, 0.15305163, 0.029108394) * go_2(0.0, 0.0); result += mat4(-0.14902157, -0.03339153, -0.08532003, -0.10736339, 0.08702709, 0.07607574, -0.09955836, -0.016585784, -0.030078214, -0.060374748, -0.2854279, 0.02441719, 0.034877967, 0.2099041, 0.11125731, -0.059071556) * go_2(0.0, 1.0); result += mat4(-0.08436325, 0.06893047, -0.045362443, -0.02237741, -0.07583875, -0.034830183, -0.024008518, -0.2882329, -0.011109783, 0.101859994, 0.091137715, 0.0020565533, -0.044729806, -0.18168025, 0.069466636, 0.04994174) * go_2(1.0, -1.0); result += mat4(0.11915174, 0.089596465, -0.18965814, 0.015218237, 0.13500094, 0.19921367, -0.008298205, 0.29650384, -0.049439427, -0.27590424, 0.36169067, -0.030582754, 0.02151196, 0.019915426, 0.04543398, 0.16126189) * go_2(1.0, 0.0); result += mat4(0.1620274, -0.08264547, 0.082442135, -0.0034478644, 0.09888509, -0.0034957859, -0.107241705, -0.17729597, -0.05138647, 0.02052103, -0.019507123, 0.037574988, -0.1694345, 0.17871588, -0.22510391, 0.019049853) * go_2(1.0, 1.0); result += mat4(-0.10962245, -0.1329873, -0.060855392, 0.025941676, -0.19536193, -0.120365486, -0.04313703, -0.052912965, 0.20854498, 0.08341353, 0.008687068, -0.20432276, 0.15677948, -0.19000018, 0.01821201, -0.041512605) * go_3(-1.0, -1.0); result += mat4(0.012287526, -0.14180368, -0.098788455, 0.025949089, 0.09442778, 0.2247651, -0.12453263, 0.10435483, 0.274603, 0.06133054, 0.10506106, 0.14727746, -0.048299775, -0.082819685, 0.07319359, -0.047460355) * go_3(-1.0, 0.0); result += mat4(-0.070726536, -0.034744017, 0.07521428, 0.070649154, -0.05958955, -0.100232825, -0.010651838, 0.045392875, 0.2930271, -0.04952355, 0.3112155, 0.117203265, 0.025166962, 0.11176862, 0.06716659, 0.07175864) * go_3(-1.0, 1.0); result += mat4(-0.011560962, -0.14032063, -0.17424704, 0.07652749, -0.04220116, 0.052874275, -0.00225693, -0.031843517, -0.07520102, -0.13775803, 0.2449317, 0.069658786, 0.052280303, -0.105218224, 0.03574522, -0.020500354) * go_3(0.0, -1.0); result += mat4(0.08793712, 0.26712346, 0.08315631, 0.23813692, -0.04439029, 0.031587064, 0.09561177, -0.13380238, -0.24982157, 0.31701845, -0.3875432, 0.10487225, 0.09201869, -0.037252493, -0.006935219, -0.14650282) * go_3(0.0, 0.0); result += mat4(0.077635325, 0.13732299, -0.071563005, 0.096517466, -0.15051986, -0.111744404, 0.03996857, -0.052670125, -0.1819665, 0.054554947, -0.13774712, -0.20061246, -0.0023742192, 0.15647805, -0.024121126, 0.075497724) * go_3(0.0, 1.0); result += mat4(0.0073632775, -0.06535298, 0.039895996, 0.20666869, 0.13625242, 0.04823007, -0.07135618, 0.04787906, 0.01383074, 0.15382123, -0.15519714, 0.056721795, 0.061946746, -0.0586851, 0.028934354, -0.02264129) * go_3(1.0, -1.0); result += mat4(-0.19791882, -0.111910924, -0.010451344, -0.30566537, -0.1416239, -0.14523096, 0.116883226, -0.18241516, 0.2680614, -0.18487626, 0.17472346, 0.08346682, -0.14510359, -0.029229192, -0.005879142, 0.050247498) * go_3(1.0, 0.0); result += mat4(0.030153519, -0.092469186, -0.022912916, 0.10200855, -0.04237032, -0.05917764, 0.10479645, -0.05619482, -0.18949397, -0.019547248, 0.013868889, -0.1524476, 0.14048979, -0.032521486, 0.1322921, 0.070972025) * go_3(1.0, 1.0); result += vec4(0.012053958, -4.6962363e-05, 0.0020099226, -0.033494607); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_3_tf //!BIND conv2d_3_tf1 //!SAVE conv2d_4_tf //!WIDTH conv2d_3_tf.w //!HEIGHT conv2d_3_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_3_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_3_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_3_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_3_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.06738501, 0.034009207, -0.21538448, 0.14296548, 0.12896985, -0.23526315, -0.08848608, 0.019602662, 0.14937137, 0.11353096, 0.11884168, -0.016765572, 0.030985225, 0.046430565, 0.06614828, -0.19202724) * go_0(-1.0, -1.0); result += mat4(-0.10326068, 0.11014975, 0.17069744, -0.21474148, 0.16761585, 0.13434832, -0.101021074, 0.006307025, 0.07478008, -0.1060066, 0.035315692, 0.033488914, -0.24906659, 0.06269967, 0.11120735, -0.040928528) * go_0(-1.0, 0.0); result += mat4(0.09334615, 0.057705753, 0.12213245, -0.06402275, 0.30694544, 0.034585163, 0.20345578, 0.07489286, 0.07483618, -0.14240396, 0.034846418, -0.03811241, 0.010882573, 0.13204294, 0.017563924, -0.047203008) * go_0(-1.0, 1.0); result += mat4(-0.21673942, -0.024010994, -0.10238504, -0.041160326, 0.06838163, -0.20950818, 0.06526309, -0.079094924, 0.02208821, -0.28130978, 0.086275116, -0.089067616, 0.12133826, -0.062600106, -0.020521903, -0.07654401) * go_0(0.0, -1.0); result += mat4(-0.03055029, -0.15683146, -0.20331301, -0.06252028, 0.13350682, 0.20338707, 0.038425338, 0.1581342, -0.27322498, -0.14999662, -0.16681097, 0.0971585, -0.20014858, -0.081635274, -0.0781877, -0.20625232) * go_0(0.0, 0.0); result += mat4(0.38375977, -0.019825654, 0.1886721, 0.22616312, 0.3402173, 0.1825304, -0.05531195, 0.30973226, -0.2676023, 0.14413352, 0.021706983, 0.01732799, 0.23466855, -0.13805965, 0.22570935, 0.018103868) * go_0(0.0, 1.0); result += mat4(-0.15169825, 0.0270689, -0.2503316, 0.17289825, -0.16437647, 0.039233048, -0.35572487, -0.048393793, 0.19270042, 0.24260359, 0.12041881, -0.0009793913, 0.11656858, 0.11007414, -0.0757491, 0.047933612) * go_0(1.0, -1.0); result += mat4(-0.18657999, -0.11252566, -0.05237504, -0.07368097, 0.13882741, -0.13710637, -0.006996468, -0.062354874, 0.23452504, 0.15333645, -0.0022776406, -0.17910439, 0.03629509, -0.16264829, -0.010011833, -0.15313338) * go_0(1.0, 0.0); result += mat4(-0.060544558, -0.04913478, -0.061717357, 0.02323648, 0.28739056, -0.07434013, 0.19110644, 0.100050166, 0.0073363045, 0.08185653, -0.024797903, -0.14424153, -0.20838726, 0.16154376, -0.048517212, -0.025453888) * go_0(1.0, 1.0); result += mat4(0.14975396, -0.13142908, 0.36210674, -0.054021083, -0.10632155, 0.045697935, -0.18946633, 0.02228141, -0.08919603, 0.09800842, -0.17634438, 0.09512711, -0.03425503, -0.12298555, -0.05354435, -0.17112055) * go_1(-1.0, -1.0); result += mat4(0.09958265, -0.057276618, -0.16262266, -0.06415915, 0.14579074, -0.36784375, 0.08034197, -0.04537706, 0.005460582, 0.22313322, 0.07382161, 0.014990379, 0.044636846, -0.2811128, -0.22621547, -0.06044004) * go_1(-1.0, 0.0); result += mat4(0.10569276, -0.03738662, 0.16100396, 0.058593616, -0.048862137, -0.08796426, 0.20101094, -0.11039573, 0.17196764, -0.04601554, 0.008571281, -0.073729075, 0.051433694, -0.051276565, 0.087334655, -0.0360379) * go_1(-1.0, 1.0); result += mat4(0.011119538, -0.28781965, 0.28637868, -0.1742508, -0.07121849, 0.10379717, 0.012615981, -0.029563965, -0.18678424, 0.05291095, 0.039143506, -0.028248642, -0.014103922, 0.029155696, 0.10433492, 0.16305852) * go_1(0.0, -1.0); result += mat4(-0.2231037, -0.13697462, -0.29124337, 0.08519773, 0.15893684, -0.17763218, 0.06950923, 0.34361118, -0.024844287, 0.044008408, -0.033844844, -0.086971916, -0.07884748, 0.2543499, 0.056884114, 0.10068364) * go_1(0.0, 0.0); result += mat4(-0.07710048, -0.23218372, 0.04346047, 0.21769643, 0.06473219, -0.18066105, -0.2511205, 0.15309611, 0.04535977, 0.16450433, 0.10846344, 0.0016952346, -0.010874939, 0.28966382, -0.121990964, 0.12956186) * go_1(0.0, 1.0); result += mat4(-0.007910202, 0.17766511, 0.14364475, 0.1016258, 0.0051045395, 0.18691733, 0.005813767, -0.0070582186, 0.019418601, -0.1604435, 0.016088275, -0.18265302, -0.15719391, -0.17369832, -0.036745597, -0.19647408) * go_1(1.0, -1.0); result += mat4(0.08938396, -0.0073808245, 0.11225727, -0.012303106, 0.096785046, 0.030483445, 0.027719889, -0.052584838, -0.14887555, -0.03422243, 0.12646855, -0.1722482, 0.010239037, 0.06406088, -0.20053658, 0.01964698) * go_1(1.0, 0.0); result += mat4(-0.120734036, -0.12450362, -0.06582111, 0.1639675, -0.19787048, -0.08049789, -0.014257596, 0.058436662, -0.0009387449, -0.08698089, -0.017400503, 0.06295286, 0.09890349, -0.057190523, -0.103520766, -0.04207548) * go_1(1.0, 1.0); result += mat4(-0.0118413875, -0.031288836, 0.09749554, -0.012266401, -0.07998591, 0.22615653, -0.06207416, 0.03257896, -0.076378696, -0.079426095, -0.13968349, -0.15423697, -0.1091681, -0.02893125, -0.032659534, -0.063735925) * go_2(-1.0, -1.0); result += mat4(0.119372696, 0.013176554, -0.029381052, 0.21919228, 0.045041792, 0.24844484, 0.26363325, 0.08480674, 0.087083444, 0.11984778, -0.088715754, 0.06421046, 0.05225977, -0.05140334, -0.055052705, -0.049854077) * go_2(-1.0, 0.0); result += mat4(0.0035781674, 0.0861361, -0.07675145, -0.056479637, 0.16973391, -0.12113791, 0.10729832, -0.03773517, 0.058618728, 0.12148276, 0.17260705, -0.06968724, 0.076358154, -0.15307103, 0.17700425, -0.13467014) * go_2(-1.0, 1.0); result += mat4(-0.02752418, -0.06366472, -0.025610954, 0.0013539721, -0.06465272, 0.0806373, -0.07336035, 0.10114861, 0.0041146413, 0.15878421, -0.044668555, -0.12150811, -0.1071482, -0.05086587, 0.18589285, 0.05065092) * go_2(0.0, -1.0); result += mat4(0.07200056, 0.021739854, 0.29476613, -0.08475931, 0.15018553, -0.07886365, 0.36336347, -0.020576432, 0.25866082, -0.059272554, 0.054249667, -0.17822553, 0.1755872, 0.3244387, -0.39173844, 0.33894604) * go_2(0.0, 0.0); result += mat4(-0.11570926, 0.1342677, -0.19511898, 0.0075454637, -0.01890476, -0.14239742, 0.18921931, 0.033990458, 0.31306365, -0.006998358, 0.029190077, -0.005679954, -0.15341778, 0.07766778, -0.25691047, -0.0964161) * go_2(0.0, 1.0); result += mat4(0.019746238, 0.0021332854, -0.00879096, -0.1338671, -0.0001600663, -0.29465106, 0.0867611, -0.114963025, 0.07874301, -0.012734178, -0.11124061, -0.010926616, -0.04941506, -0.07516841, 0.116663, -0.29018974) * go_2(1.0, -1.0); result += mat4(-0.01651721, 0.05955898, 0.023618208, 0.098695934, 0.018553663, -0.054378513, 0.1436929, 0.1693743, -0.27483663, 0.029127488, 0.09619316, -0.06109113, -0.08619361, 0.09315214, -0.02478657, 0.18544984) * go_2(1.0, 0.0); result += mat4(0.09570196, -0.016528936, -0.1559397, 0.14312246, 0.04029428, 0.08773151, -0.043646842, 0.17894371, -0.082413055, 0.0027082344, -0.100171275, 0.01547501, 0.18122818, -0.11933676, 0.26404107, -0.3169703) * go_2(1.0, 1.0); result += mat4(-0.12073344, 0.08683522, -0.09249099, 0.058786053, -0.14480567, -0.121013954, 0.033335857, 0.009353379, -0.055087596, -0.13002734, 0.08890566, 0.05508963, -0.0075715426, -0.15936922, -0.03968994, -0.1690259) * go_3(-1.0, -1.0); result += mat4(0.2011206, 0.23898427, 0.23656492, 0.1287573, 0.14850396, 0.40532517, -0.107408255, 0.40119782, 0.099813245, -0.03830304, 0.101520434, -0.026478073, -0.048469637, 0.106440455, 0.056632314, -0.17825997) * go_3(-1.0, 0.0); result += mat4(-0.076735444, 0.05965795, -0.0052469415, -0.21785147, 0.11887833, 0.067560315, 0.051149055, 0.23626682, -0.1297049, -0.035512198, 0.20352256, -0.025064934, 0.04958706, 0.0454198, 0.0113334535, 0.0417486) * go_3(-1.0, 1.0); result += mat4(-0.09055751, 0.033915352, -0.21836667, 0.22006813, -0.099022895, 0.11720966, -0.15686816, -0.13586599, -0.094427735, -0.08831514, -0.06182928, 0.09213704, -0.03642064, 0.18129414, -0.012926811, 0.12179882) * go_3(0.0, -1.0); result += mat4(0.19389409, 0.09512252, 0.14768016, -0.16623649, -0.031052284, -0.026814984, 0.106168024, -0.2026781, -0.04581419, -0.0016849053, -0.04101923, 0.038959503, -0.011938445, 0.20096186, -0.26666564, 0.4824324) * go_3(0.0, 0.0); result += mat4(0.17727576, 0.07309147, 0.12131863, -0.163096, 0.17225246, 0.26256254, 0.27685758, 0.09094053, 0.029605515, -0.20217367, 0.047564875, 0.043115832, 0.15089568, -0.09670934, 0.24131384, 0.03337442) * go_3(0.0, 1.0); result += mat4(-0.34192136, 0.12063195, -0.31159517, 0.04170889, -0.30147067, -0.21330686, -0.1514457, -0.121126845, 0.04409098, 9.2206596e-05, 0.027680017, 0.03230512, -0.27993527, -0.093485355, 0.07568645, -0.23585452) * go_3(1.0, -1.0); result += mat4(0.0537712, -0.20847629, 0.1740093, -0.013894753, -0.32719997, -0.059484575, -0.006098233, -0.10336451, -0.14706188, -0.07424865, -0.07045905, 0.17093194, -0.22147557, 0.09086218, -0.11033544, -0.05306482) * go_3(1.0, 0.0); result += mat4(0.00489003, -0.11509064, -0.021005848, 0.16637677, -0.089347586, 0.17545725, -0.17313693, 0.13742085, -0.14577347, 0.07951095, -0.092139855, 0.017118992, -0.053472433, 0.079414465, 0.0330263, -0.11189824) * go_3(1.0, 1.0); result += vec4(-0.034743138, 0.012946433, -0.082333155, 0.07721756); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_3_tf //!BIND conv2d_3_tf1 //!SAVE conv2d_4_tf1 //!WIDTH conv2d_3_tf.w //!HEIGHT conv2d_3_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_3_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_3_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_3_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_3_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.25835788, 0.050451655, -0.1845038, -0.07232528, 0.1323318, 0.26276684, 0.10842882, -0.083056524, 0.17426784, -0.3594826, 0.2728965, 0.08388844, -0.004007842, 0.020535901, -0.051425606, 0.07750436) * go_0(-1.0, -1.0); result += mat4(-0.11410436, 0.014572361, -0.27057216, -0.023974562, 0.05234827, 0.15328228, -0.17502303, -0.3199359, 0.12188045, -0.095813684, 0.024145132, 0.0856916, -0.027453909, -0.043129764, 0.16971985, 0.021623038) * go_0(-1.0, 0.0); result += mat4(0.06611095, 0.038625732, -0.13717118, -0.04497733, 0.15213469, 0.04770935, 0.0729271, -0.062052976, 0.004571303, 0.035141192, -0.059409596, 0.044652313, 0.17520894, 0.09665589, -0.1479193, 0.06528058) * go_0(-1.0, 1.0); result += mat4(-0.1845968, 0.091479465, -0.09394898, -0.13545018, -0.029501775, -0.21426639, 0.09255898, 0.1257644, 0.20256902, 0.06267267, 0.10378081, 0.13494423, 0.058310498, 0.03642236, -0.16268995, -0.048100803) * go_0(0.0, -1.0); result += mat4(0.2155119, -0.3683131, 0.049449228, -0.20559964, -0.11761922, -0.2518804, -0.020712897, 0.12895772, -0.07543782, 0.5805017, -0.11301444, -0.038493153, -0.06710986, -0.09321189, 0.108671665, -0.03259695) * go_0(0.0, 0.0); result += mat4(0.035307787, 0.108389005, -0.27493554, 0.27029404, 0.25523573, -0.28636125, -0.20766719, -0.008661457, -0.004480811, -0.046390545, -0.16221444, 0.008979624, -0.061375532, 0.035076566, -0.018924266, 0.01380219) * go_0(0.0, 1.0); result += mat4(-0.051922515, -0.12463486, -0.10383422, 0.02220095, -0.1573033, 0.13980615, 0.13248625, -0.16803266, -0.0692132, -0.21552645, 0.13744529, 0.23034313, 0.0052666534, 0.028977966, 0.07720251, -0.06477756) * go_0(1.0, -1.0); result += mat4(-0.14097473, 0.2770271, -0.172289, -0.03000696, -0.028684044, 0.040578447, -0.2290285, 0.082329154, -0.042402364, -0.20926563, 0.08233207, 0.11862443, -0.07038536, -0.02273004, 0.091550544, -0.065856494) * go_0(1.0, 0.0); result += mat4(0.14879914, -0.023923844, -0.23569296, 0.20306346, 0.17502785, 0.28776234, -0.2788995, 0.10012439, -0.05635638, -0.025840463, 0.09222198, 0.118032, 0.08057015, 0.1286071, 0.060189806, -0.052669708) * go_0(1.0, 1.0); result += mat4(0.07076086, -0.15111323, -0.07427972, 0.008372168, -0.17791592, -0.16254742, 0.013961132, -0.0944912, -0.23380096, 0.17377278, -0.09683394, 0.019931393, -0.12042098, 0.0016406325, 0.09393333, -0.06882231) * go_1(-1.0, -1.0); result += mat4(0.21465093, 0.04142968, 0.06840044, -0.37831602, -0.05549571, 0.044905066, -0.07873589, -0.026804, -0.34764197, 0.022487951, -0.077293746, 0.089457795, -0.110094436, 0.24233972, 0.06285107, -0.10851744) * go_1(-1.0, 0.0); result += mat4(0.093270175, 0.084138945, 0.03938272, 0.063565865, -0.010733802, 0.13554469, -0.06650261, 0.033002816, 0.011187271, -0.12821455, 0.20785914, -0.030438649, -0.124710515, -0.022294303, 0.09732408, 0.057609864) * go_1(-1.0, 1.0); result += mat4(-0.12833868, 0.021577539, -0.02700365, 0.11799592, -0.03655647, -0.04225167, 0.11049353, -0.16036157, 0.049277548, -0.033842396, 0.10020137, 0.095509745, 0.08060231, -0.09237418, -0.035598125, -0.035926737) * go_1(0.0, -1.0); result += mat4(-0.32829186, 0.3492363, 0.030671779, -0.12606762, 0.010437313, 0.2757115, -0.21517593, -0.15800527, -0.12592544, -0.20578934, 0.10444053, 0.12993255, -0.046079267, 0.03834173, -0.19277227, -0.22124454) * go_1(0.0, 0.0); result += mat4(-0.052546192, 0.026082167, 0.13831234, 0.10982424, 0.012946818, -0.12439852, 0.10134106, -0.10050398, -0.04472338, -0.14325236, -0.20579574, 0.0044005127, 0.22013672, -0.32955512, 0.12404084, -0.008160738) * go_1(0.0, 1.0); result += mat4(-0.10774314, -0.31650826, -0.06601711, 0.19635755, -0.12622592, -0.06396423, 0.13856032, 0.16540553, 0.021387719, 0.23377723, -0.053738154, -0.1000186, -0.08338395, -0.052813534, 0.008122962, 0.13732094) * go_1(1.0, -1.0); result += mat4(-0.18270823, 0.06966014, -0.17788303, -0.27303055, -0.077971615, 0.013978423, -0.02039098, 0.12715338, -0.11924171, 0.18900296, -0.085199654, 0.215198, 0.18587974, -0.009749325, 0.0173584, -0.12018259) * go_1(1.0, 0.0); result += mat4(0.052129295, -0.107416354, 0.12711766, 0.03708665, -0.14369462, -0.055359814, -0.16639823, -0.045143317, -0.06925672, -0.040696755, 0.01999809, -0.016040625, -0.02484878, 0.07417094, 0.050875198, 0.2145528) * go_1(1.0, 1.0); result += mat4(0.055696912, -0.16680926, -0.021987487, 0.024941636, -0.0927883, 0.022136632, 0.033782948, -0.10646058, -0.14944647, 0.25457275, 0.046682496, -0.022462368, -0.07886781, 0.08165927, 0.06848105, 0.0063734027) * go_2(-1.0, -1.0); result += mat4(0.037053242, 0.033215813, 0.18291366, 0.12340375, 0.08491059, -0.28442004, -0.0127422465, -0.039834313, -0.23321372, 0.26676926, -0.05636355, -0.15672484, -0.12891728, -0.15486577, -0.032004442, -0.092745155) * go_2(-1.0, 0.0); result += mat4(0.015779478, -0.18457565, 0.24996394, 0.036197674, 0.15694007, 0.15863103, -0.07332398, 0.0016235278, -0.15536517, -0.056062788, 0.14102836, 0.16915025, -0.08001087, 0.07073164, 0.13796777, 0.123867124) * go_2(-1.0, 1.0); result += mat4(0.045792986, -0.15135059, -0.1354885, -0.043678258, -0.35655212, 0.51232076, -0.12816145, -0.046569496, -0.014127674, -0.06282611, -0.098873, -0.06359104, -0.0919222, 0.11822437, 0.079254694, 0.00579688) * go_2(0.0, -1.0); result += mat4(-0.15683417, 0.61610246, -0.3024612, 0.12917964, -0.09303367, 0.23612969, -0.40842506, -0.12374661, -0.07572449, -0.2613284, -0.09970177, -0.015227848, 0.106239066, -0.21411185, 0.051998455, -0.1364518) * go_2(0.0, 0.0); result += mat4(0.23850034, -0.14394449, -0.0031468747, -0.2380617, -0.027200876, -0.041352056, -0.01864445, 0.033848196, -0.12064239, -0.110480845, 0.08450956, -0.22328654, 0.17664163, 0.22268307, 0.050886698, -0.17475672) * go_2(0.0, 1.0); result += mat4(-0.17808256, 0.010803805, 0.03315186, 0.033143792, -0.14205995, 0.25039625, -0.08784382, -0.13454252, 0.19576813, 0.10755282, 0.22821628, 0.019456752, -0.0422955, -0.016182603, -0.12066697, 0.0548465) * go_2(1.0, -1.0); result += mat4(0.11563777, -0.257929, 0.0010403778, 0.080267854, -0.0025255163, 0.2855168, -0.060352214, -0.07816255, -0.00090574916, 0.049510725, 0.03720483, 0.059250016, -0.08674136, 0.20522198, -0.28694284, 0.1299507) * go_2(1.0, 0.0); result += mat4(-0.14638457, 0.04063328, 0.03139636, -0.007934521, 0.07689684, -0.09467145, 0.10607347, 0.054510128, 0.003306194, 0.05347124, 0.062762424, -0.041480847, -0.07677865, -0.139573, 0.010972524, 0.21957156) * go_2(1.0, 1.0); result += mat4(-0.026845628, -0.043439507, 0.034738723, 0.07281683, 0.14474197, 0.031586993, -0.22767854, -0.0707655, 0.105201736, -0.28805482, 0.008668302, -0.16329518, 0.06157049, 0.3803886, 0.26345953, -0.011096537) * go_3(-1.0, -1.0); result += mat4(-0.23328833, 0.085731484, -0.07755016, 0.33559516, 0.07704345, 0.115106605, -0.24114038, -0.44630137, 0.2726737, -0.32170138, -0.009236524, -0.11666051, 0.0457048, 0.07876708, 0.13134004, -0.035318643) * go_3(-1.0, 0.0); result += mat4(-0.05140272, 0.011605703, 0.13899171, -0.05071015, 0.18413687, -0.31413674, -0.13043414, -0.15118152, -0.15326938, -0.10720126, -0.23738635, 0.13481396, 0.25115076, -0.009316611, -0.2584441, -0.14389823) * go_3(-1.0, 1.0); result += mat4(-0.039723795, -0.14869407, -0.1692942, 0.026501274, -0.10685166, -0.121267825, -0.08584318, -0.09580693, -0.10626739, -0.068417974, 0.11321909, -0.13664317, 0.061380867, -0.2587898, 0.14850819, 0.008178645) * go_3(0.0, -1.0); result += mat4(0.06912782, 0.24230564, -0.048150286, 0.2203717, -0.17417085, 0.105546735, -0.16648416, -0.0045053074, 0.09764028, 0.37122592, -0.1939995, -0.27899942, -0.088152565, -0.53869057, 0.21676709, -0.08056594) * go_3(0.0, 0.0); result += mat4(0.07651754, 0.03704878, -0.0197015, 0.1660726, 0.07002748, -0.11820414, -0.23360898, 0.1481592, 0.029847002, 0.054057185, 0.013176299, 0.06552942, -0.13865773, -0.20105527, -0.37550658, 0.005769631) * go_3(0.0, 1.0); result += mat4(-0.22697811, -0.17426412, 0.10148018, 0.008134666, 0.10771455, 0.16943407, -0.016319012, -0.40176705, -0.06854668, -0.049045276, 0.20919096, 0.13240765, -0.050125647, 0.14902508, 0.052697595, -0.13817468) * go_3(1.0, -1.0); result += mat4(0.04301619, 0.23184754, -0.023551717, 0.3768405, 0.028999053, 0.06709736, -0.05993663, -0.059861984, 0.15499207, -0.22217415, 0.111131504, -0.09082529, -0.19389243, 0.024621522, -0.15305442, 0.010799284) * go_3(1.0, 0.0); result += mat4(-0.035496738, 0.010802548, -0.028718363, 0.19263634, 0.16900502, -0.16661702, -0.027631328, 0.18309957, -0.015860107, -0.03309961, -0.091390446, 0.14000848, -0.0036591904, 0.47659522, -0.09373507, -0.29020965) * go_3(1.0, 1.0); result += vec4(0.08895955, -0.027667087, 0.20500831, 0.00037762933); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_4_tf //!BIND conv2d_4_tf1 //!SAVE conv2d_5_tf //!WIDTH conv2d_4_tf.w //!HEIGHT conv2d_4_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_4_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_4_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_4_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_4_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.018134737, -0.2296755, -0.07276725, -0.029795367, 0.05382051, 0.092847414, -0.024469728, -0.1674685, 0.0017946451, 0.30074653, 0.0034195695, -0.04892261, 0.18229689, -0.20116119, -0.12702174, -0.08259108) * go_0(-1.0, -1.0); result += mat4(-0.1357695, -0.08149211, 0.09314453, -0.21966846, 0.34740716, 0.043606415, 0.04225903, 0.034449834, 0.17248215, 0.39148283, -0.13868807, -0.010550686, 0.044238456, -0.09693464, -0.005044985, 0.24383289) * go_0(-1.0, 0.0); result += mat4(0.19959371, 0.098685324, 0.058746945, 0.010580748, 0.08051514, 0.031898864, 0.017556064, 0.13004355, -0.01727653, 0.11044019, 0.040673427, -0.20064595, -0.23321067, 0.06398686, -0.19126236, -0.2430858) * go_0(-1.0, 1.0); result += mat4(-0.12870286, -0.113455534, 0.23722827, 0.070718594, 0.19049989, -0.1927299, -0.06343845, 0.113127775, 0.082530305, -0.10972526, -0.090779535, 0.05731582, 0.11018802, -0.18049154, 0.09269507, -0.10304576) * go_0(0.0, -1.0); result += mat4(0.15513484, 0.06659583, 0.08125296, -0.012350324, -0.09492788, 0.5048303, 0.13206847, 0.39554298, 0.28953737, -0.20913891, -0.26781562, -0.17539899, 0.023778774, 0.29716817, 0.15768486, 0.37702608) * go_0(0.0, 0.0); result += mat4(0.0724462, 0.015571356, -0.032217246, 0.0050658924, -0.22708446, 0.03968809, 0.016753826, 0.0025668752, -0.055932112, 0.113931604, 0.19766758, -0.030027265, -0.17384295, 0.15013468, -0.0070017707, -0.09469028) * go_0(0.0, 1.0); result += mat4(-0.078361556, -0.0954201, -0.006358101, 0.040500037, 0.4190454, -0.17622913, -0.07234791, 0.05462559, 0.18641087, 0.058313597, -0.0180785, 0.13818781, -0.14640772, 0.0699486, 0.0073663946, -0.076789856) * go_0(1.0, -1.0); result += mat4(-0.21421191, 0.08736062, 0.09041226, 0.03608585, 0.02769972, 0.09641289, 0.11824623, 0.05653645, 0.16464607, 0.19839554, -0.13379547, 0.054417104, 0.067530684, 0.18971571, 0.13785432, -0.097639814) * go_0(1.0, 0.0); result += mat4(-0.32658005, -0.14606023, -0.069448665, 0.032998275, -0.28331423, 0.0011900732, -0.020304207, -0.13535896, 0.08298347, 0.045509677, -0.030503955, -0.037504148, 0.049955815, 0.0925771, 0.00058534974, -0.12398032) * go_0(1.0, 1.0); result += mat4(-0.2955836, 0.29059318, -0.018196672, -0.35866606, -0.01309431, 0.03540315, 0.010609202, 0.11956812, 0.10296229, 0.22536302, 0.015201129, -0.23797737, -0.16960852, -0.11414787, -0.034440614, 0.112644605) * go_1(-1.0, -1.0); result += mat4(-0.14952518, 0.07024436, -0.083184876, -0.0814617, -0.13303639, 0.016159372, -0.13521518, 0.2221334, -0.056617837, 0.12958299, 0.064461656, -0.20146395, -0.16023181, 0.2640758, 0.27528805, -0.1426518) * go_1(-1.0, 0.0); result += mat4(-0.04382363, 0.09856003, -0.08561442, -0.15699928, -0.121069774, 0.04685383, -0.009170197, -0.031489655, 0.18730178, 0.238442, 0.22497098, 0.032015145, -0.03709115, 0.1535079, 0.21674158, 0.10678019) * go_1(-1.0, 1.0); result += mat4(-0.12200952, 0.24224263, 0.034097504, -0.028179523, -0.011962496, -0.04489487, -0.05198827, 0.22194928, -0.045400873, -0.049828544, 0.111477956, -0.098361604, 0.12788995, -0.016093334, -0.19886433, -0.011161484) * go_1(0.0, -1.0); result += mat4(0.30563712, 0.013071727, -0.004799883, 0.12888052, -0.259498, -0.041566677, 0.07311124, 0.162324, 0.28371668, -0.004693743, -0.0019395344, 0.029358242, 0.08730285, 0.12184509, 0.05508437, 0.048439097) * go_1(0.0, 0.0); result += mat4(0.12760857, 0.115813166, -0.217695, -0.10629871, -0.227366, 0.09030426, -0.15313712, 0.020528946, -0.20743734, 0.088583544, 0.04594053, -0.22891994, 0.18949282, -0.042186577, -0.17330512, -0.010711361) * go_1(0.0, 1.0); result += mat4(0.029503195, 0.0063797613, -0.17004286, -0.096844055, 0.010218098, 0.04247233, 0.02362808, 0.14700809, -0.08082364, 0.11159672, -0.018505255, -0.15228583, 0.15693732, -0.025359154, 0.024829186, 0.1943192) * go_1(1.0, -1.0); result += mat4(-0.03912932, -0.21989027, 0.12203028, 0.18702275, -0.118537985, 0.21039696, 0.09102061, 0.012288879, 0.031666897, 0.1318455, -0.04901404, -0.07516063, -0.44782668, 0.04884501, 0.047070876, 0.008728358) * go_1(1.0, 0.0); result += mat4(-0.08669101, 0.3053463, -0.08963947, 0.0034188698, -0.070004664, 0.064788476, 0.093737036, 0.070050925, 0.12728429, -0.13179256, -0.014913502, 0.09308136, -0.027638942, 0.008638711, 0.08794172, -0.05531093) * go_1(1.0, 1.0); result += mat4(0.0728421, 0.07872358, 0.11454748, 0.08497922, 0.071820416, -0.11789207, -0.08184197, 0.1359588, -0.2143346, -0.05876081, 0.023172129, -0.08430511, -0.19276723, 0.14283359, 0.15604696, -0.055187486) * go_2(-1.0, -1.0); result += mat4(0.068641685, 0.2732106, -0.2809107, 0.12736696, -0.08642367, 0.023898933, -0.17859498, -0.18299665, -0.06684587, -0.12204666, 0.45898953, -0.24240111, 0.25182098, -0.04395751, 0.10637211, -0.22135144) * go_2(-1.0, 0.0); result += mat4(0.0852072, 0.051133018, 0.03333165, -0.0008938216, 0.10251267, 0.0550774, 0.041769378, -0.21259712, 0.286912, 0.123342015, 0.282759, -0.0730124, 0.14275575, -0.15580742, -0.15224406, 0.045376908) * go_2(-1.0, 1.0); result += mat4(0.03328225, 0.11563978, -0.07451964, 0.030546209, -0.04698351, -0.18544962, 0.037350416, 0.13969816, 0.0556746, -0.06359919, 0.06478219, -0.031694926, 0.13396506, 0.09443612, -0.01922686, -0.06290365) * go_2(0.0, -1.0); result += mat4(0.07495407, 0.063429266, -0.106221214, -0.085107304, 0.2497817, -0.46598253, -0.18833177, -0.2731128, -0.13024822, 0.56053543, 0.055704467, -0.12331414, -0.031199086, 0.05061188, 0.22097112, -0.6611177) * go_2(0.0, 0.0); result += mat4(0.08276988, -0.044184342, -0.03562185, -0.06159881, 0.27694225, -0.07192965, -0.08663714, 0.020221777, 0.14095962, -0.06229397, 0.051374253, -0.038158998, 0.10664802, -0.041305423, 0.051260717, -0.054698635) * go_2(0.0, 1.0); result += mat4(0.12800686, 0.03485072, 0.039914366, 0.034041498, -0.08305794, -0.046292894, 0.22765331, 0.10904922, 0.0013937047, -0.08750301, 0.009126207, -0.065589435, 0.2837707, 0.08884436, -0.07234862, -0.093502745) * go_2(1.0, -1.0); result += mat4(0.113439895, 0.06081726, 0.1122302, -0.022936966, 0.10329637, -0.31816107, -0.051597945, 0.23846027, -0.083913095, -0.29872265, -0.040147282, -0.08981918, -0.04329814, -0.12339693, -0.034489952, 0.013393211) * go_2(1.0, 0.0); result += mat4(0.33091688, 0.1726297, 0.034332044, -0.091396205, 0.15434311, -0.0022870845, -0.15506189, 0.08710491, -0.16063525, 0.042252056, 0.017086457, 0.08134797, 0.08631321, 0.037843138, 0.088296555, 0.0064518084) * go_2(1.0, 1.0); result += mat4(0.09161051, 0.114355795, -0.15304486, -0.030537153, 0.1835368, -0.3287635, 0.031197926, 0.09717476, 0.04276852, 0.113250345, 0.05949038, -0.10599563, 0.43574792, -0.060788117, 0.18409383, 0.12678055) * go_3(-1.0, -1.0); result += mat4(-0.018356865, -0.0072578182, 0.12020777, -0.013127592, 0.20136636, -0.22984362, 0.06896224, 0.00044982752, 0.008428429, -0.123316936, -0.09989286, 0.078248784, -0.16313677, -0.003020313, -0.46285018, -0.08967125) * go_3(-1.0, 0.0); result += mat4(-0.03451497, -0.10864502, 0.13207638, 0.17194521, 0.0037514758, -0.20222199, -0.12535086, 0.001511977, 0.056294486, -0.2112898, 0.078261316, 0.10118746, -0.044742294, 0.21793383, -0.19927903, -0.21338293) * go_3(-1.0, 1.0); result += mat4(-0.034903776, -0.10167085, 0.031066334, 0.0379958, 0.20532596, -0.17457838, 0.16556816, -0.0021619152, 0.02682665, 0.03396325, -0.059273884, 0.1922813, -0.072151475, -0.010240544, 0.2302027, 0.12385962) * go_3(0.0, -1.0); result += mat4(-0.20170145, -0.08203941, -0.028107846, -0.18003726, 0.44744352, -0.13190243, 0.13233365, 0.03626546, 0.085763134, -0.25613126, -0.11213388, 0.15529087, -0.271649, 0.050587676, -0.062583975, 0.057289865) * go_3(0.0, 0.0); result += mat4(-0.040649455, -0.17949733, 0.35847965, -0.040587306, 0.24314344, -0.23811667, 0.13958354, 0.04961874, 0.09858903, -0.04202913, -0.21850993, 0.0700419, -0.09130745, -0.096835814, 0.0022782686, -0.25416258) * go_3(0.0, 1.0); result += mat4(-0.08215545, -0.019647893, 0.055263475, 0.053733055, 0.098485716, -0.1041945, -0.06541415, -0.08868577, -0.07262986, 0.03513784, -0.110529095, -0.03369232, 0.056786604, 0.2569229, -0.05931065, -0.22081214) * go_3(1.0, -1.0); result += mat4(0.066926084, 0.029664058, -0.10779271, 0.11026963, 0.23927264, -0.16914488, 0.022947345, 0.12303853, -0.07066212, -0.013205378, 0.15348643, 0.035568032, 0.20966691, 0.010149819, -0.08814468, -0.064854674) * go_3(1.0, 0.0); result += mat4(0.11493852, -0.074924305, -0.14840698, -0.16956823, 0.056806292, -0.06387947, -0.06880271, -0.04637334, -0.1929893, 0.18226422, 0.064644486, -0.1594863, 0.027403917, 0.13951495, -0.06569123, -0.07700207) * go_3(1.0, 1.0); result += vec4(-0.043347504, -0.20504741, -0.037821215, -0.014486937); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_4_tf //!BIND conv2d_4_tf1 //!SAVE conv2d_5_tf1 //!WIDTH conv2d_4_tf.w //!HEIGHT conv2d_4_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_4_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_4_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_4_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_4_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.047881734, -0.09396414, -0.2839081, 0.3140853, 0.052613556, 0.09940423, 0.23960467, -0.022228222, -0.12065009, 0.07898222, 0.08657881, 0.010852739, -0.050450284, 0.01683982, 0.031813968, 0.053060856) * go_0(-1.0, -1.0); result += mat4(-0.10252411, -0.03116448, -0.30114275, -0.0316799, -0.017501019, -0.03006003, -0.2095696, 0.10134927, -0.3901916, -0.15335023, -0.11955071, 0.1337449, 0.101239376, -0.25044814, 0.2128469, 0.018979514) * go_0(-1.0, 0.0); result += mat4(-0.13392173, 0.052036732, 0.1682114, -0.026263753, 0.027221246, -0.15121374, 0.13723798, 0.08950682, -0.1182108, -0.07294226, 0.023392374, 0.052329235, -0.05632852, -0.07036173, 0.06872573, 0.05238042) * go_0(-1.0, 1.0); result += mat4(0.18112028, 0.18242362, -0.06812871, 0.032463413, 0.124638766, -0.26765212, -0.07678663, 0.33806562, 0.09674393, 0.15574542, 0.23634006, -0.02873782, -0.1626769, -0.14760062, -0.007274849, 0.09866139) * go_0(0.0, -1.0); result += mat4(-0.10726673, -0.10925056, 0.19967109, -0.19936769, 0.15942842, -0.14870064, 0.15493345, -0.08489036, -0.49053356, -0.17321263, 0.28426084, 0.18721215, -0.09898434, -0.2751838, -0.11833524, 0.028445128) * go_0(0.0, 0.0); result += mat4(-0.11788817, -0.23724948, -0.046072144, 0.035621114, 0.04527003, -0.0073492974, 0.11097195, 0.06806836, 0.04814677, -0.1408476, -0.1325629, 0.00929532, -0.16699041, -0.03034791, 0.08320368, -0.15429299) * go_0(0.0, 1.0); result += mat4(0.2729515, 0.008244692, -0.17441982, -0.39026466, 0.17381759, 0.31194404, 0.055934936, 0.20744409, 0.20119062, 0.0734271, 0.0796807, 0.0031037466, -0.0016392237, 0.033733975, 0.07149338, 0.042083208) * go_0(1.0, -1.0); result += mat4(0.07985744, 0.10945015, 0.018472541, 0.1397503, 0.2005682, 0.42641, 0.23022486, -0.2916921, 0.028285174, -0.31885162, -0.27070364, -0.10390779, 0.0751492, 0.12752363, -0.2279459, 0.08998453) * go_0(1.0, 0.0); result += mat4(0.18450491, -0.140783, -0.008006845, 0.09029298, 0.12536179, 0.26949662, 0.09491545, 0.063907005, 0.11212244, 0.09778506, -0.1835966, -0.053119674, 0.0072294096, 0.25018227, 0.010868525, -0.22721334) * go_0(1.0, 1.0); result += mat4(-0.028011927, -0.20073172, 0.5976166, -0.19494139, 0.17958745, -0.03838646, 0.058325976, -0.29409218, -0.12793432, 0.03245129, 0.35662368, -0.05048354, -0.13368197, -0.06151968, -0.012714591, -0.1763054) * go_1(-1.0, -1.0); result += mat4(0.18468465, 0.31682113, 0.12818255, -0.117110476, 0.13709468, -0.10034022, -0.07994527, -0.1259309, 0.04067299, -0.1147398, 0.28361055, 0.27916273, 0.03696692, 0.16829546, 0.27819383, 0.08305029) * go_1(-1.0, 0.0); result += mat4(-0.28920117, -0.033877946, 0.01586206, 0.04681198, 0.024248574, -0.045777842, -0.03342128, 0.07525412, -0.063377544, -0.016737273, 0.11235511, -0.04325238, -0.24170023, -0.09993599, -0.03205371, 0.14339828) * go_1(-1.0, 1.0); result += mat4(-0.008357902, -0.11038377, 0.03709221, 0.26775306, 0.07963845, -0.25377446, -0.17630441, -0.10966474, 0.057311732, -0.083327, 0.044497233, 0.06903858, -0.26531395, -0.103399664, -0.14806591, 0.269314) * go_1(0.0, -1.0); result += mat4(0.05450808, -0.041993964, -0.07217651, 0.034468375, 0.2117634, 0.0075620585, 0.05825411, -0.2252478, -0.0527787, 0.049732126, -0.032040413, -0.09361454, 0.29585132, 0.018413153, 0.18384546, -0.024226356) * go_1(0.0, 0.0); result += mat4(-0.031109914, 0.19351351, 0.07405522, -0.06313074, -0.09983541, -0.011495182, 0.11749038, -0.16775608, 0.2790974, -0.09338754, 0.07913264, 0.103792936, -0.18679164, -0.15639925, 0.112943865, 0.07930375) * go_1(0.0, 1.0); result += mat4(0.004106195, -0.036833283, 0.12908752, 0.12869535, -0.02472107, 0.17561707, -0.025890926, -0.18789047, 0.096218705, -0.16306408, -0.02198454, -0.010134957, -0.09710009, 0.002062143, -0.046785697, 0.0029441968) * go_1(1.0, -1.0); result += mat4(0.19648251, -0.015663045, -0.0730215, 0.028611008, 0.13529862, -0.015256192, -0.04119306, -0.24628192, 0.02601027, -0.21184283, -0.1962902, 0.09109358, -0.06792383, 0.092336476, 0.12215351, -0.08596062) * go_1(1.0, 0.0); result += mat4(-0.17530201, -0.0351919, -0.31872514, -0.13933206, -0.07000922, -0.049807087, 0.0010997375, -0.033573963, 0.07442056, -0.33290103, -0.40381998, 0.09435, -0.3280128, -0.09953127, -0.11283648, 0.20685865) * go_1(1.0, 1.0); result += mat4(-0.052573867, -0.035328753, -0.11132943, -0.17515652, 0.05021051, 0.058642425, -0.046640664, 0.0799107, -0.027398815, -0.33619994, -0.22135767, 0.07894002, -0.14941697, -0.0940996, -0.11655085, 0.049795926) * go_2(-1.0, -1.0); result += mat4(-0.039301276, 0.041062318, 0.20312686, -0.009338705, 0.013706282, -0.0245852, 0.03458311, 0.09601228, -0.18203016, -0.012260314, 0.17984508, -0.056576703, -0.102844186, 0.24047872, 0.05307189, 0.16066082) * go_2(-1.0, 0.0); result += mat4(0.1478775, 0.0046362123, 0.05459521, 0.07162838, -0.01896149, 0.23700175, -0.14174299, 0.06988599, -0.32545477, -0.08065096, -0.061227743, -0.0010796773, 0.094327345, -0.20760082, -0.19523263, 0.19859222) * go_2(-1.0, 1.0); result += mat4(-0.049676366, -0.10381536, 0.02546116, -0.13127093, 0.10954914, 0.0048147943, 0.06962328, -0.30456528, -0.11956627, 0.0150488885, -0.10711722, 0.1684613, -0.1939089, -0.10577047, -0.11980919, -0.036988296) * go_2(0.0, -1.0); result += mat4(-0.054795764, 0.09491116, -0.08494948, 0.059765853, 0.0131597435, 0.20786162, 0.11999637, 0.024381055, 0.22830428, 0.027053319, -0.011646274, -0.12145409, -0.07899559, -0.012688263, 0.10684157, 0.3824219) * go_2(0.0, 0.0); result += mat4(-0.23994572, -0.0031532666, -0.0050638164, 0.14236279, 0.05690383, -0.06259682, 0.052624144, 0.20461404, -0.19230312, -0.11072268, 0.013023965, 0.08931543, -0.21997221, 0.11760443, -0.40943825, 0.28656834) * go_2(0.0, 1.0); result += mat4(-0.06606179, 0.26007771, 0.033754125, 0.119690455, 0.024669139, -0.06752839, 0.12688096, -0.0063201943, -0.17123021, 0.07548857, -0.14213699, 0.034093797, -0.15632647, -0.123243414, -0.42634043, 0.1715022) * go_2(1.0, -1.0); result += mat4(-0.046503466, 0.13876389, 0.17973013, -0.25938338, -0.18824704, -0.11876702, 0.31065792, -0.041042212, -0.061369427, 0.2057992, 0.17295738, 0.3836555, -0.21109799, -0.10167118, 0.16577047, 0.113483034) * go_2(1.0, 0.0); result += mat4(-0.24534856, -0.014482421, 0.22515748, -0.12773542, 0.12794174, -0.02528619, 0.41710484, 0.09154934, -0.17805946, -0.25428918, 0.07294183, 0.047079418, -0.30949152, -0.08919157, 0.17888431, 0.17706038) * go_2(1.0, 1.0); result += mat4(-0.1741826, 0.046225294, -0.10761791, 0.2619953, 0.007373745, 0.05104337, -0.22309966, 0.34529984, -0.034363825, -0.022187237, -0.08609555, 0.16842419, 0.28136057, 0.17843607, -0.11307746, -0.05668021) * go_3(-1.0, -1.0); result += mat4(-0.12310616, -0.29661375, -0.10581025, -0.049584012, 0.19651765, 0.08436489, -0.14533581, -0.029874112, -0.15422897, -0.062741704, -0.22694711, -0.15547274, -0.15181333, 0.0286061, 0.022438493, -0.062447168) * go_3(-1.0, 0.0); result += mat4(0.3497046, -0.09455009, 0.060618952, -0.2134236, 0.054515295, 0.07451165, -0.09267233, -0.010513333, 0.13842636, 0.11563433, -0.054750167, 0.050432, 0.1514256, 0.04284002, -0.2095581, 0.07907657) * go_3(-1.0, 1.0); result += mat4(-0.11745651, -0.04717057, 0.085377194, -0.065956995, 0.07280491, 0.2730059, 0.11088276, 0.2437957, 0.14018989, 0.1164107, -0.09516929, 0.0022427947, 0.111544006, -0.0680495, 0.09324579, -0.12482022) * go_3(0.0, -1.0); result += mat4(-0.07995795, -0.03387884, 0.019846136, 0.10231208, -0.07017192, 0.18659039, 0.035161644, 0.101182766, -0.14901665, 0.21307294, 0.063894205, -0.27546507, -0.24792959, -0.067731075, 0.13146006, -0.19333683) * go_3(0.0, 0.0); result += mat4(0.034206454, 0.1472648, -0.07406727, 0.014654025, 0.18703444, 0.1319857, -0.10610886, 0.08427947, -0.017536618, -0.06487879, -0.12095286, -0.050414838, 0.03260879, 0.1558894, -0.031887084, 0.11840288) * go_3(0.0, 1.0); result += mat4(0.114811294, -0.14574333, -0.09392587, 0.042283528, 0.08919092, 0.18259068, 0.0980717, 0.21024778, -0.1280008, -0.027260462, -0.1129027, 0.18722472, 0.13733985, 0.047153983, 0.030871978, 0.1998385) * go_3(1.0, -1.0); result += mat4(-0.06783575, 0.004612595, 0.1153467, -0.11531557, -0.048889533, 0.07673577, -0.02041786, 0.22744459, -0.13092506, 0.13484807, 0.40003043, -0.053706612, -0.16985156, -0.04791236, -0.052443005, -0.08363625) * go_3(1.0, 0.0); result += mat4(0.18187882, 0.017893985, 0.17856054, 0.005413129, 0.014147176, 0.15102178, 0.12436294, -0.02176765, -0.16727823, -0.0364111, 0.17074408, 0.12899421, 0.31984514, -0.0072070034, 0.031895883, -0.1991405) * go_3(1.0, 1.0); result += vec4(-0.011865144, 0.11717201, -0.13823777, -0.059450272); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_5_tf //!BIND conv2d_5_tf1 //!SAVE conv2d_6_tf //!WIDTH conv2d_5_tf.w //!HEIGHT conv2d_5_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_5_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_5_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_5_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_5_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.082203194, 0.021720003, 0.03725474, -0.08048348, 0.2063248, -0.033020593, -0.17585336, 0.06476272, 0.012244563, 0.026554609, 0.014708393, 0.26606125, 0.14248778, 0.12817341, -0.039826933, -0.12751861) * go_0(-1.0, -1.0); result += mat4(0.24573852, 0.19695967, -0.06257417, -0.04782871, 0.3511875, -0.018083302, -0.077342674, 0.15247667, 0.20321761, -0.07479984, -0.09548503, 0.08109568, -0.23808748, 0.07246303, -0.004242619, 0.16162953) * go_0(-1.0, 0.0); result += mat4(0.13296306, 0.19495387, 0.009222276, 0.033592198, 0.20443891, 0.16063854, -0.2581601, -0.016132578, -0.2296461, -0.23647323, -0.15407176, -0.18265317, 0.2343241, -0.049697313, -0.09398783, 0.41931856) * go_0(-1.0, 1.0); result += mat4(-0.10866088, -0.40605694, -0.0042648134, 0.07943803, 0.26914695, 0.14816476, 0.037706107, -0.123223364, -0.19962949, -0.053534556, -0.08397409, -0.04244924, -0.075791344, 0.29629225, 0.2311928, 0.099177904) * go_0(0.0, -1.0); result += mat4(-0.1748319, -0.2003186, -0.32659066, -0.21007413, 0.20122464, 0.032196607, -0.026299698, 0.33395135, 0.11411664, 0.05971959, 0.09001304, -0.15936212, 0.012322024, 0.19936106, -0.411186, -0.08319479) * go_0(0.0, 0.0); result += mat4(-0.07349218, 0.006184436, 0.096199185, -0.050186496, 0.064047046, -0.03813128, -0.057007037, -0.025550695, -0.2863145, -0.008512981, -0.20615962, 0.18009211, 0.008298396, 0.22452813, 0.010843521, 0.20169461) * go_0(0.0, 1.0); result += mat4(0.2691149, 0.059546687, 0.08922005, 0.2252196, 0.30341956, -0.024489028, 0.087045394, -0.03856442, -0.14083561, -0.17683443, 0.14137806, 0.15520614, 0.2073925, -0.19525874, 0.23661858, 0.3098405) * go_0(1.0, -1.0); result += mat4(0.006530723, 0.04180736, -0.04762067, -0.064395495, 0.02396811, -0.13332283, 0.0037775645, 0.026309434, 0.0033065109, -0.08315753, 0.02917419, 0.12330464, 0.22819455, -0.07489677, 0.12829056, -0.097994626) * go_0(1.0, 0.0); result += mat4(-0.09983759, 0.032783493, 0.11085758, 0.08993078, -0.057110567, -0.018973934, -0.14946178, -0.03921629, 0.039757587, 0.015860094, 0.04989561, -0.19634786, 0.04351146, 0.019315343, 0.25972188, 0.17989321) * go_0(1.0, 1.0); result += mat4(-0.04111906, -0.165601, 0.0003682197, -0.056232415, -0.32716644, -0.24015541, -0.057547837, 0.05966729, 0.06854747, 0.03599213, -0.18798864, 0.1183447, 0.014268468, -0.1310834, 0.06415977, -0.19414157) * go_1(-1.0, -1.0); result += mat4(-0.00070661673, 0.17671427, 0.10584568, -0.060910843, -0.104282066, -0.22676118, -0.01907062, 0.24882245, -0.043454725, 0.07691623, -0.48371696, 0.013537671, -0.025488405, 0.061228953, 0.18548754, 0.028671112) * go_1(-1.0, 0.0); result += mat4(-0.0121596735, 0.09595702, -0.08244918, -0.1176173, 0.26773354, -0.021729136, 0.075465776, -0.0928876, 0.12461298, 0.16830076, -0.15302569, 0.113850676, 0.09811088, 0.13006307, 0.24999009, 0.10261325) * go_1(-1.0, 1.0); result += mat4(-0.032246377, 0.038265374, -0.26476422, -0.1442876, -0.19866082, 0.08649541, 0.041478764, 0.11155026, 0.21576422, -0.09572912, -0.11174068, -0.19722937, -0.15801935, 0.29604745, -0.08606268, -0.15532136) * go_1(0.0, -1.0); result += mat4(-0.06315591, 0.16151646, -0.009230362, -0.04341246, 0.09085519, 0.21924476, 0.38044852, 0.193819, 0.16622902, 0.0025134624, -0.22688466, -0.025276015, 0.07714917, 0.16302192, -0.11767101, -0.11086476) * go_1(0.0, 0.0); result += mat4(-0.04170153, 0.001859292, -0.26352355, 0.10982333, -0.031867817, 0.15773517, -0.060263418, 0.11117763, -0.017359972, 0.0127261225, 0.0782802, -0.16908924, 0.080516845, -0.05691526, -0.07530135, -0.14553802) * go_1(0.0, 1.0); result += mat4(0.06112685, -0.032287434, 0.17445667, -0.044935808, -0.11449107, -0.051394563, -0.029589338, -0.14555557, 0.03440661, 0.11035615, -0.17175, -0.14851089, 0.037362, -0.18740481, 0.17278154, 0.18073405) * go_1(1.0, -1.0); result += mat4(-0.27670652, 0.19484822, 0.2609349, 0.1455016, 0.04438468, 0.1449185, 0.11185832, -0.18598269, -0.019846648, 0.11886126, -0.098498635, 0.15737785, 0.011406795, -0.18860829, -0.13705735, 0.17535745) * go_1(1.0, 0.0); result += mat4(-0.30244905, -0.28695273, 0.1146976, 0.21144345, -0.037980128, -0.027679864, -0.13992494, -0.04884521, -0.032023884, -0.07921183, -0.16042095, -0.06935386, -0.06570237, -0.1107404, -0.018163798, 0.22625941) * go_1(1.0, 1.0); result += mat4(-0.07292955, -0.07321777, -0.045146503, -0.33291966, -0.096732594, -0.07203495, 0.33692798, 0.2870733, 0.122160144, -0.076574564, 0.042844944, 0.26448342, 0.07672146, -0.028775277, -0.12088313, 0.15583947) * go_2(-1.0, -1.0); result += mat4(0.21589327, 0.05258274, 0.09705794, -0.024653846, -0.039402515, 0.28485695, 0.14711736, -0.10556087, -0.15140481, 0.09039498, 0.017308712, 0.11862922, 0.08230978, 0.21678248, -0.043815188, -0.226433) * go_2(-1.0, 0.0); result += mat4(-0.029258793, 0.26618922, 0.02564014, -0.23189862, -0.24074338, -0.18556763, 0.25973624, 0.04746873, 0.0137007125, -0.22239363, -0.12414957, 0.048228756, -0.22406264, 0.282667, -0.021001073, -0.17465611) * go_2(-1.0, 1.0); result += mat4(0.32401654, -0.1495363, -0.20869227, 0.04271639, -0.0087802755, 0.031325378, 0.23834595, 0.039336167, 0.17265107, 0.20947595, 0.28737286, 0.0028783784, -0.057340365, -0.050347418, -0.11915604, -0.1831807) * go_2(0.0, -1.0); result += mat4(0.1811338, 0.07732653, 0.20975596, -0.47129005, 0.07121942, 0.08410583, 0.44170937, -0.19524159, -0.17807977, 0.12837476, 0.20816846, -0.1741958, -0.04411918, 0.06024972, 0.18159702, -0.052485272) * go_2(0.0, 0.0); result += mat4(-0.15229738, 0.27513, 0.28150418, -0.19543962, -0.02045864, -0.07207227, 0.09589587, 0.09110817, 0.061413247, 0.0046052113, 0.11619411, -0.2988938, 0.065739445, 0.10205611, 0.12847126, -0.028355654) * go_2(0.0, 1.0); result += mat4(0.0657154, -0.047568597, -0.16148911, 0.16392621, -0.25281775, -0.061153214, 0.017480455, -0.026288848, 0.20319715, 0.04763355, 0.010444491, -0.26671803, -0.25821987, 0.32863674, -0.30734694, -0.18190521) * go_2(1.0, -1.0); result += mat4(-0.042703815, 0.06633036, -0.048434302, -0.17176376, -0.12699759, -0.1124558, 0.083266065, 0.03354623, -0.13468939, 0.12706263, 0.053659134, -0.06930602, 0.008196115, 0.2034998, -0.06351442, -0.039730288) * go_2(1.0, 0.0); result += mat4(0.09614661, 0.22500272, 0.088511504, -0.16960482, 0.15364788, -0.18854137, -0.13163191, -0.07503735, -0.23177068, -0.0053305267, -0.041978605, 0.0971947, -0.049034655, 0.04486706, 0.09076307, -0.02310868) * go_2(1.0, 1.0); result += mat4(-0.1304683, 0.17743458, -0.09817326, -0.0646786, 0.07886976, 0.20109388, -0.034114968, -0.2029261, -0.03348398, 0.029337432, -0.07302782, -0.02240758, 0.030242773, -0.30032325, 0.02085572, -0.027314361) * go_3(-1.0, -1.0); result += mat4(-0.037377544, 0.026350772, -0.07430488, -0.114671774, -0.126935, -0.046512567, -0.033628833, -0.19018382, -0.041053895, -0.031206857, 0.08562848, -0.01875709, 0.21099389, -0.092511, 0.0073047103, -0.009811013) * go_3(-1.0, 0.0); result += mat4(0.11358029, 0.17468451, -0.12739041, -0.14332245, -0.22230148, 0.16862972, -0.04462456, 0.2469604, -0.008622369, 0.0081848325, -0.17032363, -0.16024362, 0.21178265, 0.037127133, 0.08559072, 0.11584694) * go_3(-1.0, 1.0); result += mat4(0.008993893, -0.08037705, 0.4426555, 0.15593371, 0.15273719, -0.03249998, 0.055109, -0.1512612, -0.037183985, 0.20825677, -0.08516227, -0.06664223, -0.10011001, -0.3505215, -0.17941694, 0.052089088) * go_3(0.0, -1.0); result += mat4(-0.109703645, -0.13505603, 0.1336451, 0.13118869, 0.010915504, 0.12748592, 0.21201555, -0.40841985, -0.11059143, 0.033772044, -0.039282143, 0.03095394, 0.10394723, -0.21343367, -0.10699851, -0.028351074) * go_3(0.0, 0.0); result += mat4(0.019704714, 0.06243651, 0.09896519, -0.17492259, 0.012675787, -0.004239029, 0.21319824, 0.069183126, -0.0071114586, 0.123431124, -0.24479835, 0.00723795, -0.045293927, 0.014101029, 0.15746681, 0.042405806) * go_3(0.0, 1.0); result += mat4(0.023828225, -0.0015190929, 0.1194638, 0.082163885, 0.10532113, 0.042044062, 0.02528007, 0.015175004, 0.026613194, 0.33525538, -0.1627064, -0.29887968, -0.197707, 0.038967777, -0.15811683, -0.106895216) * go_3(1.0, -1.0); result += mat4(0.044362027, -0.04946742, -0.14815849, -0.17660522, -0.034201477, -0.012243106, -0.050183997, 0.06407372, 0.039822515, 0.15880872, -0.0672721, -0.4081093, 0.019489579, -0.060278706, -0.015096743, -0.07799167) * go_3(1.0, 0.0); result += mat4(0.11861756, 0.27113584, -0.14107186, -0.10246008, -0.124051, -0.1627854, 0.10698585, 0.2846401, -0.061731786, 0.1724438, -0.12428688, -0.09986041, -0.034171514, -0.07100923, 0.041739646, -0.11308375) * go_3(1.0, 1.0); result += vec4(-0.02981662, -0.26338395, -0.011632586, 0.15063232); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_5_tf //!BIND conv2d_5_tf1 //!SAVE conv2d_6_tf1 //!WIDTH conv2d_5_tf.w //!HEIGHT conv2d_5_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_5_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_5_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_5_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_5_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.17082009, 0.031344634, -0.06131912, 0.00887183, -0.01528174, 0.12943709, 0.24537678, 0.008178781, -0.312396, -0.023583878, 0.07827866, -0.1231261, 0.15081584, -0.18161978, -0.25179705, -0.036934935) * go_0(-1.0, -1.0); result += mat4(-0.05768411, 0.16785417, -0.1788644, -0.0067257965, 0.021445744, 0.10066516, -0.23864186, 0.1450302, 0.12892793, 0.19856106, -0.24444748, 0.16531628, -0.044425935, -0.02775357, 0.009059946, -0.12958384) * go_0(-1.0, 0.0); result += mat4(-0.025798557, -0.17238182, -0.34056288, -0.20921059, -0.03576266, 0.1476854, -0.06264234, 0.14452787, -0.04130045, -0.07275762, 0.034578666, 0.2914669, 0.20879944, 0.21359251, -0.048695553, 0.2638088) * go_0(-1.0, 1.0); result += mat4(-0.022791177, 0.4204545, 0.116855636, 0.20241925, -0.010444933, -0.14462502, 0.022550104, -0.24423064, -0.09417524, 0.045358784, -0.11405829, 0.035979558, -0.2283092, -0.06670842, -0.23852053, -0.22417003) * go_0(0.0, -1.0); result += mat4(-0.14526704, 0.040880535, 0.14076385, 0.07795045, -0.059177604, -0.13056375, -0.3373641, -0.19344307, -0.29891858, -0.32578763, -0.29061425, 0.1562214, -0.13578376, 0.36586633, 0.24936736, 0.054629393) * go_0(0.0, 0.0); result += mat4(-0.025790233, -0.13020341, -0.10084969, 0.15767297, -0.09738769, 0.04034404, 0.0038675873, 0.043515608, 0.16899958, -0.29117966, 0.03420067, 0.14432564, -0.10473084, 0.21014084, 0.07775908, -0.09303797) * go_0(0.0, 1.0); result += mat4(-0.07443987, -0.16225167, 0.036251917, 0.028432872, 0.03759333, 0.004027401, -0.033941846, 0.0019474924, 0.02357054, 0.30748722, 0.1652115, -0.17361522, 0.16905582, 0.08048018, -0.23639561, -0.029408466) * go_0(1.0, -1.0); result += mat4(0.0461233, -0.09346199, -0.07063276, -0.19447634, -0.049339604, -0.0032855074, -0.22661209, -0.0543389, 0.11924857, -0.21691081, -0.1645725, -0.0075736847, 0.018572787, -0.06552861, -0.01777661, -0.11651732) * go_0(1.0, 0.0); result += mat4(-0.06425901, 0.123392984, -0.16395192, -0.093448035, -0.029316641, 0.0986573, -0.23135012, 0.011170849, 0.00023920486, 0.15296175, 0.35453254, -0.05189021, 0.20708887, -0.103900835, 0.081992395, -0.21829562) * go_0(1.0, 1.0); result += mat4(-0.019074136, -0.1572586, 0.27919227, 0.09119617, 0.035954695, 0.2941489, 0.18262725, -0.055522963, -0.21364328, -0.1573611, 0.104966134, 0.08228523, 0.19945285, -0.0039229114, -0.1565048, 0.028975379) * go_1(-1.0, -1.0); result += mat4(-0.18501253, 0.006473006, 0.06637501, 0.04295065, 0.06411007, 0.1166344, -0.10060226, 0.46296063, -0.08600344, -0.03560105, 0.012215349, 0.017885283, 0.061346993, 0.17336361, 0.01935021, 0.20198092) * go_1(-1.0, 0.0); result += mat4(-0.04451627, -0.10372061, -0.13968691, 0.14479733, 0.1660607, 0.19334625, 0.0085214665, 0.28863636, -0.07600901, -0.014777084, 0.13209191, -0.09045013, 0.104893915, -0.04776884, -0.007936376, 0.104568765) * go_1(-1.0, 1.0); result += mat4(0.023751335, -0.108048, -0.050531313, 0.15916029, 0.13246661, 0.04644228, -0.09586482, -0.17222965, -0.22898191, -0.033484615, 0.078883134, -0.052609313, -0.2721741, 0.045986425, 0.13972299, -0.28923607) * go_1(0.0, -1.0); result += mat4(-0.23364568, -0.008875902, -0.40894926, 0.060443908, -0.2839635, -0.5270991, -0.2500865, 0.002020195, -0.24488612, -0.04982319, -0.009110353, -0.018023955, 0.06647274, -0.25225738, 0.26154432, -0.033934146) * go_1(0.0, 0.0); result += mat4(-0.1535129, -0.21257545, -0.16553773, 0.17471452, -0.06203719, 0.15238857, 0.18702018, 0.18572305, 0.07740396, -0.074217625, -0.072156586, -0.2183728, 0.00403749, 0.13750519, 0.30362993, 0.06550286) * go_1(0.0, 1.0); result += mat4(0.37164542, -0.1980723, -0.15659203, 0.19498909, 0.01748114, 0.011807152, -0.05424202, 0.11926474, 0.050406165, -0.12925303, -0.020280985, 0.08429331, 0.14769496, -0.077555746, -0.15216178, -0.27070466) * go_1(1.0, -1.0); result += mat4(0.35804263, 0.08539285, -0.14785156, -0.13532467, 0.058254432, 0.20448379, -0.006173341, 0.058168225, -0.21714899, -0.13472849, -0.09392532, -0.12753737, -0.097461835, -0.11419082, 0.09384189, 0.06414768) * go_1(1.0, 0.0); result += mat4(0.023494452, -0.22187226, -0.16694295, 0.0204334, -0.26720086, 0.15916729, 0.3098874, -0.10292057, 0.008854983, 0.13375004, -0.04409455, 0.09286524, 0.095829524, 0.12427317, -0.048659876, 0.18300754) * go_1(1.0, 1.0); result += mat4(-0.119153984, 0.10163183, 0.025017537, -0.40096784, 0.026778705, 0.15821172, -0.19947284, -0.33337715, 0.2952563, 0.16820388, -0.057061996, -0.029319009, -0.12184868, 0.09031512, 0.12028806, 0.021044692) * go_2(-1.0, -1.0); result += mat4(0.086744264, -0.046958666, 0.2130253, -0.46672252, 0.07135636, 0.0100029735, -0.13828261, -0.012365689, -0.11374441, 0.21084632, -0.059631422, -0.013799735, -0.037889663, -0.10701892, -0.09493782, 0.15516634) * go_2(-1.0, 0.0); result += mat4(0.031181194, -0.01535001, 0.029270316, 0.13128386, 0.11838377, -0.17051528, 0.12228499, -0.04841128, 0.33350074, -0.006144013, -0.09055018, 0.27470216, -0.26665646, -0.08703671, -0.01719071, -0.23449609) * go_2(-1.0, 1.0); result += mat4(-0.12856458, 0.005562174, -0.19517267, 0.13270985, 0.2776414, 0.032003902, -0.15778573, 0.15344355, 0.26930434, -0.13459459, 0.035019353, 0.08896612, 0.12847935, -0.122637205, 0.001815178, 0.08290523) * go_2(0.0, -1.0); result += mat4(0.33805037, -0.15318587, -0.20955376, -0.26121393, -0.026022578, -0.1617741, 0.1336867, 0.026223289, 0.012059392, -0.17295446, -0.060811974, 0.14027825, -0.21134059, -0.08408573, -0.23773228, 0.110836074) * go_2(0.0, 0.0); result += mat4(0.16176093, 0.15307428, -0.07711325, -0.3458805, 0.061291527, 0.023916256, 0.21370678, 0.0015756418, 0.10642374, 0.24807373, 0.11164451, 0.10780487, 0.087194376, -0.2718231, -0.008457387, 0.054078236) * go_2(0.0, 1.0); result += mat4(-0.03259038, -0.20923306, 0.165477, 0.098864526, -0.02734457, 0.08871225, -0.01552188, 0.047712058, 0.055032052, -0.13044262, -0.2899521, 0.22230095, -0.029343741, -0.16427459, -0.005436118, -0.05111821) * go_2(1.0, -1.0); result += mat4(0.20065974, -0.1556366, -0.12620135, 0.44572976, -0.020925352, 0.12025185, 0.20588058, 0.06391864, 0.046870507, 0.16942503, -0.049370963, 0.008779016, 0.04954915, 0.090298936, -0.16466027, 0.011152038) * go_2(1.0, 0.0); result += mat4(0.13587528, 0.047841422, 0.19804007, -0.1672396, -0.072491, 0.04543739, 0.25287256, 0.015226213, 0.02007356, -0.049578942, -0.08796175, 0.1714897, -0.07819061, 0.1509537, 0.093094915, 0.031139288) * go_2(1.0, 1.0); result += mat4(-0.013774682, 0.118201815, -0.009592314, -0.10837201, -0.0686881, -0.083380274, 0.107689425, 0.046642892, 0.119898744, -0.05502989, -0.19719897, 0.0005697584, -0.0921928, 0.032281205, 0.2568853, 0.2325449) * go_3(-1.0, -1.0); result += mat4(0.02991112, -0.09898633, 0.06076172, -0.20906185, 0.0026118348, 0.06130956, 0.06760944, -0.16662054, 0.065741204, -0.13144116, 0.011419801, 0.22552124, 0.1465757, -0.07417319, -0.10788749, -0.24952699) * go_3(-1.0, 0.0); result += mat4(-0.19238451, -0.024058497, 0.19580396, -0.067399554, -0.18832864, -0.11752747, -0.078949094, -0.23762032, -0.04141864, 0.022530237, -0.02222157, 0.0054874527, 0.057746816, -0.34854797, 0.028730657, -0.08976777) * go_3(-1.0, 1.0); result += mat4(0.16888975, 0.19949849, -0.08456147, -0.03619044, -0.019596824, 0.11214634, 0.13971676, 0.22926724, 0.03219445, -0.04566354, -0.14948955, -0.22817011, -0.08714846, -0.19684613, 0.15479128, 0.2433362) * go_3(0.0, -1.0); result += mat4(0.16050309, -0.102841675, 0.20855242, -0.011171905, -0.10309409, 0.22455123, 0.15892951, -0.06582373, 0.010079549, -0.2055006, -0.09385158, 0.006519388, 0.11838815, 0.37134558, -0.165772, 0.12704434) * go_3(0.0, 0.0); result += mat4(0.11643292, 0.03294274, -0.09800525, -0.13601723, -0.081318736, -0.059975546, -0.039105035, -0.2893635, -0.13024913, -0.058016162, -0.09961072, 0.10532414, 0.24250132, -0.35546342, -0.092634924, 0.093994915) * go_3(0.0, 1.0); result += mat4(-0.18799333, 0.25611782, 0.014645917, -0.063751906, 0.06498416, 0.16619027, -0.14411639, 0.3914421, -0.07343631, -0.116468735, -0.10941946, -0.2553544, -0.37774643, -0.0018441634, 0.06827239, -0.0122299045) * go_3(1.0, -1.0); result += mat4(-0.11884597, -0.2477297, 0.048488285, -0.06438257, -0.124703035, 0.25932777, 0.0650111, -0.0930877, 0.06463341, -0.000544085, 0.0147504965, -0.170097, -0.13241997, 0.20983136, -0.15956205, 0.03424298) * go_3(1.0, 0.0); result += mat4(-0.034574904, 0.06755256, 0.09508443, -0.17162292, 0.046379335, 0.2178781, 0.08699012, -0.055380464, -0.2237568, -0.07427848, -0.028395249, -0.3225617, -0.084454566, -0.24776657, 0.254169, 0.13229847) * go_3(1.0, 1.0); result += vec4(0.18765923, -0.07697714, 0.028134674, -0.060966115); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_6_tf //!BIND conv2d_6_tf1 //!SAVE conv2d_7_tf //!WIDTH conv2d_6_tf.w //!HEIGHT conv2d_6_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_6_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_6_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_6_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_6_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.21919365, 0.36627784, 0.12603314, 0.24306288, 0.06447028, 0.06472204, -0.05997039, -0.15651788, 0.017059859, -0.006497198, -0.4189735, 0.021636713, -0.23887977, -0.014220949, 0.031113686, -0.17342716) * go_0(-1.0, -1.0); result += mat4(-0.10818789, -0.03273837, 0.33918005, -0.19290088, 0.0955361, -0.34107623, -0.054906327, -0.18083344, -0.060723677, 0.24395694, 0.112975016, -0.07254578, -0.14389384, 0.13235968, -0.15054801, -0.26216486) * go_0(-1.0, 0.0); result += mat4(-0.23442148, -0.07857079, 0.022283873, -0.2656417, 0.037092753, -0.037313666, -0.5057047, 0.042533103, -0.120424, 0.00021930189, -0.0044566668, -0.45536995, 0.00040759926, 0.14597592, -0.094990164, -0.036161344) * go_0(-1.0, 1.0); result += mat4(0.15024352, 0.19903262, -0.0734784, 0.092836305, -0.025753846, 0.024750374, -0.07550193, 0.035420835, 0.11084378, 0.26119822, -0.08443512, -0.0047807065, -0.042685136, 0.24889739, 0.098650105, 0.2088369) * go_0(0.0, -1.0); result += mat4(-0.25551823, 0.14455976, 0.19886157, -0.23465924, 0.20711218, -0.20875362, -0.11320392, -0.30852005, -0.06795657, 0.008670962, 0.30601278, 0.6929064, 0.17079145, 0.15744895, 0.06441601, 0.06514001) * go_0(0.0, 0.0); result += mat4(0.03142604, -0.006410137, -0.023654792, -0.05708553, 0.062985405, -0.077010594, 0.078804865, 0.050882503, 0.010274228, -0.15558401, 0.09490256, 0.14964707, -0.11966925, -0.36176664, 0.27809814, -0.18862294) * go_0(0.0, 1.0); result += mat4(0.05609992, 0.0041612233, -0.08498908, 0.04479823, -0.080117956, -0.17423204, -0.22858045, 0.054569032, -0.050866384, -0.020000307, 0.027000953, -0.67724514, 0.16240878, -0.04641204, 0.0648367, -0.20613132) * go_0(1.0, -1.0); result += mat4(0.08542306, -0.08254248, -0.11090553, -0.14140448, -0.10788511, -0.13011602, -0.29319742, -0.26007155, 0.11033401, -0.31966573, 0.32668245, 0.19542319, 0.06329418, 0.20904626, 0.2724067, -0.009155685) * go_0(1.0, 0.0); result += mat4(-0.007403411, 0.0012836396, -0.23446666, -0.03017208, 0.062420018, -0.13611084, -0.2975928, 0.13173148, -0.03679939, 0.13743873, -0.10121899, 0.074514665, 0.1497629, -0.09523838, 0.39018926, 0.37807035) * go_0(1.0, 1.0); result += mat4(0.11441487, -0.19565523, -0.25757137, -0.16148767, 0.15575317, -0.12657928, 0.10479676, 0.062919036, 0.010544159, 0.22931573, 0.20360178, 0.4637635, -0.3395036, -0.52467215, 0.08759308, 0.028030418) * go_1(-1.0, -1.0); result += mat4(0.2699195, -0.34218305, 0.15259695, 0.03139074, -0.024053533, -0.029567484, 0.28480124, 0.20525953, 0.15452823, -0.217713, 0.15861876, -0.012275699, 0.21408023, 0.097508304, -0.57126766, -0.14679857) * go_1(-1.0, 0.0); result += mat4(-0.0755847, -0.09751562, -0.29480466, -0.22285318, 0.14196442, 0.114573136, -0.22294767, 0.12463806, 0.3322209, -0.04631724, -0.11097061, -0.27986854, -0.16099304, -0.060079545, 0.00299308, 0.120776065) * go_1(-1.0, 1.0); result += mat4(0.050933484, -0.13776319, -0.18809728, 0.24035202, -0.32528606, -0.41684148, -0.029342847, 0.28642926, -0.07963454, -0.12905268, 0.07606093, 0.24670005, -0.08815598, -0.23320907, -0.008099349, 0.21512873) * go_1(0.0, -1.0); result += mat4(0.19247563, 0.18083979, -0.09719762, 0.15314941, -0.22350982, 0.46515045, -0.3571128, 0.35953265, 0.06921985, -0.4482386, -0.18732521, -0.5043983, 0.35159567, -0.33315298, -0.21884166, -0.16283798) * go_1(0.0, 0.0); result += mat4(-0.021124054, -0.007966742, 0.0052493825, 0.022550896, 0.030403977, 0.3377868, -0.47602004, -0.077664234, -0.07222509, -0.07486097, -0.37971064, -0.5107857, -0.06299477, 0.04930232, -0.3330487, 0.29845512) * go_1(0.0, 1.0); result += mat4(-0.063705474, -0.07917637, -0.02026607, -0.05142568, 0.021577014, -0.07379867, 0.033937998, 0.08148773, -0.02717838, -0.03233838, 0.098000035, 0.036476444, -0.13366953, 0.014477577, 0.24064232, 0.39313284) * go_1(1.0, -1.0); result += mat4(-0.16046515, -0.094624564, 0.35435164, 0.09942324, -0.07137174, -0.27999225, 0.124644354, -0.0062176553, 0.015016751, -0.05500243, -0.23249559, -0.4508382, 0.1860433, 0.10671491, -0.033345353, -0.06611453) * go_1(1.0, 0.0); result += mat4(0.21614046, -0.01307525, -0.18941112, -0.20533535, -0.14481686, -0.47801897, 0.22605121, -0.20298961, -0.06744227, -0.20377496, -0.11926173, 0.15645133, -0.31570885, -0.3495616, -0.024666889, 0.040965475) * go_1(1.0, 1.0); result += mat4(-0.11748018, -0.039976366, -0.00084064255, -0.028653437, -0.16216733, -0.036768105, 0.018064514, -0.0928936, 0.14008482, -0.064511225, 0.24329947, -0.0268608, 0.050330248, 0.08540601, -0.07272679, -0.01187671) * go_2(-1.0, -1.0); result += mat4(-0.09459936, -0.011723822, -0.06952858, -0.07808506, -0.065588176, 0.332501, -0.0120042395, 0.07668016, 0.14735217, -0.14856043, -0.06702449, -0.020953184, -0.023006834, 0.06135422, 0.1491448, -0.028061569) * go_2(-1.0, 0.0); result += mat4(0.25136968, 0.25146323, -0.108277924, -0.20407207, -0.0013780294, 0.16108194, 0.25143847, 0.06672421, -0.033905584, -0.021144686, -0.019152718, 0.34619498, 0.14560962, 0.034437314, 0.024790365, -0.049976267) * go_2(-1.0, 1.0); result += mat4(-0.24928351, 0.12637813, 0.23609994, 0.12722939, -0.036997862, -0.16554876, 0.11144095, -0.10040036, -0.020359103, -0.080701865, -0.3142192, 0.27257237, 0.13546956, -0.14416885, 0.028196262, -0.2886465) * go_2(0.0, -1.0); result += mat4(0.28524777, -0.4236231, 0.27420738, -0.21095508, 0.23475651, 0.115876295, -0.18837357, -0.0260708, 0.030670704, -0.11516913, -0.11365572, -0.2203149, -0.018612983, -0.10719593, -0.031727783, 0.1403327) * go_2(0.0, 0.0); result += mat4(0.07240512, 0.03139215, 0.12328737, -0.021201206, -0.13971715, 0.072742075, -0.0011289873, 0.0053133667, 0.035639685, -0.04322272, -0.19288473, -0.15812221, -0.19126481, 0.0698514, 0.17619178, -0.035605464) * go_2(0.0, 1.0); result += mat4(-0.18552057, 0.07259671, 0.011667668, -0.15630563, 0.11414356, 0.14482655, -0.04021029, 0.18495587, -0.11386139, -0.09058561, -0.011265998, 0.23358451, 0.0521358, 0.12495261, 0.021644838, -0.048094347) * go_2(1.0, -1.0); result += mat4(-0.09222373, 0.0533347, 0.055820454, 0.22382596, 0.18713981, 0.2668916, -0.019384036, 0.012698582, 0.13325234, 0.20361474, -0.33106443, -0.08571572, -0.21243028, -0.10996386, 0.123459645, 0.1534967) * go_2(1.0, 0.0); result += mat4(0.18133277, 0.18108074, -0.05638664, 0.29533157, -0.2108019, -0.033636626, 0.5015888, -0.15116066, -0.041320793, -0.14764231, 0.07314567, -0.18865979, 0.10276937, 0.094240844, -0.1364283, 0.27812913) * go_2(1.0, 1.0); result += mat4(0.06040915, 0.23753685, 0.19019844, 0.23948252, -0.07535012, 0.11848904, 0.14389765, 0.050067905, 0.16150077, -0.030053454, 0.12478255, 0.26020208, 0.111198805, 0.06787492, -0.12771018, 0.006687384) * go_3(-1.0, -1.0); result += mat4(-0.5421617, 0.10414128, -0.21526064, -0.08883624, 0.13145073, -0.29695904, 0.57386386, 0.073361695, -0.09538372, 0.27593842, 0.070922814, 0.21769938, 0.06214975, 0.11847816, 0.10033405, 0.29360098) * go_3(-1.0, 0.0); result += mat4(-0.16294672, -0.014815565, 0.22046989, 0.16858687, 0.058917344, 0.21384977, 0.18803519, 0.105688855, 0.0355118, 0.20571202, -0.07341922, 0.26624045, -0.0415102, 0.050942056, 0.19727907, 0.20122413) * go_3(-1.0, 1.0); result += mat4(-0.020470422, 0.15815964, -0.13437317, -0.1967045, 0.074902646, 0.08356444, 0.055913117, -0.12837863, -0.18647918, 0.07002247, 0.038864706, -0.07288784, 0.04135125, -0.016055549, -0.1340297, -0.15578008) * go_3(0.0, -1.0); result += mat4(-0.07685624, 0.00079105416, -0.068755336, 0.110282525, -0.014170752, 0.041282844, -0.17035173, 0.19439398, -0.3036256, 0.024148455, -0.19566648, -0.06736254, 0.14203559, -0.13016985, -0.32845357, -0.14266774) * go_3(0.0, 0.0); result += mat4(0.0087252045, 0.098839566, -0.08770506, -0.08499465, 0.015245115, -0.110854514, 0.054458305, -0.018121868, -0.09666134, -0.08316006, 0.24617113, -0.17195955, 0.2574254, 0.06734342, -0.13792352, -0.07306126) * go_3(0.0, 1.0); result += mat4(-0.0073954533, -0.20126835, -0.22545357, -0.29462856, 0.057408337, 0.11939119, -0.01846476, 0.12534486, 0.15751605, -0.14282645, -0.14219986, 0.14283386, 0.14090413, 0.10500912, 0.03039335, 0.17448832) * go_3(1.0, -1.0); result += mat4(0.043910783, -0.09140025, -0.21666165, 0.07616939, 0.104454786, 0.309926, -0.12906921, 0.1140117, 0.09372434, 0.049547072, -0.086615674, -0.034449168, 0.096705064, 0.26001686, 0.027063297, 0.12422948) * go_3(1.0, 0.0); result += mat4(0.1365422, 0.2679611, 0.12037257, 0.43346113, 0.08223084, -0.016788265, 0.13570398, -0.017974345, -0.17922844, -0.09475725, 0.073539585, -0.106947675, 0.08998511, 0.04133868, 0.16586913, -0.26291734) * go_3(1.0, 1.0); result += vec4(-0.19233678, 0.016725872, -0.008011114, -0.1977463); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_6_tf //!BIND conv2d_6_tf1 //!SAVE conv2d_7_tf1 //!WIDTH conv2d_6_tf.w //!HEIGHT conv2d_6_tf.h //!COMPONENTS 4 #define go_0(x_off, y_off) (max((conv2d_6_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_6_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_6_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_6_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.36016628, 0.019064043, 0.3073228, 0.16891135, 0.026739368, 0.31136194, 0.11260383, -0.26918694, 0.0419928, -0.3365078, 0.20189743, -0.04136312, 0.039564647, 0.033199426, 0.18768296, -0.017119858) * go_0(-1.0, -1.0); result += mat4(0.28663483, -0.41716507, 0.059281543, 0.043736435, 0.0028875466, 0.13817391, -0.12543318, -0.2794053, -0.023528943, 0.10610115, 0.09100278, 0.040132936, -0.21949205, -0.027810011, -0.0301218, 0.084047124) * go_0(-1.0, 0.0); result += mat4(0.39674807, -0.0040878756, -0.038235947, 0.11880838, 0.009898328, 0.19107847, -0.009313831, -0.1554276, -0.047341663, 0.18049581, -0.029317195, 0.0708909, 0.0708316, -0.110617444, 0.14584038, -0.022261223) * go_0(-1.0, 1.0); result += mat4(-0.20400241, 0.0896492, -0.010386381, -0.052133385, 0.005023956, -0.06628705, -0.16436209, -0.25345984, -0.05285192, 0.09706557, -0.03778914, -0.152546, 0.17023252, 0.063713826, 0.00743037, 0.056634087) * go_0(0.0, -1.0); result += mat4(-0.080793336, 0.4204207, 0.19098237, 0.20028038, -0.054076545, 0.22064368, -0.25853387, -0.3643562, 0.2085573, -0.023731, -0.06727709, -0.18683033, -0.18032159, -0.06388348, 0.304463, -0.2517781) * go_0(0.0, 0.0); result += mat4(0.11940941, 0.10624008, 0.16120581, 0.2369602, 0.3321827, 0.4272075, -0.10403669, -0.31388018, -0.006372124, -0.00653671, 0.109810196, 0.2277172, 0.005771998, 0.086026914, -0.08934813, -0.094941735) * go_0(0.0, 1.0); result += mat4(-0.13233568, 0.24112508, -0.0068006413, 0.12466225, 0.11396591, -0.07249253, -0.29090378, -0.12828146, -0.22001141, -0.08532405, -0.11932601, 0.29452974, 0.09572195, 0.017603843, 0.12454017, 0.16321751) * go_0(1.0, -1.0); result += mat4(0.042107448, -0.00807216, 0.06580674, -0.1289527, 0.13977426, -0.037159685, -0.21001346, -0.08698161, 0.22370502, -0.29170328, 0.2179206, 0.36621302, 0.0825477, -0.016513655, -0.11157249, 0.12861598) * go_0(1.0, 0.0); result += mat4(0.2246826, -0.13262233, 0.12131653, -0.15522355, 0.38104856, 0.030237729, 0.1286289, -0.19770473, -0.16175011, -0.13688888, 0.23505463, 0.21333031, 0.76352316, -0.17949077, -0.13124311, 0.1613879) * go_0(1.0, 1.0); result += mat4(-0.050607495, 0.0846705, -0.06136092, -0.033436477, 0.41138348, 0.037043408, -0.02676336, -0.37771952, 0.22147503, 0.06490757, -0.04266158, -0.22606373, 0.045775007, -0.054498192, -0.21495876, -0.036050417) * go_1(-1.0, -1.0); result += mat4(-0.06242522, 0.2700824, -0.05602621, -0.12361551, 0.14477442, 0.19403581, 0.23505251, -0.072234035, -0.15831544, 0.4640447, -0.104754634, -0.004539681, -0.20246096, 0.23216484, -0.35886365, 0.11360777) * go_1(-1.0, 0.0); result += mat4(0.14777757, 0.18951412, 0.027219458, 0.11216015, 0.02997997, -0.13466355, -0.0010830094, 0.021302953, 0.23441231, -0.14529245, 0.08068729, 0.10044398, 0.3972878, 0.26570204, 0.0046810666, -0.2863261) * go_1(-1.0, 1.0); result += mat4(-0.10385485, 0.1053724, 0.16961229, 0.20727012, -0.025148917, -0.011365095, 0.03899919, -0.030950211, 0.079080455, -0.32767853, 0.064670205, -0.035771385, 0.16833797, -0.21567492, 0.30871257, -0.19965471) * go_1(0.0, -1.0); result += mat4(-0.23420888, -0.004894698, -0.18162623, -0.31107524, 0.11976508, 0.14924951, -0.08723316, 0.21401922, -0.58200324, -0.01177345, -0.049033508, 0.19593577, -0.21139073, 0.13016601, 0.08734843, 0.4158892) * go_1(0.0, 0.0); result += mat4(0.0009789813, 0.33274913, 0.017405733, -0.042906318, -0.26410276, -0.09291333, 0.019387102, 0.105381854, -0.009176527, 0.09483514, -0.28462934, -0.03644404, 0.285194, -0.4260311, 0.14902237, -0.115670316) * go_1(0.0, 1.0); result += mat4(-0.09344311, 0.4463103, 0.19984834, -0.09733857, -0.118717775, -0.0708026, 0.24919955, -0.11234634, 0.1246395, -0.052909933, 0.1525815, 0.07724016, 0.0070534665, -0.06404165, -0.18149726, -0.014058336) * go_1(1.0, -1.0); result += mat4(-0.17353044, 0.15376104, 0.004588994, -0.13554202, -0.19920237, -0.18918681, 0.11327512, -0.117296435, -0.0785251, 0.013677155, -0.2103214, 0.06843426, -0.27790928, 0.09837545, -0.00019213746, 0.09132539) * go_1(1.0, 0.0); result += mat4(-0.01586651, 0.014929441, 0.2426186, -0.1889374, -0.0865462, -0.07454513, -0.20797268, -0.22366855, 0.19704159, 0.0048206006, -0.16707218, -0.14162683, 0.036798395, -0.1663155, -0.12009389, 0.09603803) * go_1(1.0, 1.0); result += mat4(-0.041532192, 0.05753804, 0.17927068, -0.042112097, 0.12080969, -0.15052572, -0.34855765, -0.07356988, -0.28199884, -0.18958664, 0.15879883, 0.08511588, 0.0034213227, -0.05338495, -0.37285298, 0.06626709) * go_2(-1.0, -1.0); result += mat4(-0.20219134, 0.22150375, -0.29405454, 0.06597703, -0.018885285, -0.010551704, -0.010774283, 0.08758955, -0.2015349, -0.17006227, -0.24321876, -0.06864207, -0.118437864, -0.043977212, -0.029736811, 0.14040919) * go_2(-1.0, 0.0); result += mat4(-0.18709077, -0.09723938, 0.12783436, -0.15167634, 0.29039705, -0.11009911, 0.018371418, -0.060096707, -0.07256923, -0.25799567, -0.06276934, -0.035992302, -0.06729111, -0.059956793, -0.024079734, 0.011838878) * go_2(-1.0, 1.0); result += mat4(0.010449175, -0.08212451, 0.1409803, 0.11861122, -0.18035835, 0.051930565, 0.01049551, -0.09447962, 0.12029649, 0.040604513, -0.059971705, -0.0044667358, -0.22080486, -0.11187681, 0.124374695, -0.004155485) * go_2(0.0, -1.0); result += mat4(-0.28584236, -0.38480133, -0.13987814, -0.4463469, -0.3890419, -0.022498172, 0.17334452, 0.21895568, -0.15450422, -0.10905497, 0.15111905, -0.22554915, 0.106121585, -0.029144369, 0.36059046, 0.22140682) * go_2(0.0, 0.0); result += mat4(-0.23780307, -0.023033705, 0.068205886, -0.110635854, -0.26720005, -0.1608183, 0.19523881, 0.07972837, -0.018495852, -0.2793956, 0.17668398, -0.12020479, -0.079556085, -0.02284952, 0.031480275, 0.31818348) * go_2(0.0, 1.0); result += mat4(0.22501226, -0.00829407, 0.059581667, 0.16512989, 0.18711442, 0.1200968, 0.11812652, -0.16091056, 0.15733972, 0.045156084, 0.20640492, -0.16852027, -0.11217177, 0.06746273, -0.050218176, 0.08643783) * go_2(1.0, -1.0); result += mat4(0.20715691, -0.1082907, 0.027892975, 0.19515261, -0.17838904, 0.1532257, -0.108409844, -0.06632365, -0.13805026, 0.23020233, 0.12416581, -0.14861803, 0.16650471, 0.08158386, -0.09051303, -0.06981649) * go_2(1.0, 0.0); result += mat4(-0.04617126, 0.06579221, 0.25964734, 0.28500968, 0.07641255, -0.090885855, -0.0972522, 0.18298368, -0.06393334, 0.103463, -0.23062052, -0.15270731, 0.13633437, 0.074707486, 0.15065335, -0.024602572) * go_2(1.0, 1.0); result += mat4(0.118319295, 0.010410938, 0.044655934, -0.104725905, 0.030477569, 0.12867387, 0.039075315, 0.18922117, 0.13301082, -0.1601557, 0.038168408, -0.07372259, -0.09522213, -0.095107146, -0.16679631, 0.044673234) * go_3(-1.0, -1.0); result += mat4(0.46229, -0.30780822, -0.09081465, 0.1433387, -0.0315039, 0.059409115, -0.24948491, -0.17146957, 0.060843736, -0.041989822, 0.054005735, 0.22835566, 0.12036598, -0.0070898845, 0.17276852, -0.17754094) * go_3(-1.0, 0.0); result += mat4(-0.35119572, 0.020034311, 0.08751943, 0.08193488, 0.041884877, 0.22649358, -0.07447533, 0.20845473, -0.04859846, -0.16206735, 0.06819576, -0.053000778, 0.18146423, 0.04694148, 0.045293212, 0.06783575) * go_3(-1.0, 1.0); result += mat4(0.280914, -0.14998704, -0.23485807, -0.015608296, 0.1549556, -0.11992663, -0.094974115, 0.05887284, 0.053392075, 0.10322464, -0.075066686, 0.068358354, -0.18663338, 0.009901499, -0.123370335, -0.12502703) * go_3(0.0, -1.0); result += mat4(0.7748568, -0.17870626, -0.20770052, 0.024692526, -0.056430295, -0.06324113, -0.03660047, 0.29629672, -0.51896983, -0.027231261, 0.05903762, 0.077677645, -0.061675485, -0.20277846, 0.10352223, -0.08198446) * go_3(0.0, 0.0); result += mat4(-0.06347568, 0.21643166, -0.09718546, 0.0372257, -0.029537952, -0.0357135, -0.09548363, 0.18225233, -0.29609334, -0.3496132, 0.18245913, -0.10162589, -0.18189451, -0.09077887, 0.117313184, -0.06863874) * go_3(0.0, 1.0); result += mat4(-0.047373574, -0.020289376, -0.25748715, -0.13568166, 0.15656634, -0.06841899, 0.012100781, -0.13611819, 0.0016357322, -0.23870537, 0.14035743, -0.14700134, 0.2535575, -0.13697346, -0.13693139, -0.10365287) * go_3(1.0, -1.0); result += mat4(0.4283934, -0.316192, -0.012617617, 0.018468965, 0.21436644, 0.18408814, -0.42651537, 0.12504087, -0.13894933, 0.091662176, -0.20096369, -0.080727175, -0.005487846, 0.17046383, 0.1383948, -0.0054956395) * go_3(1.0, 0.0); result += mat4(0.20014295, -0.027282396, -0.06317007, 0.04452042, 0.064600386, 0.072222926, -0.33409226, 0.08063831, -0.022607977, 0.1308856, -0.39691743, -0.094889864, -0.1810531, 0.011367248, -0.2531222, -0.22468317) * go_3(1.0, 1.0); result += vec4(0.26886886, 0.05874665, 0.10268232, 0.05833081); return result; } //!DESC Anime4K-v4.0-Restore-CNN-(VL)-Conv-3x1x1x112 //!HOOK MAIN //!BIND MAIN //!BIND conv2d_1_tf //!BIND conv2d_1_tf1 //!BIND conv2d_2_tf //!BIND conv2d_2_tf1 //!BIND conv2d_3_tf //!BIND conv2d_3_tf1 //!BIND conv2d_4_tf //!BIND conv2d_4_tf1 //!BIND conv2d_5_tf //!BIND conv2d_5_tf1 //!BIND conv2d_6_tf //!BIND conv2d_6_tf1 //!BIND conv2d_7_tf //!BIND conv2d_7_tf1 //!SAVE MAIN //!WIDTH conv2d_1_tf.w //!HEIGHT conv2d_1_tf.h #define g_0 (max((conv2d_1_tf_tex(conv2d_1_tf_pos)), 0.0)) #define g_1 (max((conv2d_1_tf1_tex(conv2d_1_tf1_pos)), 0.0)) #define g_2 (max(-(conv2d_1_tf_tex(conv2d_1_tf_pos)), 0.0)) #define g_3 (max(-(conv2d_1_tf1_tex(conv2d_1_tf1_pos)), 0.0)) #define g_4 (max((conv2d_2_tf_tex(conv2d_2_tf_pos)), 0.0)) #define g_5 (max((conv2d_2_tf1_tex(conv2d_2_tf1_pos)), 0.0)) #define g_6 (max(-(conv2d_2_tf_tex(conv2d_2_tf_pos)), 0.0)) #define g_7 (max(-(conv2d_2_tf1_tex(conv2d_2_tf1_pos)), 0.0)) #define g_8 (max((conv2d_3_tf_tex(conv2d_3_tf_pos)), 0.0)) #define g_9 (max((conv2d_3_tf1_tex(conv2d_3_tf1_pos)), 0.0)) #define g_10 (max(-(conv2d_3_tf_tex(conv2d_3_tf_pos)), 0.0)) #define g_11 (max(-(conv2d_3_tf1_tex(conv2d_3_tf1_pos)), 0.0)) #define g_12 (max((conv2d_4_tf_tex(conv2d_4_tf_pos)), 0.0)) #define g_13 (max((conv2d_4_tf1_tex(conv2d_4_tf1_pos)), 0.0)) #define g_14 (max(-(conv2d_4_tf_tex(conv2d_4_tf_pos)), 0.0)) #define g_15 (max(-(conv2d_4_tf1_tex(conv2d_4_tf1_pos)), 0.0)) #define g_16 (max((conv2d_5_tf_tex(conv2d_5_tf_pos)), 0.0)) #define g_17 (max((conv2d_5_tf1_tex(conv2d_5_tf1_pos)), 0.0)) #define g_18 (max(-(conv2d_5_tf_tex(conv2d_5_tf_pos)), 0.0)) #define g_19 (max(-(conv2d_5_tf1_tex(conv2d_5_tf1_pos)), 0.0)) #define g_20 (max((conv2d_6_tf_tex(conv2d_6_tf_pos)), 0.0)) #define g_21 (max((conv2d_6_tf1_tex(conv2d_6_tf1_pos)), 0.0)) #define g_22 (max(-(conv2d_6_tf_tex(conv2d_6_tf_pos)), 0.0)) #define g_23 (max(-(conv2d_6_tf1_tex(conv2d_6_tf1_pos)), 0.0)) #define g_24 (max((conv2d_7_tf_tex(conv2d_7_tf_pos)), 0.0)) #define g_25 (max((conv2d_7_tf1_tex(conv2d_7_tf1_pos)), 0.0)) #define g_26 (max(-(conv2d_7_tf_tex(conv2d_7_tf_pos)), 0.0)) #define g_27 (max(-(conv2d_7_tf1_tex(conv2d_7_tf1_pos)), 0.0)) vec4 hook() { vec4 result = mat4(0.09689336, 0.06046458, 0.072598994, 0.0, 0.11994565, 0.104477674, 0.09302802, 0.0, -0.05718302, 0.050438102, 0.08814741, 0.0, 0.0308889, 0.0033925986, -0.01715605, 0.0) * g_0; result += mat4(-0.028314235, 0.06597744, 0.0966897, 0.0, 0.035656154, 0.07770106, 0.075551905, 0.0, 0.0001793458, -0.000479495, -0.00297406, 0.0, -0.053916585, -0.016807461, -0.0057141334, 0.0) * g_1; result += mat4(-0.047189303, -0.0207, -0.020910334, 0.0, -0.07933196, -0.06961211, -0.086069845, 0.0, 0.0943727, 0.008463375, 0.010755166, 0.0, 0.062410597, 0.022625161, 0.04068433, 0.0) * g_2; result += mat4(0.10270994, -0.019080428, 0.0050091282, 0.0, -0.004672948, -0.013966742, -0.0063746064, 0.0, -2.5856789e-05, 0.03151499, -0.0023983798, 0.0, 0.113539025, 0.12381699, 0.100360274, 0.0) * g_3; result += mat4(0.07868885, -0.030913834, -0.009213676, 0.0, 0.04870991, 0.021467991, 0.038739506, 0.0, -0.042969644, -0.07122453, -0.08798675, 0.0, -0.09784122, 0.021434791, 0.02510374, 0.0) * g_4; result += mat4(0.050420716, 0.0729716, 0.076532185, 0.0, -0.019112485, -0.01037939, -0.026948035, 0.0, -0.02591423, 0.008927897, -0.00042541025, 0.0, 0.1043701, -0.0071186824, -0.041817162, 0.0) * g_5; result += mat4(-0.16143242, -0.0009298223, -0.01228508, 0.0, 0.07744052, -0.018313263, -0.0488145, 0.0, 0.09241393, 0.07128674, 0.055164956, 0.0, 0.054884013, -0.04834418, -0.06281626, 0.0) * g_6; result += mat4(-0.049036566, -0.05979936, -0.05594288, 0.0, -0.014564307, 0.031926468, 0.037857566, 0.0, 0.015474487, -0.11385003, -0.11527764, 0.0, -0.07076006, 0.057038613, 0.095983796, 0.0) * g_7; result += mat4(0.03094887, -0.008734403, 0.00042712069, 0.0, 0.053891554, 0.05837673, 0.06200635, 0.0, 0.09071558, -0.04202184, -0.046172567, 0.0, -0.0425916, 0.04905093, 0.020835675, 0.0) * g_8; result += mat4(0.096628904, -0.037792254, -0.043241944, 0.0, -0.011923947, -0.025950424, -0.031381752, 0.0, -0.060941868, -0.07859433, -0.07535451, 0.0, -0.026777223, 0.08604982, 0.07829908, 0.0) * g_9; result += mat4(-0.06435972, 0.0036599538, 0.00786578, 0.0, -0.061972067, -0.05681472, -0.06667608, 0.0, -0.106890626, 0.007406496, 0.029977169, 0.0, -0.20519382, -0.044860814, 0.0021225857, 0.0) * g_10; result += mat4(-0.16876474, 0.012789643, 0.026692612, 0.0, 0.017817136, 0.026935097, 0.02227043, 0.0, 0.01690181, 0.07716103, 0.086527, 0.0, 0.07923805, -0.10443151, -0.10859543, 0.0) * g_11; result += mat4(0.003730466, -0.024648283, -0.022169832, 0.0, -0.0062762927, 0.022062732, 0.032966793, 0.0, 0.016349113, 0.017197203, 0.020952817, 0.0, -0.1763789, 0.035497356, 0.053835396, 0.0) * g_12; result += mat4(0.020886675, -0.07054202, -0.079142675, 0.0, 0.06664387, 0.044960167, 0.042230908, 0.0, -0.095019594, 0.012421141, 0.0142890485, 0.0, 0.056814816, -0.012751135, -0.014684506, 0.0) * g_13; result += mat4(0.011765893, 0.0008920681, -0.0018258415, 0.0, -0.010473814, -0.023085753, -0.028783914, 0.0, -0.023034256, -0.0024786016, -0.0052162083, 0.0, 0.1643386, -0.06132718, -0.09289065, 0.0) * g_14; result += mat4(0.016597198, 0.09389637, 0.10833379, 0.0, -0.043163072, -0.04714812, -0.035274632, 0.0, 0.09634976, -0.009292612, -0.022424143, 0.0, -0.08765172, 0.0051558353, 0.010900356, 0.0) * g_15; result += mat4(0.030815786, 0.021069322, 0.01812191, 0.0, 0.084839165, -0.0080813095, -0.029270556, 0.0, -0.10456346, 0.062386703, 0.0665605, 0.0, 0.11926609, -0.1104228, -0.13291118, 0.0) * g_16; result += mat4(-0.07159541, -0.007267032, -0.010134558, 0.0, 0.008234213, 0.045609634, 0.040295456, 0.0, 0.018416971, 0.01308482, 0.014649557, 0.0, 0.035107512, -0.02140815, -0.030279048, 0.0) * g_17; result += mat4(0.01918586, 0.03875863, 0.03229402, 0.0, -0.07917104, 0.041135103, 0.057182517, 0.0, 0.08609541, 0.0079662455, 0.004327576, 0.0, -0.14332893, 0.03120354, 0.056732506, 0.0) * g_18; result += mat4(0.03200192, -0.0035752193, -0.0031064528, 0.0, -0.010902813, 0.014607456, 0.019431474, 0.0, -0.016461229, -0.004938204, -0.004655488, 0.0, -0.033470232, 0.0026075812, 0.005896968, 0.0) * g_19; result += mat4(0.037410006, 0.048742272, 0.04348088, 0.0, 0.037719514, 0.030768529, 0.03127472, 0.0, 0.056426726, 0.03066893, 0.016440205, 0.0, -0.010599352, 0.022832409, 0.023211194, 0.0) * g_20; result += mat4(-0.005733291, 0.06365659, 0.06663611, 0.0, -0.041917093, -0.016493445, -0.020438088, 0.0, -0.0014357592, -0.0022506563, -0.0045095007, 0.0, 0.029893145, -0.009129354, -0.015173116, 0.0) * g_21; result += mat4(0.013052085, 0.005108175, 0.0025906067, 0.0, -0.021950055, -0.036447693, -0.036141638, 0.0, -0.036296472, 0.0068928464, 0.013102313, 0.0, 0.0060471976, -0.024798103, -0.023548538, 0.0) * g_22; result += mat4(0.0067743887, -0.06191211, -0.062355213, 0.0, 0.0016080744, -0.020445071, -0.016840393, 0.0, 0.028264903, 0.01852915, 0.015891539, 0.0, -0.023877412, -0.013271666, -0.008158679, 0.0) * g_23; result += mat4(-0.04317466, -0.018953001, -0.020452993, 0.0, -0.009322576, -0.03022352, -0.030970376, 0.0, 0.05653658, 0.05430553, 0.046692245, 0.0, 0.05615359, 0.059338935, 0.056018773, 0.0) * g_24; result += mat4(0.022878079, 0.03392234, 0.033057988, 0.0, -0.017554542, -0.0141542535, -0.014122613, 0.0, -0.048634093, -0.05316463, -0.047988772, 0.0, -0.058002178, -0.040221967, -0.034025013, 0.0) * g_25; result += mat4(-0.018253656, -0.04197674, -0.040467236, 0.0, -0.04358929, -0.028309818, -0.025425073, 0.0, -0.008488672, -0.001727991, 0.00035808363, 0.0, -0.0011709273, 0.0052514165, 0.0059479307, 0.0) * g_26; result += mat4(-0.08333935, -0.09818201, -0.09476284, 0.0, -0.033692095, -0.046259012, -0.045797516, 0.0, -0.007577072, 0.0022402718, 0.0016200038, 0.0, 0.0029786075, -0.020728534, -0.018938033, 0.0) * g_27; result += vec4(0.047567394, -0.02504617, -0.028163986, 0.0); return result + MAIN_tex(MAIN_pos); } ================================================ FILE: app/src/main/assets/shaders/Anime4K_Upscale_CNN_x2_M.glsl ================================================ // MIT License // Copyright (c) 2019-2021 bloc97 // All rights reserved. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //!DESC Anime4K-v3.2-Upscale-CNN-x2-(M)-Conv-4x3x3x3 //!HOOK MAIN //!BIND MAIN //!SAVE conv2d_tf //!WIDTH MAIN.w //!HEIGHT MAIN.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (MAIN_texOff(vec2(x_off, y_off))) vec4 hook() { vec4 result = mat4(-0.010995803, 0.077095956, -0.043992598, 0.06048717, 0.1164834, -0.11689607, 0.072985925, -0.078805886, 0.01182932, 0.054985743, -0.09018186, 0.044907484, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, -1.0); result += mat4(0.1813623, -0.14752422, 0.025720436, -0.17639883, 0.15697388, 0.10445984, -0.1843076, 0.5264643, 0.047516696, -0.097305484, 0.09740847, -0.29619336, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 0.0); result += mat4(-0.014534763, 0.09486465, 0.046173926, 0.039391946, 0.09609376, -0.060574662, 0.042200956, -0.3269777, 0.051006425, 0.059818447, 0.04366627, 0.17699827, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 1.0); result += mat4(0.04268535, -0.08152529, 0.10577459, -0.036936995, -0.051562306, 0.054872766, 0.09194519, 0.0025066638, -0.01073954, 0.00064474024, 0.10038221, 0.02131141, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, -1.0); result += mat4(-0.51751363, -0.40028602, 0.3469574, 0.5933738, -0.91357684, -0.67692596, 0.57815677, 0.39809322, -0.16341521, -0.27169713, 0.12232366, 0.4318641, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 0.0); result += mat4(0.12601124, -0.06263236, -0.45907676, -0.41514075, 0.3330334, -0.1929565, -0.6333532, -0.6552794, -0.045809917, 0.046351526, -0.26173338, -0.30252662, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 1.0); result += mat4(0.0030332592, 0.012103107, 0.010537323, -0.02038607, 0.095558085, 0.097704545, 0.083433494, 0.026790185, 0.01943357, -0.061712462, -0.00015703632, -0.032268334, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, -1.0); result += mat4(0.016870102, 0.5215812, -0.11525501, 0.027527615, -0.09045733, 0.61310345, -0.1575268, 0.1905386, 0.020172214, 0.3503187, -0.08209157, -0.051328037, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 0.0); result += mat4(0.005494087, -0.010656317, 0.07682753, -0.08116042, -0.03934524, 0.16589017, 0.101483546, -0.066603065, 0.03494657, -0.07885597, 0.074227594, 0.0016264897, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 1.0); result += vec4(0.014463938, -0.0031906287, 0.007015422, -0.003888468); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(M)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_tf //!SAVE conv2d_1_tf //!WIDTH conv2d_tf.w //!HEIGHT conv2d_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.08532478, -0.14302494, -0.017921071, -0.0032664281, -0.09841952, 0.024187077, 0.10701477, 0.14110753, -0.05714981, -0.10897174, 0.073803626, 0.103992954, 0.07914382, 0.032193683, -0.18346278, -0.09723936) * go_0(-1.0, -1.0); result += mat4(-0.034482613, -0.10742312, -0.047286414, -0.08641124, -0.33896688, -0.036533825, -0.48337597, 0.034040943, -0.13598205, -0.080917805, 0.08540263, -0.012667689, -0.009171425, -0.120026454, -0.20536867, -0.032149274) * go_0(-1.0, 0.0); result += mat4(0.18687321, 0.066278316, 0.024327392, 0.08816582, -0.08017908, 0.09488853, 0.26018232, -0.101504356, 0.17487666, 0.31057635, 0.14785016, -0.09622089, -0.07537452, -0.13844088, -0.05810814, 0.09907489) * go_0(-1.0, 1.0); result += mat4(-0.04183032, 0.15207712, 0.005002397, 0.32277516, -0.16169126, -0.119836345, -0.04068436, -0.096728764, 0.11943901, 0.1789597, -0.20412198, 0.19009817, 0.36630696, 0.06946421, -0.5254373, -0.11896399) * go_0(0.0, -1.0); result += mat4(-0.31916487, -0.98911583, 1.0728644, -0.39280394, 0.33458877, -0.17325239, -0.645045, -0.28524077, -0.14512783, 0.24996442, -0.09837877, 0.05468934, 0.31559715, -0.020504637, -0.026724018, 0.24507573) * go_0(0.0, 0.0); result += mat4(-0.23759829, -0.08530173, -0.16665787, -0.22463752, 0.109896734, 0.13446991, -0.049552456, -0.02385489, -0.01245375, 0.3833208, 0.05758832, 0.1528937, 0.0501858, -0.19651426, 0.0076587177, -0.03297025) * go_0(0.0, 1.0); result += mat4(0.14554465, -0.01826686, 0.10284085, -0.19152659, -0.017585073, -0.05511482, 0.06362406, 0.023924058, -0.0018977845, -0.103172876, 0.03287086, -0.20085956, 0.36062446, 0.10749464, -0.20984372, 0.018256644) * go_0(1.0, -1.0); result += mat4(-0.005534592, 0.3709197, -0.18287498, 0.1720451, 0.030155553, -0.023265475, 0.0058617783, -0.031765483, 0.037328955, -0.2730994, 0.35090837, -0.3269043, -0.028477207, 0.32756507, -0.15989502, 0.12158258) * go_0(1.0, 0.0); result += mat4(0.10873739, 0.19583772, 0.060394943, 0.09410379, -0.04739245, 0.026561242, 0.022990001, 0.1093272, -0.01071349, -0.022938967, -0.046423864, 0.2385325, -0.0319821, 0.046962265, 0.09081178, -0.11001857) * go_0(1.0, 1.0); result += mat4(0.13012704, 0.112289295, 0.030790284, -0.050499484, 0.11784853, 0.08107028, -0.07556717, -0.15643, 0.015249331, 0.015299608, 0.07748125, 0.054485757, 0.044857923, 0.12161275, -0.048292994, -0.033995003) * go_1(-1.0, -1.0); result += mat4(0.12931514, 0.15114146, 0.070513315, 0.11246343, 0.4142387, 0.213479, -0.5439916, 0.07776645, 0.13109331, 0.2021147, 0.25932786, -0.22157331, 0.02377734, -0.014970623, -0.1943276, 0.18440372) * go_1(-1.0, 0.0); result += mat4(-0.22365458, -0.19829084, -0.06881161, -0.06468993, 0.17202774, 0.0048758537, -0.09235021, 0.18941896, 0.064125344, -0.09067088, 0.09748182, 0.13561936, -0.05876288, -0.0122420965, -0.054380875, -0.17743628) * go_1(-1.0, 1.0); result += mat4(0.18582906, -0.09263032, -0.08210888, -0.20515606, 0.11484005, 0.08557595, 0.0009253741, -0.051202174, -0.18535301, -0.1529345, -0.13092944, 0.03770747, -0.020947013, 0.19187425, -0.15494856, -0.048979875) * go_1(0.0, -1.0); result += mat4(-0.38131633, 0.4278787, 0.19763695, 0.27655518, -0.08711912, 0.07374453, -0.064803004, 0.5983854, 0.2361923, -0.057221692, -0.37138999, -0.24259573, 0.13890724, 0.25706333, -0.54021406, 0.08095518) * go_1(0.0, 0.0); result += mat4(0.0991328, -0.022651536, -0.029148921, -0.009812537, -0.09523686, -0.15704902, 0.052389514, 0.21561539, 0.1950314, -0.08572602, 0.0016523858, 0.14125621, -0.030999828, 0.12009709, 0.0373512, -0.105043754) * go_1(0.0, 1.0); result += mat4(-0.11251988, 0.12106985, 0.011923068, 0.3662747, 0.004800994, 0.017972551, 0.004761366, -0.07934206, -0.13755941, -0.022852683, 0.1502225, 0.009758547, -0.16964264, 0.00984782, 0.07855833, 0.035730787) * go_1(1.0, -1.0); result += mat4(0.01964957, -0.27226487, 0.033933397, -0.117632054, -0.009058229, 0.047830686, -0.01125145, 0.136628, 0.0056388285, 0.3028781, -0.12286517, 0.23498532, -0.009319075, -0.444048, 0.16174883, -0.06367683) * go_1(1.0, 0.0); result += mat4(0.02343933, -0.010915871, -0.058680378, -0.21886891, -0.010750894, -0.06671997, 0.0602906, -0.07903071, 0.066891186, 0.06650588, 0.14362891, -0.101870626, 0.02264628, -0.06940821, -0.077616625, 0.110911585) * go_1(1.0, 1.0); result += vec4(0.032014452, -0.020821465, 0.0826416, -0.002838458); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(M)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_1_tf //!SAVE conv2d_2_tf //!WIDTH conv2d_1_tf.w //!HEIGHT conv2d_1_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.06963679, -0.07560548, -0.069522075, 0.0038078027, -0.08002613, 0.13671301, 0.084461786, -0.039376218, 0.19136548, -0.123174496, 0.26566333, -0.16583005, -0.18664864, -0.023539122, -0.21928434, -0.026818147) * go_0(-1.0, -1.0); result += mat4(0.16660932, -0.18558703, 0.37230486, 0.118128106, -0.14098641, 0.14659132, -0.22217897, 0.12952235, -0.4139033, -0.04308319, 0.12885277, -0.17986743, -0.23556231, -0.08351981, -0.43240538, 0.019033253) * go_0(-1.0, 0.0); result += mat4(-0.18008037, -0.04448665, 0.011906908, -0.023056917, 0.18136618, -0.04723555, -0.0050158803, -0.14823224, -0.2105281, 0.023047728, -0.14040631, -0.03178526, -0.13477588, -0.01820428, 0.058358394, 0.23792502) * go_0(-1.0, 1.0); result += mat4(0.07363309, -0.061728477, 0.03573137, -0.0050971056, -0.012813505, -0.17236637, 0.1697835, 0.055788577, -0.22263195, 0.10324512, 0.58971673, -0.4872246, -0.1555681, 0.032747746, -0.096495196, 0.070196226) * go_0(0.0, -1.0); result += mat4(0.14174286, 0.099460006, -0.088765986, 0.58350676, -0.025177564, -0.46004987, 0.37007022, -0.11437029, -0.5164534, -0.60465246, 0.38859612, -0.32846406, 0.050266482, -0.20334712, 0.18316261, -0.19327633) * go_0(0.0, 0.0); result += mat4(-0.09377763, -0.0012762006, -0.028991895, -0.26523829, 0.20173682, 0.037923716, -0.03174243, 0.07103378, -0.10764164, -0.30752546, 0.20556998, -0.1892279, 0.08115748, -0.023550175, -0.07627362, 0.11746628) * go_0(0.0, 1.0); result += mat4(-0.06998859, -0.017997518, 0.069938794, -0.14943017, -0.14179112, 0.16643842, -0.110231474, 0.08895815, -0.24074875, 0.3277253, -0.07435203, -0.23452802, 0.039962552, -0.07145652, -0.022511544, -0.04571222) * go_0(1.0, -1.0); result += mat4(-0.059785757, -0.23771374, -0.030571314, 0.25222278, 0.106601834, 0.34398326, 0.14511436, -0.03867526, -0.38982397, -0.11944689, 0.12997924, -0.13079585, 0.005729482, 0.012653905, -0.063693404, 0.09632285) * go_0(1.0, 0.0); result += mat4(-0.04933823, 0.0547175, 0.050636575, -0.10060694, 0.1344485, 0.19752938, -0.100068115, -0.028829506, -0.14096203, -0.079092234, 0.092109434, 0.011606209, -0.04052607, -0.008347507, 0.06956573, -0.028109524) * go_0(1.0, 1.0); result += mat4(0.21918017, -0.11115073, 0.2262453, -0.06889667, -0.11256312, -0.07438075, -0.088454485, 0.13672407, -0.06905764, 0.08128395, 0.016103368, 0.050190717, 0.09691516, 0.05845721, 0.4886816, 0.041121427) * go_1(-1.0, -1.0); result += mat4(-0.3449472, 0.09711974, -0.13881907, -0.018265123, 0.27855873, -0.07030004, 0.29545054, 0.37216932, 0.08657718, 0.099066615, -0.10574013, -0.17667885, -0.14855732, -0.11351448, 0.66945946, 0.11312157) * go_1(-1.0, 0.0); result += mat4(0.2526151, -0.04594331, -0.06606611, 0.09104881, 0.06857995, -0.075284235, -0.17664689, 0.21578754, 0.0696524, 0.09142951, 0.080997564, -0.0682772, -0.0011445724, -0.11736295, 0.2519232, -0.101926275) * go_1(-1.0, 1.0); result += mat4(-0.12913518, 0.058357026, 0.195421, -0.15651494, 0.2877076, 0.0033844314, -0.07831594, 0.052855384, -0.031295884, 0.03301088, -0.18408822, 0.06732994, 0.23742151, -0.12568143, 0.22810535, -0.11545694) * go_1(0.0, -1.0); result += mat4(-0.49203303, -0.22656603, 0.1723193, -0.51250046, -0.09742038, 0.758559, -0.3387505, -0.6193586, 0.14136684, 0.27679884, -0.050113205, 0.31041816, -0.36475047, -0.48746544, 0.3233227, 0.4579754) * go_1(0.0, 0.0); result += mat4(0.46636763, 0.1507748, -0.2581362, 0.15413165, -0.17160143, 0.14256273, -0.074575804, -0.099299066, -0.0017214464, 0.13778336, -0.07378213, -0.15489665, -0.10533715, -0.0011083825, 0.39584312, 0.0023906573) * go_1(0.0, 1.0); result += mat4(0.026959421, -0.06391859, 0.0034752619, 0.14521928, -0.0010877338, -0.032619733, 0.005375293, -0.018952755, 0.03381545, -0.007652831, 0.034141563, 0.046016496, 0.11219674, 0.030913852, 0.077403754, 0.17192438) * go_1(1.0, -1.0); result += mat4(0.040326044, 0.17290725, -0.1220239, -0.09594783, -0.025229257, 0.17913155, -0.26623353, -0.033396784, -0.03075146, 0.009143897, -0.0136083895, -0.13886899, 0.075683735, -0.11584183, 0.22182357, 0.19350322) * go_1(1.0, 0.0); result += mat4(0.15726025, -0.10215694, -0.060057458, 0.26487043, -0.04075552, -0.016496127, 0.0015382086, 0.108562306, 0.026795091, 0.0441233, -0.08754318, -0.0460157, 0.048422016, 0.14107347, 0.07986661, 0.1047697) * go_1(1.0, 1.0); result += vec4(0.0766796, 0.08115133, -0.05703058, 0.14025708); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(M)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_2_tf //!SAVE conv2d_3_tf //!WIDTH conv2d_2_tf.w //!HEIGHT conv2d_2_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.18038331, 0.21830973, -0.10019419, -0.022745568, -0.14944611, -0.15669158, 0.46361133, -0.07289843, 0.02976627, -0.09000817, 0.113060996, 0.05635241, 0.012762965, -0.022688959, 0.01629751, 0.061114635) * go_0(-1.0, -1.0); result += mat4(0.024338024, -0.10004009, -0.13709056, -0.0851965, 0.23927099, -0.024349794, -0.16574804, 0.084686354, -0.047885604, 0.09688507, -0.12733915, 0.06980246, 0.11480734, 0.014669346, -0.07505829, 0.04676309) * go_0(-1.0, 0.0); result += mat4(0.054203495, 0.011881634, -0.036115017, -0.0686298, -0.13682245, -0.15678032, 0.057050128, -0.03368558, 0.13011025, 0.033391044, -0.09841339, -0.027057761, -0.18701133, 0.20852546, -0.13660902, 0.0005817616) * go_0(-1.0, 1.0); result += mat4(-0.08077834, 0.35952288, -0.07647382, -0.0033230998, 0.13929126, -0.09155619, 0.14128102, 0.16005981, 0.18161216, -0.09485738, 0.0029118075, 0.052682754, 0.03242074, 0.08299826, 0.073796146, -0.06446532) * go_0(0.0, -1.0); result += mat4(-0.36655015, 0.4606936, 0.19073649, 0.31655258, -0.006838053, -0.579939, 0.089126326, -0.14021218, -0.3437716, 0.16714323, 0.17705944, -0.22418492, -0.3883696, -0.2302651, 0.2581861, 0.21983066) * go_0(0.0, 0.0); result += mat4(0.0992383, -0.014257871, -0.023896435, 0.19868234, 0.0408007, 0.07995299, 0.16102871, -0.11668251, 0.22458278, -0.05587917, 0.19373615, -0.016202094, -0.25106144, 0.15634494, 0.11624891, -0.2930768) * go_0(0.0, 1.0); result += mat4(0.024616942, 0.36248252, -0.14779098, -0.019894283, -0.007111256, 0.010641561, -0.09541178, 0.21236233, 0.009501827, 0.08132797, -0.13983901, 0.027207611, 0.038444366, -0.013995817, -0.16242191, 0.03294123) * go_0(1.0, -1.0); result += mat4(0.0131698875, -0.18124102, -0.13503514, -0.06099072, 0.07422735, -0.20906176, -0.049005672, 0.08739405, -0.031758767, -0.1978915, 0.23094437, 0.54512614, 0.21338555, -0.011205669, -0.23727885, -0.29533875) * go_0(1.0, 0.0); result += mat4(-0.0010255767, -0.07168225, -0.033568826, 0.22161655, -0.087293416, 0.11350447, 0.13653576, 0.061226424, -0.13074352, 0.058425818, 0.038460605, 0.2749964, -0.012814839, 0.085885845, -0.038151987, -0.17960808) * go_0(1.0, 1.0); result += mat4(0.19728905, -0.040724937, -0.18270236, 0.046735186, 0.03507326, 0.119867206, -0.12691991, 0.18119748, -0.052895024, 0.11348764, -0.043787055, 0.004703516, 0.006752757, -0.06939761, -0.009801806, -0.075640485) * go_1(-1.0, -1.0); result += mat4(0.051735226, 0.1732299, -0.10672899, 0.0320877, -0.4913656, 0.2102274, 0.43920282, 0.059108034, 0.08349019, -0.16517872, 0.15436842, -0.1075667, 0.022741623, -0.26693836, 0.3645307, 0.017874828) * go_1(-1.0, 0.0); result += mat4(0.034464058, 0.014929155, 0.054227423, 0.14167373, -0.0023630706, -0.08904212, 0.11918041, -0.034539603, 0.06048089, -0.06807333, 0.14447778, 0.035260547, 0.09979546, -0.1924939, 0.14596114, -0.12069667) * go_1(-1.0, 1.0); result += mat4(-0.04427228, -0.23673469, 0.010357103, -0.2907043, -0.06845721, -0.078984015, 0.06867713, -0.058163825, -0.12154615, 0.08430951, 0.1922373, 0.030108064, -0.43081748, -0.38715646, -0.022240646, -0.15403675) * go_1(0.0, -1.0); result += mat4(0.46885306, -0.33421394, -0.6695223, -0.41841158, 0.30317923, 0.24244753, -0.1047785, -0.18656285, 0.06261881, -0.4405616, 0.24233986, 0.40070608, 0.81440526, 0.11305212, -0.8826317, -0.023478031) * go_1(0.0, 0.0); result += mat4(-0.07879348, -0.024378026, -0.041883785, -0.17030984, 0.23229122, -0.011237109, 0.12058088, 0.20766267, -0.36519575, 0.09599417, -0.1271098, 0.06990154, 0.21161246, 0.041002538, -0.36046275, 0.007304667) * go_1(0.0, 1.0); result += mat4(0.10873893, 0.003872542, -0.13476561, -0.036068805, -0.054637462, 0.02304618, 0.04707738, -0.2856381, 0.07124422, 0.010866545, 0.20484549, -0.008342406, -0.43660247, -0.041055538, 0.33536008, -0.060022205) * go_1(1.0, -1.0); result += mat4(0.1966458, 0.0016302796, -0.25712642, -0.09639119, -0.006955351, 0.10882133, 0.1107341, 0.062697805, -0.1074494, 0.17361663, 0.6429869, -0.39846307, -0.26302996, 0.048710946, 0.40387508, 0.4299715) * go_1(1.0, 0.0); result += mat4(0.18948616, 0.24086732, -0.064474985, -0.11069709, 0.1279659, -0.13438123, -0.028438117, 0.125883, 0.018153818, -0.21942288, 0.020390838, -0.22797634, -0.10821287, -0.17175092, 0.122016855, 0.20699544) * go_1(1.0, 1.0); result += vec4(-0.05101961, -0.060740646, -0.024465766, 0.058471628); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(M)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_3_tf //!SAVE conv2d_4_tf //!WIDTH conv2d_3_tf.w //!HEIGHT conv2d_3_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_3_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_3_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.14533128, 0.07266841, 0.13238011, -0.23328504, 0.031516243, 0.058471266, -0.06394412, 0.090752736, -0.0042359144, 0.12357294, -0.04377495, 0.0011743477, 0.05412243, -0.08146249, 0.04002749, -0.032876283) * go_0(-1.0, -1.0); result += mat4(-0.036972385, -0.15238069, -0.3453321, -0.36025128, 0.07597202, -0.02368151, -0.3889606, 0.34607083, 0.3133179, -0.21712309, -0.4210954, 0.21450534, 0.15226828, 0.25326282, 0.45327064, -0.3350824) * go_0(-1.0, 0.0); result += mat4(0.019018406, -0.33060563, -0.092601225, 0.14970545, 0.1441509, -0.19228427, -0.032771986, 0.26331595, 0.052981265, -0.06627376, -0.08634131, 0.038706224, 0.13403937, -4.4842476e-05, 0.049002815, -0.12719193) * go_0(-1.0, 1.0); result += mat4(0.17527401, -0.0035254909, -0.047959115, -0.4526988, -0.07510284, 0.0013256798, -0.07539148, 0.24220634, -0.08708839, -0.14494033, -0.17085724, -0.099797316, 0.0068515535, -0.08918779, 0.27164719, -0.1702649) * go_0(0.0, -1.0); result += mat4(0.31848368, 0.48983255, -0.44140294, -0.65174145, -0.004199057, 0.19494705, 0.5196497, -0.027118586, 0.032509074, -0.23900363, -0.14489244, 0.36314297, -0.23168536, -0.20960593, 0.61471456, 0.12401275) * go_0(0.0, 0.0); result += mat4(-0.24317405, 0.21560913, 0.15564032, 0.11606844, -0.15039803, -0.59578896, 0.14100945, -0.026194477, 0.37237462, -0.49472088, -0.15215331, -0.38820064, -0.25089455, -0.29643852, -0.09513793, 0.019779462) * go_0(0.0, 1.0); result += mat4(0.12498539, 0.0710632, -0.25012368, -0.2272255, -0.08647026, 0.12277892, 0.011025097, -0.12168395, -0.13489573, 0.016708186, -0.15583871, -0.057124946, 0.1216943, 0.019803725, 0.06952334, -0.032985855) * go_0(1.0, -1.0); result += mat4(0.28794885, 0.33783793, -0.14469545, -0.081780486, -0.50320613, -0.067601606, -0.06847453, -0.021648854, -0.34295765, 0.15071863, -0.06619896, -0.084465064, 0.31909832, 0.015414661, 0.14930317, -0.11295768) * go_0(1.0, 0.0); result += mat4(0.24530606, 0.25526014, 0.09971985, -0.07749641, -0.2361951, -0.07997673, 0.03617294, 0.02959561, -0.4498983, -0.014073485, -0.20587012, 0.06396779, 0.1262825, 0.027433183, 0.14469334, 0.011538011) * go_0(1.0, 1.0); result += mat4(-0.038572453, -0.023108613, -0.039481267, -0.012160024, -0.004521989, -0.028665857, 0.04295255, 0.10580258, 0.05439479, -0.072261885, 0.11030243, 0.08934696, 0.09133867, 0.017547369, 0.097613186, 0.05491059) * go_1(-1.0, -1.0); result += mat4(-0.09972817, 0.057730395, 0.12665828, 0.32861367, -0.16186063, 0.0745509, 0.2394045, -0.08687853, -0.034404907, -0.05843572, 0.0684561, -0.1355754, 0.19248672, -0.60372186, 0.12583947, 0.4388962) * go_1(-1.0, 0.0); result += mat4(0.10341107, 0.061113223, 0.08773817, -0.082504354, -0.16612078, 0.2681751, 0.019737698, -0.17122322, -0.135949, 0.3048101, 0.087803006, 0.11373851, 0.013192192, -0.27022064, 0.35529897, -0.15321451) * go_1(-1.0, 1.0); result += mat4(-0.032835662, 0.11123062, -0.11322452, -0.17300649, 0.04680824, 0.12849288, 0.17269878, -0.048671383, 0.05189037, -0.009078046, 0.22105052, 0.013008137, -0.009738674, 0.15391739, 0.20969556, 0.14189166) * go_1(0.0, -1.0); result += mat4(-0.47377753, 0.3038031, 0.18604809, 0.1931698, -0.2964668, -0.12287907, -0.7107761, 0.26619422, -0.33923018, 0.19200724, 0.013786281, -0.17496964, 0.079325035, -0.3694445, 0.0054486147, -0.33018264) * go_1(0.0, 0.0); result += mat4(0.14903802, -0.028043179, 1.5238678e-05, 0.021232028, 0.16025065, 0.14746875, -0.22831628, -0.12177345, 0.038778774, 0.32188168, -0.042017702, 0.27155936, 0.17920609, 0.04099755, 0.28527525, 0.074623376) * go_1(0.0, 1.0); result += mat4(0.057019282, -0.112741895, 0.030361209, 0.14567861, 0.056265317, -0.01573537, -0.06707608, 0.016657263, 0.09829025, -0.026795063, 0.023042196, 0.09438241, -0.025483066, -0.052787006, 0.19730279, 0.021218104) * go_1(1.0, -1.0); result += mat4(0.19868211, -0.01531125, 0.108596824, -0.035456363, 0.0033609823, 0.057961613, -0.013726211, 0.101742364, 0.33357215, 0.14468077, 0.29711527, -0.24662566, -0.119014986, -0.1899639, 0.11246697, -0.0035374009) * go_1(1.0, 0.0); result += mat4(-0.05602109, -0.15539522, 0.010730943, 0.057116497, -0.02037749, 0.084210664, -0.028235348, 0.10574697, 0.056925274, 0.07922333, -0.090088, 0.1615985, -0.0044301567, -0.089945644, 0.024176618, -0.041844133) * go_1(1.0, 1.0); result += vec4(0.0015292584, -0.043625206, -0.09429898, -0.06280405); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(M)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_4_tf //!SAVE conv2d_5_tf //!WIDTH conv2d_4_tf.w //!HEIGHT conv2d_4_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_4_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_4_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.06051604, -0.028152643, -0.21418124, 0.13032125, 0.42565975, -0.09571944, -0.34494513, 0.30004, -0.073245734, -0.028659137, 0.0032105136, -0.05009555, -0.048971225, 0.04814533, 0.002843805, -0.046224426) * go_0(-1.0, -1.0); result += mat4(-0.07495975, 0.018714864, 0.21229684, -0.13614887, 0.79988647, -0.0697328, 0.38232988, 0.24165109, 0.25947478, -0.0009418982, -0.17369923, 0.10007766, 0.024117598, 0.028611807, 0.15090801, -0.06344829) * go_0(-1.0, 0.0); result += mat4(-0.07982219, 0.0900347, 0.007609254, -0.0034791247, 0.013611781, -0.13560618, 0.09685799, 0.06276075, 0.134693, -0.14370437, -0.25175703, -0.0016138123, -0.0075672898, -0.13325731, -0.061100446, 0.0059743375) * go_0(-1.0, 1.0); result += mat4(-0.039018434, -0.19668463, -0.43018532, 0.31886247, 0.4965479, 0.114569925, 0.19110382, 0.27343535, 0.0707728, -0.11877004, -0.25827697, 0.37012872, 0.1474777, 0.07056952, -0.14965728, 0.061595406) * go_0(0.0, -1.0); result += mat4(0.506543, -0.16268773, 0.455319, -0.0702646, 0.70102173, -0.14041683, 0.70184857, 0.4817842, -0.3389246, -0.14463086, 0.13763213, -1.1259074, 0.47722015, 0.38352612, -0.04293366, -0.5604627) * go_0(0.0, 0.0); result += mat4(0.17606944, 0.15897374, 0.13499324, 0.29241478, -0.032824475, 0.11128662, -0.22204424, -0.051803727, 0.013195331, -0.42040786, -0.3950585, 0.70745844, 0.38646924, -0.19080774, -0.15171832, -0.10742828) * go_0(0.0, 1.0); result += mat4(-0.039278325, 0.18421806, -0.044948544, 0.07902063, -0.2149251, 0.09913459, -0.09743655, -0.26899317, -0.002695496, -0.07554527, -0.22373366, 0.17830558, -0.047994815, -0.06789183, -0.06755918, -0.104452066) * go_0(1.0, -1.0); result += mat4(-0.0493473, -0.30411786, -0.056439694, -0.06582185, -0.21309847, 0.100670904, -0.22966193, -0.045954112, 0.12728062, -0.25081897, -0.094699375, -0.4036555, 0.060854495, -0.64373237, -0.21522263, -0.6683476) * go_0(1.0, 0.0); result += mat4(0.063481025, 0.11744312, -0.043330096, 0.33817932, -0.06679828, -0.23207302, -0.10188898, -0.10590511, 0.058780864, 0.047292337, -0.11834696, 0.10076128, -0.036641665, 0.30200714, -0.0002892557, -0.10303763) * go_0(1.0, 1.0); result += mat4(-0.10842604, 0.042055763, 0.29702973, -0.07409644, -0.030164458, -0.012098744, -0.06396587, -0.08787527, 0.051854923, 0.12997511, 0.11468497, 0.15022379, 0.007814715, 0.014517445, 0.025484756, 0.01078619) * go_1(-1.0, -1.0); result += mat4(-0.29229385, 0.040265664, -0.15376821, 0.075579196, -0.05593569, -0.045405343, 0.12099204, 0.1571252, 0.17841713, 0.04673325, 0.14550509, 0.08603346, -0.049786013, 0.06121843, -0.16273825, -0.13857752) * go_1(-1.0, 0.0); result += mat4(0.06903744, 0.2628764, -0.13582836, -0.35678583, -0.13821034, -0.019381443, -0.19570538, -0.09298511, 0.08965436, 0.09745909, 0.20055099, 0.024967568, 0.08144204, 0.004633625, 0.12809834, -0.009431525) * go_1(-1.0, 1.0); result += mat4(0.09784006, 0.010729353, 0.046643205, -0.110926524, -0.21556224, 0.00016300633, 0.122175336, 0.15004392, 0.013864355, 0.24767809, 0.13865592, 0.0155424485, -0.1450483, -0.15688781, -0.06195043, -0.13745981) * go_1(0.0, -1.0); result += mat4(0.018991318, 0.55401963, 0.11709872, -0.028442185, -0.46035343, -0.10215539, -0.60193926, 0.47882316, -0.23346989, 0.037200127, 0.22814943, -0.08231696, -0.36430013, -0.011152757, 0.48752213, 0.29796222) * go_1(0.0, 0.0); result += mat4(-0.07258066, -0.023222538, 0.23230423, -0.30317304, 0.03942911, -0.06899803, 0.23778579, 0.07418621, -0.17443737, 0.33387753, 0.007354842, -0.123447575, -0.1745315, 0.11071779, -0.11949625, -0.22832453) * go_1(0.0, 1.0); result += mat4(-0.024909232, -0.0308135, 0.12170621, -0.13298757, 0.045828197, -0.1532345, -0.06633672, 0.23591088, 0.04964077, 0.14091493, 0.038343724, -0.029780807, 0.05762822, -0.048930667, -0.02434709, 0.07109019) * go_1(1.0, -1.0); result += mat4(-0.16039175, 0.3004474, -0.17278233, 0.13677922, 0.18838613, 0.15054552, 0.32901475, -0.1288333, 0.26378244, -0.05119892, 0.34533516, 0.25180495, 0.19452183, 0.0843233, -0.08029368, 0.39877903) * go_1(1.0, 0.0); result += mat4(-0.07097129, -0.26492423, -0.055032317, -0.093516104, -0.11795062, 0.04086253, -0.07989471, 0.059686553, 0.09378249, 0.45851848, 0.2510942, 0.19599153, 0.019765077, -0.02920918, -0.04125142, -0.13859107) * go_1(1.0, 1.0); result += vec4(0.04400571, -0.04015565, 0.0140529545, 0.05474095); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(M)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_5_tf //!SAVE conv2d_6_tf //!WIDTH conv2d_5_tf.w //!HEIGHT conv2d_5_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_5_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_5_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.014236042, -0.0031431736, -0.1551387, 0.12515116, -0.28528872, 0.36161992, 0.15750743, -0.17111474, 0.13792591, -0.0657419, -0.17471549, 0.14650472, 0.034169197, -0.019157575, 0.23520657, -0.20358163) * go_0(-1.0, -1.0); result += mat4(0.02015035, 0.12993371, 0.11199667, -0.09854378, 0.5001741, 0.03462961, 0.24919736, 0.08505297, -0.20902094, -0.24141377, -0.15360375, 0.049974803, -0.037157424, -0.048510186, 0.20106035, -0.118480384) * go_0(-1.0, 0.0); result += mat4(0.086798504, -0.009607818, 0.034812123, -0.005187592, 0.0351509, 0.021755, -0.04996161, -0.041231696, 0.0020545553, 0.015730752, -0.07507172, 0.018597523, -0.02393343, 0.07624775, 0.03892451, -0.0025574185) * go_0(-1.0, 1.0); result += mat4(0.035725456, 0.06809103, 0.51926994, -0.39983147, -0.16402833, -0.1243394, -0.25922915, 0.28285915, 0.15959994, -0.2351732, 0.2650535, -0.30193794, -0.11468332, 0.050777763, -0.51894253, 0.4408367) * go_0(0.0, -1.0); result += mat4(-0.27042082, 0.22243942, 0.14902467, 0.38428563, 0.46612173, 0.5169912, -0.22330502, -0.11300288, -0.36141354, 0.0668681, 0.2984152, 0.1275798, -0.24121419, 0.2952039, -0.45109174, -0.3822957) * go_0(0.0, 0.0); result += mat4(0.26543504, -0.05742226, -0.052103903, -0.013124308, -0.14358385, -0.04024543, 0.07665455, -0.012301872, -0.18752757, -0.03913891, 0.038205814, -0.006583095, -0.25550908, -0.25725332, -0.12454206, -0.0058936924) * go_0(0.0, 1.0); result += mat4(-0.0018946569, 0.019746022, -0.13080788, 0.11450627, -0.013743845, -0.027179785, -0.14425103, 0.07109661, 0.023703793, 0.086905524, 0.03151253, 0.0132474145, 0.041018624, 0.04548913, 0.2718715, -0.20008296) * go_0(1.0, -1.0); result += mat4(-0.076830454, 0.11652955, 0.5068201, -0.3082819, 0.058615055, -0.006765798, -0.057522714, 0.049981344, -0.006897243, -0.21763432, 0.16896053, -0.21176189, -0.061227098, 0.03566485, 0.08901554, -0.050980624) * go_0(1.0, 0.0); result += mat4(0.02327798, 0.07662976, 0.034811985, -0.03238033, -0.0021881019, -0.030997375, -0.069672935, 0.04040273, -0.1217442, 0.104173124, 0.09862539, 0.020557549, -0.022286594, 0.10287763, -0.021694934, 0.07542515) * go_0(1.0, 1.0); result += mat4(0.124069154, -0.08579466, -0.07816314, 0.11332851, -0.034682628, -0.11038275, 0.04750615, -0.096100725, 0.039588403, -0.15149672, -0.05529172, 0.034304325, -0.022520235, -0.05023852, -0.2674731, 0.21886522) * go_1(-1.0, -1.0); result += mat4(-0.1948599, -0.14946899, -0.39548838, 0.18042913, -0.007919619, 0.19826505, 0.23789087, 0.009140256, 0.11857748, 0.18215668, 0.13606293, -0.09209675, -0.080678545, -0.020431137, -0.07728839, -0.051353537) * go_1(-1.0, 0.0); result += mat4(-0.07616472, -0.0032800382, -0.045657665, -0.039144326, -0.37786487, -0.08877774, 0.053579114, -0.070886396, 0.011311804, 0.107276045, 0.013236154, 0.009832061, 0.08292063, 0.12258811, 0.0005569043, -0.009806432) * go_1(-1.0, 1.0); result += mat4(-0.28062925, 0.15946878, -0.1021801, -0.06471589, -0.26999477, 0.21230288, -0.14243907, 0.2555922, -0.09608517, 0.26339412, 0.20891234, -0.23538485, 0.33958244, -0.12569186, 0.43289876, -0.33462036) * go_1(0.0, -1.0); result += mat4(0.16265294, 0.2625464, -0.34452894, 0.2233622, 0.13850005, -0.42999864, -0.5385177, -0.11035979, 0.51662, -0.78238726, -0.09422375, 0.83759475, 0.44468537, 0.14301361, 0.108906105, 1.1596143) * go_1(0.0, 0.0); result += mat4(-0.73757625, -0.12369605, 0.23523071, 0.006587637, -0.15445381, 0.22757277, 0.052819528, 0.10183905, -0.07912228, -0.16998893, -0.13360223, 0.014348178, -0.17778571, -0.41047302, 0.10241381, -0.08526306) * go_1(0.0, 1.0); result += mat4(0.14712952, 0.048995696, 0.05299946, -0.06817572, 0.1498064, -0.079825334, 0.40354064, -0.31789717, -0.1998377, 0.00955295, -0.32318407, 0.30898204, -0.039571725, -0.026203401, -0.16292085, 0.08574385) * go_1(1.0, -1.0); result += mat4(-0.6353329, -0.56000775, -0.17279743, 0.18198174, -0.19555812, 0.056538377, 0.34365895, -0.07799055, 0.19011354, -0.13952748, 0.029196098, -0.19596763, -0.069196045, -0.17402656, 0.07948411, -0.016226962) * go_1(1.0, 0.0); result += mat4(0.25592864, 0.083498634, -0.28515807, 0.10789751, 0.0043962947, 0.07085363, 0.048724182, -0.025131436, -0.0049440865, -0.033094388, -0.032935806, 0.04266025, 0.20026933, 0.0927841, -0.006839351, -0.013012285) * go_1(1.0, 1.0); result += vec4(0.02021373, 0.0014037411, 0.0012718709, 0.017278494); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(M)-Conv-4x1x1x56 //!HOOK MAIN //!BIND conv2d_tf //!BIND conv2d_1_tf //!BIND conv2d_2_tf //!BIND conv2d_3_tf //!BIND conv2d_4_tf //!BIND conv2d_5_tf //!BIND conv2d_6_tf //!SAVE conv2d_last_tf //!WIDTH conv2d_tf.w //!HEIGHT conv2d_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define g_0 (max((conv2d_tf_tex(conv2d_tf_pos)), 0.0)) #define g_1 (max(-(conv2d_tf_tex(conv2d_tf_pos)), 0.0)) #define g_2 (max((conv2d_1_tf_tex(conv2d_1_tf_pos)), 0.0)) #define g_3 (max(-(conv2d_1_tf_tex(conv2d_1_tf_pos)), 0.0)) #define g_4 (max((conv2d_2_tf_tex(conv2d_2_tf_pos)), 0.0)) #define g_5 (max(-(conv2d_2_tf_tex(conv2d_2_tf_pos)), 0.0)) #define g_6 (max((conv2d_3_tf_tex(conv2d_3_tf_pos)), 0.0)) #define g_7 (max(-(conv2d_3_tf_tex(conv2d_3_tf_pos)), 0.0)) #define g_8 (max((conv2d_4_tf_tex(conv2d_4_tf_pos)), 0.0)) #define g_9 (max(-(conv2d_4_tf_tex(conv2d_4_tf_pos)), 0.0)) #define g_10 (max((conv2d_5_tf_tex(conv2d_5_tf_pos)), 0.0)) #define g_11 (max(-(conv2d_5_tf_tex(conv2d_5_tf_pos)), 0.0)) #define g_12 (max((conv2d_6_tf_tex(conv2d_6_tf_pos)), 0.0)) #define g_13 (max(-(conv2d_6_tf_tex(conv2d_6_tf_pos)), 0.0)) vec4 hook() { vec4 result = mat4(-0.0067711817, 0.08160003, 0.0247279, 0.03084815, -0.026977416, -0.02120602, -0.025078611, -0.029852165, -0.011627478, -0.012742972, 0.022736797, -0.0028815821, -0.007515677, 0.0172887, -0.023259213, 0.009608947) * g_0; result += mat4(-0.028660107, -0.014015208, -0.027838672, -0.013171922, 0.0029435428, 0.027047642, -0.017478354, 0.022834882, -0.037572853, -0.0034044068, -0.0149029335, -0.013362301, 0.009827443, -0.015742151, -0.0074795415, -0.0022266617) * g_1; result += mat4(-0.07579662, -0.039754186, -0.066026606, -0.046816852, 0.1099032, 0.043956704, 0.073109835, 0.04680284, -0.06896613, -0.008838632, -0.044584926, -0.01319039, -0.0021152915, -0.04503326, 0.027061926, -0.028334105) * g_2; result += mat4(0.15458213, 0.059769996, 0.09327123, -0.028782733, 0.023459995, -0.15390377, -0.13432898, -0.1127775, 0.072764635, -0.0020463336, 0.034736466, -0.0012086042, -0.05847183, -0.029952323, 0.052969377, 0.09590908) * g_3; result += mat4(-0.07476772, -0.016574614, 0.04131183, 0.017335678, 0.009654406, 0.072183535, -0.002266456, 0.086873695, 9.310129e-05, 0.0056416965, -0.004188391, 0.023132093, -0.05183336, -0.025825873, -0.03684392, -0.0075729224) * g_4; result += mat4(0.00878842, 0.03869637, -0.035759524, 0.003345386, -0.064184256, -0.034568302, -0.06672922, -0.0686381, -0.06794392, -0.10685906, 0.04679947, -0.012535639, 0.006932529, -0.007783515, 0.109123886, 0.13804391) * g_5; result += mat4(-0.03160699, 0.050473, -0.09030729, 0.0649397, 0.11466501, 0.17912874, -0.0081851315, 0.052244574, 0.051632743, 0.061941486, 0.06546816, 0.12174249, -0.05104755, -0.018193979, -0.032196652, -0.035292786) * g_6; result += mat4(0.013612735, -0.0024100312, -0.068611205, -0.07369285, -0.019647537, -0.066944756, -0.010012875, -0.06785739, -0.062246565, -0.087313406, -0.044278186, -0.09368995, 0.052555013, 0.13604961, 0.05645059, 0.08763303) * g_7; result += mat4(0.04218486, -0.05028401, 0.059086576, -0.03545452, 0.027737848, 0.0043074046, 0.0011001764, -0.073026665, -0.04094988, 0.044061556, -0.009812515, 0.06841999, -0.06612581, 0.037223976, -0.07759491, -0.04356598) * g_8; result += mat4(-0.027558247, 0.014248466, -0.019813016, -0.058107473, -0.016717663, -0.020424338, 0.0053625097, -0.009917319, 0.013678771, 0.0113340765, 0.0061787106, -0.036083996, -0.020179711, -0.011310535, 0.054827053, -0.0008278952) * g_9; result += mat4(0.028690035, -0.012079616, 0.11931408, -0.048533775, 0.069336995, 0.0049852817, 0.013774468, 0.035233382, -0.07384821, 0.0003354423, -0.0059171803, -0.04503906, 0.08727279, 0.005138857, -0.17724465, 0.055782065) * g_10; result += mat4(-0.20744391, 0.24348328, -0.3145766, 0.17026486, -0.022870807, -0.01648648, -0.05912279, -0.012555373, -0.066004686, 0.03182394, 0.16285324, -0.1221846, -0.31816196, 0.007928748, 0.43180224, -0.015949022) * g_11; result += mat4(0.16363169, 0.14781676, -0.2377973, -0.1571377, -0.09038187, 0.0046504294, 0.033955004, -0.051421452, 0.046735536, 0.006827522, -0.121338, 0.12671822, 0.15833299, -0.1858712, -0.1942371, 0.17336044) * g_12; result += mat4(-0.018145572, -0.015550516, 0.044410378, 0.046016492, 0.084021375, 0.05327457, -0.008270992, -0.045435544, 0.07185879, -0.131923, 0.26721445, -0.26745328, -0.07093472, 0.042701527, 0.13793674, -0.095621444) * g_13; result += vec4(0.016836504, 0.010161949, 0.021351453, 0.01278978); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(M)-Depth-to-Space //!HOOK MAIN //!BIND MAIN //!BIND conv2d_last_tf //!SAVE MAIN //!WIDTH conv2d_last_tf.w 2 * //!HEIGHT conv2d_last_tf.h 2 * //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * vec4 hook() { vec2 f0 = fract(conv2d_last_tf_pos * conv2d_last_tf_size); ivec2 i0 = ivec2(f0 * vec2(2.0)); float c0 = conv2d_last_tf_tex((vec2(0.5) - f0) * conv2d_last_tf_pt + conv2d_last_tf_pos)[i0.y * 2 + i0.x]; float c1 = c0; float c2 = c1; float c3 = c2; return vec4(c0, c1, c2, c3) + MAIN_tex(MAIN_pos); } ================================================ FILE: app/src/main/assets/shaders/Anime4K_Upscale_CNN_x2_S.glsl ================================================ // MIT License // Copyright (c) 2019-2021 bloc97 // All rights reserved. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //!DESC Anime4K-v3.2-Upscale-CNN-x2-(S)-Conv-4x3x3x3 //!HOOK MAIN //!BIND MAIN //!SAVE conv2d_tf //!WIDTH MAIN.w //!HEIGHT MAIN.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (MAIN_texOff(vec2(x_off, y_off))) vec4 hook() { vec4 result = mat4(-0.0057322932, 0.12928207, -0.056848746, 0.18680117, -0.0306273, 0.25602463, 0.053723164, 0.20419341, 0.0018709862, 0.022848232, -0.04105527, 0.10169034, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, -1.0); result += mat4(0.009471417, -0.12957802, 0.096014425, 0.21836184, 0.00021601951, -0.22997683, 0.23666254, 0.41192335, 0.021762101, 0.0047863554, 0.008233427, 0.108514786, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 0.0); result += mat4(-0.01156376, -0.18988979, 0.04614705, -0.044767227, 0.01050636, -0.26426336, 0.23741047, 0.0027636609, -0.027718676, -0.14202335, -0.016650287, -0.06637125, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 1.0); result += mat4(0.057809234, -0.11033858, 0.056533534, -0.06292466, 0.13880666, -0.18710336, 0.2441031, -0.25326246, 0.0032683122, -0.026437074, 0.0023248852, 7.640766e-05, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, -1.0); result += mat4(-0.49110603, 0.4429004, -0.44015464, -0.41174838, -0.87738293, 0.7808468, -1.0929365, -0.59699076, -0.18409836, 0.185138, -0.11773224, -0.17097276, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 0.0); result += mat4(0.10580959, -0.055947904, -0.03431237, -0.080236495, 0.14862584, -0.15393938, -0.18872876, -0.3170681, 0.03559387, -0.003990826, 0.021298569, 0.012844483, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 1.0); result += mat4(-0.040715586, -0.25781113, 0.08896714, -0.1225879, -0.15790503, -0.54010904, 0.29588607, 0.10401059, 0.003413123, -0.108357325, 0.0112870345, -0.11888622, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, -1.0); result += mat4(0.0049315444, 0.02376202, -0.08224771, 0.121118225, -0.041512914, -0.027994309, -0.585988, -0.069672115, -0.017247835, 0.0056576864, 0.04319012, 0.055003505, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 0.0); result += mat4(0.37521392, 0.15916082, 0.059708964, 0.19046007, 0.8120325, 0.38343868, 0.3436578, 0.5287958, 0.16570656, 0.06957687, 0.014022592, 0.074799836, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 1.0); result += vec4(-0.01050964, -0.00939481, 0.17684458, 0.027366742); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(S)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_tf //!SAVE conv2d_1_tf //!WIDTH conv2d_tf.w //!HEIGHT conv2d_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.011029496, 0.05866063, -0.09460646, -0.017664742, -0.022488879, 0.18384217, -0.00397663, -0.064733066, 0.08466802, 0.10667488, 8.0212536e-05, 0.0908869, 0.13580276, 0.00097438256, 0.12176522, -0.08218466) * go_0(-1.0, -1.0); result += mat4(0.16062798, -0.10190268, 0.03280682, 0.05621916, -0.009684231, -0.08464307, 0.17058301, -0.096469186, 0.1967505, -0.1450099, 0.093607284, -0.28240147, -0.21377413, 0.10079291, -0.1741522, 0.17330575) * go_0(-1.0, 0.0); result += mat4(-0.060160473, 0.06316997, 0.0046929033, -0.049405966, 0.13851729, 0.06830702, -0.0586872, -0.040827133, 0.007052838, -0.03576886, -0.111261636, 0.039155316, -0.07380389, -0.09369825, 0.04471156, 0.09678487) * go_0(-1.0, 1.0); result += mat4(-0.36683616, -0.035950605, -0.24414362, -0.009159744, 0.19335322, -0.099253505, 0.075083904, -0.00076695543, 0.65291303, -0.25599423, 0.19827642, 0.065899536, -0.07423247, -0.068967685, 0.0050554527, -0.060272824) * go_0(0.0, -1.0); result += mat4(-0.020688485, -0.83178276, 0.11104878, 0.26454413, 0.13655476, 0.37675047, -0.22219229, -0.01751935, 0.44552696, 0.92510307, 0.16063261, -0.62011045, 0.19366647, -0.06996067, -0.2504841, 0.00803723) * go_0(0.0, 0.0); result += mat4(0.0051537007, -0.057168536, -0.16110587, 0.25232598, -0.04447099, 0.11997351, 0.14808103, -0.34443566, -0.26212573, -0.21970181, 0.2724405, 0.21050811, -0.07949061, -0.064808235, -0.21208277, -0.0042361654) * go_0(0.0, 1.0); result += mat4(-0.0888952, -0.20169449, 0.19144905, -0.016882861, -0.013283103, 0.07552998, -0.24686803, 0.012453213, -0.065454446, -0.016123284, -0.47316182, 0.070926026, 0.09219782, 0.13118166, 0.074736096, 0.0077910526) * go_0(1.0, -1.0); result += mat4(0.5832154, 0.1138069, -0.039765622, 0.3182784, -0.25497997, 0.0013993139, 0.39285088, -0.48511526, -0.39891505, -0.19094779, -0.082146175, -0.20826934, 0.020590555, -0.0012490178, -0.4398621, 0.14377014) * go_0(1.0, 0.0); result += mat4(0.21917395, 3.4314657e-05, 0.25734863, -0.3433305, 0.015720673, 0.2676127, -0.06807297, 0.15040149, -0.23638041, -0.0050233034, -0.13666134, 0.4542111, -0.033572577, -0.08450588, -0.23341487, 0.053490847) * go_0(1.0, 1.0); result += mat4(-0.17482175, 0.057647135, 0.33135444, 0.0850751, -0.1718849, -0.0854123, 0.036795795, -0.13874969, -0.10903869, -0.19007301, -0.06064334, -0.03786032, -0.036696054, 0.07844446, 0.012523185, -0.01562906) * go_1(-1.0, -1.0); result += mat4(-0.04411997, -0.10331819, 0.10050193, 0.12406485, 0.07431592, 0.30109692, -0.17511666, -0.13263564, -0.10192587, 0.07821255, -0.22415096, 0.25552443, 0.17881326, -0.13914281, 0.109979235, -0.0016463579) * go_1(-1.0, 0.0); result += mat4(-0.01911644, -0.15412527, 0.028903123, 0.20831817, 0.00375175, 0.08110953, 0.074919395, -0.17581624, -0.015677985, 0.06504228, 0.08817818, -0.12518327, -0.09537373, 0.028905088, -0.051288474, 0.054334078) * go_1(-1.0, 1.0); result += mat4(0.2852779, -0.28924024, 0.36805123, 0.21079305, -0.28336474, 0.1679663, -0.08641141, -0.10699407, -0.16090055, 0.1287612, -0.15910125, 0.05734755, 0.15883245, 0.0053026294, 0.080674745, 0.0505137) * go_1(0.0, -1.0); result += mat4(0.17639062, 0.3790122, -0.19588692, -0.020314282, 0.26197383, 0.09014768, 0.19696823, -0.41025418, -0.08308115, -0.33279485, -0.22528782, 0.06172439, -0.1365661, -0.13094363, -0.005086559, 0.089024484) * go_1(0.0, 0.0); result += mat4(0.05262993, 0.0006296959, 0.1657725, -0.32591924, 0.12126701, 0.061543245, -0.10526848, 0.041583937, 0.094976954, 0.09416157, -0.22019257, -0.058390073, -0.2073888, 0.057273377, 0.19558284, 0.004208022) * go_1(0.0, 1.0); result += mat4(0.30005738, 0.18478931, -0.23342943, 0.22455733, -0.016488122, 0.099634305, 0.31620836, -0.15731157, 0.09595808, 0.0013774688, 0.48273298, -0.07027936, -0.18764344, -0.26194447, -0.11794225, -0.012173601) * go_1(1.0, -1.0); result += mat4(0.117986746, -0.13846518, -0.019614812, -0.3011192, 0.5501164, 0.3408611, -0.40090847, 0.15706886, 0.13050972, 0.051776595, 0.20792943, 0.23389706, -0.22965533, -0.053367328, 0.3911586, -0.032988597) * go_1(1.0, 0.0); result += mat4(0.054753624, -0.008485731, -0.2451672, 0.17528129, 0.13657846, 0.010480436, 0.07651423, -0.43316832, 0.12736236, 0.13804524, 0.12529011, -0.30946237, -0.14423579, 0.08403089, 0.24335162, 0.057288036) * go_1(1.0, 1.0); result += vec4(0.012077211, 0.013045883, 0.0380778, -0.02908858); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(S)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_1_tf //!SAVE conv2d_2_tf //!WIDTH conv2d_1_tf.w //!HEIGHT conv2d_1_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.036115196, -0.06971895, -0.07508942, 0.016036168, 0.12120111, 0.24536026, 0.044755507, -0.20663576, 0.029635755, -0.15427187, 0.027148994, -0.20795093, 0.10170582, 0.077919215, 0.66063017, -0.4632968) * go_0(-1.0, -1.0); result += mat4(-0.0052889925, -0.019060908, -0.08660142, -0.022095207, -0.08097976, -0.015142803, -0.18552722, -0.078493506, -0.16293915, -0.20099808, -0.08370822, 0.3701389, 0.09094984, 0.2487225, 0.24338846, 0.044003833) * go_0(-1.0, 0.0); result += mat4(-0.061406493, -0.017232792, -0.10917424, 0.11203319, 0.040699825, -0.019294346, 0.084953666, -0.018133596, 0.07209552, 0.016069936, 0.17805555, -0.089537814, 0.15809004, 0.1027023, 0.15044671, -0.15530108) * go_0(-1.0, 1.0); result += mat4(0.0948676, -0.040305693, -0.005591629, -0.048048403, -0.07547777, 0.056606572, 0.021390207, 0.32600567, -0.20805131, -0.099587254, 0.029613169, 0.0092129605, -0.29429698, -0.09898621, 0.44470885, -0.89487344) * go_0(0.0, -1.0); result += mat4(-0.122259885, 0.11445877, 0.06666907, 0.1869428, -0.1553992, -0.1658741, 0.2988138, -0.57746625, -0.34609964, 0.11169158, -0.41877756, 0.38075635, 0.21293911, 0.09640372, -0.12754214, -0.08026104) * go_0(0.0, 0.0); result += mat4(0.15128808, 0.050087795, 0.09219755, -0.18080945, 0.0044571217, -0.046019405, -0.1289922, 0.20305426, 0.19601224, 0.04667917, 0.17465587, 0.027672665, 0.18441725, 0.06845396, 0.11288585, -0.23283863) * go_0(0.0, 1.0); result += mat4(-0.072962, -0.06639447, 0.049347494, -0.1386401, 0.10396071, 0.08187777, -0.04280746, 0.07390891, 0.06628344, 0.037797406, 0.021885803, -0.013147403, 0.22376558, 0.36243078, 0.12874891, -0.0023783944) * go_0(1.0, -1.0); result += mat4(0.074945286, 0.16045591, -0.11798349, 0.12910712, 0.054760084, -0.095626175, -0.047832094, 0.03493912, 0.11817307, 0.037452437, -0.14301221, -0.027356789, -0.052390423, 0.11373512, 0.07686775, 0.010008694) * go_0(1.0, 0.0); result += mat4(-0.023999173, -0.091900624, 0.02388157, 0.03173873, 0.0065633506, -0.033716757, -0.1198324, 0.12057766, 0.026465805, -0.07517131, -0.07760598, 0.060463097, 0.07345541, 0.046037503, 0.21101558, -0.26785463) * go_0(1.0, 1.0); result += mat4(0.15544604, -0.03902825, 0.04630384, -0.25173616, -0.0691359, 0.07476507, 0.009071253, 0.089964196, -0.26539803, -0.3958477, -0.22155671, 0.20735882, -0.105860494, -0.003996804, -0.044815883, 0.39544627) * go_1(-1.0, -1.0); result += mat4(0.6169709, 0.23717614, -0.37884676, -0.7484867, 0.020169826, -0.30718836, 1.0965588, -0.20711036, -0.39149985, -0.06843563, -0.06522909, 0.103805855, 0.03265825, -0.15137726, 0.12837899, -0.01294922) * go_1(-1.0, 0.0); result += mat4(-0.23638196, -0.4560866, -0.11948684, -0.1464144, 0.10690008, 0.007835961, 0.11864342, -0.13101323, -0.16509797, 0.075027354, 0.08122998, 0.13451207, 0.0011890623, 0.052157886, 0.08372405, -0.07085038) * go_1(-1.0, 1.0); result += mat4(-0.21997726, -0.16488647, -0.0291317, 0.17997476, 0.1493211, 0.027494298, 0.0034613227, -0.3207727, 0.18699001, 0.14728633, -0.042895135, -0.07612043, 0.125076, -0.14714554, -0.03480009, -0.22753975) * go_1(0.0, -1.0); result += mat4(-0.5342686, -0.7426105, -0.38294584, 0.42549992, 0.46053204, 0.7867879, 0.106234804, -0.041163098, 0.5198579, -0.5219404, 0.14809476, -0.41802374, 0.06810794, -0.15122683, -0.047409, 0.13178343) * go_1(0.0, 0.0); result += mat4(-0.50428164, 0.18220626, 0.35510704, -0.081787474, 0.03155813, 0.019284263, 0.0032388573, -0.20513348, -0.05385551, 0.17803182, -0.26206362, 0.2870375, 0.008557827, 0.08401449, -0.027598893, -0.010791235) * go_1(0.0, 1.0); result += mat4(0.16657415, 0.067647465, 0.093076974, -0.14438486, -0.10017002, 0.0022367141, 0.03250936, -0.052794546, -0.009178676, -0.019673595, -0.0016697067, -0.15424626, -0.112123474, -0.11079971, 0.011987111, -0.11747758) * go_1(1.0, -1.0); result += mat4(-0.023021797, -0.058703423, -0.037978355, -0.062433913, -0.13130441, 0.048656322, 0.056839373, 0.109036915, -0.07823158, 0.14785293, 0.058555078, -0.11679035, -0.14002073, 0.07395252, 0.098268874, -0.06710464) * go_1(1.0, 0.0); result += mat4(0.14906375, 0.030001195, -0.10338215, 0.0662968, -0.161953, -0.13682815, 0.09563142, 0.009514228, -0.009491218, 0.06737101, -0.1393389, 0.15231515, -0.073147796, 0.00767062, 0.028675212, 0.014213088) * go_1(1.0, 1.0); result += vec4(0.018736731, -0.0026039074, 0.050130025, -0.055364225); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(S)-Conv-4x3x3x8 //!HOOK MAIN //!BIND conv2d_2_tf //!SAVE conv2d_last_tf //!WIDTH conv2d_2_tf.w //!HEIGHT conv2d_2_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max(-(conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.019100675, -0.014241565, 0.004667036, -0.03865062, 0.106731094, 0.026099661, 0.014594411, -0.011881356, 0.0040967264, -0.004626336, 0.006469508, 0.010875305, -0.033909045, -0.085905954, 0.07861378, 0.019452631) * go_0(-1.0, -1.0); result += mat4(0.20777655, -0.060354974, 0.0023840065, -0.064121604, -0.17397617, 0.019293457, -0.09707183, 0.080641985, 0.01025124, -0.017382381, 0.008661793, -0.010995665, 0.21943407, -0.115574986, 0.14471593, -0.068836235) * go_0(-1.0, 0.0); result += mat4(0.057942886, -0.06311754, 0.2253396, -0.04159292, -0.020731755, 0.007877151, 0.041525815, 0.025278691, 0.03041967, -0.025137542, 0.024364179, -0.024543528, 0.029438615, -0.015506873, 0.081686, -0.07812221) * go_0(-1.0, 1.0); result += mat4(0.054237515, 0.0676094, -0.0047708177, 0.0043467237, -0.10032304, -0.020498628, 0.04240586, 0.07272254, 0.0784221, 0.017945962, -0.022310399, -0.013134622, 0.015638694, -0.10001543, 0.1043031, 0.05898838) * go_0(0.0, -1.0); result += mat4(-0.021652509, 0.35796642, 0.059497777, 0.23948468, 0.15454951, -0.10017235, -0.19072174, -0.44812536, -0.03974552, 0.04529369, 0.22207436, 0.026222564, -0.09705454, 0.5623026, -0.3354105, -0.017278556) * go_0(0.0, 0.0); result += mat4(-0.053682446, -0.03411237, -0.09399936, 0.15128824, -0.07463, -0.042020727, 0.0031783928, 0.13481957, -0.07731454, 0.044114403, -0.23085599, 0.060444202, -0.15015422, 0.0018040676, -0.18684982, 0.2812511) * go_0(0.0, 1.0); result += mat4(0.0029329916, 0.001596018, 0.0007512241, 0.016544111, -0.04876942, -0.05272409, 0.037884697, 0.049948208, 0.015518177, 0.11368592, -0.03815777, -0.013149978, -0.027638039, 0.107719295, -0.04115787, 0.02745414) * go_0(1.0, -1.0); result += mat4(0.016691081, 0.010204119, 0.04078854, 0.01613337, 0.03325829, 0.0114824055, -0.017286912, -0.07284126, -0.110984206, -0.21041764, 0.0089543555, 0.18986733, 0.01537506, -0.2059135, 0.029074017, 0.013117443) * go_0(1.0, 0.0); result += mat4(0.013965926, 0.029871881, 0.0034499036, -0.011343668, 0.022120327, -0.0068748263, 0.009324342, -0.039081004, 0.08032371, 0.050809264, 0.035050742, -0.2032847, 0.06305391, -0.021958945, 0.038569167, -0.22465245) * go_0(1.0, 1.0); result += mat4(0.046307724, -0.012419472, 0.007673863, -0.042344846, 0.011042414, 0.016994251, -0.018166406, -0.016955731, -0.13240299, 0.01768431, -0.027607648, 0.0699927, -0.02840628, 0.004414203, 0.0049618417, 0.011084679) * go_1(-1.0, -1.0); result += mat4(-0.119954154, -0.007455482, -0.031108133, -0.009946449, 0.0077065965, 0.01660345, 0.032943666, 0.016376585, 0.10273124, 0.1556573, -0.24643841, 0.107307844, -0.068235755, 0.0561896, -0.0104672015, 0.042693343) * go_1(-1.0, 0.0); result += mat4(-0.01634601, 0.04195375, -0.10401894, 0.047641944, -0.034602515, -0.0034419263, -0.010457858, 0.015194475, -0.03962551, -0.030031368, 0.16036317, 0.019283568, -0.05877721, 0.016504882, -0.15523468, 0.018161612) * go_1(-1.0, 1.0); result += mat4(-0.08083991, 0.0024665035, -0.049373373, 0.030371357, 0.0113322195, -0.014676956, 0.011646689, -0.01142667, 0.124930486, 0.06625774, -0.045840867, -0.009693036, -0.012649251, -0.07388084, 0.008790075, 0.0013844534) * go_1(0.0, -1.0); result += mat4(-0.33941835, -0.2763476, -0.118311435, -0.063535266, 0.20936015, 0.13731301, 0.13443594, 0.07464433, 0.059650812, -0.36973104, 0.16444235, -0.37082872, 0.06432777, -0.18283032, -0.044489607, -0.13895285) * go_1(0.0, 0.0); result += mat4(0.13533665, 0.08268915, -0.03675727, -0.14348659, 0.0186255, -0.05051692, 0.056702953, 0.0061717895, 0.047663026, -0.088188455, 0.23254345, -0.014015464, 0.08400204, -0.0073777726, 0.2202068, -0.12366078) * go_1(0.0, 1.0); result += mat4(0.04361004, 0.046543695, 0.0064863074, -0.03358146, -0.022602187, 0.018138997, -0.011071864, 0.010244091, -0.019814799, -0.17250171, 0.040823266, -0.040131986, 0.010125854, 0.020660749, 0.0020435036, -0.010819304) * go_1(1.0, -1.0); result += mat4(-0.004810193, -0.11286074, 0.051985834, 0.04788631, -0.023950428, 0.036145125, -0.038203828, 0.052401308, 0.022986965, 0.26420745, -0.06076917, -0.09252999, 0.03164547, 0.15652153, -0.037934, -0.0035418556) * go_1(1.0, 0.0); result += mat4(0.03358366, -0.005219482, 0.007060882, -0.06569114, -0.02941682, 0.00966056, -0.0153679885, 0.019905418, -0.107232265, -0.03405676, -0.044340115, 0.26892832, -0.04723829, -0.02589829, 0.004563232, 0.19318114) * go_1(1.0, 1.0); result += vec4(-0.00346731, -0.0046263863, -0.004627155, -0.0057769152); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(S)-Depth-to-Space //!HOOK MAIN //!BIND MAIN //!BIND conv2d_last_tf //!SAVE MAIN //!WIDTH conv2d_last_tf.w 2 * //!HEIGHT conv2d_last_tf.h 2 * //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * vec4 hook() { vec2 f0 = fract(conv2d_last_tf_pos * conv2d_last_tf_size); ivec2 i0 = ivec2(f0 * vec2(2.0)); float c0 = conv2d_last_tf_tex((vec2(0.5) - f0) * conv2d_last_tf_pt + conv2d_last_tf_pos)[i0.y * 2 + i0.x]; float c1 = c0; float c2 = c1; float c3 = c2; return vec4(c0, c1, c2, c3) + MAIN_tex(MAIN_pos); } ================================================ FILE: app/src/main/assets/shaders/Anime4K_Upscale_CNN_x2_VL.glsl ================================================ // MIT License // Copyright (c) 2019-2021 bloc97 // All rights reserved. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x3 //!HOOK MAIN //!BIND MAIN //!SAVE conv2d_tf //!WIDTH MAIN.w //!HEIGHT MAIN.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (MAIN_texOff(vec2(x_off, y_off))) vec4 hook() { vec4 result = mat4(0.3053028, -0.037464816, 0.113983095, 0.12537485, -0.18630321, 0.084269725, -0.01351514, -0.20190673, -0.12298384, -0.037622184, -0.070214555, -0.19367279, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, -1.0); result += mat4(-0.41849324, 0.099702746, -0.04276645, -0.047299717, 0.20074473, 0.14217933, 0.15571699, 0.19553481, 0.21868695, -0.053848714, 0.016413521, 0.14117444, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 0.0); result += mat4(0.030540446, -0.052293833, 0.0715466, -0.31160545, 0.07808315, -0.16860045, 0.032828577, -0.2955024, -0.110374965, 0.04043687, -0.014024628, 0.058699366, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 1.0); result += mat4(-0.10727635, 0.054200135, 0.20853694, 0.21086875, 0.122690216, -0.091823794, 0.310609, -0.01738923, -0.0013488946, 0.10835534, -0.077265196, 0.086751856, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, -1.0); result += mat4(-0.77150255, 0.40530515, -0.41257596, -0.14367618, 0.46888494, 0.2650122, -0.934199, 0.40476102, 0.32293493, 0.20251967, 0.19891106, -0.29698747, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 0.0); result += mat4(-0.12505147, -0.41904053, -0.065798186, 0.34075752, 0.026240354, -0.2977496, 0.032647505, -0.003566783, 0.10290523, -0.23417123, -0.06014203, 0.094735645, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 1.0); result += mat4(0.11207838, -0.04062474, 0.023897955, 0.08605987, -0.020888371, 0.045541205, -0.07231824, -0.25884083, -0.11796847, -0.002691391, 0.0050435597, 0.02756291, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, -1.0); result += mat4(0.4615728, 0.041790638, 0.08971143, 0.20213957, -0.38537467, 0.19938901, 0.08594364, -0.08621994, -0.08163473, -0.133266, -0.09561729, -0.014209637, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 0.0); result += mat4(0.0787417, -0.0483673, 0.07621572, -0.060169693, -0.013465177, -0.17152289, 0.02515561, 0.17675288, -0.05173998, 0.10768042, -0.029858522, -0.013957215, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 1.0); result += vec4(0.0072128535, -0.05658625, 0.052939568, -0.1760861); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x3 //!HOOK MAIN //!BIND MAIN //!SAVE conv2d_tf1 //!WIDTH MAIN.w //!HEIGHT MAIN.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (MAIN_texOff(vec2(x_off, y_off))) vec4 hook() { vec4 result = mat4(-0.112743355, 0.0422517, 0.21350034, -0.0967133, 0.16265953, 0.0022497, 0.015078242, 0.08204187, 0.035236806, -0.0468228, -0.09464228, -0.001864949, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, -1.0); result += mat4(0.25631642, -0.41485596, -0.16662048, 0.13201024, 0.057921384, 0.2240005, -0.30038536, -0.08305622, 0.2228756, 0.32263795, 0.10608189, -0.18616734, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 0.0); result += mat4(0.08997524, 0.11516871, 0.19212262, -0.035154644, 0.11612274, -0.04056247, 0.14974374, 0.029173585, -0.07629641, -0.14353512, 0.041081246, 0.20230265, 0.0, 0.0, 0.0, 0.0) * go_0(-1.0, 1.0); result += mat4(0.2262286, 0.055954933, -0.14499907, 0.17314723, 0.16590612, -0.06688698, -0.11118816, -0.012938116, -0.043101817, 0.026133137, 0.2958395, 0.06543993, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, -1.0); result += mat4(-0.07311521, -0.3041244, -0.47978505, -0.6350967, -0.17432262, 0.34965977, 0.25399777, -0.16590433, -0.49957857, 0.0549526, -0.40869385, -0.08780993, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 0.0); result += mat4(-0.3014447, -0.00021343959, -0.14953177, 0.028001398, -0.14931908, -0.14910097, -0.13287953, -0.45026535, 0.17378895, 0.024704922, -0.027308129, -0.10292025, 0.0, 0.0, 0.0, 0.0) * go_0(0.0, 1.0); result += mat4(-0.06732655, -0.13119644, 0.066014715, 0.081011154, -0.15154321, 0.2407805, 0.07733481, 0.12312706, 0.1741804, 0.008495716, -0.14125362, -0.043644864, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, -1.0); result += mat4(0.11465958, 0.42001364, 0.011069392, 0.3203028, -0.058801666, -0.37830314, -0.030540617, 0.2245139, -0.11310525, -0.14845212, 0.19957744, 0.25789997, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 0.0); result += mat4(-0.16037206, 0.21326372, 0.020099448, 0.018666709, 0.122083254, -0.16033986, -0.10725163, 0.2556128, 0.1650688, -0.10475823, 0.048623525, -0.103755645, 0.0, 0.0, 0.0, 0.0) * go_0(1.0, 1.0); result += vec4(0.007717166, -0.027800834, 0.0795002, 0.0053199283); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_tf //!BIND conv2d_tf1 //!SAVE conv2d_1_tf //!WIDTH conv2d_tf.w //!HEIGHT conv2d_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.0056740534, -0.21186607, -0.18014967, 0.118979976, -0.0015611284, -0.07708486, 0.060131397, 0.11653345, 0.027150517, 0.10837246, 0.08583816, -0.14032431, 0.017552888, 0.0035846964, 0.03980114, 0.064649396) * go_0(-1.0, -1.0); result += mat4(-0.03289318, -0.12004539, 0.26514888, -0.15079662, 0.04214227, -0.027273783, -0.027950313, 0.19614808, 0.18510003, -0.10346252, -0.029836183, 0.09174428, -0.0088710375, -0.18273513, 0.06601674, 0.009983851) * go_0(-1.0, 0.0); result += mat4(0.08476211, 0.043996535, 0.056711517, 0.009976895, 0.07039107, -0.024862664, -0.059921104, 0.046850603, 0.04983447, 0.04863198, 0.21777405, -0.0576961, 0.045321796, -0.0060038245, 0.096396215, -0.10842004) * go_0(-1.0, 1.0); result += mat4(-0.15746164, 0.041757874, 0.035169285, -0.1734288, -0.24219254, -0.13318908, 0.2272079, -0.02902605, 0.07750601, -0.1467191, -0.12296749, -0.07533314, -0.07073083, 0.17909113, 0.04789308, 0.17245363) * go_0(0.0, -1.0); result += mat4(0.057547905, 0.1464685, -0.33115456, -0.26956198, -0.26298407, -0.059824817, 0.022509675, -0.09251868, 0.36277944, -0.2072429, 0.21095088, -0.45492023, 0.07428653, 0.1593302, -0.2945834, 0.12825087) * go_0(0.0, 0.0); result += mat4(-0.1318458, 0.27804148, 0.037600737, 0.12047866, 0.0065036337, 0.0017241207, 0.060497303, -0.14786585, -0.15149063, 0.02731698, 0.048886403, -0.0025970868, -0.026979815, 0.07348884, 0.015636757, -0.107966796) * go_0(0.0, 1.0); result += mat4(-0.079988025, -0.01626299, 0.06517438, 0.086406484, -0.1484504, 0.070595, 0.20620634, 0.09713373, -0.13620836, 0.012067949, -0.00068703433, -0.038030174, 0.22300471, -0.0012400965, -0.014827909, -0.08927486) * go_0(1.0, -1.0); result += mat4(0.15634936, 0.052028038, 0.038081627, 0.12720168, 0.07342066, -0.04318368, -0.0065998454, 0.12109317, -0.45398173, 0.03666754, -0.17773737, 0.038516667, -0.13009632, -0.007457001, -0.013938809, 0.09776142) * go_0(1.0, 0.0); result += mat4(0.029636936, 0.12864171, 0.11347291, -0.11812842, -0.0870342, 0.035678383, 0.050338242, 0.045754932, -0.07072752, 0.010447726, 0.039642975, -0.08795004, -0.1191525, 0.00967509, 0.13485421, -0.053204738) * go_0(1.0, 1.0); result += mat4(-0.011072695, -0.09613245, -0.09094804, 0.028029291, -0.04031162, 0.15690295, 0.25094184, -0.21776834, 0.06524669, 0.06412185, -0.052852992, -0.08097702, -0.039127756, 0.036357917, 0.104585476, 0.25095442) * go_1(-1.0, -1.0); result += mat4(-0.08328618, -0.006246033, 0.099708706, -0.014916097, 0.17727195, 0.4369228, 0.14760216, 0.06707674, 0.025167737, -0.022487842, -0.038962565, 0.15380669, 0.08125089, 0.09844594, 0.33538374, -0.003161368) * go_1(-1.0, 0.0); result += mat4(-0.0128195705, -0.05475118, -0.037705053, -0.0012077648, -0.17425515, 0.091487505, -0.12909423, 0.0074876705, 0.13438368, 5.778033e-05, 0.04563314, -0.12185897, -0.053612474, -0.049824294, -0.12851205, 0.12856449) * go_1(-1.0, 1.0); result += mat4(-0.025741795, 0.01867236, -0.00027440622, 0.10502768, 0.27042285, -0.14947751, 0.11143123, 0.2575913, -0.07414089, -0.33919522, -0.13194235, -0.20088726, 0.23121537, -0.08197353, 0.06693911, 0.015411386) * go_1(0.0, -1.0); result += mat4(0.09143717, 0.22842278, 0.06501074, -0.20009698, -0.042117566, -0.23452093, -0.074082755, -0.10612558, 0.077631965, 0.08343657, -0.07657599, -0.43297377, 0.7092466, -0.16272525, 0.17222248, -0.056038965) * go_1(0.0, 0.0); result += mat4(0.081200436, 0.046752565, 0.028254949, 0.18820632, 0.096592255, 0.05896745, 0.14845169, 0.034777895, 0.07195204, -0.1908046, -0.015341971, 0.02606145, -0.010377239, 0.0755547, -0.15285216, 0.047916733) * go_1(0.0, 1.0); result += mat4(-0.06825636, -0.049540907, -0.024328846, 0.03506251, 0.2060094, 0.054119263, -0.06671269, 0.052428722, 0.055792283, -0.14336903, -0.03180757, 0.013760968, -0.037398104, -0.06880077, -0.023608573, 0.0360965) * go_1(1.0, -1.0); result += mat4(-0.16937497, -0.30156836, 0.0021435453, 0.025772978, -0.17990975, 0.046133514, -0.32447076, -0.083382785, -0.081322014, -0.022132374, -0.05319431, 0.11794733, 0.08943906, 0.12927428, 0.105764806, -0.051034793) * go_1(1.0, 0.0); result += mat4(-0.011012306, 0.047636557, 0.050260928, 0.051847618, 0.010985655, -0.13752967, 0.023869954, 0.07011459, -0.18244945, 0.07239806, -0.013638856, -0.026982805, 0.11395993, -0.031304818, -0.08714153, 0.077115685) * go_1(1.0, 1.0); result += mat4(0.08707592, 0.2265186, 0.13363098, -0.039588258, -0.029561255, 0.019238092, 0.024606103, -0.0019022018, -0.062285982, -0.0629511, -0.03753033, 0.109805316, 0.016018672, -0.08284564, -0.04092752, -0.030386891) * go_2(-1.0, -1.0); result += mat4(0.0016500859, 0.01616536, -0.099148355, 0.24161765, 0.028064307, -0.028680569, 0.054400917, -0.1978921, -0.08584302, -0.096797146, -0.06546965, -0.09342837, 0.030265866, 0.07057579, -0.02080932, 0.053178705) * go_2(-1.0, 0.0); result += mat4(-0.030304352, 0.047440585, -0.04248429, 0.08568772, -0.051317703, 0.036739342, 0.00865767, -0.018183297, -0.07335176, 0.025001721, -0.068509035, 0.1814819, -0.09756565, -0.024179723, -0.05959287, 0.0352454) * go_2(-1.0, 1.0); result += mat4(0.023015196, -0.022870664, -0.12028372, -0.111095205, 0.11065281, -0.19900022, -0.24012049, -0.017028643, -0.13484617, 0.050107025, 0.10741765, 0.037951697, 0.013090438, -0.0010045726, -0.029447839, -0.1859787) * go_2(0.0, -1.0); result += mat4(0.17922719, -0.24138594, -0.44595388, -0.032014426, 0.06897096, 0.07125395, 0.1944457, -0.035794795, -0.24022278, -0.13230884, -0.1277025, 0.21229011, -0.12249393, 0.06141907, 0.2687936, -0.26896995) * go_2(0.0, 0.0); result += mat4(0.0397242, -0.30710965, 0.28815824, -0.06642567, -0.07588877, -0.019552408, 0.0057806037, 0.11465521, 0.03560534, -0.10640553, 0.023589289, -0.16667193, 0.02066607, -0.01026633, -0.02655378, 0.082493655) * go_2(0.0, 1.0); result += mat4(-0.007902949, -0.08501038, -0.029395591, -0.07072227, -0.01800967, -0.14564751, -0.08372804, -0.049974415, 0.1756957, -0.02042449, -0.04413007, -0.016873527, -0.2385717, -0.001741017, 0.08298281, -0.019873247) * go_2(1.0, -1.0); result += mat4(-0.01803727, 0.0642893, 0.21513617, 0.066888265, -0.042107955, -0.123470366, 0.045296013, -0.11958806, 0.48208967, -0.027188249, 0.12136116, 0.05246265, 0.13522038, -0.016297493, 0.028486907, -0.059840377) * go_2(1.0, 0.0); result += mat4(-0.1373251, -0.11281026, -0.06418318, 0.08444032, 0.062874556, -0.009133875, -0.049571835, -0.042995855, 0.12483249, -0.025967957, -0.11202483, 0.09862257, 0.099986054, 0.009230306, -0.09042664, 0.046612263) * go_2(1.0, 1.0); result += mat4(0.03203309, 0.106030256, 0.045741174, -0.020529225, -0.028610658, -0.055219248, -0.21404657, 0.07746393, -0.059359375, 0.0033258004, -0.0054513607, 0.06856653, 0.18043655, -0.119936846, -0.05639265, -0.10240379) * go_3(-1.0, -1.0); result += mat4(-0.0004331875, 0.10426754, -0.008130048, 0.012795991, -0.14372933, -0.40797862, 0.105197415, -0.0041354536, -0.079792455, 0.0914027, 0.012418237, -0.11449173, 0.020261409, -0.14681602, -0.13355242, 0.18290488) * go_3(-1.0, 0.0); result += mat4(0.052306626, 0.010864275, -0.072627716, -0.009773121, 0.09484167, -0.09631301, 0.14896165, -0.21220942, -0.11994051, -0.002957136, -0.118194886, 0.08661347, 0.10005298, -0.029620873, 0.101668894, 0.0242806) * go_3(-1.0, 1.0); result += mat4(-0.055188183, -0.06322889, 0.12994595, 0.03140751, -0.092755616, 0.04239107, 0.18460171, 0.08471877, 0.014203371, 0.13608724, 0.035351243, -0.07883493, -0.10067456, 0.14417742, 0.0054235114, 0.100745104) * go_3(0.0, -1.0); result += mat4(-0.043811034, -0.16055201, -0.11927185, 0.20517266, 0.16734722, 0.27720267, 0.1205665, 0.045803893, -0.07874647, 0.06764307, -0.11157022, 0.080770165, -0.044105835, -0.03276538, -0.10945451, 0.100562036) * go_3(0.0, 0.0); result += mat4(-0.044731796, -0.12854387, -0.061937924, -0.21604767, -0.036132332, -0.024353411, -0.16718283, 0.14903957, -0.11620588, 0.14563644, 0.23363836, 0.08400659, 0.15248756, -0.1424437, 0.112882614, -0.04096889) * go_3(0.0, 1.0); result += mat4(-0.0486021, -0.05714939, 0.042517707, -0.06106919, -0.12970918, -0.071898215, -0.044727243, -0.026308542, 0.05687118, -0.0394057, -0.109454155, -0.0021216893, 0.018588595, 0.08061093, 0.0500373, -0.0034918839) * go_3(1.0, -1.0); result += mat4(0.11269324, -0.17924047, -0.12965205, -0.07287767, -0.015830642, -0.044497102, 0.20014328, -0.14054494, 0.1232692, 0.2395109, 0.14093149, 0.03518561, -0.14088139, -0.09045081, -0.07283352, 0.053434785) * go_3(1.0, 0.0); result += mat4(0.020512339, 0.026349569, -0.06666101, 0.05554806, -0.03044066, 0.26656216, 0.019155584, -0.12118906, 0.087923005, -0.1716557, 0.050843164, 0.037432503, -0.030232614, 0.030457936, 0.04232163, -0.066400655) * go_3(1.0, 1.0); result += vec4(-0.0216415, 0.09015036, -0.030761974, -0.26541537); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_tf //!BIND conv2d_tf1 //!SAVE conv2d_1_tf1 //!WIDTH conv2d_tf.w //!HEIGHT conv2d_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.04688368, 0.13853125, 0.1714716, -0.03034447, -0.08090605, 0.1225867, 0.17535992, 0.012508419, -0.0010665918, -0.07481546, -0.15541986, 0.0671128, -0.029307734, -0.076674186, 0.03925896, -0.07140553) * go_0(-1.0, -1.0); result += mat4(-0.13273083, 0.062933214, 0.04200143, -0.0080243945, -0.120439716, -0.090192355, -0.022639645, 0.00020024918, -0.11211478, -0.12949537, 0.025783822, 0.009155746, 0.01004339, -0.0661901, 0.10630156, 0.053137038) * go_0(-1.0, 0.0); result += mat4(0.07113487, -0.16011865, -0.10838903, -0.0034704183, 0.110606894, -0.14915739, 0.036511585, -0.003103608, -0.0551775, -0.13140677, 0.05270299, 0.12139221, 0.02226174, 0.008415268, -0.06647426, 0.118130066) * go_0(-1.0, 1.0); result += mat4(-0.045172617, -0.0020388453, -0.27287582, 0.002428232, -0.2833772, 0.13788106, 0.073339015, 0.10666715, 0.08455194, 0.16499293, 0.089058325, 0.008815447, 0.034657538, -0.109856166, -0.11499077, -0.02918854) * go_0(0.0, -1.0); result += mat4(0.07910854, -0.26334837, -0.3246593, -0.08246522, 0.09211476, 0.40793833, -0.09658794, -0.14430091, -0.50632644, 0.087234974, 0.26298127, 0.3687086, 0.06492316, 0.23082961, 0.18233871, -0.09283792) * go_0(0.0, 0.0); result += mat4(-0.022744032, 0.21690565, 0.2694824, -0.12230013, -0.07969618, 0.21595429, -0.034979805, 0.008938489, 0.21289209, -0.446482, -0.042927746, -0.13587558, -0.032581557, -0.07182814, -0.054092336, -0.009542036) * go_0(0.0, 1.0); result += mat4(-0.0034912943, -0.080354184, -0.08577375, -0.1521193, 0.09809233, 0.034529503, -0.100664355, 0.008191219, -0.014303411, -0.02862216, -0.18669915, -0.12384598, 0.046499267, 0.093707144, 0.10661308, 0.15079576) * go_0(1.0, -1.0); result += mat4(-0.031025652, -0.0384342, 0.14258307, 0.25531343, 0.0075049917, -0.03966595, 0.062381975, 0.19593526, -0.2868182, 0.03162008, -0.4391041, -0.524017, -0.034463473, -0.0066741486, -0.24586639, 0.10521736) * go_0(1.0, 0.0); result += mat4(-0.07452321, -0.0227877, -0.025402244, 0.115727395, -0.039511252, -0.07785703, -0.013689458, 0.0066024344, -0.052957747, 0.011206241, -0.0021671024, 0.077190824, -0.11709912, 0.046635598, 0.123751156, -0.03712064) * go_0(1.0, 1.0); result += mat4(0.055411004, -0.0020031065, 0.06685547, -0.018829947, -0.06378933, -0.18389674, -0.0023551763, 0.0670314, 0.13038594, 0.0601923, -0.03035789, -0.019537423, -0.014483204, -0.056800704, 0.08663347, -0.106859975) * go_1(-1.0, -1.0); result += mat4(-0.06603686, 0.07360526, -0.0072026253, -0.06778907, -0.039178446, 0.012397263, -0.13482279, 0.05745685, -0.055182382, -0.10545766, 0.003857615, 0.041947857, -0.15239377, 0.041826613, 0.058879383, -0.0042669442) * go_1(-1.0, 0.0); result += mat4(-0.0697229, -0.010702144, -0.032265816, 0.013317131, 0.105028264, 0.21032134, 0.06845646, -0.018358687, 0.064568676, 0.08437135, -0.000723181, 0.1324007, 0.05527932, -0.049871888, -0.10125047, -0.005040889) * go_1(-1.0, 1.0); result += mat4(-0.006467578, -0.05120533, -0.011780779, -0.011742203, -0.34242442, -0.020819988, 0.17381702, -0.059836414, -0.028882682, 0.23210457, 0.16579404, -0.03708216, -0.23541835, -0.03290251, 0.029319672, 0.26189178) * go_1(0.0, -1.0); result += mat4(-0.30955994, -0.06408282, -0.16872866, 0.10767772, -0.041430887, 0.051697977, 0.12523535, -0.060389146, 0.026289431, 0.06359533, 0.13526368, 0.2479901, -0.3263977, 0.10216362, -0.0030894123, 0.046437826) * go_1(0.0, 0.0); result += mat4(0.10061438, -0.17047118, -0.21593021, -0.023389054, -0.17507865, -0.30822313, -0.22044766, 0.16078933, 0.07099252, -0.11573018, 0.24712858, -0.0659458, -0.037504572, -0.12297423, 0.03342632, -0.058119852) * go_1(0.0, 1.0); result += mat4(-0.020957774, -0.0224927, 0.04069268, -0.07911167, 0.074009344, 0.065916434, 0.008222278, 0.11625076, -0.25299504, 0.03357169, -0.021988, 0.015821831, -0.0021187372, -0.030700417, -0.004374924, 0.027358979) * go_1(1.0, -1.0); result += mat4(0.06549052, -0.048067164, 0.05489091, -0.28851983, 0.13378961, 0.026875904, -0.09877994, -0.19947459, -0.1274035, -0.022928834, -0.26344195, -0.025870804, 0.022505255, 0.0070861108, 0.121051334, -0.025964163) * go_1(1.0, 0.0); result += mat4(0.059426542, -0.0327433, 0.2313695, -0.07046268, 0.20479666, 0.027021704, 0.2564928, -0.11689885, -0.07407976, -0.019611249, 0.093463086, -0.121553615, 0.035009407, -0.008135333, -0.075931996, 0.047803063) * go_1(1.0, 1.0); result += mat4(-0.059434246, -0.1652242, -0.124611154, 0.04743711, 0.10530296, -0.13869187, -0.036534663, -0.035206333, 0.06067593, 0.06126907, 0.120151915, -0.06722673, 0.008103894, 0.037225723, -0.007520425, 0.065720856) * go_2(-1.0, -1.0); result += mat4(-3.6759695e-05, -0.036789574, 0.013370567, -0.037871476, -0.013454664, 0.15086569, 0.10164699, 0.057703357, -0.12871023, 0.12827681, -0.055057358, -0.040753044, -0.0142621, 0.08563361, -0.04615499, -0.03130452) * go_2(-1.0, 0.0); result += mat4(-0.117965914, 0.09056485, 0.07272314, 0.009695964, -0.11331058, 0.07467256, -0.08291521, 0.00937355, -0.04097737, 0.07752905, -0.017335521, -0.12539999, 0.039462104, -0.0007037007, 0.06034812, -0.09497377) * go_2(-1.0, 1.0); result += mat4(0.20828065, 0.0400099, 0.047638226, -0.046423353, -0.026133502, 0.098207295, 0.056742374, 0.017029466, -0.058164768, -0.046973787, -0.17328712, -0.0012984811, 0.050085854, 0.11296557, 0.12639083, 0.058543045) * go_2(0.0, -1.0); result += mat4(-0.098907426, 0.22031747, 0.101559944, 0.06616554, 0.026110496, 0.56487054, 0.23754556, -0.07540935, 0.31768414, -0.47653618, 0.015073956, -0.33731326, 0.087285936, -0.24593173, -0.26141426, 0.15003823) * go_2(0.0, 0.0); result += mat4(0.046026446, -0.13767281, 0.064847544, 0.07717139, 0.08544123, -0.11092969, 0.072325274, 0.010849038, -0.3055905, 0.66436774, 0.1434729, 0.0494463, 0.07115603, 0.083811216, 0.020431712, 0.06537088) * go_2(0.0, 1.0); result += mat4(-0.15532711, 0.030139687, 0.040853374, 0.11089222, -0.08150315, -0.015851755, -0.06787692, 0.096075505, -0.011956207, -0.0017758606, 0.1277494, 0.16156575, -0.038588695, -0.0626418, -0.041797023, -0.19467135) * go_2(1.0, -1.0); result += mat4(0.12917455, 0.017410474, -0.20125067, -0.08040003, -0.13494664, 0.17789102, -0.19909395, 0.08441434, 0.078570575, -0.06330619, 0.23767303, 0.5442659, -0.009227878, -0.021818208, 0.14318731, -0.09042824) * go_2(1.0, 0.0); result += mat4(0.097801, 0.09345441, 0.17846581, -0.14773296, 0.06536365, 0.07642184, -0.011880635, 0.02086135, 0.013336972, -0.053295113, -0.13410404, 0.027241753, 0.087728985, -0.044033397, -0.13098569, 0.009423933) * go_2(1.0, 1.0); result += mat4(-0.02488427, 0.0134966355, -0.0075000813, 0.07272353, 0.015842725, 0.13765687, 0.028079558, -0.08384948, -0.06666623, -0.023220664, 0.025091043, -0.055167805, -0.18826278, 0.04423603, 0.13499942, 0.059128854) * go_3(-1.0, -1.0); result += mat4(0.01935146, -0.030980906, -0.031569187, -0.0036869382, 0.036753897, 0.118464164, 0.15871695, -0.09842428, 0.023324292, 0.071796335, -0.07869346, -0.10751301, -0.2588698, 0.064011686, 0.17386378, -0.039197855) * go_3(-1.0, 0.0); result += mat4(0.08590827, 0.005497696, -0.026512025, 0.015661815, 0.1102415, -0.08268483, -0.0032903247, 0.10049029, -0.008157236, -0.035823178, -0.017570151, -0.081716835, -0.3531045, 0.010005245, 0.017141227, -0.016376914) * go_3(-1.0, 1.0); result += mat4(-0.16617337, -0.007689783, 0.00954665, 0.07117733, -0.001669262, -0.012331606, 0.051613946, 0.062780835, 0.06123557, -0.20243123, -0.19181818, 0.032895602, 0.19760677, 0.004464939, 0.12754539, -0.27360034) * go_3(0.0, -1.0); result += mat4(0.15006685, -0.083587274, -0.03215495, -0.16992462, -0.011944293, 0.058361508, -0.088097006, 0.023880545, -0.04168166, -0.06960282, -0.092672385, -0.057278465, 0.23540072, -0.1721208, -0.018213503, -0.23494521) * go_3(0.0, 0.0); result += mat4(-0.124885194, 0.1905868, 0.11108704, 0.03163991, 0.11383064, 0.101223364, 0.069428995, -0.14298953, -0.07609092, 0.13704266, -0.07749446, -0.0005389336, -0.04617235, 0.18011934, 0.08350316, 0.09416366) * go_3(0.0, 1.0); result += mat4(0.073356606, 0.067966126, -0.21285574, 0.0782625, -0.0034364646, -0.032581426, -0.05538558, -0.1317288, 0.14552782, -0.1132393, 0.13063973, -0.00833602, 0.0026844777, 0.028135289, -0.02536825, -0.028372496) * go_3(1.0, -1.0); result += mat4(-0.318728, 0.07862527, -0.12176221, 0.35010242, -0.029198067, 0.016302662, 0.17667587, 0.12605923, 0.1556697, -0.06061443, 0.05843511, 0.10891248, 0.01267106, -0.018492714, -0.15945031, -0.050723754) * go_3(1.0, 0.0); result += mat4(-0.21555941, -0.016813517, -0.084676236, -0.07545412, -0.14518794, -0.014592766, -0.2446481, 0.0530632, 0.0847341, 0.12342537, -0.028644923, 0.083479315, -0.04179012, 0.0025225023, 0.16006976, -0.026940256) * go_3(1.0, 1.0); result += vec4(-0.060742114, -0.037577342, 0.055704296, 0.03134311); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_1_tf //!BIND conv2d_1_tf1 //!SAVE conv2d_2_tf //!WIDTH conv2d_1_tf.w //!HEIGHT conv2d_1_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_1_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_1_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.13129333, -0.022117995, -0.009753253, 0.020439912, 0.044090994, -0.0916335, 0.0036765633, -0.11719207, -0.06413809, 0.04079378, -0.00085516454, -0.06306388, -0.12660664, -0.054126263, -0.005513979, 0.06364538) * go_0(-1.0, -1.0); result += mat4(-0.028422508, 0.23270117, -0.28674677, -0.10820166, 0.024321957, -0.0811145, -0.07290707, -0.02125165, -0.064260505, 0.052076746, -0.009654081, 0.08363882, -0.02037171, 0.15006389, 0.121593125, -0.011237004) * go_0(-1.0, 0.0); result += mat4(-0.14672333, 0.015381624, 0.1028172, -0.041823238, 0.0072677187, -0.042953942, 0.06426537, -0.0938381, -0.05990813, -0.04599802, -0.11264726, -0.027826328, -0.058160868, 0.10747306, -0.07327458, 0.07998872) * go_0(-1.0, 1.0); result += mat4(-0.08702181, -0.03750975, -0.045659006, 0.04488332, 0.09102003, 0.066556975, -0.04353586, 0.08994567, -0.13561495, -0.10653702, 0.006989605, 0.028230097, 0.07177144, 0.2938447, -0.00943923, 0.022120917) * go_0(0.0, -1.0); result += mat4(-0.1801194, -0.11119162, 0.1977298, -0.247902, -0.16654298, -0.07423158, 0.114130594, 0.0014401592, 0.006954727, -0.09810646, -0.051310766, 0.19487657, 0.2545855, -0.06328558, -0.04617056, 0.09444692) * go_0(0.0, 0.0); result += mat4(0.011378825, 0.16044368, 0.017211074, 0.14472178, 0.032992378, -0.008925819, 0.035120245, -0.012409223, 0.074333005, 0.1178002, -0.128956, -0.13624239, -0.2791275, 0.21457297, -0.1476131, 0.04874687) * go_0(0.0, 1.0); result += mat4(-0.03491764, -0.061763793, 0.05779039, 0.0054837577, -0.023937583, 0.08281698, 0.032306053, -0.014566218, 0.12738499, -0.0132100545, -0.051833414, 0.0057818824, 0.012158851, -0.20231532, -0.0043795826, 0.10285843) * go_0(1.0, -1.0); result += mat4(-0.22269921, -0.15135509, -0.039143335, 0.033390045, 0.06770212, -0.14538582, -0.08011057, 0.03796648, -0.025913516, 0.13925864, 0.18309896, 0.012709204, -0.24912506, 0.3217706, 0.0394195, 0.017977878) * go_0(1.0, 0.0); result += mat4(0.00080196525, 0.059145816, 0.05720508, 0.0056548906, 0.005168018, 0.09938438, 0.0200503, -0.05516137, 0.061309986, -0.019621318, -0.1541441, 0.019540716, 0.030571707, -0.09054893, 0.032851614, -0.27210873) * go_0(1.0, 1.0); result += mat4(0.27061436, -0.114008114, -0.0020118617, -0.1656827, 0.09770587, 0.029897455, -0.03307522, -0.04661818, 0.033011347, 0.18498488, -0.05162084, 0.087471776, -0.24665618, -0.12538423, -0.08123797, -0.010210389) * go_1(-1.0, -1.0); result += mat4(0.075188264, 0.0020608555, 0.18558815, 0.041179713, 0.11232638, 0.05507779, -0.19599183, 0.027942855, 0.06199144, 0.22141005, -0.06121163, 0.014993597, 0.24105869, -0.019737717, -0.112485714, 0.0157406) * go_1(-1.0, 0.0); result += mat4(0.09425698, 0.0207658, 0.12074599, 0.009430481, 0.11889248, -0.025782838, 0.0034711843, 0.05113582, 0.012531833, -0.0018606635, -0.09137569, 0.018120576, 0.4051155, 0.02222076, -0.16001017, 0.10981527) * go_1(-1.0, 1.0); result += mat4(-0.03582557, 0.014994796, -6.4688604e-05, 0.24618183, -0.11697727, 0.24388117, 0.038502026, -0.3511993, 0.101741396, -0.10748137, 0.035059888, -0.017535849, 0.09450039, 0.06541661, 0.12149035, 0.28798738) * go_1(0.0, -1.0); result += mat4(-0.27143848, 0.017990451, -0.69144464, 0.037944376, -0.04551905, 0.09263134, 0.4259611, -0.14107811, -0.10641847, 0.23065196, 0.040813655, -0.07789163, 0.3087666, 0.08190437, 0.16409059, -0.06455426) * go_1(0.0, 0.0); result += mat4(-0.08290655, -0.35286915, -0.18082355, -0.32229406, 0.1608227, 0.030915622, 0.09207708, 0.02655054, 0.039464593, 0.026095424, 0.052584656, 0.033881903, -0.01751319, -0.0011676399, 0.04002607, 0.1630013) * go_1(0.0, 1.0); result += mat4(-0.012021132, 0.12163766, -0.07410629, -0.06879096, 0.017859738, -0.039261997, -0.028677614, -0.23610398, -0.15963873, -0.0006119958, 0.11275506, 0.0082659265, 0.05677582, 0.08676638, -0.08669759, -0.10475464) * go_1(1.0, -1.0); result += mat4(0.12792721, 0.06888765, 0.31803077, 0.26002547, -0.067599155, -0.011822328, -0.2589909, -0.30024147, 0.11076704, 0.15200609, -0.018180368, -0.19146141, 0.22298847, 0.059484895, 0.034478076, 0.15610938) * go_1(1.0, 0.0); result += mat4(0.0870121, -0.016420847, -0.011579898, 0.097182855, -0.120095566, -0.06843338, -0.043460473, -0.060684606, -0.027540063, -0.008499213, 0.033570655, -0.06866259, 0.01429712, -0.07424434, 0.0009466247, 0.09142678) * go_1(1.0, 1.0); result += mat4(-0.03781424, 0.04587032, 0.03744051, 0.02712279, -0.051038064, 0.0669144, -0.02640278, 0.12384894, -0.0022533627, -0.010022036, 0.07536463, -0.030489929, 0.09418577, 0.155089, -0.011290433, -0.02102941) * go_2(-1.0, -1.0); result += mat4(-0.0053278613, -0.07160643, 0.039028414, 0.04123311, -0.10693177, -0.1170874, 0.07230816, -0.033255517, -0.119176835, 0.0786526, -0.11880206, -0.11354601, -0.037539184, 0.14404313, 0.069760695, 0.024738638) * go_2(-1.0, 0.0); result += mat4(0.03413808, -0.006487654, 0.10006853, 0.22228058, -0.13796462, -0.14042488, 0.04017443, -0.031790894, -0.06673143, 0.009888688, 0.08831443, -0.0045771743, -0.028375361, -0.04704813, 0.07128581, -0.07012518) * go_2(-1.0, 1.0); result += mat4(-0.06954315, -0.23728988, -0.14192343, -0.08236467, -0.2552115, 0.04102959, -0.06355397, -0.08340241, 0.17617856, 0.20281969, -0.16249381, 0.10843737, -0.04392261, -0.08587206, 0.053069845, -0.15482199) * go_2(0.0, -1.0); result += mat4(0.124981806, 0.12828638, -0.061472785, -0.20108232, -0.14905351, -0.40766275, -0.35427195, -0.13183996, 0.09307428, -0.07697028, 0.06702549, -0.22656697, 0.019868268, -0.19361132, 0.08784669, 0.20249842) * go_2(0.0, 0.0); result += mat4(-0.004661343, -0.09333453, -0.24876262, -0.07906779, 0.110697776, -0.37069768, -0.042212646, -0.0046135853, -0.2254257, -0.023392014, 0.031476703, -0.045574382, -0.12675518, -0.076056994, -0.08228006, -0.040303517) * go_2(0.0, 1.0); result += mat4(0.16182694, 0.0512523, 0.051189836, 0.048962783, -0.05156489, -0.17987493, -0.012037288, 0.06953726, -0.09458492, 0.1610021, -0.004063283, -0.032922342, 0.08995396, 0.1939926, -0.018710036, -0.08153231) * go_2(1.0, -1.0); result += mat4(-0.064830944, 0.06121252, -0.18886387, -0.12976822, -0.031117212, 0.12219633, 0.19070715, 0.12495262, -0.11994464, -0.24687837, -0.08425294, -0.016920334, -0.13286817, -0.3260188, -0.11776061, 0.1651019) * go_2(1.0, 0.0); result += mat4(-0.17652592, 0.002499805, -0.030541016, -0.01393431, 0.031418208, 0.08209422, 0.12430871, 0.4387016, -0.108871914, -0.09041422, 0.031226631, -0.1638517, 0.20756467, 0.014476537, -0.012701195, -0.03440563) * go_2(1.0, 1.0); result += mat4(0.005320072, -0.0032291536, -0.017209187, 0.031944863, -0.2479921, -0.24433962, -0.13832912, 0.07835928, -0.17707248, 0.028202811, -0.19121435, 0.164587, 0.123152815, 0.0050288937, 0.084104605, -0.0380019) * go_3(-1.0, -1.0); result += mat4(0.16008669, -0.018608516, -0.013778938, 0.033447385, -0.01242472, -0.070916265, 0.026909694, -0.07318777, 0.15158044, 0.12047607, -0.1709358, 0.2031767, 0.0025611701, -0.21457459, 0.2791286, 0.10159932) * go_3(-1.0, 0.0); result += mat4(0.14320926, 0.020023825, -0.0484187, 0.011563084, -0.2640472, -0.013056275, 0.004234292, -0.095376395, 0.28363484, -0.0058227647, -0.0777649, 0.05238444, 0.41757923, -0.07081097, 0.012567031, -0.13029522) * go_3(-1.0, 1.0); result += mat4(0.07266207, 0.042793367, -0.08212271, -0.23401663, -0.19457819, 0.4191269, -0.03095442, 0.15339781, -0.28451788, 0.09316364, 0.10231693, -0.22844811, 0.111623526, 0.120017685, 0.18777381, 0.014420896) * go_3(0.0, -1.0); result += mat4(0.15037206, -0.29763284, 0.2601235, 0.0193363, 0.13686465, 0.009907918, -0.37781665, 0.04916627, 0.14114739, 0.5043813, 0.0447959, -0.029427614, 0.041768756, 0.27211213, 0.14163221, 0.086162075) * go_3(0.0, 0.0); result += mat4(0.19159287, 0.21363218, 0.15053211, 0.08992885, 0.100828275, 0.09379921, 0.030783929, 0.11664482, -0.059145752, -0.19400764, -0.09351283, -0.016430443, -0.12910964, -0.067078374, 0.11760082, 0.121194765) * go_3(0.0, 1.0); result += mat4(-0.055059325, 0.09299572, 0.06848913, 0.06334532, -0.1476285, 0.111801244, -0.033960916, 0.06474366, -0.04952303, 0.27885208, -0.052447475, 0.09226763, -0.15024844, -0.0033919013, 0.013498364, 0.09135676) * go_3(1.0, -1.0); result += mat4(-0.017010042, -0.122343406, -0.19097193, -0.27957183, -0.18206005, 0.102321096, 0.22794476, 0.0439245, -0.23710132, -0.08070259, 0.17377135, 0.23811814, 0.17799385, 0.049567625, 0.1470908, 0.07329385) * go_3(1.0, 0.0); result += mat4(0.0038071256, 0.19454515, -0.01222965, -0.07390379, -0.0532754, 0.03942833, 0.123840906, 0.023459576, -0.0658742, -0.023957543, -0.14682837, 0.1221027, -0.010986398, -0.066184506, 0.03026491, -0.0638446) * go_3(1.0, 1.0); result += vec4(-0.06427697, -0.00039365015, 0.011889719, 0.060232002); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_1_tf //!BIND conv2d_1_tf1 //!SAVE conv2d_2_tf1 //!WIDTH conv2d_1_tf.w //!HEIGHT conv2d_1_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_1_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_1_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_1_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.012110923, 0.07818654, 0.07964548, 0.11885079, -0.07694473, -0.01378252, 0.006632789, -0.12876098, 0.0069211307, 0.022278586, 0.069553085, 0.16569804, -0.11123615, 0.06125189, -0.11232848, 0.1559266) * go_0(-1.0, -1.0); result += mat4(-0.3261174, -0.25586754, 0.21129315, 0.3135101, 0.1509055, 0.0044283345, 0.024674175, -0.08000473, 0.01213029, 0.09093019, 0.04942677, 0.09806723, -0.16454464, -0.14433062, -0.058094524, -0.060819894) * go_0(-1.0, 0.0); result += mat4(0.023174008, 0.02858724, 0.07685972, 0.036857616, -0.10415571, 0.10241035, -0.01893166, 0.02065923, 0.058356714, 0.096426114, -0.03772327, -0.1529002, 0.13740575, -0.048291504, -0.06152548, -0.15199897) * go_0(-1.0, 1.0); result += mat4(0.029300174, -0.13222043, 0.0139825605, -0.02274408, 0.062944874, 0.028447356, 0.05960515, 0.034447193, 0.03133432, -0.019283533, -0.024591971, -0.0043914663, 0.15245225, 0.006851478, -0.051783554, 0.17453748) * go_0(0.0, -1.0); result += mat4(-0.09125915, 0.081739366, 0.01196335, 0.23130219, -0.22557035, -0.13537665, 0.0022028848, -0.043430023, 0.22759882, 0.07920754, -0.027986467, -0.14051494, -0.19557038, -0.03585936, -0.4258294, -0.03856216) * go_0(0.0, 0.0); result += mat4(0.18511422, -0.09368415, 0.1551229, 0.04322566, -0.023400841, -0.02261204, 0.15129441, -0.007954805, -0.10739125, 0.019459398, 0.013128325, 0.018073296, 0.20886365, -0.20662378, -0.03814699, -0.09272838) * go_0(0.0, 1.0); result += mat4(-0.027352437, -0.039882626, 0.12598103, -0.093930446, 0.030846786, -0.09325075, -0.009084744, -0.024584265, 0.07159868, 0.14162529, 0.19019091, 0.058855128, -0.09880401, -0.01843218, 0.14753596, -0.2449532) * go_0(1.0, -1.0); result += mat4(0.06565521, 0.09150168, -0.08654865, 0.0829788, -0.07596146, -0.01815166, -0.08786775, -0.03477514, 0.20538878, -0.012766377, 0.020719538, 0.088188395, -0.034300096, 0.29972988, -0.20005241, 0.018425167) * go_0(1.0, 0.0); result += mat4(0.11713916, 0.024167519, 0.05167596, -0.0027117804, -0.016994188, 0.048177514, -0.012556207, 0.010979094, 0.09098878, 0.028514355, 0.06063336, -0.06624107, 0.012754856, 0.013208708, -0.061374772, -0.0025992664) * go_0(1.0, 1.0); result += mat4(-0.09053513, 0.03183455, 0.017340872, 0.12934409, -0.022161964, -0.0015361432, -0.049972344, -0.12763855, 0.12779881, -0.04697911, 0.018968226, -0.119873665, 0.05462772, -0.13919477, -0.10226718, -0.2540179) * go_1(-1.0, -1.0); result += mat4(-0.29912186, -0.09291771, 0.050926663, 0.49361777, 0.21372582, 0.076717265, -0.058968987, -0.1572678, 0.3194591, -0.120582424, 0.03942037, 0.023128232, 0.24321598, 0.07046334, -0.21204855, -0.648296) * go_1(-1.0, 0.0); result += mat4(0.05366883, -0.020366706, 0.020979457, -0.06893884, 0.04837168, 0.017253762, 0.008874203, -0.020785445, -0.20425391, 0.060179923, 0.046167206, 0.09863377, -0.14381303, 0.038928367, -0.06590863, -0.18408588) * go_1(-1.0, 1.0); result += mat4(0.07099762, 0.2029403, -0.033945918, 0.15202214, 0.0901113, -0.27336198, -0.17693861, -0.16206753, -0.17642029, 0.09400492, -0.11165698, -0.07863893, -0.16306102, -0.056210615, 0.22173557, 0.013508989) * go_1(0.0, -1.0); result += mat4(0.08541511, -0.27093616, -0.35273993, -0.48919773, 0.038383547, -0.16013749, 0.012996215, -0.03434873, 0.07024113, -0.28971404, 0.10623425, -0.0019642068, -0.062374946, 0.3291145, 0.22468035, -0.42971882) * go_1(0.0, 0.0); result += mat4(0.020427933, 0.15062793, 0.08308975, -0.025095072, 0.030093266, -0.09649862, -0.03382388, -0.0016017791, 0.105402954, 0.020693144, -0.051065, 0.07704679, 0.02864139, -0.00135146, 0.03762216, 0.029277142) * go_1(0.0, 1.0); result += mat4(0.01700994, 0.12214317, 0.06749582, 0.07354159, -0.093085855, -0.065021954, 0.010773045, -0.00095128635, -0.045384295, -0.072611265, -0.043900184, 0.049471326, 0.029131187, 0.03180158, -0.13313527, 0.05280797) * go_1(1.0, -1.0); result += mat4(0.14751251, -0.15087761, 0.09932281, -0.099232934, -0.062390897, 0.112391844, -0.09159478, 0.15856399, 0.034708973, 0.01819943, -0.02730164, -0.13562973, -0.05687333, -0.0114601655, 0.07025971, 0.02496533) * go_1(1.0, 0.0); result += mat4(-0.0117268525, -0.026162883, 0.07481553, 0.13420302, 0.029870516, 0.07405776, -0.06379041, 0.09631234, -0.07754842, 0.035888605, 0.0034764851, -0.040771756, -0.092022054, -0.034230903, -0.02281844, -0.0028173258) * go_1(1.0, 1.0); result += mat4(-0.059846643, 0.016772347, -0.02287152, 0.07036337, -0.024946844, 0.09826078, -0.068491876, 0.20852126, 0.073890835, -0.058288682, 0.013093785, -0.05776076, 0.0516503, 0.052794468, 0.10837015, 0.038539834) * go_2(-1.0, -1.0); result += mat4(-0.16391893, -0.008062687, -0.35022175, 0.2510062, -0.15820411, 0.048403125, 0.024878092, 0.037888516, -0.035924178, -0.068953894, -0.025386479, 0.24405715, -0.018495679, -0.051277515, 0.14754932, -0.031538483) * go_2(-1.0, 0.0); result += mat4(-0.038429607, -0.047140498, -0.018157095, -0.029318782, -0.04094171, -0.11870087, 0.11214255, 0.07142628, 0.021007229, -0.005681072, 0.1662777, 0.10829575, 0.112268396, 0.03567479, -0.06738845, 0.0032037434) * go_2(-1.0, 1.0); result += mat4(-0.032217573, 0.2102397, -0.20617546, -0.07920811, 0.12918773, 0.054486286, -0.13656865, 0.05806265, 0.01963165, 0.049910642, 0.15538268, 0.10724465, -0.09697837, -0.03070673, -0.0071386313, -0.11899626) * go_2(0.0, -1.0); result += mat4(0.130827, 0.0051715383, -0.07212691, 0.45726067, 0.2773031, 0.2973666, 0.3951691, 0.01333662, -0.14561643, 0.04508669, 0.121690124, 0.13326228, -0.22579186, 0.058161184, 0.09281702, -0.00079749606) * go_2(0.0, 0.0); result += mat4(-0.00771113, 0.09912341, -0.41895548, -0.06705759, 0.029148718, 0.052991726, 0.18665347, -0.031787418, 0.23053595, 0.09444956, 0.10691037, -0.06325714, -0.05335701, 0.1917427, -0.0065284846, 0.032622546) * go_2(0.0, 1.0); result += mat4(-0.056801565, -0.019131258, -0.0939022, -0.08130343, -0.11051993, 0.0035269214, -0.047361933, -0.0543875, 0.10854369, 0.06445185, 0.016828364, -0.022595318, 0.1450623, 0.033027507, -0.020425137, 0.16169788) * go_2(1.0, -1.0); result += mat4(-0.08747717, 0.07770065, 0.018155783, 0.07160794, 0.09860347, -0.04329888, -0.0043579484, -0.2014418, -0.060260013, 0.0036374568, -0.17566042, -0.2268221, 0.001273691, -0.2609373, -0.19417606, -0.04102927) * go_2(1.0, 0.0); result += mat4(-0.086845055, -0.114253804, -0.13433142, -0.025941795, -0.0155711295, -0.13578776, 0.12059696, -0.08760523, -0.0057348222, 0.12164273, 0.07270617, -0.06352636, 0.08894258, 0.04140841, 0.1230304, -0.030357126) * go_2(1.0, 1.0); result += mat4(0.03320213, 0.015911903, -0.06288296, -0.121976145, 0.2713457, 0.13913193, -0.092420585, 0.105714336, 0.10294281, -0.04591945, -0.11767934, 0.032249406, -0.06506192, -0.04639334, 0.08137017, -0.031746846) * go_3(-1.0, -1.0); result += mat4(0.13717805, 0.0071242675, -0.077256985, -0.14974317, -0.08467893, -0.20126395, -0.06240603, 0.09554399, -0.075844854, 0.28380412, 0.046030026, 0.053188596, 0.50943077, 0.1179795, 0.32203588, -0.06712207) * go_3(-1.0, 0.0); result += mat4(-0.18528835, 0.0016975187, -0.0041140947, 0.11234392, -0.34049067, -0.056880493, -0.04325441, 0.09905571, 0.10978758, 0.009608353, -0.10801905, -0.04071131, -0.09096832, -0.12350487, 0.011801418, 0.22521795) * go_3(-1.0, 1.0); result += mat4(0.040283076, -0.034117915, -0.026142653, -0.06058959, 0.12511659, 0.4131219, 0.59190845, 0.39758852, 0.16032091, -0.5975032, -0.14516282, 0.115154505, 0.03874097, 0.18462797, 0.22934213, 0.05285643) * go_3(0.0, -1.0); result += mat4(-0.17804009, 0.33769128, -0.14572927, -0.029545018, 0.3897, -0.055615567, 0.15232995, 0.48788264, -0.21422523, 0.03397293, 0.0337794, -0.19830915, -0.022457365, -0.35096076, 0.42616987, -0.19268763) * go_3(0.0, 0.0); result += mat4(-0.13191561, -0.18337126, 0.017879983, -0.070472844, -0.09409196, -0.025770849, -0.060219247, 0.10869267, -0.17341033, -0.09199785, -0.0667796, -0.093538545, -0.21300837, 0.030474098, -0.04540468, 0.041321553) * go_3(0.0, 1.0); result += mat4(-0.0998177, -0.08669185, -0.0090886615, 0.0021083376, 0.08900095, 0.5062186, 0.45537788, 0.029077586, -0.1001008, -0.0077697043, -0.0096318, 0.11706454, 0.07401959, -0.00650215, 0.06092762, 0.037442297) * go_3(1.0, -1.0); result += mat4(-0.18500404, 0.0024998419, -0.11761331, -0.026825588, 0.27255726, 0.093010515, 0.3281413, -0.051473666, -0.050259475, -0.17258662, -0.23394547, 0.104795866, 0.035074063, -0.061560635, 0.05975411, -0.094255395) * go_3(1.0, 0.0); result += mat4(-0.023440497, -0.021479638, 0.0036277648, 0.004972212, 0.02416659, -0.09856867, -0.03971455, -0.27094853, 0.026615402, -0.0047890246, -0.13755885, 0.16591635, -0.0016293586, 0.133207, 0.047790572, 0.029041538) * go_3(1.0, 1.0); result += vec4(-0.0063728676, -0.029053684, -0.052831043, 0.006475641); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_2_tf //!BIND conv2d_2_tf1 //!SAVE conv2d_3_tf //!WIDTH conv2d_2_tf.w //!HEIGHT conv2d_2_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_2_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_2_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.0431447, 0.047972627, 0.09522898, 0.19048582, 0.0015511789, 0.1182684, -0.065335006, 0.061233886, -0.02451869, 0.065670215, -0.015341636, 0.06836347, 0.10215459, 0.17516296, 0.0857072, 0.072732896) * go_0(-1.0, -1.0); result += mat4(0.10117189, 0.049022958, -0.016017418, -0.12119866, 0.089112304, 0.016286526, -0.025251161, 0.03239003, -0.0783818, -0.086096615, -0.13673106, -0.15934734, -0.51308054, -0.061430074, -0.16208844, 0.2227776) * go_0(-1.0, 0.0); result += mat4(-0.011567444, 0.025550444, -0.018439503, -0.015003767, 0.11606929, -0.11613111, -0.040906087, -0.015202219, 0.03932618, -0.1106059, 0.03703376, 0.018548314, -0.12761284, -0.038109995, -0.23577367, 0.20272344) * go_0(-1.0, 1.0); result += mat4(0.025444161, -0.075270735, 0.10999789, 0.16305386, 0.016178958, -0.074034974, 0.1177035, -0.077481024, -0.047774278, -0.029782977, 0.23137823, -0.2389453, 0.033015423, -0.10381626, -0.16437943, 0.20906886) * go_0(0.0, -1.0); result += mat4(-0.098473966, 0.11013442, -0.18486807, 0.1907086, -0.17564997, -0.08509439, -0.42472756, -0.17446618, 0.3440862, 0.12719585, -0.12213955, -0.02246555, 0.18982963, 0.20809166, -0.36067408, 0.51116616) * go_0(0.0, 0.0); result += mat4(-0.019805575, 0.07812505, 0.061653323, -0.08379226, 0.026396899, 0.009063019, -0.10845824, 0.0827647, 0.045301896, -0.07748021, -0.07435832, 0.14860612, -0.077515624, 0.010588131, -0.22704287, 0.26849246) * go_0(0.0, 1.0); result += mat4(-0.02884339, -0.09512523, -0.038564682, 0.08862835, 0.041666254, -0.10532901, 0.040582962, -0.10063983, -0.15736029, -0.03644334, -0.005061672, 0.04302295, -0.046482194, -0.05262547, 0.05110866, 0.03204655) * go_0(1.0, -1.0); result += mat4(-0.005932702, 0.033263832, 0.0044865874, -0.02328917, 0.056534443, -0.14084046, 0.022353357, 0.015087431, -0.2734596, -0.026544483, 0.06297078, 0.11277746, 0.06127936, 0.02466357, -0.04970561, 0.02098484) * go_0(1.0, 0.0); result += mat4(0.013603583, 0.036264602, 0.10985147, 0.01532773, -0.09012781, 0.1132652, -0.17016481, 0.025332611, -0.077462606, 0.02990799, -0.10627784, -0.006231141, -0.089164406, -0.051507175, -0.043900985, 0.09049239) * go_0(1.0, 1.0); result += mat4(-0.15391691, 0.1915742, 0.014101639, -0.022153432, 0.06291936, -0.017871676, -0.016763045, -0.14741553, -0.011252563, -0.20720159, -0.030648025, -0.0142307645, 0.010291614, -0.09243969, -0.052940153, 0.0061574522) * go_1(-1.0, -1.0); result += mat4(0.032283742, 0.030768922, 0.1070225, -0.027818602, 0.10032608, 0.0061178426, -0.03561339, -0.26687133, 0.14369439, -0.11362691, -0.08980895, 0.066520914, 0.33414948, 0.006998835, 0.09193012, -0.2857383) * go_1(-1.0, 0.0); result += mat4(-0.059588976, -0.02046844, -0.042585023, 0.031939838, 0.12796514, -0.06155685, 0.03540324, 0.009929082, -0.0039611827, 0.10790477, 0.049435645, -0.083034374, 0.23874004, -0.07460337, -0.020173345, -0.2006587) * go_1(-1.0, 1.0); result += mat4(-0.13217632, 0.052319963, -0.026713084, -0.0051368694, -0.10380872, -0.28659084, 0.0044393227, 0.005174543, -0.05092618, -0.07092548, -0.027397033, -0.01609789, 0.13699281, -0.14706929, 0.17737861, -0.23746766) * go_1(0.0, -1.0); result += mat4(0.19268502, 0.14133929, -0.1305119, -0.4034132, 0.057504695, -0.24550998, -0.081932545, 0.45489246, -0.29331785, 0.19625074, 0.063166246, 0.15158689, 0.6715147, -0.4610189, 0.08921431, 0.17761138) * go_1(0.0, 0.0); result += mat4(0.044718128, -0.011809122, 0.024131307, -0.30093196, -0.05607289, 0.047759805, 0.004210022, 0.098192796, 0.030430846, 0.008207501, 0.12266905, -0.10549182, 0.11584339, -0.091016166, -0.08635591, -0.13889709) * go_1(0.0, 1.0); result += mat4(-0.19226642, 0.07147627, -0.14759602, 0.4041079, 0.0744628, -0.19612685, 0.1498252, -0.06273549, 0.017959936, 0.10858338, -0.14985329, 0.062042814, -0.13240446, -0.24362786, 0.113626175, -0.15332204) * go_1(1.0, -1.0); result += mat4(0.08383099, -0.13935047, -0.25981048, 0.16491203, 0.07513876, -0.28346774, 0.19722275, -0.044425573, 0.020889329, -0.22140723, 0.025403097, -0.09183192, 0.014202567, -0.18666178, 0.062913105, -0.047674105) * go_1(1.0, 0.0); result += mat4(-0.1862771, 0.25878942, -0.043018065, 0.22144824, 0.016088247, 0.12113542, -0.11965952, -0.01587184, 0.07830932, -0.16069177, 0.13421321, 0.018718706, 0.09548377, 0.018543294, 0.013614677, -0.1054485) * go_1(1.0, 1.0); result += mat4(-0.2121733, -0.015635416, 0.027564054, -0.085904464, 0.064805664, -0.070543915, 0.08966146, -0.06359783, 0.01131311, 0.046913184, -0.09809833, -0.092063695, -0.087217696, 0.012411829, 0.0045399712, 0.027389864) * go_2(-1.0, -1.0); result += mat4(-0.19307798, 0.09449126, 0.084036835, 0.30262446, 0.011706106, 0.029800637, 0.04612629, 0.006186647, 0.11228541, 0.055147965, 0.17659879, -0.023410015, 0.19965266, -0.06684007, -0.081968054, -0.052410994) * go_2(-1.0, 0.0); result += mat4(-0.058564443, 0.08252549, 0.058217794, 0.0864448, -0.25663558, 0.080260284, -0.0010294432, 0.05830051, -0.07684524, 0.1820709, 0.04438993, 0.019178499, -0.12425012, -0.04596089, -0.010032888, -0.0012803525) * go_2(-1.0, 1.0); result += mat4(-0.43352658, 0.15262963, 0.25620222, 0.22428556, 0.09667152, 0.0037820593, -0.07951691, -0.11553085, 0.12982155, 0.17988266, -0.14283511, 0.074744284, 0.03604327, 0.00452661, -0.12865154, -0.020020623) * go_2(0.0, -1.0); result += mat4(0.06850602, -0.18057181, 0.2093389, -0.07333886, 0.28406742, -0.048766967, 0.18114483, 0.47292945, -0.2340266, -0.06862712, 0.28263155, 0.3150323, -0.054724697, -0.16958356, 0.27928987, -0.19666018) * go_2(0.0, 0.0); result += mat4(0.03281329, 0.0038649621, -0.07108877, 0.10791149, 0.15235375, -0.3083721, 0.168294, 0.10379698, 0.029038485, 0.16282903, 0.04483725, -0.018684763, 0.108186625, 0.027885616, -0.019351846, 0.1623065) * go_2(0.0, 1.0); result += mat4(-0.110499054, 0.31347123, 0.030852, 0.01631416, -0.1466389, 0.080429435, -0.18689284, 0.10667815, 0.20645237, -0.18004708, -0.10570413, -0.15435064, -0.019000605, -3.126077e-06, 0.037761535, -0.015040956) * go_2(1.0, -1.0); result += mat4(-0.023364332, -0.023399066, 0.2712722, 0.049637552, -0.10222765, -0.2698945, 0.20991959, 0.04921932, 0.21510898, -0.0751939, -0.19781734, -0.28162366, -0.041881047, 0.0065111094, -0.04102195, 0.0982682) * go_2(1.0, 0.0); result += mat4(-0.032176614, 0.019144032, -0.08985387, 0.091637276, 0.1012352, 0.0003583357, 0.07897295, -0.09531175, -0.001155058, 0.074372366, -0.026186578, 0.07283374, 0.06052053, 0.009307753, -0.03874333, -0.06228009) * go_2(1.0, 1.0); result += mat4(-0.022224072, -0.15717922, -0.1406057, -0.05941157, -0.028769474, -0.21226564, -0.036570027, 0.22266355, 0.14120889, 0.014577123, 0.10216447, 0.018429281, 0.056729726, -0.055834044, 0.058146577, -0.11999068) * go_3(-1.0, -1.0); result += mat4(0.009995364, -0.020045493, -0.0057422677, 0.0643022, 0.016475432, -0.030856136, 0.042140726, 0.15077904, -0.32955253, 0.0694449, 0.17931722, 0.3439302, -0.12484157, -0.10958869, -0.15755124, -0.09755644) * go_3(-1.0, 0.0); result += mat4(-0.008314924, 0.07704758, 0.043228816, -0.08110893, 0.099286236, -0.053224478, 0.22877018, -0.189486, -0.00798416, 0.018341504, 0.10734141, 0.0752633, -0.042524844, -0.086395286, 0.14299925, 0.026488977) * go_3(-1.0, 1.0); result += mat4(-0.052531082, 0.19139186, 0.12205995, -0.2573172, 0.15157184, 0.0073150825, 0.089774385, 0.06604469, -0.16528498, -0.002511137, 0.14287429, -0.07819732, 0.025014274, 0.15338829, 0.0761692, -0.02803716) * go_3(0.0, -1.0); result += mat4(-0.21000335, 0.15277153, 0.08546171, 0.2816124, -0.16559112, -0.11068559, 0.47053605, -0.009787771, -0.0013089112, -0.06985127, 0.44743782, 0.25142467, -0.32670796, 0.044035822, -0.12545367, -0.2996084) * go_3(0.0, 0.0); result += mat4(-0.11526387, 0.15654811, 0.099616654, 0.15473685, 0.21278231, 0.046207245, 0.117993094, -0.26825273, -0.12539764, 0.14013724, 0.17357737, -0.05387817, 0.076738276, -0.13339446, 0.15005626, -0.2108176) * go_3(0.0, 1.0); result += mat4(-0.0008846504, -0.05998622, -0.028892396, 0.04784136, 0.0104263965, 0.10899508, -0.073364735, 0.077516064, -0.074248806, -0.21749993, -0.26203, 0.041161157, 0.09366407, -0.026498007, 0.0122177545, 0.03892727) * go_3(1.0, -1.0); result += mat4(0.04349908, 0.13671173, 0.2242545, -0.028021423, -0.03802222, 0.0052366396, -0.010709643, 0.031290106, 0.06291333, -0.024909683, -0.15439379, -0.04502091, 0.2062182, -0.5983536, -0.09670497, -0.38446042) * go_3(1.0, 0.0); result += mat4(-0.008962513, 0.13044207, 0.04964221, 0.012250417, 0.012129821, 0.019985713, -0.06421885, 0.009168735, -0.044516414, 0.071368866, -0.006634213, 0.06497366, 0.08578495, -0.10586125, 0.06628038, -0.14006054) * go_3(1.0, 1.0); result += vec4(0.056541316, 0.041788545, -0.036094554, -0.021763096); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_2_tf //!BIND conv2d_2_tf1 //!SAVE conv2d_3_tf1 //!WIDTH conv2d_2_tf.w //!HEIGHT conv2d_2_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_2_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_2_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_2_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.0647927, 0.053666476, -0.14723225, 0.027874574, -0.0003166473, 0.07337155, -0.061972085, -0.012667777, -0.17071614, 0.091927536, -0.051160213, 0.21336353, 0.13854574, 0.09582817, 0.032316446, 0.13838023) * go_0(-1.0, -1.0); result += mat4(-0.0398984, 0.108049214, 0.093780346, -0.022015186, -0.15188989, -0.1381083, 0.2998843, 0.21623154, -0.08862326, 0.025862623, 0.06895634, 0.13529755, 0.06957801, -0.0011681129, 0.105972745, -0.04722446) * go_0(-1.0, 0.0); result += mat4(-0.026321493, -0.04828038, -0.012545767, -0.005490858, -0.054038163, 0.075943105, -0.11526662, 0.022242405, -0.03543104, -0.12451852, -0.14911178, 0.013503498, 0.08773292, 0.09695139, -0.013498657, -0.27424073) * go_0(-1.0, 1.0); result += mat4(0.018575635, -0.11321618, -0.07853153, 0.04104883, 0.0018416744, 0.11579002, 0.03685964, -0.031546146, -0.1755398, 0.23517849, -0.08095411, 0.031999595, -0.18542038, -0.26171613, -0.20567231, -0.05683613) * go_0(0.0, -1.0); result += mat4(0.1538556, 0.21723682, 0.12131733, -0.15308167, 0.103326, -0.006956118, 0.043583486, -0.23811384, -0.103285454, 0.05543916, -0.37894246, 0.32072112, 0.22651967, 0.03516268, 0.34612176, 0.23688535) * go_0(0.0, 0.0); result += mat4(0.040021293, 0.0029912095, 0.04885362, 0.061496444, 0.016926387, -0.118446946, 0.038948335, -0.0934512, -0.25194243, -0.054018084, -0.07149527, 0.017903058, 0.0845516, 0.33802906, 0.11953944, -0.081294954) * go_0(0.0, 1.0); result += mat4(-0.09558082, -0.36974236, -0.07524102, 0.11131445, 0.047626104, 0.12854609, -0.10264962, -0.044669047, -0.05572307, 0.34475142, -0.16806377, -0.0037204176, 0.03400533, -0.04047774, 0.024379745, 0.09056291) * go_0(1.0, -1.0); result += mat4(-0.039392482, 0.2553437, 0.11705501, 0.03219211, 0.073977776, -0.16610906, -0.032796364, -0.054669864, -0.07123178, 0.00079619256, -0.36920992, -0.029054813, 0.12830003, 0.004987549, 0.08724278, -0.029499404) * go_0(1.0, 0.0); result += mat4(0.021272454, -0.063295126, 0.011779576, 0.103093, -0.011095461, 0.027948728, -0.014605259, -0.04723974, -0.05334346, -0.044831257, -0.07296399, -0.03314197, -0.01687865, -0.09261895, -0.06128567, 0.092708185) * go_0(1.0, 1.0); result += mat4(0.0077418387, 0.00871427, 0.060824487, 0.1093608, -0.021077013, -0.057341542, -0.04769576, -0.08144089, 0.0212823, -0.06731425, -0.04134463, -0.0016761447, -0.03402026, 0.036424547, 0.11689576, -0.14946719) * go_1(-1.0, -1.0); result += mat4(0.18536687, 0.020073935, 0.17041959, 0.024790209, 0.08397728, -0.13884324, 0.013950321, -0.055075396, -0.09317963, -0.05723721, -0.060491834, 0.0017911601, -0.109154835, 0.010338362, -0.1982491, -0.21752335) * go_1(-1.0, 0.0); result += mat4(0.031852514, 0.031424347, 0.07817056, 0.07770759, 0.019805199, -0.091223724, 0.11914662, 0.1673029, -0.018734453, 0.16275099, 0.23245652, 0.36139074, -0.1396047, -0.14774057, 0.13756078, -0.123794965) * go_1(-1.0, 1.0); result += mat4(-0.034937833, 0.20777488, 0.10104809, -0.035140667, 0.2536575, 0.010970045, 0.16896339, -0.081219964, -0.062478427, -0.0010431948, -0.027980985, 0.11446318, -0.127309, 0.21002083, 0.044436257, -0.16986957) * go_1(0.0, -1.0); result += mat4(0.06309646, -0.042341243, 0.36642808, 0.18653205, 0.06973023, 0.06315932, -0.323688, 0.25672218, 0.042820994, 0.13792914, -0.12892757, -0.09220378, -0.18939693, 0.03862022, -0.17376114, -0.24673308) * go_1(0.0, 0.0); result += mat4(-0.02130602, -0.35428852, -0.011634983, -3.9823462e-05, 0.110818714, -0.2981158, 0.060209107, 0.012538829, -0.0744833, -0.050204318, -0.12676497, -0.031484153, -0.28799182, 0.22338839, -0.070876874, -0.02102363) * go_1(0.0, 1.0); result += mat4(-0.07929991, 0.014598492, 0.23034762, 0.024872296, 0.07480494, -0.17139243, -0.014421178, 0.056448363, -0.028626937, -0.022152562, 0.044871796, -0.048653606, 0.009350802, 0.019022083, -0.08554845, -0.0922645) * go_1(1.0, -1.0); result += mat4(-0.027405115, 0.1831188, 0.28516722, 0.19882526, 0.27299204, -0.06910511, 0.03244419, -0.0031333128, 0.061055277, -0.114398144, 0.03729459, -0.07840815, -0.37776002, -0.24129418, -0.54815483, -0.2702045) * go_1(1.0, 0.0); result += mat4(0.053723935, 0.13472083, 0.09563273, 0.19009806, -0.18722993, -0.25939655, -0.016197463, -0.067061596, 0.1647598, 0.061905228, 0.06191816, -0.018582113, -0.07218153, 0.11278394, 0.05478068, -0.104871586) * go_1(1.0, 1.0); result += mat4(0.0036616288, -0.045782693, -0.226954, -0.05043515, -0.078096785, -0.036197383, 0.09269631, 0.016823346, -0.0060579977, -0.041455746, 0.09032774, -0.09217121, 0.058089796, 0.060311552, 0.033079024, 0.022586476) * go_2(-1.0, -1.0); result += mat4(0.0436363, -0.079482526, 0.0027447809, 0.039558932, 0.13275702, 6.898711e-05, -0.21961488, -0.11315821, 0.0076181027, -0.025279062, -0.15829584, -0.063141204, 0.062049046, 0.13117202, -0.02435016, 0.109555416) * go_2(-1.0, 0.0); result += mat4(-0.010148116, 0.056620967, -0.015910713, -0.07370375, 0.1529919, 0.005792597, 0.02771225, -0.17027487, 0.096740395, 0.063347995, 0.17823112, 0.054105148, 0.04995114, -0.28613812, 0.06369567, 0.15978208) * go_2(-1.0, 1.0); result += mat4(-0.13688345, 0.16967694, -0.061759472, 0.013682004, -0.1290496, 0.07167547, -0.065592445, -0.17897636, 0.057080988, 0.035630587, 0.09140394, -0.08695068, 0.16807681, 0.014749346, 0.07875138, 0.034913708) * go_2(0.0, -1.0); result += mat4(-0.098915346, -0.31459075, -0.10892429, 0.1557498, -0.19764107, -0.26881596, -0.03589311, 0.45288458, -0.34171388, 0.12675741, 0.18415868, -0.19770056, 0.29025507, -0.15812592, 0.09685835, 0.0027761247) * go_2(0.0, 0.0); result += mat4(0.06425249, -0.01169722, 0.06379363, 0.053835012, -0.07356561, -0.06367294, 0.108630784, -0.14137438, 0.08536725, -0.03209748, 0.07250959, -0.014214082, 0.07170588, -0.25647813, 0.1092683, 0.18791042) * go_2(0.0, 1.0); result += mat4(-0.023783233, 0.14261739, 0.102011986, -0.03633555, -0.05032627, 0.09378387, 0.11764051, 0.1353335, 0.032817088, -0.1352964, -0.00667997, -0.13388929, 0.022861317, 0.0037358075, 0.018605746, -0.0009892831) * go_2(1.0, -1.0); result += mat4(0.22419162, -0.23105696, -0.09900454, -0.15831396, 0.12398773, 0.097933106, -0.13189293, 0.1330756, -0.19673057, -0.037342317, -0.13462654, -0.08974021, 0.030326528, -0.0815862, -0.118352115, 0.009187904) * go_2(1.0, 0.0); result += mat4(-0.012130391, -0.06408448, 0.13710785, -0.06678414, -0.09970725, -0.14895032, -0.02366641, 0.029581001, -0.07101809, 0.09414698, 0.018300869, 0.009139046, -0.0027311493, -0.2359952, -0.011602826, -0.007582444) * go_2(1.0, 1.0); result += mat4(-0.15473361, -0.06868751, -0.030721204, -0.08650113, 0.071349874, -0.08177769, 0.1611948, 0.18305337, -0.0144878505, 0.10975452, -0.026968453, -0.04909913, -0.059665974, 0.056036238, -0.11623168, -0.10584912) * go_3(-1.0, -1.0); result += mat4(-0.096973225, 0.054132458, -0.010600018, 0.089397885, -0.0031138035, 0.037452973, 0.041115325, 0.1924831, 0.14759748, 0.032560788, -0.082884625, 0.0324635, -0.083511285, -0.050381303, 0.025589975, -0.0981257) * go_3(-1.0, 0.0); result += mat4(-0.09183111, 0.034952193, -0.048511654, 0.020719057, 0.1863456, 0.01902738, 0.14455654, -0.008500172, 0.16385981, -0.07806569, -0.031216217, -0.17002788, -0.08882952, 0.07335293, -0.2223089, 0.01706056) * go_3(-1.0, 1.0); result += mat4(-0.08361569, 0.046698716, -0.016646344, 0.09351987, 0.0054158634, -0.13641126, -0.12396605, 0.011380122, 0.040951792, -0.11222528, -0.0031548145, -0.0022303525, 0.0350846, -0.03280425, -0.09972476, -0.113325305) * go_3(0.0, -1.0); result += mat4(-0.19961461, -0.27561286, -0.12783135, -0.062596925, 0.005870981, -0.24796526, 0.18717633, -0.16945636, -0.076396205, -0.08411448, 0.13751988, 0.21014418, -0.008655945, -0.09848541, -0.14536901, -0.2132181) * go_3(0.0, 0.0); result += mat4(0.14118621, 0.20831147, -0.020545695, 0.008340737, 0.016840864, -0.16912372, -0.121718146, 0.15108089, -0.19803092, -0.07827729, -0.047639225, -0.12277847, 0.04974115, -0.09349339, -0.2756667, -0.19581003) * go_3(0.0, 1.0); result += mat4(-0.0036992705, 0.16539848, 0.022026122, 0.07740234, -0.035687633, -0.004568715, 0.017408118, -0.09757294, -0.094941914, -0.3381112, -0.12724453, 0.025583982, -0.18571027, 0.047607586, -0.0704089, -0.055323426) * go_3(1.0, -1.0); result += mat4(0.13821335, 0.028168043, 0.09990671, -0.032266147, -0.067236245, 0.11512147, -0.112986445, -0.10818019, -0.10062181, 0.21276556, 0.01681818, 0.069806606, 0.09628121, 0.06456379, 0.10394843, -0.02343886) * go_3(1.0, 0.0); result += mat4(0.041937463, 0.072631165, 0.045366894, -0.0046993676, 0.03946691, 0.121010706, -0.030089365, -0.007266469, 0.0092267515, 0.14853416, -0.033248078, -0.027284347, -0.10031526, 0.15864117, -0.16782752, -0.18466589) * go_3(1.0, 1.0); result += vec4(0.07722432, -0.025165567, 0.034291282, -0.09902708); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_3_tf //!BIND conv2d_3_tf1 //!SAVE conv2d_4_tf //!WIDTH conv2d_3_tf.w //!HEIGHT conv2d_3_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_3_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_3_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_3_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_3_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.004729794, -0.0124398535, -0.08538641, -0.058604605, 0.008671952, 0.25604513, 0.020800482, 0.24144122, -0.028920606, -0.04705229, 0.030192787, 0.0010597534, 0.017666103, 0.0041322373, 0.20027764, 0.08919112) * go_0(-1.0, -1.0); result += mat4(0.0001626656, 0.05816014, -0.0060765734, 0.08811165, 0.35835367, -0.016291425, -0.56892496, 0.083845764, 0.15026698, -0.15916558, 0.08069463, -0.3931291, -0.0123534845, -0.111639686, -0.14637001, -0.08171439) * go_0(-1.0, 0.0); result += mat4(-0.114976816, 0.023376396, 0.13855027, 0.07438716, -0.069991484, 0.20377779, 0.23929878, -0.040769435, 0.018832395, 0.005638609, -0.091848075, 0.027843866, 0.023744943, -0.06620523, -0.11678267, 0.0844119) * go_0(-1.0, 1.0); result += mat4(0.0035854098, -0.08432094, -0.17799544, -0.10041983, 0.25605857, 0.021009786, 0.030499447, -0.09928291, 0.052178737, -0.08286175, -0.057888374, 0.024606042, 0.046342995, 0.13875343, 0.11279266, 0.19826262) * go_0(0.0, -1.0); result += mat4(-0.016232021, -0.21539623, 0.0936961, 0.021143785, 0.094262615, 0.049040064, 0.40978724, 0.15347758, 0.08884813, -0.24887115, -0.14756748, -0.5020875, 0.112477, 0.1466549, -0.33418837, 0.5769466) * go_0(0.0, 0.0); result += mat4(-0.16832942, -0.07354198, -0.12081261, -0.055348314, 0.39716053, 0.25583258, 0.09870877, 0.2151021, -0.025700683, -0.1801462, -0.04616654, -0.02782245, -0.054461803, -0.00042802413, -0.00163228, -0.004240747) * go_0(0.0, 1.0); result += mat4(-0.05193433, -0.0018198475, -0.17647028, -0.19462106, 0.1538165, 0.054894235, 0.12183955, 0.07340974, -0.0019901982, 0.0357373, -0.07597063, -0.06681543, -0.00090057997, -0.053894397, -0.010301875, -0.16553953) * go_0(1.0, -1.0); result += mat4(-0.30873474, -0.2836045, 0.057037193, -0.5016378, 0.11952749, 0.102353275, 0.2351629, -0.14635189, -0.019398788, -0.08776502, 0.021669978, -0.089918956, -0.2187901, -0.1180891, -0.049789533, -0.16109149) * go_0(1.0, 0.0); result += mat4(-0.078335494, -0.08867304, 0.03349591, -0.1000293, -0.20235832, 0.22917585, -0.09905303, 0.08381748, 0.014350217, -0.14478815, -0.027479894, -0.026432173, -0.10309177, -0.09860884, -0.019177807, -0.06963025) * go_0(1.0, 1.0); result += mat4(0.008169383, 0.12532842, -0.23369955, 0.077973194, 0.09076616, -0.021277165, 0.1721421, -0.26914293, -0.014729218, -0.023279984, -0.057670787, 0.003598546, -0.015225789, -0.0115396585, -0.26196182, -0.10724508) * go_1(-1.0, -1.0); result += mat4(0.16542235, 0.06589374, 0.07410237, 0.26753154, -0.3356288, 0.3096256, 0.07112498, -0.0992165, 0.15020338, -0.11021673, 0.18803611, 0.12918204, 0.109007336, -0.031968266, 0.057093572, 0.035949256) * go_1(-1.0, 0.0); result += mat4(0.065006174, 0.031055925, 0.0390232, -0.01678507, -0.21553491, 0.14171642, -0.19541772, -0.033691674, -0.06241631, 0.07497651, 0.024557155, 0.056778047, -0.060191352, -0.0261998, 0.07493729, -0.0699132) * go_1(-1.0, 1.0); result += mat4(-0.008541382, 0.020270415, -0.027760057, -0.040962905, -0.26732433, 0.34379438, -0.23012447, 0.0051356517, -0.04059567, 0.0972959, 0.039965224, -0.14796777, -0.0016924662, -0.116963714, -0.026353523, -0.29799464) * go_1(0.0, -1.0); result += mat4(0.03329303, -0.12663862, -0.0004959157, -0.11162377, 0.26238343, 0.43260252, -0.16504994, 0.10727678, -0.22505566, 0.43474057, 0.43304008, 0.05143919, 0.40494493, 0.08689636, -0.035733614, 0.25727916) * go_1(0.0, 0.0); result += mat4(0.12175736, -0.014467151, -0.17461288, -0.18480565, -0.26439998, 0.307935, -0.058916792, -0.014292711, -0.0569471, 0.10751278, -0.04134206, 0.1847734, -0.07519831, -0.033909313, -0.05001451, -0.136606) * go_1(0.0, 1.0); result += mat4(0.1424893, -0.026820501, 0.19645774, -0.0011315406, -0.14680974, 0.07662838, 0.21108222, 0.13260938, 0.17923595, -0.085527614, 0.08217639, 0.06579479, 0.05985784, -0.09016323, 0.11172888, 0.111903176) * go_1(1.0, -1.0); result += mat4(0.19842595, 0.0093640275, 0.10433465, 0.13341904, -0.082806975, 0.22555825, -0.1315717, 0.11907785, 0.24012424, 0.47776055, 0.1835734, 0.17483878, 0.079803735, 0.01155073, -0.21146573, -0.16484722) * go_1(1.0, 0.0); result += mat4(0.15064004, 0.021381427, 0.18301587, 0.21225913, 0.054995645, 0.03212186, 0.052798916, -0.048424408, 0.03609021, 0.0964704, -0.059469886, -0.05133066, -0.08157349, 0.051145166, -0.09107608, -0.1362262) * go_1(1.0, 1.0); result += mat4(0.090521574, -0.014747857, -0.081675015, -0.118686825, 0.04848682, -0.033071827, 0.008534588, 0.023765508, 0.16849907, -0.21797262, -0.17049783, -0.07824179, -0.033794608, 0.052612655, 0.095820345, -0.07262317) * go_2(-1.0, -1.0); result += mat4(0.22816367, -0.13772108, -0.036353834, -0.47638395, -0.0530902, 0.14089061, 0.076203234, 0.18006112, 0.121814854, -0.20750527, 0.08266107, -0.28634354, 0.14301859, -0.13458411, 0.00501663, -0.039783802) * go_2(-1.0, 0.0); result += mat4(-0.103384845, -0.14389835, 0.08275834, -0.068423435, 0.22643796, -0.02966374, -0.2847584, 0.037081387, 0.02349005, -0.19353923, -0.00095957273, -0.13623689, -0.073120415, 0.03941467, 0.21864155, -0.014019576) * go_2(-1.0, 1.0); result += mat4(-0.082576886, 0.17085212, 0.08971252, -0.04213377, -0.032548156, 0.022137715, 0.08399252, -0.0011743539, -0.09410863, -0.41728264, -0.20709297, -0.18933547, 0.027059928, 0.09743364, 0.2504647, -0.041173562) * go_2(0.0, -1.0); result += mat4(-0.20924084, 0.291118, 0.029851688, 0.16953468, 0.02936709, 0.12213576, 0.22944322, 0.108747594, 0.0001881129, -0.27398208, -0.009702691, 0.15449248, -0.9472944, -0.26114875, -0.28161275, -0.3495961) * go_2(0.0, 0.0); result += mat4(-0.12994622, -0.2758638, -0.1091727, -0.0968308, -0.14323105, 0.035175014, -0.08023811, 0.006023802, -0.031529594, -0.1486306, -0.3398172, -0.23240276, -0.29163983, 0.173475, 0.18809283, 0.22197202) * go_2(0.0, 1.0); result += mat4(0.048254848, -0.083444916, -0.014334202, 0.060992356, -0.023099286, -0.09492961, 0.05592045, 0.0026059286, 0.08998117, -0.108810075, -0.053304546, 0.045926623, 0.068255246, 0.099023566, 0.01595483, 0.1336309) * go_2(1.0, -1.0); result += mat4(0.21916585, 0.2837387, 0.14624594, 0.18843961, -0.06747584, 0.054924384, -0.082568415, 0.05011459, 0.014297759, -0.3884833, -0.054417178, -0.18970548, 0.088336475, -0.030646667, -0.2980552, -0.030035203) * go_2(1.0, 0.0); result += mat4(-0.02748568, -0.011897529, -0.2370837, -0.016740574, -0.0282112, 0.050353892, -0.10761107, -0.00036999505, 0.037646662, -0.17742962, 0.06489219, -0.158852, -0.08016933, 0.07808515, -0.105895035, 0.079869986) * go_2(1.0, 1.0); result += mat4(-0.0058994526, -0.037170693, 0.2574696, 0.06199102, -0.04497728, -0.10667442, -0.15183865, 0.0212881, -0.030842574, 0.073473394, 0.010764398, -0.00084518327, -0.03893014, -0.009649613, 0.07443129, 0.15108284) * go_3(-1.0, -1.0); result += mat4(0.11325495, -0.096435815, -0.097331434, -0.049700152, -0.17231967, 0.047090057, -0.019111065, 0.104790315, -0.15004838, 0.13950798, 0.055996202, -0.070548095, 0.047154237, -0.007650949, -0.053611025, -0.012242293) * go_3(-1.0, 0.0); result += mat4(0.12787002, -0.04958212, 0.053988468, 0.0017896162, 0.049493514, -0.009475431, -0.0022641935, 0.03933694, -0.005174597, 0.043754533, -0.1432976, 0.037084177, -0.04601288, -0.032077815, -0.059897035, 0.12584484) * go_3(-1.0, 1.0); result += mat4(0.019409029, 0.10492923, 0.268368, 0.12597778, -0.17733063, -0.0085961, -0.27136415, -0.049664587, 0.012515404, -0.21444482, -0.39275557, -0.12297177, 0.06800057, 0.19228315, 0.06245887, 0.35772634) * go_3(0.0, -1.0); result += mat4(-0.16317715, 0.2288402, -0.23235172, 0.22230752, -0.1646375, 0.13366091, 0.16681044, -0.17399235, 0.33997267, -0.3179832, -0.34756508, 0.39843196, -0.10748536, 0.322923, 0.23339489, 0.08684083) * go_3(0.0, 0.0); result += mat4(0.02835275, 0.12314228, 0.24030593, 0.30856124, 0.055735108, -0.044914473, 0.0031432225, 0.07469899, 0.1778018, 0.107083894, -0.023706734, -0.15501897, 0.0943098, -0.034707237, -0.18622099, 0.05257965) * go_3(0.0, 1.0); result += mat4(0.042839274, 0.12597966, 0.08979042, -0.0647561, -0.050434645, 0.049438696, -0.20008127, -0.05572608, 0.046238814, 0.12622325, -0.019017145, -0.13960391, -0.040050175, 0.14298008, -0.20270552, 0.13391526) * go_3(1.0, -1.0); result += mat4(-0.0073277587, 0.10606624, -0.08940439, -0.09656414, 0.12387374, -0.0013147948, 0.23607181, -0.00037969893, 0.050353236, -0.17266603, 0.27796733, -0.09877832, 0.02711225, 0.096394345, 0.07457944, 0.21541388) * go_3(1.0, 0.0); result += mat4(-0.18612787, -0.00027517386, -0.17136407, -0.06413671, 0.025629476, -0.04570916, 0.0008431566, -0.03419168, 0.08123608, 0.09465922, 0.11975521, 0.1269741, 0.08413221, 0.12125001, 0.04727287, 0.072378494) * go_3(1.0, 1.0); result += vec4(0.04244928, -0.014280219, 0.017129054, -0.08807801); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_3_tf //!BIND conv2d_3_tf1 //!SAVE conv2d_4_tf1 //!WIDTH conv2d_3_tf.w //!HEIGHT conv2d_3_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_3_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_3_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_3_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_3_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.01973856, -0.05053795, 0.015545361, 0.10867395, 0.33441806, 0.14731607, 0.6793983, -0.21394718, -0.00846322, 0.09146322, -0.07427475, -0.078477465, -0.090998545, 0.133366, 0.105515696, -0.13784988) * go_0(-1.0, -1.0); result += mat4(-0.05404873, 0.09784018, -0.1337389, -0.18082313, 0.13461179, -0.3816801, 0.12209786, 0.08176651, 0.10461896, -0.43315184, 0.017470734, 0.20423968, -0.03941875, -0.101959296, -0.09440259, 0.09154717) * go_0(-1.0, 0.0); result += mat4(0.17229515, -0.06907825, -0.008382803, -0.16671611, -0.01576541, 0.03985307, 0.08209482, -0.11707446, -0.11793074, 0.13702396, -0.02013158, 0.07302033, -0.022301994, -0.11464677, 0.036753565, -0.093276784) * go_0(-1.0, 1.0); result += mat4(-0.017650167, 0.009475923, -0.17856382, 0.15925962, 0.06434641, -0.15568036, 0.038135886, 0.18855911, -0.04427734, 0.1878215, 0.10856261, 0.0041275816, -0.12046199, 0.13610138, 0.3741596, -0.12934728) * go_0(0.0, -1.0); result += mat4(-0.24631616, 0.0169485, -0.035534818, 0.37795424, -0.08546174, 0.07817259, 0.42897213, -0.47965595, -0.0146556785, -0.20510523, -0.18889453, 0.06476019, 0.1021008, -0.35398817, -0.031071864, -0.21416448) * go_0(0.0, 0.0); result += mat4(0.32810766, 0.050585747, -0.17658374, -0.13881154, 0.16417882, -0.21286008, -0.106835455, -0.1722344, -0.14151084, 0.08962986, 0.057395387, -0.01623662, 0.02570415, 0.15626897, -0.12687978, 0.080729105) * go_0(0.0, 1.0); result += mat4(-0.050597478, -0.018753758, -0.036346875, -0.017908493, 0.058593344, 0.008303028, 0.05254987, -0.06635018, -0.022532012, 0.029511122, 0.026682215, -0.054647952, 0.069466785, -0.08892492, 0.025351115, -0.023130694) * go_0(1.0, -1.0); result += mat4(0.2412473, -0.16138165, -0.15117447, 0.11851003, -0.096868426, 0.082690425, 0.27923304, 0.11590443, 0.19363573, -0.15770023, -0.066793665, 0.011681678, 0.14037277, -0.112065665, -0.048159517, 0.009453693) * go_0(1.0, 0.0); result += mat4(0.1580054, -0.0060506654, 0.05267837, -0.09178131, -0.09107123, 0.23191126, 0.21108283, -0.070422985, 0.024321035, 0.06131459, 0.066626504, 0.032481454, 0.044402298, 0.1390604, -0.14432502, 0.040869843) * go_0(1.0, 1.0); result += mat4(0.10264861, 0.013504324, 0.012482852, -0.1781206, -0.12799414, -0.27026084, -0.123830505, 0.098105, -0.039127555, 0.09367889, 0.122323096, 0.1416734, 0.044763107, -0.21801683, -0.14018978, 0.17646866) * go_1(-1.0, -1.0); result += mat4(0.017453065, 0.11498537, -0.10998983, -0.3116098, -0.3099762, 0.5024706, 0.051817298, 0.03170681, -0.18937826, 0.07946567, -0.11978771, -0.09523745, -0.0033551592, -0.11768945, 0.08932359, -0.06689581) * go_1(-1.0, 0.0); result += mat4(0.1507582, -0.013266159, -0.073085934, -0.07252967, -0.06301927, -0.13218755, 0.12984878, -0.13678701, 0.023422396, 0.082123175, 0.006906731, -0.004018426, -0.15813835, 0.13711788, 0.016018609, 0.13443229) * go_1(-1.0, 1.0); result += mat4(-0.06960673, 0.16156524, -0.1374069, -0.05803206, -0.077960715, -0.10676749, 0.26282015, 0.03521529, 0.058099385, -0.014738148, 0.0011174522, 0.24279532, -0.023991548, -0.108812414, -0.08886019, 0.20584475) * go_1(0.0, -1.0); result += mat4(-0.08043308, 0.063343, 0.055290066, -0.15991378, -0.08096304, -0.23888679, 0.019161629, 0.38381267, 0.3672934, -0.119608454, -0.43623593, -0.46014485, -0.5323366, 0.1318621, 0.087373205, -0.05535459) * go_1(0.0, 0.0); result += mat4(0.20640239, -0.1369444, -0.21677823, 0.08202178, 0.10515278, 0.06810837, 0.073207974, 0.23623931, 0.102422275, -0.05016664, -0.0039228587, -0.1810343, -0.2235563, -0.1246854, 0.1428113, -0.10609135) * go_1(0.0, 1.0); result += mat4(-0.031941894, -0.08905056, 0.21501167, 0.11244667, -0.011811734, 0.21630247, 0.07589472, -0.040489636, -0.11824066, -0.11520391, -0.10075633, -0.035642453, 0.062144946, 0.0073282206, 0.14119269, -0.060479023) * go_1(1.0, -1.0); result += mat4(-0.29382935, -0.056808118, 0.051812876, -0.061358813, -0.08344258, 0.124203674, 0.037964176, -0.01961274, -0.000951725, 0.50005037, -0.24176972, 0.06487161, -0.15469861, 0.04336187, 0.17826353, 0.040010225) * go_1(1.0, 0.0); result += mat4(0.02044482, -0.0879271, -0.01053958, -0.31148303, 0.07497373, -0.11548258, -0.1666126, 0.02369657, -0.058044076, 0.010801491, -0.005933901, -0.08910467, 0.007953008, 0.03761974, -0.029501524, 0.16816042) * go_1(1.0, 1.0); result += mat4(0.1779597, -0.10213089, 0.29942423, -0.016642543, -0.015537001, -0.04676146, 0.09585872, -0.0055750017, -0.014361908, -0.20667697, -0.11348746, 0.13081487, -0.10437329, 0.14328459, 0.11648822, -0.09163837) * go_2(-1.0, -1.0); result += mat4(0.019033967, -0.12420627, -0.07748253, 0.43203858, -0.109799065, 0.07605535, 0.060791396, -0.24517195, -0.15674245, 0.21267459, 0.10665515, -0.073150024, -0.1358355, 0.0054066703, -0.16434059, -0.06031853) * go_2(-1.0, 0.0); result += mat4(-0.18834068, 0.26840356, -0.12937617, 0.16103932, -0.0062331813, -0.13630053, -0.013911821, 0.022389365, -0.044232946, -0.056454606, 0.022426741, 0.18010215, 0.041900013, 0.03375041, -0.11376866, -0.010313381) * go_2(-1.0, 1.0); result += mat4(0.12497669, -0.31161824, 0.097568035, 0.19443443, -0.05056519, -0.0031457904, 0.1055554, -0.083650924, 0.07630523, -0.34177595, -0.093093194, 0.20701368, -0.030962149, -0.054470222, -0.23853977, 0.004326528) * go_2(0.0, -1.0); result += mat4(0.34370202, 0.085750066, -0.16071722, -0.54335934, -0.35595295, -0.050744478, -0.17405547, 0.008628697, -0.007086256, 0.23164117, 0.340156, 0.5475976, -0.15292351, 0.28019544, 0.038059216, 0.0044727) * go_2(0.0, 0.0); result += mat4(-0.08231968, -0.0052294536, 0.07451547, 0.22278999, -0.3305531, 0.0017458396, 0.10818422, -0.21325395, -0.08807993, -0.110342845, 0.10082142, -0.051594347, 0.24192205, -0.18042035, -0.0095462985, -0.08757798) * go_2(0.0, 1.0); result += mat4(0.096379586, 0.021887815, -0.05097233, -0.06797989, -0.026171045, 0.022944937, -0.015915364, 0.037667938, 0.17216732, -0.014889412, 0.07343887, 0.028236505, 0.0015047621, 0.1355103, -0.09918284, -0.07673695) * go_2(1.0, -1.0); result += mat4(-0.25385055, 0.15163356, 0.0030003798, 0.18464413, 0.05611221, 0.099498056, -0.07128191, 0.042955168, 0.027493173, 0.07440157, 0.07814497, 0.096160784, 0.13571084, 0.056412842, -0.031997006, -0.16073681) * go_2(1.0, 0.0); result += mat4(-0.21634746, 0.025153082, -0.064477116, 0.0005679147, -0.0029436245, 0.12794618, 0.024849026, 0.03018052, 0.11723976, 0.059955597, -0.013594654, 0.09091745, 0.04775348, 0.21260159, -0.07463213, -0.06727042) * go_2(1.0, 1.0); result += mat4(-0.12166018, 0.024545137, 0.08611618, -0.17627168, 0.09042604, -0.14157623, -0.22147785, 0.09100581, 0.11078359, 0.031410985, -0.17170976, 0.09532806, -0.059569277, 0.09392676, 0.11784347, -0.21471368) * go_3(-1.0, -1.0); result += mat4(0.1483187, -0.2217563, 0.12032977, 0.14932398, 0.27428308, -0.04568031, 0.12670338, 0.09586169, 0.06700745, 0.005126449, 0.0027694793, -0.033667028, 0.06447861, -0.08585174, -0.05509812, -0.11358761) * go_3(-1.0, 0.0); result += mat4(-0.22750492, 0.032906335, -0.029479047, 0.11580199, -0.05812372, -0.032269973, 0.05219915, 0.041658226, 0.010897959, 0.065550454, 0.0076911976, -0.045743827, 0.11614996, -0.10393113, -0.0012606392, -0.034367524) * go_3(-1.0, 1.0); result += mat4(0.09350742, 0.09561609, 0.3735968, 0.031685118, -0.042026598, 0.17006761, -0.3910107, 0.16984761, 0.25679177, 0.036610503, -0.13772772, 0.11101589, -0.1137049, 0.07211461, 0.18065079, -0.12324793) * go_3(0.0, -1.0); result += mat4(-0.020749722, 0.14413361, -0.061903823, -0.21550268, 0.31306142, -0.11532895, 0.029482557, 0.03282164, -0.09800627, -0.20765196, 0.33030233, 0.075725295, 0.49252015, 0.042455837, -0.07264194, -0.10401895) * go_3(0.0, 0.0); result += mat4(-0.22697076, -0.15738785, 0.09740376, -0.072098814, -0.06638972, 0.12336611, 0.0073687397, 0.048267826, 0.06717852, -0.027047804, -0.123397194, 0.17829034, 0.04215185, 0.066311836, -0.061742183, -0.046373066) * go_3(0.0, 1.0); result += mat4(0.041311592, 0.2813485, 0.055084586, -0.01823069, 0.08105147, -0.087944716, -0.10135052, -0.02653456, 0.063169874, -0.1351186, 0.06722432, -0.016406318, 0.08666922, 0.0555909, 0.12086502, -0.17224412) * go_3(1.0, -1.0); result += mat4(0.26026788, -0.18303715, 0.029279215, -0.12858874, 0.027197823, 0.0919464, 0.00849638, 0.10547888, -0.12952055, -0.14414985, 0.1903315, 0.05004528, -0.12657289, 0.038008716, -0.036606666, -0.054025438) * go_3(1.0, 0.0); result += mat4(0.069167465, 0.2699947, -0.11137602, -0.05888806, -0.107324794, -0.07598601, 0.06042177, 0.0064530694, -0.039780665, -0.076666445, -0.00846108, -0.06165907, -0.06978219, -0.19108103, -0.040026028, -0.120319635) * go_3(1.0, 1.0); result += vec4(-0.14375664, -0.0056876075, 0.052177623, 0.07152566); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_4_tf //!BIND conv2d_4_tf1 //!SAVE conv2d_5_tf //!WIDTH conv2d_4_tf.w //!HEIGHT conv2d_4_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_4_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_4_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_4_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_4_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(-0.15667982, -0.31441393, 0.29112124, -0.15737213, 0.022372838, 0.10690639, -0.12019085, -0.051941186, -0.30367845, 0.02612279, 0.2372532, 0.2021648, -0.20481086, -0.003770439, 0.14981231, 0.066780254) * go_0(-1.0, -1.0); result += mat4(0.03270688, -0.42270073, 0.044317324, 0.15907793, 0.14681059, -0.2934784, 0.24933252, -0.067273855, 0.07752533, -0.23194817, 0.0686707, 0.08999225, 0.121678345, -0.12916678, 0.012397381, 0.012315053) * go_0(-1.0, 0.0); result += mat4(-0.10090412, -0.20792678, 0.11076032, -0.02938975, -0.1944187, -0.2003259, 0.04438032, 0.36946484, -0.019868722, -0.15830222, 0.042811528, 0.015641417, 0.113098525, 0.080257006, 0.011135628, -0.2877629) * go_0(-1.0, 1.0); result += mat4(0.15482685, 0.06579119, 0.28301102, 0.23729764, 0.15990537, 0.4529694, 0.107880585, 0.10668121, -0.42430598, -0.2631025, 0.10513542, -0.036242936, -0.09827965, -0.0069260495, -0.11689201, -0.041436482) * go_0(0.0, -1.0); result += mat4(0.08472191, -0.13051608, 0.047930017, 0.36831668, 0.1164478, 0.21384816, 0.22062506, 0.2094167, 0.48668453, 0.32302913, 0.36268055, -0.091801375, -0.079141125, -0.26613805, -0.16608004, 0.03810683) * go_0(0.0, 0.0); result += mat4(-0.13474251, -0.04824603, 0.23303726, -0.116136365, 0.0056330245, 0.15829784, 0.0012259148, 0.12648389, 0.038680512, 0.05131116, 0.024099711, 0.4555406, 0.0035716395, 0.11633299, 0.094744846, -0.2457627) * go_0(0.0, 1.0); result += mat4(-0.0576871, -0.04037522, 0.16857862, 0.0031084458, -0.027274646, -0.18154246, 0.13337846, 0.035422433, -0.0030749738, -0.17288287, 0.019983152, -0.31871706, -0.03280405, 0.06825421, -0.1563798, 0.05031885) * go_0(1.0, -1.0); result += mat4(-0.066631876, 0.012560506, 0.1690693, -0.018248236, 0.0450104, 0.016296914, -0.14910112, -0.16191053, 0.5078224, -0.017615631, 0.15226597, -0.13373777, 0.20148668, 0.060258996, 0.13215344, 0.18430072) * go_0(1.0, 0.0); result += mat4(0.12976126, -0.072738245, 0.053067926, 0.09752956, -0.04716214, 0.04136464, 0.014162617, -0.06621296, -0.09617736, 0.057469178, 0.01280261, -0.042976785, -0.12570308, 0.006027807, 0.031038594, 0.06569918) * go_0(1.0, 1.0); result += mat4(-0.12655424, -0.41563693, -0.030971345, -0.06357555, -0.14121394, -0.15667427, 0.14398985, 0.05995984, 0.0821605, 0.12462943, 0.007492498, -0.0030187522, -0.22804567, -0.10487421, 0.13180672, -0.13978589) * go_1(-1.0, -1.0); result += mat4(-0.075991526, 0.12352044, -0.17844258, 0.010614991, -0.18293494, 0.25009897, -0.080779895, 0.21548378, 0.22215544, 0.048670914, -0.057372037, 0.078176, 0.17490411, 0.004919551, 0.059619516, 0.12660357) * go_1(-1.0, 0.0); result += mat4(-0.06282951, 0.10929357, 0.026720649, -0.15939257, 0.17107709, -0.04334904, -0.03047162, -0.101681694, 0.03118431, 0.19994627, 0.025729552, 0.035035726, -0.0012207883, -0.08618888, 0.061205562, 0.009940555) * go_1(-1.0, 1.0); result += mat4(-0.23581573, 0.08002133, -0.15170844, 0.08872338, -0.25767094, -0.09273545, 0.18153891, 0.2544269, -0.084598936, -0.089766875, -0.14610913, 0.002247754, 0.1802837, -0.019625561, 0.30239686, -0.032793984) * go_1(0.0, -1.0); result += mat4(0.5223286, 0.10347663, 0.4000593, 0.25440502, -0.07646958, -0.31940606, 0.053407036, -0.09356492, 0.2738851, 0.23945184, -0.2907089, -0.45822915, 0.13415676, 0.17187089, 0.08731114, -0.27670014) * go_1(0.0, 0.0); result += mat4(0.059273496, -0.107137166, 0.12087539, 0.179237, -0.021209063, -0.02548005, 0.061256204, 0.033822674, 0.54491127, -0.2475085, 0.08055858, -0.4071213, -0.045093834, 0.07161349, 0.08219979, -0.31735933) * go_1(0.0, 1.0); result += mat4(-0.29527053, 0.021469543, 0.07202354, -0.07103959, 0.03990857, 0.2490762, -0.19419849, -0.13916986, -0.05325315, 0.12922864, -0.041463424, -0.031249814, 0.073991664, -0.09723187, 0.35132217, 0.024760868) * go_1(1.0, -1.0); result += mat4(0.09606787, -0.0951808, -0.0059865676, -0.052033573, -0.3118038, 0.4432636, -0.12943317, 0.09484738, 0.10621756, -0.10550469, 0.11264014, 0.1402276, -0.012679125, -0.08809835, 0.029994955, -0.15121669) * go_1(1.0, 0.0); result += mat4(0.123397775, 0.048338536, -0.00975707, -0.103767075, -0.041053303, -0.07228534, 0.046792876, 0.0668788, 0.29554394, 0.012451002, 0.19568972, 0.112091154, 0.10882395, -0.0995439, 0.051324263, 0.24967718) * go_1(1.0, 1.0); result += mat4(0.2699648, 0.17300771, -0.16056584, 0.1099392, 0.11674778, -0.19811755, 0.111880325, -0.06075038, -0.095849104, -0.04510651, -0.04180761, -0.0052786698, 0.11037549, -0.24115366, 0.018509468, -0.07819484) * go_2(-1.0, -1.0); result += mat4(0.10981622, 0.044488225, 0.050722387, -0.3146652, -0.0013019707, -0.24084032, -0.10475088, 0.026944289, 0.1592903, 0.33087498, 0.061839584, -0.043863457, -0.06904603, -0.08635262, 0.088630445, -0.15485142) * go_2(-1.0, 0.0); result += mat4(-0.06810522, 0.19927117, -0.08130387, 0.11612667, -0.015104349, -7.738651e-05, -0.06419643, -0.14813533, 0.026650215, 0.015038833, 0.08161237, 0.058321163, 0.015005185, -0.16189656, 0.024501886, 0.1927279) * go_2(-1.0, 1.0); result += mat4(0.31858218, 0.11962043, -0.20560326, -0.13190113, 0.02138715, -0.057066392, -0.085771754, -0.124566585, 0.044749223, 0.13687828, 0.1195792, 0.14021616, 0.26204133, 0.05119197, -0.13980037, 0.050747477) * go_2(0.0, -1.0); result += mat4(-0.21238558, -0.0734057, -0.2036023, -0.34308743, -0.29370925, 0.2393742, -0.37877437, 0.036869828, -0.17053255, -0.26900926, -0.23330869, 0.32902205, -0.4882585, 0.27430108, -0.033711653, 0.15501487) * go_2(0.0, 0.0); result += mat4(0.23487025, 0.085289046, -0.14281847, 0.12543266, 0.15871634, -0.13858907, 0.14810285, -0.0239261, 0.1286852, 0.07754033, 0.01072327, -0.14313328, 0.05480442, -0.12195059, 0.11341822, 0.08224607) * go_2(0.0, 1.0); result += mat4(0.19490337, 0.023521842, -0.24548791, 0.0035114093, -0.07937166, -0.07674376, 0.08365873, -0.003286068, 0.023862893, 0.009626835, 0.032829892, 0.0078141205, 0.053484406, -0.08297165, 0.09303188, 0.004273738) * go_2(1.0, -1.0); result += mat4(-0.0032906602, 0.13636959, 0.027821168, 0.06270053, 0.024775786, -0.077529594, 0.03799126, 0.030000908, 0.031749167, 0.04360487, 0.004448846, -0.17835903, -0.30834544, 0.013150946, -0.13758293, -0.03296242) * go_2(1.0, 0.0); result += mat4(-0.14166978, 0.034131095, 0.049779188, 0.09453289, -0.011406557, -0.07020709, -0.0031981543, -0.03443845, -0.00010218944, 0.0855161, -0.10951453, 0.042758763, 0.1718446, -0.1577923, 0.0410027, -0.04992991) * go_2(1.0, 1.0); result += mat4(0.1219178, 0.105126485, -0.041097324, -0.08110963, -0.04857337, -0.11544925, -0.14572923, 0.092435546, 0.091857366, 0.15425235, -0.020324683, -0.05764375, -0.020458939, -0.10527823, -0.085554086, 0.16358297) * go_3(-1.0, -1.0); result += mat4(-0.12372687, -0.009976829, 0.14252265, -0.1321053, -0.05965866, -0.1393898, -0.017603246, -0.02714342, -0.16824952, -0.23083204, -0.012299022, -0.06689838, -0.015830487, 0.21299921, -0.11637202, 0.0074968333) * go_3(-1.0, 0.0); result += mat4(-0.01979935, -0.182785, -0.015397454, 0.14175794, -0.011465284, 0.11285164, -0.036115747, 0.07150463, -0.083641894, -0.10221778, -0.13871445, 0.099696055, 0.04603662, -0.06463785, -0.007984529, -0.0032940735) * go_3(-1.0, 1.0); result += mat4(0.072830334, -0.057334073, 0.09086239, 0.13039105, 0.06350303, 0.17130788, -0.2181585, -0.09137403, -0.31397742, -0.019071499, -0.017274613, 0.13762084, 0.10195637, -0.021455176, 0.04011394, -0.08029658) * go_3(0.0, -1.0); result += mat4(-0.26982597, -0.40265098, -0.4151411, 0.038557775, -0.095602125, 0.3503172, -0.029988842, -0.03484708, 0.095536314, -0.0030311556, 0.31589827, 0.52763534, -0.12629713, -0.24356791, 0.0059487303, 0.42298427) * go_3(0.0, 0.0); result += mat4(0.054166105, 0.18827972, -0.081673265, -0.06720384, 0.09375001, 0.22173035, -0.14050071, 0.108400136, -0.15553835, -0.08716729, -0.037366748, 0.10971073, -0.02560103, -0.26702073, -0.05201882, 0.2432563) * go_3(0.0, 1.0); result += mat4(0.16196893, 0.0889265, -0.09887943, -0.042956755, -0.054403376, -0.123823255, 0.045847844, 0.017027669, 0.00539936, -0.112265736, 0.050549984, -0.104931094, -0.06883012, -0.25745714, 0.11155538, -0.15363649) * go_3(1.0, -1.0); result += mat4(-0.22157209, 0.18200903, -0.13290548, 0.026721261, -0.06066069, -0.18150693, 0.08768983, 0.037362453, -0.1073367, -0.070236765, -0.41223463, -0.168915, -0.15517351, -0.13949952, -0.13307643, -0.15935421) * go_3(1.0, 0.0); result += mat4(-0.026589906, 0.0930502, 0.05195435, 0.06301585, -0.01107014, -0.019382332, 0.027223695, -0.004045145, -0.15238355, -0.0345132, 0.06355168, 0.0011230056, 0.16690113, 0.0017829507, -0.0023939044, -0.09471834) * go_3(1.0, 1.0); result += vec4(0.024455175, 0.01669877, -0.066231176, 0.036848705); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_4_tf //!BIND conv2d_4_tf1 //!SAVE conv2d_5_tf1 //!WIDTH conv2d_4_tf.w //!HEIGHT conv2d_4_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_4_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_4_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_4_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_4_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.01763509, -0.17156707, -0.06841296, -0.026132878, -0.10600523, 0.11245994, 0.121395074, -0.09331501, 0.12764473, 0.0428028, -0.11837395, 0.2092563, -0.04357652, -0.0490096, 0.024701532, 0.10518723) * go_0(-1.0, -1.0); result += mat4(-0.17130826, -0.31987694, -0.07639005, 0.21362033, 0.058639023, 0.066175915, -0.25344703, -0.07923442, -0.14766373, 0.040518284, -0.031103026, -0.040075514, -0.051108997, -0.28214613, -0.18504949, 0.27544948) * go_0(-1.0, 0.0); result += mat4(0.030991005, -0.011353306, 0.15237464, 0.15458584, 0.1250524, 0.19959912, 0.14049476, 0.38410887, 0.07378578, -0.017728366, 0.0963528, -0.043756213, -0.039577194, -0.11800575, -0.08392266, -0.07599512) * go_0(-1.0, 1.0); result += mat4(0.022089608, -0.027317125, 0.051330008, -0.0075439885, 0.021650828, -0.0009390209, -0.12043464, 0.049332134, -0.055557396, -0.053297505, -0.0918705, -0.13089466, -0.10994107, 0.072746456, 0.11496739, -0.05225977) * go_0(0.0, -1.0); result += mat4(0.29730305, 0.26317745, 0.052159555, -0.32006654, 0.48288685, -0.049926184, -0.08091092, -0.13825637, -0.1485706, -0.288657, -0.41443697, 0.06856032, -0.23809211, -0.12953928, 0.4783034, -0.47557938) * go_0(0.0, 0.0); result += mat4(0.026139118, -0.23031352, 0.04861487, 0.033556074, 0.2702056, 0.22802536, -0.15385233, 0.1664119, 0.18749923, 0.36927548, -0.011473684, -0.11771165, -0.16859052, -0.4513202, 0.12863952, 0.02482837) * go_0(0.0, 1.0); result += mat4(0.0073229345, -0.061915245, 0.06710329, 0.0062416573, -0.00555983, 0.14592186, 0.11201052, -0.123630054, 0.32611257, -0.11279885, -0.059449438, 0.2891043, -0.10519016, 0.040108994, -0.012468261, 0.02083298) * go_0(1.0, -1.0); result += mat4(-0.057483062, 0.08454755, -0.15529329, -0.12572923, 0.2600099, -0.02319978, -0.04037675, 0.11496361, 0.07728194, -0.12908956, -0.025529336, 0.112581626, 0.02971823, 0.11659056, -0.01298622, 0.017061908) * go_0(1.0, 0.0); result += mat4(0.22417091, -0.00222947, 0.04980858, 0.12260437, -0.025507605, 0.042577885, 0.120813504, -0.048522256, -0.038494784, -0.0072195013, -0.23012944, -0.020850847, -0.078296244, -0.014830018, 0.19759563, -0.10000253) * go_0(1.0, 1.0); result += mat4(-0.032090195, 0.023757193, -0.08989734, 0.14419042, 0.0112194475, -0.093776144, -0.020197887, 0.29295877, 0.06872183, 0.09511462, -0.03245769, -0.06504889, 0.05132126, 0.00399527, 0.075911656, 0.250893) * go_1(-1.0, -1.0); result += mat4(-0.3418496, 0.25525784, 0.0018161442, 0.028484365, -0.17573346, -0.12457501, 0.18466166, 0.20209278, 0.10282706, 0.16353399, 0.025052028, -0.059714165, -0.055806916, -0.28651386, 0.112798095, 0.11624314) * go_1(-1.0, 0.0); result += mat4(-0.018793896, 0.07500149, -0.01728254, -0.1726998, -0.13333, 0.09590344, -0.036537904, -0.11522523, 0.19445558, 0.22680458, 0.12061006, -0.06225618, 0.1127748, 0.28380096, -0.07099846, -0.007440302) * go_1(-1.0, 1.0); result += mat4(-0.43887648, -0.10018577, -0.29267642, 0.12149727, -0.14333835, 0.04161915, 0.19442867, 0.16506511, 0.09655387, -0.0014398015, 0.13189743, -0.14068556, 0.049408, 0.0829072, 0.2950336, 0.36965907) * go_1(0.0, -1.0); result += mat4(0.41486958, -0.023498302, -0.37900022, -0.31752598, 0.13758768, -0.18782206, -0.31358528, 0.3330786, -0.4039293, -0.06539036, 0.032599606, 0.10663507, -0.26369813, -0.17365438, 0.20723309, 0.1801556) * go_1(0.0, 0.0); result += mat4(0.004117444, -0.14894462, 0.14915143, -0.047375835, -0.2609916, -0.10172324, -0.14925237, -0.33830285, 0.12131607, -0.18156646, -0.42382464, -0.052582145, 0.2329045, -0.4576963, 0.13756892, 0.055571318) * go_1(0.0, 1.0); result += mat4(-0.31689477, 0.017058033, -0.01904924, -0.016893756, -0.011479519, 0.07316262, -0.07086077, 0.08923511, -0.08190091, -0.025866933, -0.06909204, -0.028601022, 0.023224542, 0.03082087, 0.2230426, -0.16713654) * go_1(1.0, -1.0); result += mat4(0.13457374, 0.110913865, -0.1130815, -0.031438913, -0.55201167, 0.04831016, 0.25107765, -0.014003224, 0.19532952, 0.02062346, 0.04839241, 0.088673405, 0.30325848, -0.20222804, -0.085780576, 0.22512968) * go_1(1.0, 0.0); result += mat4(0.076354, 0.021940092, -0.16170324, 0.0025543426, -0.0032400405, -0.0046705627, 0.06241069, -0.031247333, 0.098353796, 0.03723474, 0.22971998, -0.017877292, 0.119858086, 0.008041448, 0.2140585, 0.10343376) * go_1(1.0, 1.0); result += mat4(0.08627595, 0.04532834, 0.027579082, -0.16222088, 0.15583228, -0.14371829, -0.07243855, -0.111895435, -0.14438897, -0.10250594, 0.0034202964, -0.066547595, -0.034390844, -0.021545287, 0.014540157, -0.10215731) * go_2(-1.0, -1.0); result += mat4(0.19720152, 0.21534947, 0.1130938, -0.011730973, 0.013247983, -0.10344174, -0.1906514, -0.015767017, -0.020093633, -0.26487067, -0.005960781, -0.057149183, 0.030110173, 0.047692046, -0.19308545, -0.25292158) * go_2(-1.0, 0.0); result += mat4(0.039498243, 0.053682897, -0.01844695, -0.017540915, 0.039454967, -0.27696076, 0.09503274, -0.038958035, 0.17321438, -0.036311295, 0.03123055, 0.02310311, 0.040591653, 0.0054627894, -0.03520426, -0.026101988) * go_2(-1.0, 1.0); result += mat4(0.055991564, 0.06512919, -0.12532505, 0.024075158, -0.04926237, -0.11701171, 0.026792146, 0.013033238, -0.052847516, -0.01550091, -0.008442071, -0.077945165, -0.033220004, -0.13678443, -0.07040586, 0.121846326) * go_2(0.0, -1.0); result += mat4(-0.19537796, -0.016634773, 0.10707109, -0.024361614, -0.16002733, -0.44066608, 0.16488662, 0.013152995, 0.22407806, 0.12854017, 0.19028598, -0.08379244, -0.05594235, -0.15909895, 0.511962, 0.39027596) * go_2(0.0, 0.0); result += mat4(-0.032652248, 0.06004893, 0.011166194, 0.102761306, -0.035113614, -0.29961765, -0.013817978, 0.20938557, 0.08488225, -0.1118558, -0.0375328, -0.035511103, 0.0046933405, 0.20203683, -0.13552529, -0.12685429) * go_2(0.0, 1.0); result += mat4(0.03054923, 0.08224908, -0.059128158, -0.02583655, -0.02133876, 0.0048713544, 0.10848829, 0.06324404, 0.028332822, -0.011002306, -0.027557913, -0.06072362, 0.1019048, -0.02587316, 0.08563405, -0.08119947) * go_2(1.0, -1.0); result += mat4(-0.10568117, 0.1075248, 0.19379964, -0.14337265, 0.019374132, -0.0907804, -0.13827625, -0.03628561, 0.014735499, -0.026882607, -0.25948793, 0.034926686, -0.05988073, -0.22735636, 0.053511668, 0.04765336) * go_2(1.0, 0.0); result += mat4(-0.029848114, 0.09183966, 0.084713496, 0.09422864, 0.069713995, -0.10584984, -0.020899031, 0.059645247, -0.075805016, -0.01828552, 0.06689195, -0.13804196, -0.023465823, -0.034038994, -0.12946706, 0.058709413) * go_2(1.0, 1.0); result += mat4(0.061918218, 0.038984764, 0.013660938, -0.19340219, -0.014949839, 0.12946278, 0.12725051, 0.13429146, 0.05993008, -0.015394284, 0.011232483, 0.0344157, 0.022161875, -0.023923954, 0.061736204, 0.025963215) * go_3(-1.0, -1.0); result += mat4(0.048136763, 0.03162042, -0.01967249, 0.06374493, 0.034645267, 0.22403605, 0.036197048, -0.06903216, -0.1024706, -0.0005459356, 0.049185563, 0.16309108, 0.07394778, 0.10351343, 0.28430694, -0.13531347) * go_3(-1.0, 0.0); result += mat4(-0.14705071, -0.09458433, 0.03063114, 0.07901115, -0.11911086, -0.06428132, -0.013549552, -0.041342866, -0.20770676, -0.15104479, 0.054365363, -0.11652907, 0.05639815, 0.070518605, 0.0017846811, -0.00056205114) * go_3(-1.0, 1.0); result += mat4(0.27148908, 0.07358356, 0.13644488, -0.13824654, 0.0112991175, -0.021521023, -0.10197379, 0.007816017, -0.13314332, 0.12318473, -0.043214846, -0.15759036, -0.19744353, -0.10267182, -0.28249928, 0.11233295) * go_3(0.0, -1.0); result += mat4(-0.096474804, 0.17893109, 0.014679829, -0.21218887, -0.24170275, 0.10603527, 0.05375366, -0.059315052, 0.17087384, 0.13633691, -0.37958893, 0.43264794, 0.17829923, 0.06485103, -0.37551817, -0.22082718) * go_3(0.0, 0.0); result += mat4(-0.30536333, -0.033212308, -0.25232, 0.11730442, -0.11176368, 0.26223183, -0.049025323, -0.01375941, -0.29028055, 0.16842811, -0.035684332, -0.4180911, -0.1611732, 0.07683385, -0.14263596, 0.17508087) * go_3(0.0, 1.0); result += mat4(0.23580009, 0.025621435, -0.15757325, 0.008123166, -0.021905439, -0.02162503, -0.059497356, -0.01636353, 0.047654126, -0.084423855, -0.033733923, 0.0127116265, -0.059593942, -0.053935718, -0.050729543, 0.013887048) * go_3(1.0, -1.0); result += mat4(-0.19232626, 0.07915767, -0.05909752, 0.007695347, 0.058876406, 0.057521783, -0.080253534, 0.2011056, -0.27965516, -0.08033169, -0.13025513, 0.12854645, 0.053400308, -0.18445957, -0.18463044, 0.27920377) * go_3(1.0, 0.0); result += mat4(-0.061806213, -0.020037206, 0.003183183, -0.029844081, -0.039553937, 0.028905323, -0.11367984, -0.097321615, -0.10112643, 0.0039709485, -0.06020118, -0.23871279, -0.077974856, 0.05806996, -0.21440302, 0.11898043) * go_3(1.0, 1.0); result += vec4(-0.023832673, 0.03702965, -0.04749135, -0.10982549); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_5_tf //!BIND conv2d_5_tf1 //!SAVE conv2d_6_tf //!WIDTH conv2d_5_tf.w //!HEIGHT conv2d_5_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_5_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_5_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_5_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_5_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.030931145, 0.013683292, -0.0650242, -0.028732346, 0.120067924, -0.029404473, 0.0038229884, -0.14631765, 0.041900825, -0.076596744, -0.11096378, -0.27100095, 0.0052598766, -0.05929686, -0.06816563, -0.086864315) * go_0(-1.0, -1.0); result += mat4(-0.043620087, -0.16360405, 0.006527374, 0.15706524, 0.08338088, -0.19027525, 0.22595987, -0.054963548, 0.01825031, -0.03149212, 0.025471251, 0.06429379, -0.011633275, -0.079389006, -0.0030728737, 0.17345747) * go_0(-1.0, 0.0); result += mat4(-0.011275288, -0.10668036, 0.05718997, 0.010336089, 0.33393976, -0.2029354, 0.075444475, -0.092244044, 0.07605498, 0.20125951, 0.10493973, -0.12306946, 0.03658231, 0.08233366, -0.12205888, -0.116969004) * go_0(-1.0, 1.0); result += mat4(-0.0070305974, 0.105127215, 0.006041873, 0.26743913, 0.028119443, 0.14823505, -0.28344348, 0.12362866, -0.1215781, 0.08104382, 0.102011785, 0.085380934, 0.061244503, -0.06230063, -0.05353345, 0.1166729) * go_0(0.0, -1.0); result += mat4(0.08945733, 0.4101902, -0.06404005, 0.040728435, 0.13076581, -0.20805469, -0.10897316, -0.14924604, 0.10090762, 0.015475414, 0.26346552, 0.12096677, -0.20199244, 0.2780031, 0.18515368, 0.35105625) * go_0(0.0, 0.0); result += mat4(0.07463155, 0.26932517, -0.06768551, 0.10470878, -0.1423996, 0.013550665, -0.06167201, -0.1022994, -0.3107166, -0.15609552, 0.1695213, -0.1277181, 0.12582655, -0.1596128, 0.015612055, -0.19826376) * go_0(0.0, 1.0); result += mat4(0.011745468, 0.006471601, 0.008110513, 0.025831396, 0.1272883, -0.221959, 0.11993834, -0.007903633, 0.009993582, -0.10170755, 0.026594637, -0.027883623, 0.030666083, -0.036415886, 0.007469573, 0.0674783) * go_0(1.0, -1.0); result += mat4(-0.022760388, -0.10911659, -0.012589904, -0.046462692, 0.36987287, 0.71668935, -0.04466556, 0.12082762, 0.0026539841, 0.07070946, -0.00020439121, -0.13925348, 0.08672072, 0.20075354, -0.066352285, 0.14655356) * go_0(1.0, 0.0); result += mat4(-0.081081845, -0.21956222, 0.06781787, -0.106362104, -0.03016425, -0.010460211, -0.009725996, -0.009805538, 0.07037355, 0.19254607, 0.038890257, 0.29580075, -0.10355764, 0.12613009, 0.02485986, -0.031927988) * go_0(1.0, 1.0); result += mat4(-0.13882205, 0.21770848, 0.015392157, 0.010310204, 0.008225721, 0.07457836, 0.09984027, -0.25452816, 0.2193511, -0.22262146, -0.12950355, 0.026151875, 0.022114651, -0.030566849, 0.034688126, 0.03047327) * go_1(-1.0, -1.0); result += mat4(0.0363441, 0.19290726, -0.1143055, 0.30871987, -0.05780708, 0.082128406, -0.115280904, 0.07636388, 0.48947453, -0.29715258, 0.146737, -0.3275992, -0.055972476, -0.09991753, 0.17435446, 0.10917291) * go_1(-1.0, 0.0); result += mat4(0.026389305, 0.054523308, -0.028950177, 0.06913328, -0.18626037, 0.08829993, 0.10407121, 0.001246911, 0.103938825, -0.3117343, -0.045564886, 0.07316613, 0.0027089121, 0.099437356, -0.046500806, -0.0927284) * go_1(-1.0, 1.0); result += mat4(0.051037624, -0.2068234, 0.061572235, -0.3345198, 0.16960172, -0.30289862, -0.002583443, 0.39312238, 0.08246557, 0.16374862, -0.31902805, -0.13205275, -0.032050006, 0.01670186, 0.13852347, 0.120012194) * go_1(0.0, -1.0); result += mat4(-0.67096996, -0.06274476, 0.18575665, 0.80282855, 0.23201196, -0.0054729837, 0.050396994, -0.42014772, 0.34904522, 0.26281372, 0.24697208, 0.55475426, 0.49850988, -0.06581312, -0.0068906257, -0.15741143) * go_1(0.0, 0.0); result += mat4(-0.04252036, -0.28224963, 0.009723064, 0.116357096, 0.2992567, -0.26702902, -0.05648925, 0.12729199, -0.37574205, 0.54211813, -0.25248805, -0.13023548, 0.18903324, -0.5182459, 0.0141203115, -0.19444294) * go_1(0.0, 1.0); result += mat4(-0.0017735233, -0.010132458, -0.040924776, -0.13767008, 0.20757031, -0.06509882, -0.09756446, 0.018974079, 0.090851985, -0.010158765, -0.03999607, -0.12055641, 0.03629025, -0.018645551, -0.05506811, -0.014202848) * go_1(1.0, -1.0); result += mat4(0.16203491, 0.011118734, -0.18486023, -0.024290733, -0.3673846, -0.20295864, 0.23055002, -0.1555852, -0.02706522, 0.03262891, 0.008724611, -0.03760652, -0.20946771, -0.01951837, 0.16955496, 0.11690098) * go_1(1.0, 0.0); result += mat4(0.0783421, 0.22656651, -0.15715368, -0.024174158, 0.020260733, 0.032390315, -0.029133298, 0.086601086, 0.13871798, -0.12525433, 0.16097449, 0.058946393, 0.029865682, 0.08508385, 0.040569812, -0.09402932) * go_1(1.0, 1.0); result += mat4(-0.05063873, 0.11269313, -0.057484943, -0.13579641, 0.047973365, -0.07103839, -0.07838756, -0.0028928046, -0.019466015, 0.018428024, 0.010016324, -0.057396665, -0.19495595, 0.034307264, -0.022888038, 0.08112259) * go_2(-1.0, -1.0); result += mat4(-0.09790086, 0.10613111, 0.06611674, 0.19356097, -0.00073371036, -0.019078335, 0.076719105, -0.016212497, -0.3283475, -0.07547389, -0.08140701, 0.3185625, -0.25060275, 0.16820994, -0.123497784, 0.43272668) * go_2(-1.0, 0.0); result += mat4(-0.06365342, 0.11186735, -0.17493224, -0.04207358, 0.0003117533, 0.034089327, -3.067692e-05, -0.03422754, 0.16267666, 0.054771993, 0.048384454, -0.041866794, 0.0036008756, 0.0021496525, 0.20258942, -0.06297619) * go_2(-1.0, 1.0); result += mat4(0.03578836, 0.08763908, -0.22370125, -0.32465744, 0.019142643, 0.011316954, 0.17920344, 0.031633645, 0.03766343, -0.116487674, -0.05281752, -0.018965483, 0.049297336, -0.34511214, 0.42598158, 0.051361635) * go_2(0.0, -1.0); result += mat4(0.26638633, -0.33628765, 0.04437907, 0.09616201, -0.020049393, 0.2560829, -0.027108455, 0.255752, 0.3666511, 0.052277412, -0.46667686, 0.48482272, 0.51302284, -0.06941614, -0.17967525, -0.07889891) * go_2(0.0, 0.0); result += mat4(0.18503937, 0.088710256, 0.2083147, -0.20758459, -0.036416974, 0.018303726, 0.03729963, -0.035969947, -0.2685231, -0.42169708, -0.039593916, -0.02642618, 0.29050872, -0.25723743, -0.111259766, 0.15001127) * go_2(0.0, 1.0); result += mat4(-0.026473878, -0.07241443, 0.022400148, -0.03214132, 0.0859297, -0.0036677981, -0.07039137, 0.03703108, 0.042322673, -0.01222808, -0.08151938, 0.033109214, -0.048737407, 0.25929528, -0.40535828, -0.123594694) * go_2(1.0, -1.0); result += mat4(0.10233285, 0.22455986, -0.13368733, 0.033236265, -0.052114893, -0.11709317, 0.009709581, 0.19201641, -0.02973698, 0.032114245, -0.09771862, 0.085680574, 0.15827927, -0.15042172, 0.21833214, -0.13262676) * go_2(1.0, 0.0); result += mat4(-0.08460587, -0.09473209, 0.019323658, -0.057233352, 0.0019434267, -0.14437936, 0.034232683, 0.0030602294, -0.023598112, 0.10692026, -0.09960999, 0.005887181, 0.014738836, -0.32473162, -0.10886747, -0.08365826) * go_2(1.0, 1.0); result += mat4(0.10900178, 0.00080280803, -0.14009437, -0.053074867, -0.07811151, -0.03456029, -0.104943685, 0.016918905, -0.11335709, 0.079421654, 0.13481963, 0.037818357, -0.027339859, 0.05856774, -0.044562265, 0.03908084) * go_3(-1.0, -1.0); result += mat4(0.07628258, -0.23815769, 0.2840278, -0.3541637, -0.044292126, -0.09310441, -0.1335055, -0.031899665, -0.11981227, 0.24012394, -0.041896038, -0.10168982, 0.20248915, -0.10036763, -0.044115108, 0.08520525) * go_3(-1.0, 0.0); result += mat4(0.07234102, -0.119480744, -0.01401321, -0.025182616, -0.031284854, -0.050089385, 0.014808948, 0.038662236, -0.18539418, 0.017342187, 0.023812262, 0.13428104, 0.020824855, -0.07433546, 0.054307282, 0.08511016) * go_3(-1.0, 1.0); result += mat4(-0.11046813, -0.04663274, 0.33497185, 0.023273284, -0.24681108, 0.116665915, 0.12045893, 0.13306482, -0.039098527, 0.04747061, 0.042796664, 0.053514794, 0.011861975, -0.048702, 0.008408589, -0.09497112) * go_3(0.0, -1.0); result += mat4(0.34634927, 0.37973458, -0.79267627, -0.7362719, 0.35489878, -0.07635863, 0.24082923, -0.27480397, -0.3236968, -0.25523046, 0.05118527, -0.040529836, -0.6000509, 0.39020586, 0.27632973, 0.5141453) * go_3(0.0, 0.0); result += mat4(0.16761221, -0.033125393, 0.00561569, 0.083019435, -0.101278506, 0.07810264, 0.12060661, 0.16048536, 0.14257826, -0.15996903, 0.018831912, -0.094429865, -0.22227801, 0.426937, -0.054677445, 0.05067348) * go_3(0.0, 1.0); result += mat4(0.02233958, 0.02608942, -0.045318656, 0.06509929, 0.035911568, 0.025316885, 0.0840986, 0.08326237, 0.048455603, -0.13630742, 0.07230253, -0.047261715, -0.092630014, 0.04786565, 0.10354939, -0.07094341) * go_3(1.0, -1.0); result += mat4(-0.1463382, -0.14900577, 0.2835977, -0.106733374, -0.11554754, -0.168429, -0.1411373, -0.20654152, -0.06388508, 0.039648015, 0.08543832, -0.13253337, 0.017264463, -0.06346233, -0.10823598, 0.067361064) * go_3(1.0, 0.0); result += mat4(0.04419582, 0.039152585, 0.06222691, 0.05757103, 0.012084537, 0.051425997, -0.061130576, 0.16752882, 0.07497411, 0.13495837, -0.15585983, -0.02050144, -0.08555421, -0.09147339, 0.025115604, 0.05948922) * go_3(1.0, 1.0); result += vec4(0.00590038, 0.03082865, 0.002111702, -0.03330112); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x3x3x16 //!HOOK MAIN //!BIND conv2d_5_tf //!BIND conv2d_5_tf1 //!SAVE conv2d_6_tf1 //!WIDTH conv2d_5_tf.w //!HEIGHT conv2d_5_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define go_0(x_off, y_off) (max((conv2d_5_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_1(x_off, y_off) (max((conv2d_5_tf1_texOff(vec2(x_off, y_off))), 0.0)) #define go_2(x_off, y_off) (max(-(conv2d_5_tf_texOff(vec2(x_off, y_off))), 0.0)) #define go_3(x_off, y_off) (max(-(conv2d_5_tf1_texOff(vec2(x_off, y_off))), 0.0)) vec4 hook() { vec4 result = mat4(0.009029573, 0.029218858, 0.029705316, -0.019268971, -0.0023235187, -0.072589695, 0.1424836, 0.09049359, 0.04342995, 0.18134294, 0.018145641, 0.14789368, 0.050923645, 0.06524081, 0.036812488, 0.11108108) * go_0(-1.0, -1.0); result += mat4(-0.026506428, 0.016968496, 0.015961196, 0.010030791, -0.3141888, -0.06769598, -0.23920257, -0.031002127, -0.07351358, -0.19290134, -0.24282931, -0.18831016, -0.0928966, 0.075177215, -0.19699521, -0.05810917) * go_0(-1.0, 0.0); result += mat4(-0.017991852, -0.079427645, 0.035970494, -0.017095685, -0.27197137, -0.20046075, 0.2616644, 0.021876303, -0.077394076, -0.04978692, 0.20363241, -0.013741705, -0.032103598, 0.14403099, 0.01442474, 0.048115995) * go_0(-1.0, 1.0); result += mat4(-0.16939245, -0.001777, 0.026244136, -0.14122388, -0.056853324, 0.54357284, -0.19769607, -0.03187079, 0.04559263, -0.16048127, 0.12830622, 0.1442168, 0.006611398, -0.01618195, 0.012860053, -0.16539487) * go_0(0.0, -1.0); result += mat4(0.13116026, -0.006161343, 0.7209969, 0.18338475, 0.3099777, 0.6500026, 0.3883795, -0.021434233, 0.31667513, 0.008917659, 0.14124091, -0.22335114, 0.12198921, -0.16449445, 0.08773425, 0.30054978) * go_0(0.0, 0.0); result += mat4(-0.10413989, -0.10316161, 0.04342709, -0.021252686, 0.120892406, 0.37798002, -0.35963747, 0.021069285, 0.37587845, -0.08159587, 0.011139747, 0.2501104, -0.094568014, 0.037900843, -0.025109999, -0.030106556) * go_0(0.0, 1.0); result += mat4(0.09680291, -0.040868275, 0.051731605, 0.089064725, -0.56098557, -0.38148618, -0.017037416, 0.08508287, -0.019247344, 0.019857002, -0.03512887, 0.031057188, -0.09648583, -0.04474188, 0.028748507, -0.11880965) * go_0(1.0, -1.0); result += mat4(-0.010236943, 0.04257042, -0.08202597, -0.004203426, -0.26801527, -0.11716526, -0.017402772, -0.05819106, -0.13394608, 0.0234606, -0.15404865, -0.06801164, -0.0047627664, -0.1975249, 0.09420144, 0.23249897) * go_0(1.0, 0.0); result += mat4(0.107361935, 0.07373787, 0.06242962, 0.05236332, -0.028867323, 0.025924044, -0.042526353, -0.0015729597, -0.1323144, -0.4040712, 0.023919407, -0.09535502, 0.049100045, 0.081110805, 0.08946112, 0.058505684) * go_0(1.0, 1.0); result += mat4(0.13236825, -0.04468476, -0.04426802, 0.031087106, -0.09093992, -0.07470971, -0.01591504, 0.05924266, -0.21910913, 0.065537, -0.18358919, -0.02533145, -0.1512009, -0.04953928, 0.015540006, -0.0043442883) * go_1(-1.0, -1.0); result += mat4(-0.14016777, -0.1086958, 0.16316028, 0.050777458, 0.23148167, 0.04944809, -0.10599886, -0.10447021, -0.40729257, -0.10926556, 0.069055155, 0.110635415, 0.108922414, -0.1716362, 0.10743909, -0.102534756) * go_1(-1.0, 0.0); result += mat4(0.017795928, -0.066930935, 0.09396082, 0.092585504, 0.14223933, 0.059458215, 0.072033696, -0.04507726, -0.19956456, 0.1251282, -0.31733638, -0.10465904, 0.08546377, 0.048638333, 0.031372465, -0.08720661) * go_1(-1.0, 1.0); result += mat4(0.108719654, -0.092161916, -0.014724377, 0.20068261, -0.24350016, 0.2113636, -0.07483714, -0.45665312, -0.25134233, 0.2753893, -0.11324696, -0.04472, 0.1576102, -0.045395147, 0.06013951, -0.12507361) * go_1(0.0, -1.0); result += mat4(0.546225, -0.281897, 0.19477816, -0.116612464, -0.3145171, -0.41660902, 0.333625, 0.35902345, 0.48333502, 0.4662005, 0.10222491, -0.15314859, -0.3036888, 0.22849742, 0.20740797, 0.41399437) * go_1(0.0, 0.0); result += mat4(0.007284074, 0.0393942, -0.31192186, -0.15687793, -0.289214, -0.015956698, -0.24718472, -0.1637855, -0.00765037, 0.26677555, 0.20215511, 0.37790874, -0.22096673, 0.25287116, -0.2446764, -0.13610223) * go_1(0.0, 1.0); result += mat4(-0.16734968, 0.16721225, -0.053508647, -0.041097626, 0.062356673, 0.07812319, -0.263546, -0.39739034, 0.003389846, 0.12676363, -0.13175991, -0.19019242, -0.011847587, -0.007580052, -0.023946386, 0.046034034) * go_1(1.0, -1.0); result += mat4(-0.17047611, 0.13298693, -0.07506747, -0.045542978, 0.33571973, 0.20192616, 0.30674616, 0.25668672, -0.24134545, 0.031693842, -0.009647641, 0.040534843, 0.03159419, -0.1100516, 0.11371316, 0.06098735) * go_1(1.0, 0.0); result += mat4(-0.05518961, 0.19402988, -0.09646874, -0.059196774, -0.0073436056, -0.1381309, 0.06868669, 0.061328378, -0.1480867, -0.15774113, -0.022572191, 0.122521356, -0.04067007, -0.10145177, 0.13006335, -0.099452734) * go_1(1.0, 1.0); result += mat4(0.06962972, 0.07768411, 0.021085173, 0.108355984, -0.03132525, 0.10220273, -0.11626593, -0.14104277, 0.018778645, -0.024237925, 0.048783034, 0.09074447, 0.4120426, -0.01948466, 0.073218934, 0.055681944) * go_2(-1.0, -1.0); result += mat4(-0.22553118, -0.12923603, -0.22068842, -0.35037905, 0.005709937, -0.09528472, 0.08718399, 0.13200706, 0.17220478, 0.096844435, -0.30439013, -0.14122063, 0.15733318, -0.1014675, 0.33836862, 0.042193163) * go_2(-1.0, 0.0); result += mat4(0.15826897, -0.034870047, 0.09295099, -0.17674965, -0.042326324, 0.06680338, -0.074267656, -0.0631393, -0.11267909, -0.19795708, 0.22005288, 0.35703793, 0.033995766, -0.12663686, -0.02449896, -0.123250045) * go_2(-1.0, 1.0); result += mat4(0.021434195, 0.058398597, 0.04828315, -0.0016824572, -0.04291545, -0.0744907, -0.07698706, -0.15937585, -0.18852457, -0.17966963, 0.023800725, 0.025979731, -0.51412296, -0.018316887, -0.23076254, -0.12298674) * go_2(0.0, -1.0); result += mat4(0.16054317, -0.0002730893, -0.54173076, -0.62443435, 0.04300197, -0.08529622, 0.15392275, 0.15742144, 0.025834514, -0.2800517, -0.17600477, 0.0020806703, -0.3010582, 0.45233512, 0.25595665, 0.103661336) * go_2(0.0, 0.0); result += mat4(-0.024034392, -0.43800178, 0.28606912, -0.20908915, 0.078471914, -0.030501373, -0.059055753, 0.050494444, 0.063274644, -0.025071034, 0.17561312, -0.100698635, -0.25631955, 0.039981876, -0.18506624, 0.08366402) * go_2(0.0, 1.0); result += mat4(-0.1413656, 0.03589635, -0.020917566, 0.017598262, 0.020156413, -0.018854238, 0.027228508, -0.03806087, -0.021715842, 0.071974196, -0.040065665, 0.08459291, -0.23530225, 0.16599682, -0.2772327, 0.10041177) * go_2(1.0, -1.0); result += mat4(-0.055056706, 0.1286236, -0.11890451, -0.1790546, 0.16517544, -0.040448934, 0.12548013, 0.017075695, 0.07185459, -0.13236302, 0.19354409, 0.12767012, 0.31120765, 0.16378082, -0.036915366, -0.19724306) * go_2(1.0, 0.0); result += mat4(-0.02225051, 0.033263147, 0.003279449, 0.08826271, -0.047833472, 6.574577e-05, 0.13721916, 0.04801998, -0.014958419, 0.08791209, -0.08076282, 0.024002168, -0.18028922, 0.23835851, -0.23309888, -0.119310364) * go_2(1.0, 1.0); result += mat4(0.044960875, 0.18821983, 0.027640678, 0.013462449, 0.19011214, 0.21559924, -0.03329638, 0.07234414, 0.030880248, -0.11273214, 0.102028474, 0.12203351, 0.035855662, 0.008828778, 0.007218363, -0.012421797) * go_3(-1.0, -1.0); result += mat4(-0.09450626, 0.025191775, -0.10738468, 0.16237053, 0.073676676, 0.12488881, -0.048748355, 0.007877263, 0.3572506, -0.07911043, 0.14684045, 0.0015310893, -0.33411503, -0.1151223, 0.004201752, 0.017775744) * go_3(-1.0, 0.0); result += mat4(-0.10607509, -0.008143826, -0.08448629, -0.27557802, 0.0046665915, 0.008158659, 0.030826218, 0.020516023, 0.2333065, -0.017463414, -0.041772116, -0.03027809, -0.028166672, -0.080471426, 0.048199337, 0.08341059) * go_3(-1.0, 1.0); result += mat4(-0.14640257, -0.18334304, -0.061674733, 0.0008892598, -0.2374775, -0.2721524, -0.040371176, 0.26362613, 0.19872928, -0.11246391, 0.0842288, 0.11188515, 0.0045209546, -0.04250933, -0.0738212, -0.069005966) * go_3(0.0, -1.0); result += mat4(-0.08760266, 0.4816288, -0.21241407, 0.22734411, -0.1783721, -0.26842996, 0.099888, -0.2867675, 0.085521065, -0.3780281, -0.018543908, -0.039699722, 0.75688565, -0.5333645, 0.47567275, 0.09518891) * go_3(0.0, 0.0); result += mat4(-0.04072665, 0.05998423, -0.48314768, -0.29495844, 0.10358383, -0.09816629, 0.028586809, -0.047708735, 0.008320228, 0.04089551, -0.18359782, -0.27615002, 0.12414414, -0.072417594, 0.25932562, 0.30268723) * go_3(0.0, 1.0); result += mat4(0.14481631, 0.06484443, -0.09898657, -0.06553556, 0.25750044, -0.07265585, 0.12903488, -0.022347894, -0.04693863, -0.000107379274, 0.030295763, -0.0325354, 0.086214684, -0.021326948, 0.039682828, -0.034843277) * go_3(1.0, -1.0); result += mat4(-0.031971477, -0.25145087, 0.03931631, 0.14262606, -0.06044626, 0.22820354, -0.10506207, 0.18064679, 0.0069641788, 0.01477993, -0.003626875, 0.118767865, 0.109416224, -0.002998205, 0.035680585, 0.07843882) * go_3(1.0, 0.0); result += mat4(0.03375426, -0.059815384, 0.11632834, -0.12411481, 0.022583738, 0.02544465, -0.054889992, -0.07031964, -0.10140042, 0.16750422, -0.1448294, -0.09316004, 0.035582513, -0.026138382, -0.031955894, 0.040148776) * go_3(1.0, 1.0); result += vec4(-0.03573331, 0.032919675, 0.011109369, 0.008329268); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x1x1x112 //!HOOK MAIN //!BIND conv2d_tf //!BIND conv2d_tf1 //!BIND conv2d_1_tf //!BIND conv2d_1_tf1 //!BIND conv2d_2_tf //!BIND conv2d_2_tf1 //!BIND conv2d_3_tf //!BIND conv2d_3_tf1 //!BIND conv2d_4_tf //!BIND conv2d_4_tf1 //!BIND conv2d_5_tf //!BIND conv2d_5_tf1 //!BIND conv2d_6_tf //!BIND conv2d_6_tf1 //!SAVE conv2d_last_tf //!WIDTH conv2d_tf.w //!HEIGHT conv2d_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define g_0 (max((conv2d_tf_tex(conv2d_tf_pos)), 0.0)) #define g_1 (max((conv2d_tf1_tex(conv2d_tf1_pos)), 0.0)) #define g_2 (max(-(conv2d_tf_tex(conv2d_tf_pos)), 0.0)) #define g_3 (max(-(conv2d_tf1_tex(conv2d_tf1_pos)), 0.0)) #define g_4 (max((conv2d_1_tf_tex(conv2d_1_tf_pos)), 0.0)) #define g_5 (max((conv2d_1_tf1_tex(conv2d_1_tf1_pos)), 0.0)) #define g_6 (max(-(conv2d_1_tf_tex(conv2d_1_tf_pos)), 0.0)) #define g_7 (max(-(conv2d_1_tf1_tex(conv2d_1_tf1_pos)), 0.0)) #define g_8 (max((conv2d_2_tf_tex(conv2d_2_tf_pos)), 0.0)) #define g_9 (max((conv2d_2_tf1_tex(conv2d_2_tf1_pos)), 0.0)) #define g_10 (max(-(conv2d_2_tf_tex(conv2d_2_tf_pos)), 0.0)) #define g_11 (max(-(conv2d_2_tf1_tex(conv2d_2_tf1_pos)), 0.0)) #define g_12 (max((conv2d_3_tf_tex(conv2d_3_tf_pos)), 0.0)) #define g_13 (max((conv2d_3_tf1_tex(conv2d_3_tf1_pos)), 0.0)) #define g_14 (max(-(conv2d_3_tf_tex(conv2d_3_tf_pos)), 0.0)) #define g_15 (max(-(conv2d_3_tf1_tex(conv2d_3_tf1_pos)), 0.0)) #define g_16 (max((conv2d_4_tf_tex(conv2d_4_tf_pos)), 0.0)) #define g_17 (max((conv2d_4_tf1_tex(conv2d_4_tf1_pos)), 0.0)) #define g_18 (max(-(conv2d_4_tf_tex(conv2d_4_tf_pos)), 0.0)) #define g_19 (max(-(conv2d_4_tf1_tex(conv2d_4_tf1_pos)), 0.0)) #define g_20 (max((conv2d_5_tf_tex(conv2d_5_tf_pos)), 0.0)) #define g_21 (max((conv2d_5_tf1_tex(conv2d_5_tf1_pos)), 0.0)) #define g_22 (max(-(conv2d_5_tf_tex(conv2d_5_tf_pos)), 0.0)) #define g_23 (max(-(conv2d_5_tf1_tex(conv2d_5_tf1_pos)), 0.0)) #define g_24 (max((conv2d_6_tf_tex(conv2d_6_tf_pos)), 0.0)) #define g_25 (max((conv2d_6_tf1_tex(conv2d_6_tf1_pos)), 0.0)) #define g_26 (max(-(conv2d_6_tf_tex(conv2d_6_tf_pos)), 0.0)) #define g_27 (max(-(conv2d_6_tf1_tex(conv2d_6_tf1_pos)), 0.0)) vec4 hook() { vec4 result = mat4(-0.11498094, -0.053904895, -0.11520678, -0.05479549, 0.028396055, 0.032767884, 0.052479446, 0.05257866, -0.25706592, -0.3454966, -0.24713765, -0.2854201, -0.10287636, 0.0023146886, -0.09190338, -0.011193905) * g_0; result += mat4(-0.05461422, 0.008780496, -0.07738697, -0.032230727, -0.047554165, -0.025061952, -0.051897213, -0.009545297, -0.14548294, -0.15184018, -0.01313442, -0.015299784, -0.0007883845, -0.12866738, -0.15260352, -0.27081275) * g_1; result += mat4(0.11007706, 0.035344437, 0.11020841, 0.0425353, 0.1613199, 0.18417408, 0.09274313, 0.11943135, 0.106862, 0.079875536, 0.0937752, 0.068030775, 0.029093558, -0.06441164, 0.06467169, -0.021989612) * g_2; result += mat4(0.049548414, -0.012455486, 0.07185561, 0.021865537, 0.020969186, -0.03374196, -0.024260623, -0.07739141, 0.07164591, 0.12741035, 0.0379913, 0.076403245, 0.07049977, 0.0744538, 0.0062989634, 0.01818882) * g_3; result += mat4(-0.12511204, -0.010836819, 0.13709816, 0.22472954, 0.21280868, -0.006484726, 0.17554289, -0.009977173, 0.078398876, 0.20698707, 0.13432744, 0.29740283, -0.24750128, -0.32757792, -0.19807857, -0.2537023) * g_4; result += mat4(-0.27207088, -0.1385644, -0.2166476, -0.07687419, -0.20300622, -0.29678395, -0.13135734, -0.20851587, 0.0361364, 0.011243289, -0.06845459, -0.11796941, 0.11575868, 0.070215136, -0.10295678, -0.12281369) * g_5; result += mat4(0.13619795, -0.0019436983, -0.12701888, -0.25933513, -0.20134166, 0.00062823144, -0.076756015, 0.11002947, 0.0059049693, -0.18756741, -0.0718802, -0.2589954, 0.23413423, 0.30107784, 0.14445266, 0.18920745) * g_6; result += mat4(0.1494216, 0.0587532, 0.05478662, -0.039123338, 0.23322394, 0.29950607, 0.24384268, 0.27843767, -0.16094431, -0.04705998, -0.016345032, 0.028868208, -0.102872886, -0.04659664, 0.104105346, 0.14305067) * g_7; result += mat4(-0.001037014, 0.010001526, -0.0052278573, 0.024779709, 0.06857274, 0.067640975, 0.085439384, 0.09242789, -0.066597246, -0.055928994, 0.0015658981, 0.016131008, -0.03524695, -0.018364554, -0.047754433, -0.014295886) * g_8; result += mat4(-0.042207, 0.02835915, -0.1404656, -0.08563323, -0.030979915, -0.0673764, 0.10733943, 0.057902794, 0.00022424995, -0.0023634837, -0.10778953, -0.10202357, -0.020368295, -0.019088887, -0.06875738, -0.08504131) * g_9; result += mat4(-0.00043458896, 0.00045652856, -0.02016843, -0.020062413, -0.08740103, -0.042085808, -0.10644177, -0.09226477, 0.11212161, -0.00048174805, 0.021872435, -0.05868698, 0.0333954, 0.058184672, 0.05532576, 0.07621587) * g_10; result += mat4(0.054245148, 0.001020329, 0.09106849, 0.05303779, 0.009889632, 0.01309413, -0.09187347, -0.08618193, -0.011621187, 0.016222361, 0.061095525, 0.060885344, 0.078050986, 0.0111776795, 0.08829944, 0.032022282) * g_11; result += mat4(0.01643529, 0.02285545, -0.03498564, 0.00769657, -0.0042474116, 0.015836312, -0.025771018, -0.0016368, -0.008897948, -0.012588166, -0.01416411, -0.003578984, 0.025991246, 0.021237152, 0.017450012, 0.025172485) * g_12; result += mat4(0.014568868, 0.017796224, -0.036679734, -0.03138748, 0.019457601, -0.027607411, -0.004529679, -0.038048342, -0.054055385, -0.03876025, 0.041948095, 0.005869784, 0.02439633, 0.05177997, 0.016000897, 0.0057169925) * g_13; result += mat4(-0.03021866, 0.017678728, -0.01371109, 0.013548159, -0.0038099394, -0.014066414, 0.028093752, 0.0027308422, -0.010615999, 0.012673458, -0.03028171, -0.016818244, -0.06530097, -0.018845048, -0.0072947564, -0.0038243714) * g_14; result += mat4(-0.019006258, -0.007847591, 0.03690709, 0.06714211, 0.0073993434, -0.009766907, -0.0021441753, -0.01308625, 0.06658726, 0.06701995, -0.027305668, -0.016032105, -0.028976806, -0.0036668575, -0.0027825525, 0.0105632655) * g_15; result += mat4(0.028945107, -0.0014701135, 0.048950657, -0.01923516, -0.0014054152, 0.002650635, -0.005300331, 0.004860559, 0.011158468, 0.005940625, -0.012095051, 0.0041518128, -0.020433836, -0.025870577, -0.0007547932, -0.026509356) * g_16; result += mat4(-0.004545374, 0.04264545, 0.021741537, 0.029115127, 0.04225599, -0.0055392785, 0.026570829, -0.031795148, -0.008307126, 0.020176455, 0.010904648, 0.017765503, -0.10806103, -0.01776947, 0.00070428237, -0.06356262) * g_17; result += mat4(-0.05663172, 0.05908046, -0.03837452, 0.06636983, -0.007960516, -0.06384041, 0.023125881, -0.030108837, 0.0038054318, -0.023263922, 0.020264054, -0.0062937695, 0.031630237, 0.020909082, 0.03594235, 0.035879835) * g_18; result += mat4(-0.0050448794, 0.033650696, -0.002830413, 0.035174295, -0.024521282, 0.013054315, -0.020833842, 0.037953895, 0.08249671, 0.024239466, -0.012758333, -0.027316988, 0.051040914, 0.0005025873, 0.039778862, 0.0024668393) * g_19; result += mat4(0.017232442, 0.022482058, 0.020233413, 0.024337437, 0.07986929, 0.06234036, 0.12662584, -0.05271183, -0.009718745, -0.0046989853, -0.0030333172, -0.04034237, -0.0113442, 0.022746231, -0.035293855, -0.009433693) * g_20; result += mat4(0.015766997, 0.013647276, -0.029327558, 0.039106004, -0.010398323, -0.032851525, 0.02908329, -0.003789618, 0.12963496, 0.010851003, 0.1126276, -0.049255487, 0.06867432, 0.07970792, 0.017840397, -0.026481882) * g_21; result += mat4(-0.058729574, -0.07886952, 0.033267397, 0.02755372, -0.0172006, 0.012404398, -0.0230168, -0.015059758, -0.09239916, -0.029533267, -0.043251917, 0.0035152994, 0.022931995, 0.101714484, -0.044946067, 0.094993) * g_22; result += mat4(-0.04708704, -0.032475296, -0.03228093, -0.08810475, 0.013745045, 0.027828002, -0.031922746, 0.022986397, -0.061620213, -0.03694645, -0.055026993, 0.0031291894, -0.028799903, -0.0025357977, -0.03441407, 0.0028600092) * g_23; result += mat4(0.058981724, -0.10447273, -0.088705614, 0.16546178, -0.023549391, -0.008831522, -0.018411588, 0.029640056, -0.068086684, -0.05414636, -0.029401174, 0.036180343, -0.031988926, -0.047249753, 0.008162177, 0.00548062) * g_24; result += mat4(0.05287462, -0.030657746, 0.02821435, 0.037005343, 0.03534311, -0.15614955, 0.07085459, -0.11997641, -0.009156166, -0.021968868, -0.054147746, -0.07307657, -0.006428544, -0.017528288, 0.012614676, 0.037840024) * g_25; result += mat4(-0.021977803, 0.047799855, 0.02660416, -0.07292106, 0.045195807, -0.0056674764, 0.10824326, -0.112114795, 0.1447127, -0.0119616175, 0.0011661504, -0.04553905, 0.13048342, 0.14574122, -0.105522245, -0.102792375) * g_26; result += mat4(-0.16397473, 0.15785863, -0.06666504, -0.01682913, 0.06070918, 0.070222184, 0.037701584, 0.026657054, -0.0835267, -0.009457008, 0.13232987, 0.13508691, -0.056414206, -0.06818828, 0.079076104, 0.032249212) * g_27; result += vec4(-0.10795144, -0.09953324, -0.055413827, -0.03875493); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x1x1x112 //!HOOK MAIN //!BIND conv2d_tf //!BIND conv2d_tf1 //!BIND conv2d_1_tf //!BIND conv2d_1_tf1 //!BIND conv2d_2_tf //!BIND conv2d_2_tf1 //!BIND conv2d_3_tf //!BIND conv2d_3_tf1 //!BIND conv2d_4_tf //!BIND conv2d_4_tf1 //!BIND conv2d_5_tf //!BIND conv2d_5_tf1 //!BIND conv2d_6_tf //!BIND conv2d_6_tf1 //!SAVE conv2d_last_tf1 //!WIDTH conv2d_tf.w //!HEIGHT conv2d_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define g_0 (max((conv2d_tf_tex(conv2d_tf_pos)), 0.0)) #define g_1 (max((conv2d_tf1_tex(conv2d_tf1_pos)), 0.0)) #define g_2 (max(-(conv2d_tf_tex(conv2d_tf_pos)), 0.0)) #define g_3 (max(-(conv2d_tf1_tex(conv2d_tf1_pos)), 0.0)) #define g_4 (max((conv2d_1_tf_tex(conv2d_1_tf_pos)), 0.0)) #define g_5 (max((conv2d_1_tf1_tex(conv2d_1_tf1_pos)), 0.0)) #define g_6 (max(-(conv2d_1_tf_tex(conv2d_1_tf_pos)), 0.0)) #define g_7 (max(-(conv2d_1_tf1_tex(conv2d_1_tf1_pos)), 0.0)) #define g_8 (max((conv2d_2_tf_tex(conv2d_2_tf_pos)), 0.0)) #define g_9 (max((conv2d_2_tf1_tex(conv2d_2_tf1_pos)), 0.0)) #define g_10 (max(-(conv2d_2_tf_tex(conv2d_2_tf_pos)), 0.0)) #define g_11 (max(-(conv2d_2_tf1_tex(conv2d_2_tf1_pos)), 0.0)) #define g_12 (max((conv2d_3_tf_tex(conv2d_3_tf_pos)), 0.0)) #define g_13 (max((conv2d_3_tf1_tex(conv2d_3_tf1_pos)), 0.0)) #define g_14 (max(-(conv2d_3_tf_tex(conv2d_3_tf_pos)), 0.0)) #define g_15 (max(-(conv2d_3_tf1_tex(conv2d_3_tf1_pos)), 0.0)) #define g_16 (max((conv2d_4_tf_tex(conv2d_4_tf_pos)), 0.0)) #define g_17 (max((conv2d_4_tf1_tex(conv2d_4_tf1_pos)), 0.0)) #define g_18 (max(-(conv2d_4_tf_tex(conv2d_4_tf_pos)), 0.0)) #define g_19 (max(-(conv2d_4_tf1_tex(conv2d_4_tf1_pos)), 0.0)) #define g_20 (max((conv2d_5_tf_tex(conv2d_5_tf_pos)), 0.0)) #define g_21 (max((conv2d_5_tf1_tex(conv2d_5_tf1_pos)), 0.0)) #define g_22 (max(-(conv2d_5_tf_tex(conv2d_5_tf_pos)), 0.0)) #define g_23 (max(-(conv2d_5_tf1_tex(conv2d_5_tf1_pos)), 0.0)) #define g_24 (max((conv2d_6_tf_tex(conv2d_6_tf_pos)), 0.0)) #define g_25 (max((conv2d_6_tf1_tex(conv2d_6_tf1_pos)), 0.0)) #define g_26 (max(-(conv2d_6_tf_tex(conv2d_6_tf_pos)), 0.0)) #define g_27 (max(-(conv2d_6_tf1_tex(conv2d_6_tf1_pos)), 0.0)) vec4 hook() { vec4 result = mat4(0.024905335, -0.0020974763, 0.02695263, 0.00016802056, -0.024053082, -0.02133723, -0.031614035, -0.031826317, 0.120421864, 0.10555479, 0.08609448, 0.116875134, 0.046175968, 0.04224941, 0.059216674, 0.035143953) * g_0; result += mat4(0.059397914, 0.016519934, 0.07189327, 0.047407165, 0.04808963, 0.02792908, 0.057017103, 0.034324065, 0.14228246, 0.11275426, 0.088058695, 0.059600517, 0.02063494, 0.052596953, 0.047207687, 0.08789091) * g_1; result += mat4(-0.013453174, 0.008474715, -0.017593835, 0.009218917, 0.070580654, 0.040542338, 0.08812338, 0.074653216, -0.016356857, 0.015809007, -0.008739107, 0.0097674895, -0.018381525, -0.007775341, -0.040571664, -0.011188163) * g_2; result += mat4(-0.026196122, -0.034825727, -0.042998232, -0.033436514, -0.01678153, -0.004592797, -0.010311677, 0.0008815291, -0.08899181, -0.10274026, -0.066960976, -0.082430154, -0.057137426, -0.07554528, -0.030993424, -0.050372377) * g_3; result += mat4(0.022921838, -0.010479244, -0.050794605, -0.073633075, -0.053708922, 0.009594084, -0.071259, -0.01054356, 0.005165821, -0.08024963, -0.049251772, -0.09581235, 0.17995799, 0.09743011, 0.13533138, 0.11643848) * g_4; result += mat4(0.09727046, 0.07292666, 0.06820908, 0.041535784, -0.0049705, 0.0048759184, -0.035702795, -0.015944308, -0.010730028, 0.018847652, 0.06466244, 0.086318985, -0.05661574, -0.040698618, 0.010839972, 0.0027009705) * g_5; result += mat4(-0.04628466, 0.010060396, 0.02609333, 0.08664702, 0.057045907, 0.033591177, 0.02186063, -0.024303377, 0.006569828, 0.08025825, 0.016128821, 0.10180713, -0.12228169, -0.112990454, -0.078443415, -0.09126021) * g_6; result += mat4(-0.12733299, -0.087755, -0.07374111, -0.044979006, -0.025347412, -0.004083168, 0.023782173, 0.02900392, -0.017815407, -0.041119996, -0.057978686, -0.13521095, 0.08364004, 0.06950181, 0.023554614, 0.008043734) * g_7; result += mat4(0.009062775, -0.003570175, -0.007378757, -0.0018487388, 0.01145638, 0.05217187, -0.008250244, 0.008433307, -0.056756936, -0.044681005, -0.08096105, -0.08033185, -0.023784965, -0.01859799, 0.013042476, 0.021188647) * g_8; result += mat4(-0.0071619656, -0.012498299, -0.05144986, -0.078112476, -0.034992415, -0.017038302, -0.04464615, -0.044504963, 0.024249, -0.004297534, 0.03674578, 0.03090718, 0.04698553, 0.008344952, 0.057619847, -0.0338724) * g_9; result += mat4(-0.011845145, -0.0045043705, -1.6646482e-06, -0.0038495932, -0.01992515, 0.004827126, 0.019493148, 0.00862289, 0.10151322, 0.0021909082, 0.09940764, 0.03728846, 0.027824005, 0.04358071, 0.014909185, 0.036326095) * g_10; result += mat4(0.022513246, 0.028257169, 0.0102195935, 0.03301329, 0.052253865, -0.0021944977, 0.08247392, 0.03256867, -0.040685873, -0.0052207555, -0.0451257, -0.054165114, 0.01647699, 0.0028809097, -0.015233776, -0.0008741886) * g_11; result += mat4(0.017371105, 0.01597189, -0.052552313, -0.008554715, -0.0023150423, 0.006076517, -0.012868931, 0.0039361073, -0.007524978, -0.004284313, -0.021520883, -0.010327569, 0.02543678, 0.008725823, -0.0073885336, 0.005528395) * g_12; result += mat4(0.019192757, 0.016561812, 0.0027538154, 0.0013078215, 0.007916496, -0.042525183, -0.013173432, -0.05265476, -0.062195376, -0.011255499, 0.020898128, 0.021532273, -0.001524097, 0.034835674, -0.004051403, -0.0292426) * g_13; result += mat4(-0.049191684, -9.43322e-06, -0.009106849, 0.012845289, -0.019482708, -0.011163468, 0.0034011535, -0.007062845, -0.006469714, 0.03177786, -0.033006195, -0.0006813464, -0.053963087, 0.00085209147, 0.02734121, 0.034086403) * g_14; result += mat4(-0.03232248, -0.004037002, -0.010319106, 0.030889064, 0.019604538, 0.0020888883, 0.010277864, 0.000661223, 0.057915937, 0.030683514, 0.00042533095, -0.013019287, -0.015896408, 0.0038484468, -0.0042103594, 0.02174542) * g_15; result += mat4(0.032975145, 0.0011456647, 0.04913679, -0.017063798, 0.0117176045, 0.007440557, 0.0020480808, 0.009415731, 0.027573857, 0.015140836, -0.01679426, -0.006124731, -0.03206279, -0.029842237, -0.010428016, -0.028513178) * g_16; result += mat4(-0.00506859, 0.055869613, 0.010164368, 0.027031485, 0.042289548, -0.0054258504, 0.032214936, -0.029970925, -0.0058315448, 0.022889478, 0.01681123, 0.02985076, -0.111186065, -0.02202099, 0.0030994313, -0.062343158) * g_17; result += mat4(-0.060951103, 0.06079555, -0.0396464, 0.070911355, -0.011480358, -0.06803282, 0.01637355, -0.043100975, -0.00423709, -0.028337711, 0.021635853, 0.0014857082, 0.030084312, 0.018155476, 0.043694943, 0.038795974) * g_18; result += mat4(-0.0060662925, 0.029721662, -0.008117774, 0.034551267, -0.024477571, 0.018841071, -0.027095588, 0.034495078, 0.082398005, 0.008998768, -0.016399248, -0.043801688, 0.05936684, 0.006066549, 0.045399766, 3.5319943e-05) * g_19; result += mat4(0.019259382, 0.02494012, 0.029301709, 0.028329274, 0.09122267, 0.06900443, 0.1412115, -0.043169618, -0.01627418, -0.004989528, -0.0042651827, -0.04556752, -0.023623291, 0.013007996, -0.04483056, -0.015727345) * g_20; result += mat4(0.016332543, 0.016384754, -0.030676385, 0.045312885, -0.0100853555, -0.032632045, 0.031514473, -0.0070776115, 0.13642761, 0.0023589598, 0.12214136, -0.062155515, 0.08240989, 0.08894205, 0.03325406, -0.016589595) * g_21; result += mat4(-0.06494277, -0.08158925, 0.030425413, 0.019835634, -0.012624623, 0.013942616, -0.030527417, -0.021668324, -0.09444672, -0.033064254, -0.044167448, 0.0011024752, 0.03210801, 0.12662941, -0.03912534, 0.1112649) * g_22; result += mat4(-0.04716062, -0.03751481, -0.031030515, -0.09067383, 0.0077815712, 0.02169541, -0.035285182, 0.02290573, -0.0704085, -0.03916127, -0.058103334, 0.004915147, -0.0333844, -0.011548617, -0.031151932, -0.00043817286) * g_23; result += mat4(0.05976319, -0.107285, -0.097245865, 0.17706421, -0.021453341, -0.0047738464, -0.017621001, 0.033400454, -0.07225561, -0.05599672, -0.027600193, 0.038664024, -0.03762786, -0.052429967, 0.0104017975, 0.007116869) * g_24; result += mat4(0.06014114, -0.029824806, 0.03209269, 0.04392036, 0.031300627, -0.16249833, 0.06878509, -0.12658615, -0.012383169, -0.025043553, -0.06527381, -0.08149099, -0.014006842, -0.018669648, 0.014510818, 0.042045828) * g_25; result += mat4(-0.023342922, 0.047104675, 0.029629575, -0.082307704, 0.04035797, -0.0013049254, 0.11085582, -0.11031226, 0.14778149, -0.016699014, -0.00634342, -0.055320874, 0.14306462, 0.15896587, -0.110229075, -0.1069649) * g_26; result += mat4(-0.17449625, 0.15787153, -0.06711028, -0.023110518, 0.06862914, 0.074063435, 0.042682912, 0.029800726, -0.08768606, -0.009814701, 0.14180017, 0.14780663, -0.05672417, -0.074305914, 0.07873489, 0.028458012) * g_27; result += vec4(0.06026231, 0.040204916, 0.037672628, 0.023496555); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Conv-4x1x1x112 //!HOOK MAIN //!BIND conv2d_tf //!BIND conv2d_tf1 //!BIND conv2d_1_tf //!BIND conv2d_1_tf1 //!BIND conv2d_2_tf //!BIND conv2d_2_tf1 //!BIND conv2d_3_tf //!BIND conv2d_3_tf1 //!BIND conv2d_4_tf //!BIND conv2d_4_tf1 //!BIND conv2d_5_tf //!BIND conv2d_5_tf1 //!BIND conv2d_6_tf //!BIND conv2d_6_tf1 //!SAVE conv2d_last_tf2 //!WIDTH conv2d_tf.w //!HEIGHT conv2d_tf.h //!COMPONENTS 4 //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * #define g_0 (max((conv2d_tf_tex(conv2d_tf_pos)), 0.0)) #define g_1 (max((conv2d_tf1_tex(conv2d_tf1_pos)), 0.0)) #define g_2 (max(-(conv2d_tf_tex(conv2d_tf_pos)), 0.0)) #define g_3 (max(-(conv2d_tf1_tex(conv2d_tf1_pos)), 0.0)) #define g_4 (max((conv2d_1_tf_tex(conv2d_1_tf_pos)), 0.0)) #define g_5 (max((conv2d_1_tf1_tex(conv2d_1_tf1_pos)), 0.0)) #define g_6 (max(-(conv2d_1_tf_tex(conv2d_1_tf_pos)), 0.0)) #define g_7 (max(-(conv2d_1_tf1_tex(conv2d_1_tf1_pos)), 0.0)) #define g_8 (max((conv2d_2_tf_tex(conv2d_2_tf_pos)), 0.0)) #define g_9 (max((conv2d_2_tf1_tex(conv2d_2_tf1_pos)), 0.0)) #define g_10 (max(-(conv2d_2_tf_tex(conv2d_2_tf_pos)), 0.0)) #define g_11 (max(-(conv2d_2_tf1_tex(conv2d_2_tf1_pos)), 0.0)) #define g_12 (max((conv2d_3_tf_tex(conv2d_3_tf_pos)), 0.0)) #define g_13 (max((conv2d_3_tf1_tex(conv2d_3_tf1_pos)), 0.0)) #define g_14 (max(-(conv2d_3_tf_tex(conv2d_3_tf_pos)), 0.0)) #define g_15 (max(-(conv2d_3_tf1_tex(conv2d_3_tf1_pos)), 0.0)) #define g_16 (max((conv2d_4_tf_tex(conv2d_4_tf_pos)), 0.0)) #define g_17 (max((conv2d_4_tf1_tex(conv2d_4_tf1_pos)), 0.0)) #define g_18 (max(-(conv2d_4_tf_tex(conv2d_4_tf_pos)), 0.0)) #define g_19 (max(-(conv2d_4_tf1_tex(conv2d_4_tf1_pos)), 0.0)) #define g_20 (max((conv2d_5_tf_tex(conv2d_5_tf_pos)), 0.0)) #define g_21 (max((conv2d_5_tf1_tex(conv2d_5_tf1_pos)), 0.0)) #define g_22 (max(-(conv2d_5_tf_tex(conv2d_5_tf_pos)), 0.0)) #define g_23 (max(-(conv2d_5_tf1_tex(conv2d_5_tf1_pos)), 0.0)) #define g_24 (max((conv2d_6_tf_tex(conv2d_6_tf_pos)), 0.0)) #define g_25 (max((conv2d_6_tf1_tex(conv2d_6_tf1_pos)), 0.0)) #define g_26 (max(-(conv2d_6_tf_tex(conv2d_6_tf_pos)), 0.0)) #define g_27 (max(-(conv2d_6_tf1_tex(conv2d_6_tf1_pos)), 0.0)) vec4 hook() { vec4 result = mat4(0.1765669, 0.14268716, 0.19186598, 0.15799578, 0.016374417, 0.018578433, 0.0039475, 0.0046772263, 0.39840183, 0.36909792, 0.35409746, 0.37422222, -0.108508386, -0.1331279, -0.10336035, -0.14776541) * g_0; result += mat4(-0.057757027, -0.14071062, -0.025283009, -0.09397916, -0.09031894, -0.14219165, -0.08299535, -0.13970287, -0.12259208, -0.14382727, -0.22002274, -0.25016093, -0.048906635, 0.06620249, 0.016965045, 0.1295978) * g_1; result += mat4(-0.16748372, -0.13718611, -0.18565705, -0.15029612, -0.080749065, -0.09955825, 0.032431383, 0.023855643, -0.2748885, -0.23232168, -0.29121292, -0.26405892, 0.16556135, 0.18657646, 0.1424068, 0.18855052) * g_2; result += mat4(0.10960496, 0.10851629, 0.095003806, 0.11053746, 0.09885307, 0.14437789, 0.13191165, 0.17365928, 0.16558935, 0.15473324, 0.21136154, 0.19976667, -0.07267957, -0.11469687, -0.029134216, -0.06817615) * g_3; result += mat4(0.10202856, 0.04216857, -0.03959349, -0.09849683, -0.1576996, -0.049997438, -0.1579918, -0.058789205, 0.029792828, -0.07311781, -0.045432188, -0.11312683, 0.24257647, 0.16204113, 0.17869382, 0.16024388) * g_4; result += mat4(0.17193612, 0.12692013, 0.13177487, 0.0796725, 0.0797928, 0.08952722, -0.012468046, 0.011071511, -0.068559825, -0.024852324, 0.0526428, 0.07917346, -0.085534215, -0.09591339, 0.04615827, 0.024577664) * g_5; result += mat4(-0.14653449, -0.067267366, -0.002524394, 0.086243175, 0.13660401, 0.08039592, 0.09179008, 0.022573143, -0.024744196, 0.09120211, 0.017654825, 0.14114714, -0.16093308, -0.14538004, -0.09950235, -0.111152865) * g_6; result += mat4(-0.188637, -0.12968326, -0.1200479, -0.06537649, -0.12589337, -0.106242515, -0.02788782, -0.025949068, 0.04948153, 0.02222735, -0.025291357, -0.12379292, 0.11074645, 0.11902375, -0.00056989543, -0.0024386419) * g_7; result += mat4(0.018286629, 0.0072215167, 0.00037828335, 0.0047001047, 0.011478272, 0.041745186, -0.015742473, -0.002282524, -0.03440817, -0.02196847, -0.07838253, -0.07993771, -0.010155526, -0.017590692, 0.027141469, 0.029741213) * g_8; result += mat4(0.016512005, 0.004950637, -0.0238836, -0.05587327, -0.03164328, -0.009499985, -0.059880238, -0.061794154, 0.023154303, -0.013266373, 0.04701534, 0.0415862, 0.06357814, 0.033057794, 0.08389772, 0.00035060212) * g_9; result += mat4(-0.016403968, -0.012538788, -0.0015746636, -0.004771009, -0.021361275, -0.009695242, 0.020548422, -0.0024130535, 0.07796766, -0.01516671, 0.09961382, 0.042754963, 0.017363647, 0.03729065, -0.004795824, 0.01550197) * g_10; result += mat4(-0.0028093113, 0.011869523, -0.02216933, 0.011177349, 0.033342455, -0.021146454, 0.07830085, 0.032490104, -0.03281833, 0.0060484232, -0.04081057, -0.04945058, -0.0056189033, -0.010636801, -0.041949317, -0.025739705) * g_11; result += mat4(0.012979897, 0.016758928, -0.049062215, -0.0035748442, 0.0085972, 0.0036381132, -0.0055621094, 0.0041307937, -0.0008907763, -0.0034079372, -0.025680453, -0.015531803, 0.012816766, 0.009977763, -0.016416566, 0.0034859509) * g_12; result += mat4(0.021753248, 0.016452711, 0.009833835, 0.0065052663, 0.0014061348, -0.046160888, -0.0132271005, -0.05051269, -0.05746351, -0.0012690664, 0.017191738, 0.018192926, -0.008879476, 0.026354216, -0.012801991, -0.029587373) * g_13; result += mat4(-0.04220692, -0.0015560482, -0.0019648245, 0.013402305, -0.018259782, -0.0036008905, 0.0035650074, -0.0019178417, 0.00051580026, 0.027355857, -0.017914988, 0.004937948, -0.046335887, 0.00013612259, 0.030293299, 0.030688645) * g_14; result += mat4(-0.036683388, -0.0031274238, -0.026074665, 0.021684237, 0.022639066, 0.0022493738, 0.011508554, -0.0006385944, 0.04890418, 0.020119468, 0.004167364, -0.008356099, -0.008598796, 0.0089028, -0.0029575853, 0.016687104) * g_15; result += mat4(0.027207986, 0.0011099194, 0.042383645, -0.015179333, 0.014744431, 0.006148344, 0.005165422, 0.0070196544, 0.030286826, 0.016620956, -0.01611366, -0.00667594, -0.029524863, -0.024751091, -0.013321004, -0.025199674) * g_16; result += mat4(0.0027477827, 0.054622147, 0.010154094, 0.025437292, 0.031773083, -0.01055473, 0.022864206, -0.029010754, -0.0029999653, 0.025018329, 0.015316208, 0.027188798, -0.10096525, -0.017268656, 0.0012529213, -0.062078856) * g_17; result += mat4(-0.053670805, 0.057336535, -0.037418038, 0.06443577, -0.016027879, -0.058168363, 0.007034215, -0.03390141, -0.0019346164, -0.027947908, 0.021723913, -0.0018286633, 0.030507812, 0.018293543, 0.042917266, 0.033528328) * g_18; result += mat4(-0.004559579, 0.029667616, -0.001870353, 0.0378995, -0.017147437, 0.020192018, -0.021574946, 0.031568103, 0.07487145, 0.0032376775, -0.018893708, -0.041981626, 0.054478757, 0.0061423797, 0.041280247, 0.000878061) * g_19; result += mat4(0.017076394, 0.023647636, 0.029403262, 0.029923365, 0.08866472, 0.060613394, 0.1314274, -0.04490231, -0.016304834, -0.0062647443, -0.0031828512, -0.03989252, -0.024330825, 0.00741213, -0.04075287, -0.01615817) * g_20; result += mat4(0.017866978, 0.017720113, -0.02846163, 0.040761847, -0.0063438355, -0.02347501, 0.029564403, -0.0029562064, 0.12505588, -0.0073986333, 0.11250363, -0.06179967, 0.07854423, 0.08546533, 0.034743227, -0.010757377) * g_21; result += mat4(-0.06416677, -0.08344284, 0.030138884, 0.017635904, -0.012087523, 0.014205202, -0.03221233, -0.023834767, -0.091186255, -0.028958676, -0.04724334, 0.00013161585, 0.027391518, 0.1249978, -0.045047652, 0.10737729) * g_22; result += mat4(-0.04326348, -0.03543181, -0.029558217, -0.08582413, 0.007812453, 0.014296562, -0.028779754, 0.018517692, -0.063755795, -0.036619596, -0.050809663, 0.005431336, -0.029205568, -0.011827915, -0.031110523, -0.005648626) * g_23; result += mat4(0.05499293, -0.10000709, -0.0943537, 0.16143042, -0.019952895, -0.0039807972, -0.014841254, 0.0320363, -0.065173544, -0.049425576, -0.023904482, 0.03759679, -0.03207411, -0.047782745, 0.01352581, 0.008140566) * g_24; result += mat4(0.055923894, -0.025134467, 0.029583648, 0.04096879, 0.027551858, -0.14995384, 0.06467113, -0.11633077, -0.01563784, -0.026909819, -0.06292879, -0.078409635, -0.009081105, -0.015533088, 0.019585673, 0.04334208) * g_25; result += mat4(-0.021717606, 0.042464726, 0.02743202, -0.07388838, 0.03460472, 0.0038285658, 0.099842004, -0.098247, 0.13276267, -0.020793032, -0.008603039, -0.051913783, 0.12959045, 0.14735717, -0.10888226, -0.10263746) * g_26; result += mat4(-0.16819532, 0.141579, -0.062480718, -0.021918943, 0.06348125, 0.06849444, 0.03888676, 0.027375204, -0.08194279, -0.012574497, 0.13523251, 0.13739482, -0.047547445, -0.058767617, 0.07009549, 0.028136581) * g_27; result += vec4(0.069033325, 0.040207114, 0.027286075, 0.0065334598); return result; } //!DESC Anime4K-v3.2-Upscale-CNN-x2-(VL)-Depth-to-Space //!HOOK MAIN //!BIND MAIN //!BIND conv2d_last_tf //!BIND conv2d_last_tf1 //!BIND conv2d_last_tf2 //!SAVE MAIN //!WIDTH conv2d_last_tf.w 2 * //!HEIGHT conv2d_last_tf.h 2 * //!WHEN OUTPUT.w MAIN.w / 1.200 > OUTPUT.h MAIN.h / 1.200 > * vec4 hook() { vec2 f0 = fract(conv2d_last_tf_pos * conv2d_last_tf_size); ivec2 i0 = ivec2(f0 * vec2(2.0)); float c0 = conv2d_last_tf_tex((vec2(0.5) - f0) * conv2d_last_tf_pt + conv2d_last_tf_pos)[i0.y * 2 + i0.x]; vec2 f1 = fract(conv2d_last_tf1_pos * conv2d_last_tf1_size); ivec2 i1 = ivec2(f1 * vec2(2.0)); float c1 = conv2d_last_tf1_tex((vec2(0.5) - f1) * conv2d_last_tf1_pt + conv2d_last_tf1_pos)[i1.y * 2 + i1.x]; vec2 f2 = fract(conv2d_last_tf2_pos * conv2d_last_tf2_size); ivec2 i2 = ivec2(f2 * vec2(2.0)); float c2 = conv2d_last_tf2_tex((vec2(0.5) - f2) * conv2d_last_tf2_pt + conv2d_last_tf2_pos)[i2.y * 2 + i2.x]; float c3 = c2; return vec4(c0, c1, c2, c3) + MAIN_tex(MAIN_pos); } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/Constants.kt ================================================ package com.yenaly.han1meviewer import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDateTime import kotlinx.datetime.format.char /** * 我觉得空字符串写出来太逆天了,所以搞了个常量 */ const val EMPTY_STRING = "" const val APP_NAME = "Han1meViewer" // 标准时间格式 /* yyyy-MM-dd */ @JvmField val LOCAL_DATE_FORMAT = LocalDate.Formats.ISO /* yyyy-MM-dd HH:mm */ @JvmField val LOCAL_DATE_TIME_FORMAT = LocalDateTime.Format { date(LocalDate.Formats.ISO); char(' ') hour(); char(':'); minute() } // 网络基本设置 const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" // intent傳值用名稱 const val FROM_DOWNLOAD = "FROM_DOWNLOAD" const val VIDEO_CODE = "VIDEO_CODE" @Deprecated("Use [ADVANCED_SEARCH_MAP] instead") const val FROM_VIDEO_TAG = "FROM_VIDEO_TAG" /** * 接受类型 [AdvancedSearchMap] 或者 [String] */ const val ADVANCED_SEARCH_MAP = "ADVANCED_SEARCH_MAP" const val COMMENT_ID = "COMMENT_ID" const val COMMENT_TYPE = "COMMENT_TYPE" const val DATE_CODE = "DATE_CODE" const val CSRF_TOKEN = "CSRF_TOKEN" // Result Code const val LOGIN_TO_MAIN_ACTIVITY = 0 // 给rv传值,判断布局需要wrap_content还是match_parent,不填则为默认 // 设置布局为MATCH_PARENT可以使rv在GridLayoutManager下能居中,反之不能 const val VIDEO_LAYOUT_WRAP_CONTENT = 1 const val VIDEO_LAYOUT_MATCH_PARENT = 2 // 給CommentFragment傳值,判斷是影片評論區還是預覽評論區 [COMMENT_TYPE] const val VIDEO_COMMENT_PREFIX = "video" const val PREVIEW_COMMENT_PREFIX = "preview" // base url @JvmField val HANIME_BASE_URL = Preferences.baseUrl const val HANIME_MAIN_HOSTNAME = "hanime1.me" const val HANIME_ALTER_HOSTNAME = "hanime1.com" const val HANIME_MAIN_BASE_URL = "https://hanime1.me/" const val HANIME_ALTER_BASE_URL = "https://hanime1.com/" @JvmField val HANIME_LOGIN_URL = HANIME_BASE_URL + "login" // github url const val HA1_GITHUB_URL = "https://github.com/Night-stars-1/Han1meViewer" const val HA1_GITHUB_ISSUE_URL = "$HA1_GITHUB_URL/issues" const val HA1_GITHUB_FORUM_URL = "$HA1_GITHUB_URL/discussions" const val HA1_GITHUB_RELEASES_URL = "$HA1_GITHUB_URL/releases" const val HA1_GITHUB_API_URL = "https://api.github.com/repos/Night-stars-1/Han1meViewer/" // for Shared Preference const val LOGIN_COOKIE = "cookie" const val ALREADY_LOGIN = "already_login" // Notification const val DOWNLOAD_NOTIFICATION_CHANNEL = "download_channel" const val UPDATE_NOTIFICATION_CHANNEL = "update_channel" // File const val FILE_PROVIDER_AUTHORITY = "${BuildConfig.APPLICATION_ID}.fileProvider" ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/FirebaseConstants.kt ================================================ package com.yenaly.han1meviewer object FirebaseConstants { // /** * 高级搜索使用统计 */ const val ADV_SEARCH_OPT = "advanced_search_options" /** * 关键H帧使用统计 */ const val H_KEYFRAMES = "h_keyframes" // // /** * 当前是否为登录状态 */ const val LOGIN_STATE = "login_state" /** * 当前APP内使用语言 */ const val APP_LANGUAGE = "app_language" /** * 当前APP来源,debug、release或ci */ const val VERSION_SOURCE = "version_source" /** * 当前正在下载的任务数量 */ const val RUNNING_DOWNLOAD_WORK_COUNT = "running_download_work_count" // // /** * 是否启用 CI 更新。 * * 由于当前使用了 Firebase,所以希望正式版更新时,减少 CI 更新的概率。 * 方便更好地控制更新以及崩溃数据统计。 */ const val ENABLE_CI_UPDATE = "enable_ci_update" val remoteConfigDefaults: Map = mapOf( ENABLE_CI_UPDATE to true ) // } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/HAdvancedSearch.kt ================================================ package com.yenaly.han1meviewer import java.io.Serializable /** * 高级搜索的枚举 * * @project Han1meViewer * @author Yenaly Liew * @time 2023/09/22 022 18:13 */ enum class HAdvancedSearch { /** * 搜索关键词,类型 [String] */ QUERY, /** * 影片类型,类型 [String] */ GENRE, /** * 排序方式,类型 [String] */ SORT, /** * 影片年份,类型 [Int] */ YEAR, /** * 影片月份,类型 [Int] */ MONTH, /** * 影片时长,类型 [String] */ DURATION, /** * 影片 tag,类型 [String] (Deprecated) 或 HashSet<String> (Deprecated) * 或 Map 或 Map */ TAGS, /** * 影片品牌,类型 [String] 或 [HashSet<String>] */ BRANDS } /** * 高级搜索的 Map,所有给 SearchActivity 的传参走这里! */ typealias AdvancedSearchMap = HashMap @Suppress("NOTHING_TO_INLINE") inline fun advancedSearchMapOf(vararg pairs: Pair) = hashMapOf(*pairs) ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/HCacheManager.kt ================================================ package com.yenaly.han1meviewer import androidx.annotation.WorkerThread import com.yenaly.han1meviewer.logic.DatabaseRepo import com.yenaly.han1meviewer.logic.model.HanimeVideo import com.yenaly.yenaly_libs.utils.createFileIfNotExists import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOn import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.decodeFromStream import kotlinx.serialization.json.encodeToStream import java.io.File /** * @project Han1meViewer * @author Yenaly Liew * @since 2025/3/5 20:11 */ object HCacheManager { private const val CACHE_INFO_FILE = "info.json" /** * 保存 HanimeVideo 信息,用于下载后直接在 APP 内观看 */ @OptIn(ExperimentalSerializationApi::class) @WorkerThread fun saveHanimeVideoInfo(videoCode: String, info: HanimeVideo) { val folder = HFileManager.getDownloadVideoFolder(videoCode) val file = File(folder, CACHE_INFO_FILE) file.createFileIfNotExists() HJson.encodeToStream(info, file.outputStream()) } /** * 加载 HanimeVideo 信息,用于下载后直接在 APP 内观看 */ @OptIn(ExperimentalSerializationApi::class) fun loadHanimeVideoInfo(videoCode: String): Flow { return flow { val entity = DatabaseRepo.HanimeDownload.find(videoCode) if (entity != null) { val folder = HFileManager.getDownloadVideoFolder(videoCode) var cacheFile = File(folder, CACHE_INFO_FILE) if (!cacheFile.exists()) { val folder = HFileManager.getDownloadVideoFolder(videoCode, true) cacheFile = File(folder, CACHE_INFO_FILE) } val info = kotlin.runCatching { if (cacheFile.exists()) HJson.decodeFromStream(cacheFile.inputStream()) else null }.getOrNull() emit( info?.copy( videoUrls = linkedMapOf( entity.quality to HanimeLink( entity.videoUri, HFileManager.DEF_VIDEO_TYPE ) ), coverUrl = entity.coverUri ?: entity.coverUrl ) ) } else { emit(null) } }.flowOn(Dispatchers.IO) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/HCrashHandler.kt ================================================ package com.yenaly.han1meviewer import com.yenaly.yenaly_libs.ActivityManager object HCrashHandler : Thread.UncaughtExceptionHandler { override fun uncaughtException(t: Thread, e: Throwable) { e.printStackTrace() ActivityManager.restart(killProcess = true) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/HFileManager.kt ================================================ package com.yenaly.han1meviewer import android.os.Environment import com.yenaly.yenaly_libs.utils.applicationContext import com.yenaly.yenaly_libs.utils.makeFolderNoMedia import java.io.File object HFileManager { const val HANIME_DOWNLOAD_FOLDER = "hanime_download" private val illegalCharsRegex = Regex("""["*/:<>?\\|\x00-\x1F\x7F]""") val appExternalDownloadFolder: File get() = File( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), APP_NAME ).also { file -> file.makeFolderNoMedia() } val appDownloadFolder: File get() = File( applicationContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), APP_NAME ).also { file -> file.makeFolderNoMedia() } const val DEF_VIDEO_TYPE = "mp4" const val DEF_VIDEO_COVER_TYPE = "png" fun createVideoName( title: String, quality: String, suffix: String = DEF_VIDEO_TYPE ) = "${title.replaceAllIllegalChars()}_${quality}.${suffix}" fun createVideoCoverName( title: String, suffix: String = DEF_VIDEO_COVER_TYPE ) = "${title.replaceAllIllegalChars()}.${suffix}" fun getDownloadFolder(again: Boolean = false): File { return if (again) { if (!Preferences.isPrivateDirectory) appDownloadFolder else appExternalDownloadFolder } else { if (Preferences.isPrivateDirectory) appDownloadFolder else appExternalDownloadFolder } } fun getDownloadVideoFolder(videoCode: String, again: Boolean = false): File { val appDownloadFolder = getDownloadFolder(again) return File(appDownloadFolder, "$HANIME_DOWNLOAD_FOLDER/$videoCode") } fun getDownloadVideoFile( videoCode: String, title: String, quality: String, suffix: String = DEF_VIDEO_TYPE ): File { return File(getDownloadVideoFolder(videoCode), createVideoName(title, quality, suffix)) } fun getDownloadVideoCoverFile( videoCode: String, title: String, suffix: String = DEF_VIDEO_COVER_TYPE ): File { return File(getDownloadVideoFolder(videoCode), createVideoCoverName(title, suffix)) } /** * Replace all illegal characters in the string with "_" * * 若文件名中有非法字符,则替换为"_",以避免文件名错误 */ private fun String.replaceAllIllegalChars(): String { return illegalCharsRegex.replace(this, "_") } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/HInitializer.kt ================================================ package com.yenaly.han1meviewer import android.content.Context import com.yenaly.yenaly_libs.base.YenalyInitializer class HInitializer : YenalyInitializer() { override fun create(context: Context) { super.create(context) // 用于处理 Firebase Crashlytics 初始化 Thread.setDefaultUncaughtExceptionHandler(HCrashHandler) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/HanimeApplication.kt ================================================ package com.yenaly.han1meviewer import android.util.Log import androidx.core.app.NotificationChannelCompat import androidx.core.app.NotificationManagerCompat import com.google.android.material.color.DynamicColors import com.google.firebase.Firebase import com.google.firebase.analytics.analytics import com.google.firebase.crashlytics.crashlytics import com.google.firebase.crashlytics.setCustomKeys import com.google.firebase.remoteconfig.remoteConfig import com.google.firebase.remoteconfig.remoteConfigSettings import com.scwang.smart.refresh.footer.ClassicsFooter import com.scwang.smart.refresh.header.MaterialHeader import com.scwang.smart.refresh.layout.SmartRefreshLayout import com.yenaly.han1meviewer.logic.network.HProxySelector import com.yenaly.han1meviewer.ui.viewmodel.AppViewModel import com.yenaly.han1meviewer.util.AnimeShaders import com.yenaly.yenaly_libs.base.YenalyApplication import com.yenaly.yenaly_libs.utils.LanguageHelper import `is`.xyz.mpv.MPVLib /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/08 008 17:32 */ class HanimeApplication : YenalyApplication() { companion object { const val TAG = "HanimeApplication" init { SmartRefreshLayout.setDefaultRefreshHeaderCreator { context, _ -> return@setDefaultRefreshHeaderCreator MaterialHeader(context) } SmartRefreshLayout.setDefaultRefreshFooterCreator { context, _ -> return@setDefaultRefreshFooterCreator ClassicsFooter(context) } } } /** * 已经在 [HInitializer] 中处理了 */ override val isDefaultCrashHandlerEnabled: Boolean = false override fun onCreate() { super.onCreate() DynamicColors.applyToActivitiesIfAvailable(this) HProxySelector.rebuildNetwork() initFirebase() initNotificationChannel() MPVLib.create(applicationContext) MPVLib.init() if (AnimeShaders.copyShaderAssets(applicationContext) <= 0) { Log.w(TAG, "Shader 复制失败") } } private fun initFirebase() { // 用于处理 Firebase Analytics 初始化 Firebase.analytics.setAnalyticsCollectionEnabled(Preferences.isAnalyticsEnabled) // 用于处理 Firebase Crashlytics 初始化 Firebase.crashlytics.apply { isCrashlyticsCollectionEnabled = !BuildConfig.DEBUG setCustomKeys { key( FirebaseConstants.APP_LANGUAGE, LanguageHelper.preferredLanguage.toLanguageTag() ) key( FirebaseConstants.VERSION_SOURCE, BuildConfig.HA1_VERSION_SOURCE ) } } // 用于处理 Firebase Remote Config 初始化 Firebase.remoteConfig.apply { setConfigSettingsAsync(remoteConfigSettings { minimumFetchIntervalInSeconds = if (BuildConfig.DEBUG) 0 else 3 * 60 * 60 fetchTimeoutInSeconds = 10 }) setDefaultsAsync(FirebaseConstants.remoteConfigDefaults) fetchAndActivate().addOnCompleteListener { AppViewModel.getLatestVersion(delayMillis = 200) } } } private fun initNotificationChannel() { val nm = NotificationManagerCompat.from(this) val hanimeDownloadChannel = NotificationChannelCompat.Builder( DOWNLOAD_NOTIFICATION_CHANNEL, NotificationManagerCompat.IMPORTANCE_HIGH ).setName("Hanime Download").build() nm.createNotificationChannel(hanimeDownloadChannel) val appUpdateChannel = NotificationChannelCompat.Builder( UPDATE_NOTIFICATION_CHANNEL, NotificationManagerCompat.IMPORTANCE_HIGH ).setName("App Update").build() nm.createNotificationChannel(appUpdateChannel) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/HanimeManager.kt ================================================ package com.yenaly.han1meviewer import android.webkit.CookieManager import androidx.core.text.parseAsHtml import com.yenaly.han1meviewer.Preferences.isAlreadyLogin import com.yenaly.han1meviewer.Preferences.loginCookie import com.yenaly.han1meviewer.logic.network.HCookieJar import com.yenaly.han1meviewer.util.CookieString import kotlinx.serialization.json.Json @JvmField val HJson = Json { ignoreUnknownKeys = true } /** * 给用户显示的错误信息 * * ぴえん化 */ val Throwable.pienization: CharSequence get() = "🥺\n$localizedMessage" // base private const val HANIME_TITLE_HTML = """Han1meViewer""" val hanimeSpannedTitle = HANIME_TITLE_HTML.parseAsHtml() /** * 獲取 Hanime 影片地址 */ fun getHanimeVideoLink(videoCode: String) = HANIME_BASE_URL + "watch?v=" + videoCode /** * 獲取 Hanime 影片分享文本 */ fun getHanimeShareText(title: String, videoCode: String): String = buildString { appendLine(title) appendLine(getHanimeVideoLink(videoCode)) append("- From Han1meViewer -") } /** * 獲取 Hanime 影片**官方**下載地址 */ fun getHanimeVideoDownloadLink(videoCode: String) = HANIME_BASE_URL + "download?v=" + videoCode val videoUrlRegex = Regex("""hanime1\.(?:com|me)/watch\?v=(\d+)""") fun String.toVideoCode() = videoUrlRegex.find(this)?.groupValues?.get(1) // log in and log out fun logout() { isAlreadyLogin = false loginCookie = CookieString(EMPTY_STRING) HCookieJar.cookieMap.clear() CookieManager.getInstance().removeAllCookies(null) } fun login(cookies: String) { isAlreadyLogin = true loginCookie = CookieString(cookies) } fun login(cookies: List) { login(cookies.joinToString(";") { it.substringBefore(';') }) } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/HanimeResolution.kt ================================================ package com.yenaly.han1meviewer import kotlinx.serialization.Serializable import okhttp3.MediaType.Companion.toMediaTypeOrNull /** * resolution to link map */ typealias ResolutionLinkMap = LinkedHashMap /** * 如果你在其他地方看到了 Quality,那就是 Resolution,我混用了。 * * @project Han1meViewer * @author Yenaly Liew * @time 2022/10/11 011 21:19 */ class HanimeResolution { private val resArray = arrayOfNulls>(5) companion object { // 目前hanime1有的分辨率好像就這些,暫時不考慮其他分辨率 const val RES_1080P = "1080P" const val RES_720P = "720P" const val RES_480P = "480P" const val RES_240P = "240P" const val RES_UNKNOWN = "Unknown" } /** * 解析分辨率,從高到低排列。 * * @param resString 分辨率 * @param resLink 分辨率對應網址 * @param type 例如 video/mp4 */ fun parseResolution(resString: String?, resLink: String, type: String? = null) { val mediaType = type?.toMediaTypeOrNull()?.takeIf { it.type.equals("video", ignoreCase = true) } val link = HanimeLink(resLink, mediaType?.subtype) when (resString) { RES_1080P -> resArray[0] = RES_1080P to link RES_720P -> resArray[1] = RES_720P to link RES_480P -> resArray[2] = RES_480P to link RES_240P -> resArray[3] = RES_240P to link null -> resArray[4] = RES_UNKNOWN to link } } fun toResolutionLinkMap(): ResolutionLinkMap { return resArray.filterNotNull().toMap(linkedMapOf()) } } @Serializable data class HanimeLink( val link: String, val subtype: String?, ) { val suffix: String get() = when (subtype?.lowercase()) { "mp4" -> "mp4" "mpeg" -> "mpeg" "x-msvideo" -> "avi" "3gpp" -> "3gp" "3gpp2" -> "3g2" "ogg" -> "ogv" "mp2t" -> "ts" "webm" -> "webm" else -> HFileManager.DEF_VIDEO_TYPE } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/Preferences.kt ================================================ package com.yenaly.han1meviewer import android.content.SharedPreferences import android.os.Build import androidx.preference.PreferenceManager import com.yenaly.han1meviewer.logic.network.HProxySelector import com.yenaly.han1meviewer.logic.network.interceptor.SpeedLimitInterceptor import com.yenaly.han1meviewer.ui.fragment.settings.DownloadSettingsFragment import com.yenaly.han1meviewer.ui.fragment.settings.HKeyframeSettingsFragment import com.yenaly.han1meviewer.ui.fragment.settings.HomeSettingsFragment import com.yenaly.han1meviewer.ui.fragment.settings.NetworkSettingsFragment import com.yenaly.han1meviewer.ui.fragment.settings.PlayerSettingsFragment import com.yenaly.han1meviewer.ui.view.video.HJzvdStd import com.yenaly.han1meviewer.ui.view.video.HMediaKernel import com.yenaly.han1meviewer.util.CookieString import com.yenaly.han1meviewer.worker.HanimeDownloadManagerV2 import com.yenaly.yenaly_libs.utils.applicationContext import com.yenaly.yenaly_libs.utils.getSpValue import com.yenaly.yenaly_libs.utils.putSpValue import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlin.time.Duration.Companion.days object Preferences { /** * [Preference][androidx.preference.PreferenceFragmentCompat]自帶的SP */ val preferenceSp: SharedPreferences get() = PreferenceManager.getDefaultSharedPreferences( applicationContext ) // app 相關 /** * 是否登入,一般跟[loginCookie]一起賦值 */ var isAlreadyLogin: Boolean get() = getSpValue(ALREADY_LOGIN, false) set(value) { loginStateFlow.value = value putSpValue(ALREADY_LOGIN, value) } val loginStateFlow = MutableStateFlow(isAlreadyLogin) /** * 保存的string格式的登入cookie */ var loginCookie get() = CookieString(getSpValue(LOGIN_COOKIE, EMPTY_STRING)) set(value) { loginCookieStateFlow.value = value putSpValue(LOGIN_COOKIE, value.cookie) } val loginCookieStateFlow = MutableStateFlow(loginCookie) // 更新 相關 private const val UPDATE_NODE_ID = "update_node_id" var updateNodeId: String get() = getSpValue(UPDATE_NODE_ID, EMPTY_STRING) set(value) = putSpValue(UPDATE_NODE_ID, value) var lastUpdatePopupTime get() = getSpValue(HomeSettingsFragment.LAST_UPDATE_POPUP_TIME, 0L) set(value) = putSpValue(HomeSettingsFragment.LAST_UPDATE_POPUP_TIME, value) val updatePopupIntervalDays get() = preferenceSp.getInt(HomeSettingsFragment.UPDATE_POPUP_INTERVAL_DAYS, 0) val useCIUpdateChannel get() = preferenceSp.getBoolean(HomeSettingsFragment.USE_CI_UPDATE_CHANNEL, false) // Check if show update dialog. val isUpdateDialogVisible: Boolean get() { val now = Clock.System.now() val lastCheckTime = Instant.fromEpochSeconds(lastUpdatePopupTime) val interval = updatePopupIntervalDays return now > lastCheckTime + interval.days } // 設定 相關 val switchPlayerKernel: String get() = preferenceSp.getString( PlayerSettingsFragment.SWITCH_PLAYER_KERNEL, HMediaKernel.Type.ExoPlayer.name ) ?: HMediaKernel.Type.ExoPlayer.name val showBottomProgress: Boolean get() = preferenceSp.getBoolean( PlayerSettingsFragment.SHOW_BOTTOM_PROGRESS, true ) val playerSpeed: Float get() = preferenceSp.getString( PlayerSettingsFragment.PLAYER_SPEED, HJzvdStd.DEF_SPEED.toString() )?.toFloat() ?: HJzvdStd.DEF_SPEED val slideSensitivity: Int get() = preferenceSp.getInt( PlayerSettingsFragment.SLIDE_SENSITIVITY, HJzvdStd.DEF_PROGRESS_SLIDE_SENSITIVITY ) val longPressSpeedTime: Float get() = preferenceSp.getString( PlayerSettingsFragment.LONG_PRESS_SPEED_TIMES, HJzvdStd.DEF_LONG_PRESS_SPEED_TIMES.toString() )?.toFloat() ?: HJzvdStd.DEF_LONG_PRESS_SPEED_TIMES val videoLanguage: String get() = preferenceSp.getString(HomeSettingsFragment.VIDEO_LANGUAGE, "zh-CHT") ?: "zh-CHT" val baseUrl: String get() = preferenceSp.getString(NetworkSettingsFragment.DOMAIN_NAME, HANIME_MAIN_BASE_URL) ?: HANIME_MAIN_BASE_URL val useBuiltInHosts: Boolean get() = preferenceSp.getBoolean(NetworkSettingsFragment.USE_BUILT_IN_HOSTS, false) val isPingTest: Boolean get() = preferenceSp.getBoolean(NetworkSettingsFragment.PING_TEST, false) val isPipAllowed: Boolean get() = preferenceSp.getBoolean(HomeSettingsFragment.ALLOW_PIP, false) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O // 關鍵H幀 相關 val whenCountdownRemind: Int get() = preferenceSp.getInt( HKeyframeSettingsFragment.WHEN_COUNTDOWN_REMIND, HJzvdStd.DEF_COUNTDOWN_SEC ) * 1_000 // 越不了界,最大就30_000ms而已 val showCommentWhenCountdown: Boolean get() = preferenceSp.getBoolean( HKeyframeSettingsFragment.SHOW_COMMENT_WHEN_COUNTDOWN, false ) val hKeyframesEnable: Boolean get() = preferenceSp.getBoolean( HKeyframeSettingsFragment.H_KEYFRAMES_ENABLE, true ) val sharedHKeyframesEnable: Boolean get() = preferenceSp.getBoolean( HKeyframeSettingsFragment.SHARED_H_KEYFRAMES_ENABLE, true ) val sharedHKeyframesUseFirst: Boolean get() = preferenceSp.getBoolean( HKeyframeSettingsFragment.SHARED_H_KEYFRAMES_USE_FIRST, false ) // 代理 相關 val proxyType: Int get() = preferenceSp.getInt( NetworkSettingsFragment.PROXY_TYPE, HProxySelector.TYPE_SYSTEM ) val proxyIp: String get() = preferenceSp.getString(NetworkSettingsFragment.PROXY_IP, EMPTY_STRING).orEmpty() val proxyPort: Int get() = preferenceSp.getInt(NetworkSettingsFragment.PROXY_PORT, -1) // 隐私 相關 val isAnalyticsEnabled: Boolean get() = preferenceSp.getBoolean(HomeSettingsFragment.USE_ANALYTICS, true) // 下载 相關 val downloadCountLimit: Int get() = preferenceSp.getInt( DownloadSettingsFragment.DOWNLOAD_COUNT_LIMIT, // HanimeDownloadManager.MAX_CONCURRENT_DOWNLOAD_DEF HanimeDownloadManagerV2.MAX_CONCURRENT_DOWNLOAD_DEF ) /** * 对应关系详见 [SpeedLimitInterceptor.SPEED_BYTES] */ val downloadSpeedLimit: Long get() { val index = preferenceSp.getInt( DownloadSettingsFragment.DOWNLOAD_SPEED_LIMIT, SpeedLimitInterceptor.NO_LIMIT_INDEX ) return SpeedLimitInterceptor.SPEED_BYTES[index] } val isPrivateDirectory: Boolean get() = preferenceSp.getBoolean( DownloadSettingsFragment.USE_PRIVATE_DIRECTORY, false ) } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/VideoCoverSize.kt ================================================ package com.yenaly.han1meviewer import android.annotation.SuppressLint import android.view.ViewGroup import androidx.core.view.updateLayoutParams import com.yenaly.yenaly_libs.utils.applicationContext import com.yenaly.yenaly_libs.utils.dp /** * 用于计算视频封面的大小动态调整! * * @project Han1meViewer * @author Yenaly Liew * @time 2024/04/08 008 21:54 */ @SuppressLint("StaticFieldLeak") object VideoCoverSize { private const val TAG = "VideoCoverSize" private val context = applicationContext private val screenWidth get() = context.resources.displayMetrics.widthPixels private val videoCoverWidth = context.resources.getDimension(R.dimen.video_cover_width) private val simplifiedVideoCoverWidth = context.resources.getDimension(R.dimen.video_cover_simplified_width) // Ratio of the video cover's width to its height private const val RATIO = 15 / 22.0 /** * 自带的一个Margin */ private val margin = 4.dp /** * 通常父View也会有一个Margin,所以这里也加上 */ private val parentMargin = 8.dp object Normal { /** * 最少显示几个视频 */ private const val AT_LEAST = 2 val videoInOneLine get() = (screenWidth / videoCoverWidth).toInt().coerceAtLeast(AT_LEAST) fun ViewGroup.resizeForVideoCover(atLeast: Int = AT_LEAST) { require(atLeast > 0) val screenWidth = screenWidth val videoInOneLine = (screenWidth / videoCoverWidth).toInt() if (videoInOneLine < atLeast) { val width = (screenWidth - parentMargin * 2) / atLeast - margin * 2 val height = (width * RATIO).toInt() updateLayoutParams { this.width = width this.height = height } } } } object Simplified { /** * 最少显示几个视频 */ private const val AT_LEAST = 3 val videoInOneLine get() = (screenWidth / simplifiedVideoCoverWidth).toInt().coerceAtLeast(AT_LEAST) fun ViewGroup.resizeForVideoCover(atLeast: Int = AT_LEAST) { require(atLeast > 0) val screenWidth = screenWidth val videoInOneLine = (screenWidth / simplifiedVideoCoverWidth).toInt() if (videoInOneLine < atLeast) { val width = (screenWidth - parentMargin * 2) / atLeast - margin * 2 val height = (width / RATIO).toInt() updateLayoutParams { this.width = width this.height = height } } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/DatabaseRepo.kt ================================================ package com.yenaly.han1meviewer.logic import com.yenaly.han1meviewer.Preferences import com.yenaly.han1meviewer.logic.dao.DownloadDatabase import com.yenaly.han1meviewer.logic.dao.HistoryDatabase import com.yenaly.han1meviewer.logic.dao.MiscellanyDatabase import com.yenaly.han1meviewer.logic.entity.HKeyframeEntity import com.yenaly.han1meviewer.logic.entity.HKeyframeHeader import com.yenaly.han1meviewer.logic.entity.HKeyframeType import com.yenaly.han1meviewer.logic.entity.SearchHistoryEntity import com.yenaly.han1meviewer.logic.entity.WatchHistoryEntity import com.yenaly.han1meviewer.logic.entity.download.HanimeDownloadEntity import com.yenaly.yenaly_libs.utils.applicationContext import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flow import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/22 022 23:00 */ object DatabaseRepo { object HKeyframe { private val hKeyframeDao = MiscellanyDatabase.instance.hKeyframeDao fun loadAll(keyword: String? = null) = if (keyword != null) hKeyframeDao.loadAll(keyword) else hKeyframeDao.loadAll() // #issue-106: 剧集分类 @OptIn(ExperimentalSerializationApi::class) fun loadAllShared(): Flow> = flow { val res = applicationContext.assets.let { assets -> assets.list("h_keyframes")?.asSequence() ?.filter { it.endsWith(".json") } ?.mapNotNull { fileName -> try { assets.open("h_keyframes/$fileName").use { inputStream -> Json.decodeFromStream(inputStream) } } catch (e: Exception) { e.printStackTrace() null } } ?.sortedWith( compareBy { it.group }.thenBy { it.episode } ) ?.groupBy { it.group ?: "???" } ?.flatMap { (group, entities) -> listOf(HKeyframeHeader(title = group, attached = entities)) + entities } .orEmpty() } emit(res) } suspend fun findBy(videoCode: String) = hKeyframeDao.findBy(videoCode) @OptIn(ExperimentalSerializationApi::class) fun observe(videoCode: String): Flow { if (Preferences.sharedHKeyframesEnable) { return flow t@{ val find = hKeyframeDao.findBy(videoCode) if (find == null || Preferences.sharedHKeyframesUseFirst) { applicationContext.assets .open("h_keyframes/$videoCode.json") .use { inputStream -> val entity = Json.decodeFromStream(inputStream) this@t.emit(entity) } } else { hKeyframeDao.observe(videoCode).collect { this@t.emit(it) } } }.catch t@{ e -> e.printStackTrace() hKeyframeDao.observe(videoCode).collect { this@t.emit(it) } } } return hKeyframeDao.observe(videoCode) } suspend fun insert(entity: HKeyframeEntity) = hKeyframeDao.insert(entity) suspend fun update(entity: HKeyframeEntity) = hKeyframeDao.update(entity) suspend fun delete(entity: HKeyframeEntity) = hKeyframeDao.delete(entity) suspend fun modifyKeyframe( videoCode: String, oldKeyframe: HKeyframeEntity.Keyframe, keyframe: HKeyframeEntity.Keyframe, ) = hKeyframeDao.modifyKeyframe(videoCode, oldKeyframe, keyframe) suspend fun appendKeyframe( videoCode: String, title: String, keyframe: HKeyframeEntity.Keyframe, ) = hKeyframeDao.appendKeyframe(videoCode, title, keyframe) suspend fun removeKeyframe( videoCode: String, keyframe: HKeyframeEntity.Keyframe, ) = hKeyframeDao.removeKeyframe(videoCode, keyframe) } object SearchHistory { private val searchHistoryDao = HistoryDatabase.instance.searchHistory @JvmOverloads fun loadAll(keyword: String? = null) = if (keyword.isNullOrBlank()) searchHistoryDao.loadAll() else searchHistoryDao.loadAll(keyword) suspend fun delete(history: SearchHistoryEntity) = searchHistoryDao.delete(history) suspend fun insert(history: SearchHistoryEntity) = searchHistoryDao.insertOrUpdate(history) suspend fun deleteByKeyword(query: String) = searchHistoryDao.deleteByKeyword(query) } object WatchHistory { private val watchHistoryDao = HistoryDatabase.instance.watchHistory fun loadAll() = watchHistoryDao.loadAll() suspend fun delete(history: WatchHistoryEntity) = watchHistoryDao.delete(history) suspend fun deleteAll() = watchHistoryDao.deleteAll() suspend fun update(history: WatchHistoryEntity) = watchHistoryDao.update(history) suspend fun insert(history: WatchHistoryEntity) = watchHistoryDao.insertOrUpdate(history) } object HanimeDownload { private val hanimeDownloadDao = DownloadDatabase.instance.hanimeDownloadDao private val hanimeUpdateDao = DownloadDatabase.instance.hUpdateDao fun loadAllDownloadingHanime() = hanimeDownloadDao.loadAllDownloadingHanime() fun loadloadUpdating() = hanimeUpdateDao.loadUpdating() /** * 查询所有视频,并且每个视频要有当前他在的分类 */ fun loadAllDownloadedHanime( sortedBy: HanimeDownloadEntity.SortedBy, ascending: Boolean, ) = when (sortedBy) { HanimeDownloadEntity.SortedBy.TITLE -> hanimeDownloadDao.loadAllDownloadedHanimeByTitle(ascending) HanimeDownloadEntity.SortedBy.ID -> hanimeDownloadDao.loadAllDownloadedHanimeById(ascending) } suspend fun delete(videoCode: String, quality: String) = hanimeDownloadDao.delete(videoCode, quality) suspend fun delete(videoCode: String) = hanimeDownloadDao.delete(videoCode) suspend fun pauseAll() = hanimeDownloadDao.pauseAll() suspend fun delete(entity: HanimeDownloadEntity) = hanimeDownloadDao.delete(entity) suspend fun insert(entity: HanimeDownloadEntity) = hanimeDownloadDao.insert(entity) suspend fun update(entity: HanimeDownloadEntity) = hanimeDownloadDao.update(entity) suspend fun find(videoCode: String, quality: String) = hanimeDownloadDao.find(videoCode, quality) suspend fun find(videoCode: String) = hanimeDownloadDao.find(videoCode) @Deprecated("查屁") suspend fun countBy(videoCode: String) = hanimeDownloadDao.countBy(videoCode) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/NetworkRepo.kt ================================================ package com.yenaly.han1meviewer.logic import android.util.Log import com.yenaly.han1meviewer.EMPTY_STRING import com.yenaly.han1meviewer.Preferences.isAlreadyLogin import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.logic.exception.CloudFlareBlockedException import com.yenaly.han1meviewer.logic.exception.HanimeNotFoundException import com.yenaly.han1meviewer.logic.exception.IPBlockedException import com.yenaly.han1meviewer.logic.exception.ParseException import com.yenaly.han1meviewer.logic.model.CommentPlace import com.yenaly.han1meviewer.logic.model.ModifiedPlaylistArgs import com.yenaly.han1meviewer.logic.model.MyListType import com.yenaly.han1meviewer.logic.model.VideoCommentArgs import com.yenaly.han1meviewer.logic.model.VideoComments import com.yenaly.han1meviewer.logic.network.HUpdater import com.yenaly.han1meviewer.logic.network.HanimeNetwork import com.yenaly.han1meviewer.logic.state.PageLoadingState import com.yenaly.han1meviewer.logic.state.VideoLoadingState import com.yenaly.han1meviewer.logic.state.WebsiteState import com.yenaly.yenaly_libs.utils.applicationContext import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOn import okhttp3.ResponseBody import org.json.JSONObject import retrofit2.Response import javax.net.ssl.SSLHandshakeException /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/08 008 22:38 */ object NetworkRepo { // fun getHomePage() = websiteIOFlow( request = { HanimeNetwork.hanimeService.getHomePage() }, action = Parser::homePageVer2 ) fun getHanimeSearchResult( page: Int, query: String?, genre: String?, sort: String?, broad: Boolean, date: String?, duration: String?, tags: Set, brands: Set, ) = pageIOFlow( request = { HanimeNetwork.hanimeService.getHanimeSearchResult( page, query, genre, sort, if (broad) "on" else null, date, duration, tags, brands ) }, action = Parser::hanimeSearch ) fun getHanimeVideo(videoCode: String) = videoIOFlow( request = { HanimeNetwork.hanimeService.getHanimeVideo(videoCode) }, action = Parser::hanimeVideoVer2 ) fun getHanimePreview(date: String) = websiteIOFlow( request = { HanimeNetwork.hanimeService.getHanimePreview(date) }, action = Parser::hanimePreview ) // // fun getMyListItems(page: Int, typeOrCode: Any) = pageIOFlow( request = { when (typeOrCode) { is String -> HanimeNetwork.myListService.getMyListItems(page, typeOrCode) is MyListType -> HanimeNetwork.myListService.getMyListItems(page, typeOrCode.value) else -> throw IllegalArgumentException("typeOrId must be String or MyListType") } }, action = Parser::myListItems ) fun getSubscriptions(page: Int) = pageIOFlow( request = { HanimeNetwork.myListService.getMyListItems(page, MyListType.SUBSCRIPTION.value) }, action = Parser::subscriptionItems ) fun deleteMyListItems( typeOrCode: Any, videoCode: String, position: Int, token: String?, ) = websiteIOFlow( request = { when (typeOrCode) { is String -> HanimeNetwork.myListService.deleteMyListItems( typeOrCode, videoCode, csrfToken = token ) is MyListType -> HanimeNetwork.myListService.deleteMyListItems( typeOrCode.value, videoCode, csrfToken = token ) else -> throw IllegalArgumentException("typeOrId must be String or MyListType") } } ) { deleteBody -> val jsonObject = JSONObject(deleteBody) val returnVideoCode = jsonObject.get("video_id").toString() if (videoCode == returnVideoCode) { return@websiteIOFlow WebsiteState.Success(position) } return@websiteIOFlow WebsiteState.Error(IllegalStateException("cannot delete it ?!")) } fun getPlaylists() = websiteIOFlow( request = HanimeNetwork.myListService::getPlaylists, action = Parser::playlists ) fun addToMyFavVideo( videoCode: String, likeStatus: Boolean, // false => "": add fav; true => "1": cancel fav; currentUserId: String?, token: String?, ) = websiteIOFlow( request = { HanimeNetwork.myListService.addToMyFavVideo( videoCode, if (likeStatus) "1" else EMPTY_STRING, token, currentUserId ) } ) { Log.d("add_to_fav_body", it) return@websiteIOFlow WebsiteState.Success(likeStatus) } fun createPlaylist( videoCode: String, title: String, description: String, csrfToken: String?, ) = websiteIOFlow( request = { HanimeNetwork.myListService.createPlaylist( csrfToken, videoCode, title, description ) }, permittedSuccessCode = intArrayOf(500) ) { Log.d("create_playlist_body", it) return@websiteIOFlow WebsiteState.Success(Unit) } fun addToMyList( listCode: String, videoCode: String, isChecked: Boolean, position: Int, csrfToken: String?, ) = websiteIOFlow( request = { HanimeNetwork.myListService.addToMyList( csrfToken, listCode, videoCode, isChecked ) } ) { Log.d("add_to_playlist_body", it) return@websiteIOFlow WebsiteState.Success(position) } fun modifyPlaylist( listCode: String, title: String, description: String, delete: Boolean, csrfToken: String?, ) = websiteIOFlow( request = { HanimeNetwork.myListService.modifyPlaylist( listCode, title, description, if (delete) "on" else null, csrfToken ) }, permittedSuccessCode = intArrayOf(302) ) { Log.d("modify_playlist_body", it) return@websiteIOFlow WebsiteState.Success( ModifiedPlaylistArgs( title = title, desc = description, isDeleted = delete, ) ) } // // fun getComments(type: String, code: String) = websiteIOFlow( request = { HanimeNetwork.commentService.getComments(type, code) }, action = Parser::comments ) fun getCommentReply(commentId: String) = websiteIOFlow( request = { HanimeNetwork.commentService.getCommentReply(commentId) }, action = Parser::commentReply ) fun postComment( csrfToken: String?, currentUserId: String, targetUserId: String, type: String, text: String, ) = websiteIOFlow( request = { HanimeNetwork.commentService.postComment( csrfToken, currentUserId, type, targetUserId, text ) } ) { Log.d("post_comment_body", it) return@websiteIOFlow WebsiteState.Success(Unit) } fun postCommentReply( csrfToken: String?, replyCommentId: String, text: String, ) = websiteIOFlow( request = { HanimeNetwork.commentService.postCommentReply( csrfToken, replyCommentId, text ) } ) { Log.d("post_comment_reply_body", it) return@websiteIOFlow WebsiteState.Success(Unit) } fun likeComment( csrfToken: String?, commentPlace: CommentPlace, foreignId: String?, isPositive: Boolean, // 你選擇的是讚還是踩,1是讚,0是踩 likeUserId: String?, commentLikesCount: Int, commentLikesSum: Int, likeCommentStatus: Boolean, // 你之前有沒有點過讚,1是0否 unlikeCommentStatus: Boolean, // 你之前有沒有點過踩,1是0否 commentPosition: Int, comment: VideoComments.VideoComment, ) = websiteIOFlow( request = { HanimeNetwork.commentService.likeComment( csrfToken, commentPlace.value, foreignId, if (isPositive) 1 else 0, likeUserId, commentLikesCount, commentLikesSum, if (likeCommentStatus) 1 else 0, if (unlikeCommentStatus) 1 else 0 ) } ) { Log.d("like_comment_body", it) return@websiteIOFlow WebsiteState.Success( VideoCommentArgs( commentPosition, isPositive, comment ) ) } // // fun subscribeArtist( csrfToken: String?, userId: String, artistId: String, // 这里表示目标状态 status: Boolean, ) = websiteIOFlow( request = { HanimeNetwork.subscriptionService.subscribeArtist( csrfToken, userId, artistId, if (status) "" else "1" ) } ) { Log.d("subscribe_artist_body", it) return@websiteIOFlow WebsiteState.Success(status) } // // fun getLatestVersion(forceCheck: Boolean = true) = flow { emit(WebsiteState.Loading) val versionInfo = HUpdater.checkForUpdate(forceCheck) emit(WebsiteState.Success(versionInfo)) }.catch { e -> when (e) { is CancellationException -> throw e else -> { e.printStackTrace() emit(WebsiteState.Error(e)) } } }.flowOn(Dispatchers.IO) fun login(email: String, password: String) = flow { emit(WebsiteState.Loading) // 首先获取token val loginPage = HanimeNetwork.hanimeService.getLoginPage() val token = loginPage.body()?.string()?.let(Parser::extractTokenFromLoginPage) val req = HanimeNetwork.hanimeService.login(token, email, password) if (req.isSuccessful) { // 再次获取登录页面,如果失败则返回 cookie // 因为登录成功再次访问 login 会 404,这是判断是否登录成功的方法 val loginPageAgain = HanimeNetwork.hanimeService.getLoginPage() if (loginPageAgain.code() == 404) { // Cookie 會返回 XSRF-TOKEN 和 hanime1_session,我們只需要後者 // 错误的,还需要 remember_web 字段!但我没找到! Log.d("login_headers", req.headers().toMultimap().toString()) emit(WebsiteState.Success(req.headers().values("Set-Cookie"))) } else { emit(WebsiteState.Error(IllegalStateException(getString(R.string.account_or_password_wrong)))) } } else { // 雙重保險 emit(WebsiteState.Error(IllegalStateException(getString(R.string.account_or_password_wrong)))) } }.catch { e -> emit(WebsiteState.Error(handleException(e))) }.flowOn(Dispatchers.IO) /** * 用于单网页的情况 * * @param permittedSuccessCode 用于处理特殊情况,比如[NetworkRepo.modifyPlaylist]需要302成功 */ private fun websiteIOFlow( request: suspend () -> Response, permittedSuccessCode: IntArray? = null, action: (String) -> WebsiteState, ) = flow { val requestResult = request.invoke() val resultBody = requestResult.body()?.string() val permitted = permittedSuccessCode?.contains(requestResult.code()) == true if ((permitted || requestResult.isSuccessful)) { emit(action.invoke(resultBody ?: EMPTY_STRING)) } else { requestResult.throwRequestException() } }.catch { e -> emit(WebsiteState.Error(handleException(e))) }.flowOn(Dispatchers.IO) /** * 用于有page分页的情况 */ private fun pageIOFlow( request: suspend () -> Response, action: (String) -> PageLoadingState, ) = flow { val requestResult = request.invoke() val resultBody = requestResult.body()?.string() if (requestResult.isSuccessful && resultBody != null) { emit(action.invoke(resultBody)) } else { requestResult.throwRequestException() } }.catch { e -> emit(PageLoadingState.Error(handleException(e))) }.flowOn(Dispatchers.IO) /** * 用于影片界面 */ private fun videoIOFlow( request: suspend () -> Response, action: (String) -> VideoLoadingState, ) = flow { val requestResult = request.invoke() val resultBody = requestResult.body()?.string() if (requestResult.isSuccessful && resultBody != null) { emit(action.invoke(resultBody)) } else { requestResult.throwRequestException() } }.catch { e -> emit(VideoLoadingState.Error(handleException(e))) }.flowOn(Dispatchers.IO) private fun Response.throwRequestException(): Nothing { val body = errorBody()?.string() when (val code = code()) { 403 -> if (!body.isNullOrBlank()) { when { "you have been blocked" in body -> throw IPBlockedException(getString(R.string.do_not_use_japan_ip)) "Just a moment" in body -> throw CloudFlareBlockedException(getString(CloudFlareBlockedException.localizedMessages.random())) else -> throw HanimeNotFoundException(getString(R.string.video_might_not_exist)) // 主要出現在影片界面,當你v數不大時會報403 } } else throw IllegalStateException("$code ${message()}") 500 -> throw HanimeNotFoundException(getString(R.string.video_might_not_exist)) // 主要出現在影片界面,當你v數很大時會報500 404 -> if (!isAlreadyLogin) { throw IllegalStateException(getString(R.string.not_logged_in_currently)) } else { throw IllegalStateException("$code ${message()}") } else -> throw IllegalStateException("$code ${message()}") } } private fun handleException(e: Throwable): Throwable { return when (e) { is CancellationException -> throw e is ParseException -> { e.printStackTrace() ParseException(getString(R.string.parse_error_msg)) } is SSLHandshakeException -> { e.printStackTrace() SSLHandshakeException(getString(R.string.network_unstable_msg)) } else -> { e.printStackTrace() e } } } // private fun getString(resId: Int) = applicationContext.getString(resId) } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/Parser.kt ================================================ package com.yenaly.han1meviewer.logic import android.annotation.SuppressLint import android.util.Log import com.yenaly.han1meviewer.EMPTY_STRING import com.yenaly.han1meviewer.HanimeResolution import com.yenaly.han1meviewer.LOCAL_DATE_FORMAT import com.yenaly.han1meviewer.Preferences.isAlreadyLogin import com.yenaly.han1meviewer.logic.exception.ParseException import com.yenaly.han1meviewer.logic.model.HanimeInfo import com.yenaly.han1meviewer.logic.model.HanimePreview import com.yenaly.han1meviewer.logic.model.HanimeVideo import com.yenaly.han1meviewer.logic.model.HomePage import com.yenaly.han1meviewer.logic.model.MyListItems import com.yenaly.han1meviewer.logic.model.Playlists import com.yenaly.han1meviewer.logic.model.Subscription import com.yenaly.han1meviewer.logic.model.VideoComments import com.yenaly.han1meviewer.logic.state.PageLoadingState import com.yenaly.han1meviewer.logic.state.VideoLoadingState import com.yenaly.han1meviewer.logic.state.WebsiteState import com.yenaly.han1meviewer.toVideoCode import kotlinx.datetime.LocalDate import org.json.JSONObject import org.jsoup.Jsoup import org.jsoup.nodes.Comment import org.jsoup.nodes.Element import org.jsoup.select.Elements /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/07/31 031 16:43 */ object Parser { /** * 所需 Regex */ object Regex { val videoSource = Regex("""const source = '(.+)'""") val viewAndUploadTime = Regex("""觀看次數:(.+)次 *(\d{4}-\d{2}-\d{2})""") } fun extractTokenFromLoginPage(body: String): String { val parseBody = Jsoup.parse(body).body() return parseBody.selectFirst("input[name=_token]")?.attr("value") ?: throw ParseException("Can't find csrf token from login page.") } fun homePageVer2(body: String): WebsiteState { val parseBody = Jsoup.parse(body).body() val csrfToken = parseBody.selectFirst("input[name=_token]")?.attr("value") // csrf token val homePageParse = parseBody.select("div[id=home-rows-wrapper] > div") val userInfo = parseBody.selectFirst("div[id=user-modal-dp-wrapper]") val avatarUrl: String? = userInfo?.selectFirst("img")?.absUrl("src") val username: String? = userInfo?.getElementById("user-modal-name")?.text() val bannerCSS = parseBody.selectFirst("div[id=home-banner-wrapper]") val bannerImg = bannerCSS?.previousElementSibling() val bannerTitle = bannerImg?.selectFirst("img")?.attr("alt") .logIfParseNull(Parser::homePageVer2.name, "bannerTitle") val bannerPic = bannerImg?.select("img")?.getOrNull(1)?.absUrl("src") .logIfParseNull(Parser::homePageVer2.name, "bannerPic") val bannerDesc = bannerCSS?.selectFirst("h4")?.ownText() var bannerVideoCode = bannerCSS?.selectFirst("a[class~=play-btn]")?.absUrl("href")?.toVideoCode() // 目前先判断注释里的,以后可能会有变化 if (bannerVideoCode == null) { bannerCSS?.traverse { node, _ -> if (node is Comment) { node.data.toVideoCode()?.let { bannerVideoCode = it return@traverse } } } } bannerVideoCode.logIfParseNull(Parser::homePageVer2.name, "bannerVideoCode") val banner = if (bannerTitle != null && bannerPic != null) { HomePage.Banner( title = bannerTitle, description = bannerDesc, picUrl = bannerPic, videoCode = bannerVideoCode, ) } else null val latestHanimeClass = homePageParse.getOrNull(0) val latestReleaseClass = homePageParse.getOrNull(1) val latestUploadClass = homePageParse.getOrNull(2) val chineseSubtitleClass = homePageParse.getOrNull(3) val hotHanimeMonthlyClass = homePageParse.getOrNull(homePageParse.size - 2) val hanimeCurrentClass = homePageParse.getOrNull(homePageParse.size - 3) val hanimeTheyWatchedClass = homePageParse.getOrNull(4) // for latest hanime val latestHanimeList = mutableListOf() val latestHanimeItems = latestHanimeClass?.select("div[class=home-rows-videos-div]") latestHanimeItems?.forEach { latestHanimeItem -> val coverUrl = latestHanimeItem.selectFirst("img")?.absUrl("src") .throwIfParseNull(Parser::homePageVer2.name, "coverUrl") val title = latestHanimeItem.selectFirst("div[class$=title]")?.text() .throwIfParseNull(Parser::homePageVer2.name, "title") val videoCode = latestHanimeItem.parent()?.absUrl("href")?.toVideoCode() .throwIfParseNull(Parser::homePageVer2.name, "videoCode") latestHanimeList.add( HanimeInfo( coverUrl = coverUrl, title = title, videoCode = videoCode, itemType = HanimeInfo.SIMPLIFIED ) ) } // for latest release val latestReleaseList = mutableListOf() val latestReleaseItems = latestReleaseClass?.select("div[class^=card-mobile-panel]") latestReleaseItems?.forEachStep2 { latestReleaseItem -> hanimeNormalItemVer2(latestReleaseItem)?.let(latestReleaseList::add) } // for latest upload val latestUploadList = mutableListOf() val latestUploadItems = latestUploadClass?.select("div[class^=card-mobile-panel]") latestUploadItems?.forEachStep2 { latestUploadItem -> hanimeNormalItemVer2(latestUploadItem)?.let(latestUploadList::add) } // for chinese subtitle val chineseSubtitleList = mutableListOf() val chineseSubtitleItems = chineseSubtitleClass?.select("div[class^=card-mobile-panel]") chineseSubtitleItems?.forEachStep2 { chineseSubtitleItem -> hanimeNormalItemVer2(chineseSubtitleItem)?.let(chineseSubtitleList::add) } // for hanime they watched val hanimeTheyWatchedList = mutableListOf() val hanimeTheyWatchedItems = hanimeTheyWatchedClass?.select("div[class^=card-mobile-panel]") hanimeTheyWatchedItems?.forEachStep2 { hanimeTheyWatchedItem -> hanimeNormalItemVer2(hanimeTheyWatchedItem)?.let(hanimeTheyWatchedList::add) } // for hanime current val hanimeCurrentList = mutableListOf() val hanimeCurrentItems = hanimeCurrentClass?.select("div[class^=card-mobile-panel]") hanimeCurrentItems?.forEachStep2 { hanimeCurrentItem -> hanimeNormalItemVer2(hanimeCurrentItem)?.let(hanimeCurrentList::add) } // for hot hanime monthly val hotHanimeMonthlyList = mutableListOf() val hotHanimeMonthlyItems = hotHanimeMonthlyClass?.select("div[class^=card-mobile-panel]") hotHanimeMonthlyItems?.forEachStep2 { hotHanimeMonthlyItem -> hanimeNormalItemVer2(hotHanimeMonthlyItem)?.let(hotHanimeMonthlyList::add) } // emit! return WebsiteState.Success( HomePage( csrfToken, avatarUrl, username, banner = banner, latestHanime = latestHanimeList, latestRelease = latestReleaseList, latestUpload = latestUploadList, chineseSubtitle = chineseSubtitleList, hanimeTheyWatched = hanimeTheyWatchedList, hanimeCurrent = hanimeCurrentList, hotHanimeMonthly = hotHanimeMonthlyList, ) ) } fun hanimeSearch(body: String): PageLoadingState> { val parseBody = Jsoup.parse(body).body() val allContentsClass = parseBody.getElementsByClass("content-padding-new").firstOrNull() val allSimplifiedContentsClass = parseBody.getElementsByClass("home-rows-videos-wrapper").firstOrNull() // emit! if (allContentsClass != null) { return hanimeSearchNormalVer2(allContentsClass) } else if (allSimplifiedContentsClass != null) { return hanimeSearchSimplified(allSimplifiedContentsClass) } return PageLoadingState.Success(mutableListOf()) } // 每一个正常视频单元 // #issue-38: 解析錯誤,原來是加廣告了!所以遇到無法處理的直接返回null。 private fun hanimeNormalItemVer2(hanimeSearchItem: Element): HanimeInfo? { val title = hanimeSearchItem.selectFirst("div[class=card-mobile-title]")?.text() .logIfParseNull(Parser::hanimeNormalItemVer2.name, "title") // title val coverUrl = hanimeSearchItem.select("img").getOrNull(1)?.absUrl("src") .logIfParseNull(Parser::hanimeNormalItemVer2.name, "coverUrl") // coverUrl val videoCode = hanimeSearchItem.previousElementSibling()?.absUrl("href")?.toVideoCode() .logIfParseNull(Parser::hanimeNormalItemVer2.name, "videoCode") // videoCode if (title == null || coverUrl == null || videoCode == null) return null val durationAndViews = hanimeSearchItem.select("div.card-mobile-duration") val mDuration = durationAndViews.getOrNull(0)?.text() // 改了 val views = durationAndViews.getOrNull(2)?.text() // 改了 return HanimeInfo( title = title, coverUrl = coverUrl, videoCode = videoCode, duration = mDuration.logIfParseNull(Parser::hanimeNormalItemVer2.name, "duration"), uploader = null, views = views.logIfParseNull(Parser::hanimeNormalItemVer2.name, "views"), uploadTime = null, genre = null, itemType = HanimeInfo.NORMAL ) } // 每一个简化版视频单元 private fun hanimeSimplifiedItem(hanimeSearchItem: Element): HanimeInfo? { val videoCode = hanimeSearchItem.attr("href").toVideoCode() .logIfParseNull(Parser::hanimeSimplifiedItem.name, "videoCode") val coverUrl = hanimeSearchItem.selectFirst("img")?.attr("src") .logIfParseNull(Parser::hanimeSimplifiedItem.name, "coverUrl") val title = hanimeSearchItem.selectFirst("div[class=home-rows-videos-title]")?.text() .logIfParseNull(Parser::hanimeSimplifiedItem.name, "title") if (videoCode == null || coverUrl == null || title == null) return null return HanimeInfo( title = title, coverUrl = coverUrl, videoCode = videoCode, itemType = HanimeInfo.SIMPLIFIED ) } // 出来后是正常视频单元的页面用这个 private fun hanimeSearchNormalVer2( allContentsClass: Element, ): PageLoadingState> { val hanimeSearchList = mutableListOf() val hanimeSearchItems = allContentsClass.select("div[class^=card-mobile-panel]") if (hanimeSearchItems.isEmpty()) { return PageLoadingState.NoMoreData } else { hanimeSearchItems.forEachStep2 { hanimeSearchItem -> hanimeNormalItemVer2(hanimeSearchItem)?.let(hanimeSearchList::add) } } Log.d("search_result", "$hanimeSearchList") return PageLoadingState.Success(hanimeSearchList) } // 出来后是简化版视频单元的页面用这个 private fun hanimeSearchSimplified( allSimplifiedContentsClass: Element, ): PageLoadingState> { val hanimeSearchList = mutableListOf() val hanimeSearchItems = allSimplifiedContentsClass.children() if (hanimeSearchItems.isEmpty()) { return PageLoadingState.NoMoreData } else hanimeSearchItems.forEach { hanimeSearchItem -> hanimeSimplifiedItem(hanimeSearchItem)?.let(hanimeSearchList::add) } return PageLoadingState.Success(hanimeSearchList) } fun hanimeVideoVer2(body: String): VideoLoadingState { val parseBody = Jsoup.parse(body).body() val csrfToken = parseBody.selectFirst("input[name=_token]")?.attr("value") // csrf token val currentUserId = parseBody.selectFirst("input[name=like-user-id]")?.attr("value") // current user id val title = parseBody.getElementById("shareBtn-title")?.text() .throwIfParseNull(Parser::hanimeVideoVer2.name, "title") val likeStatus = parseBody.selectFirst("#video-like-btn .material-icons") val likesCount = parseBody.selectFirst("input[name=likes-count]") ?.attr("value")?.toIntOrNull() val videoDetailWrapper = parseBody.selectFirst("div[class=video-details-wrapper]") val videoCaptionText = videoDetailWrapper?.selectFirst("div[class^=video-caption-text]") val chineseTitle = videoCaptionText?.previousElementSibling()?.ownText() val introduction = videoCaptionText?.ownText() val uploadTimeWithViews = videoDetailWrapper?.selectFirst("div > div > div")?.text() val uploadTimeWithViewsGroups = uploadTimeWithViews?.let { Regex.viewAndUploadTime.find(it)?.groups } val uploadTime = uploadTimeWithViewsGroups?.get(2)?.value?.let { time -> LocalDate.parse(time, LOCAL_DATE_FORMAT) } val views = uploadTimeWithViewsGroups?.get(1)?.value val tags = parseBody.getElementsByClass("single-video-tag") val tagList = mutableListOf() tags.forEach { tag -> val child = tag.childOrNull(0) if (child != null && child.hasAttr("href")) { tagList.add(child.ownText()) } } val myListCheckboxWrapper = parseBody.select("div[class~=playlist-checkbox-wrapper]") val myListInfo = mutableListOf() myListCheckboxWrapper.forEach { val listTitle = it.selectFirst("span")?.ownText() .logIfParseNull(Parser::hanimeVideoVer2.name, "myListTitle", loginNeeded = true) val listInput = it.selectFirst("input") val listCode = listInput?.attr("id") .logIfParseNull(Parser::hanimeVideoVer2.name, "myListCode", loginNeeded = true) val isSelected = listInput?.hasAttr("checked") == true if (listTitle != null && listCode != null) { myListInfo += HanimeVideo.MyList.MyListInfo( code = listCode, title = listTitle, isSelected = isSelected ) } } val isWatchLater = parseBody.getElementById("playlist-save-checkbox") ?.selectFirst("input")?.hasAttr("checked") == true val myList = HanimeVideo.MyList(isWatchLater = isWatchLater, myListInfo = myListInfo) val playlistWrapper = parseBody.selectFirst("div[id=video-playlist-wrapper]") val playlist = playlistWrapper?.let { val playlistVideoList = mutableListOf() val playlistName = it.selectFirst("div > div > h4")?.text() val playlistScroll = it.getElementById("playlist-scroll") playlistScroll?.children()?.forEach { parent -> if (parent.selectFirst(".load-more-related-link") != null) return@forEach val videoCode = parent.selectFirst("div > a")?.absUrl("href")?.toVideoCode() .throwIfParseNull(Parser::hanimeVideoVer2.name, "videoCode") val cardMobilePanel = parent.selectFirst("div[class^=card-mobile-panel]") val eachTitleCover = cardMobilePanel?.select("div > div > div > img")?.getOrNull(1) val eachIsPlaying = cardMobilePanel?.select("div > div > div > div") ?.firstOrNull() ?.text() ?.contains("播放") == true val cardMobileDuration = cardMobilePanel?.select("div.card-mobile-duration") val eachDuration = cardMobileDuration?.firstOrNull()?.text() val eachViews = cardMobileDuration?.getOrNull(2)?.text() ?.substringBefore("次") val playlistEachCoverUrl = eachTitleCover?.absUrl("src") .throwIfParseNull(Parser::hanimeVideoVer2.name, "playlistEachCoverUrl") val playlistEachTitle = eachTitleCover?.attr("alt") .throwIfParseNull(Parser::hanimeVideoVer2.name, "playlistEachTitle") playlistVideoList.add( HanimeInfo( title = playlistEachTitle, coverUrl = playlistEachCoverUrl, videoCode = videoCode, duration = eachDuration.logIfParseNull( Parser::hanimeVideoVer2.name, "$playlistEachTitle duration" ), views = eachViews.logIfParseNull( Parser::hanimeVideoVer2.name, "$playlistEachTitle views" ), isPlaying = eachIsPlaying, itemType = HanimeInfo.NORMAL ) ) } HanimeVideo.Playlist(playlistName = playlistName, video = playlistVideoList) } val relatedAnimeList = mutableListOf() val relatedTabContent = parseBody.getElementById("related-tabcontent") relatedTabContent?.also { val children = it.childOrNull(0)?.children() val isSimplified = children?.getOrNull(0)?.select("a")?.getOrNull(0) ?.getElementsByClass("home-rows-videos-div") ?.firstOrNull() != null if (isSimplified) { for (each in children) { val eachContent = each.selectFirst("a") val homeRowsVideosDiv = eachContent?.getElementsByClass("home-rows-videos-div")?.firstOrNull() if (homeRowsVideosDiv != null) { val eachVideoCode = eachContent.absUrl("href").toVideoCode() ?: continue val eachCoverUrl = homeRowsVideosDiv.selectFirst("img")?.absUrl("src") .throwIfParseNull(Parser::hanimeVideoVer2.name, "eachCoverUrl") val eachTitle = homeRowsVideosDiv.selectFirst("div[class$=title]")?.text() .throwIfParseNull(Parser::hanimeVideoVer2.name, "eachTitle") relatedAnimeList.add( HanimeInfo( title = eachTitle, coverUrl = eachCoverUrl, videoCode = eachVideoCode, itemType = HanimeInfo.SIMPLIFIED ) ) } } } else { children?.forEachStep2 { each -> val item = each.select("div[class^=card-mobile-panel]")[0] hanimeNormalItemVer2(item)?.let(relatedAnimeList::add) } } } Log.d("related_anime_list", relatedAnimeList.toString()) val hanimeResolution = HanimeResolution() val videoClass = parseBody.selectFirst("video[id=player]") val videoCoverUrl = videoClass?.absUrl("poster").orEmpty() val videos = videoClass?.children() if (!videos.isNullOrEmpty()) { videos.forEach { source -> val resolution = source.attr("size") + "P" val sourceUrl = source.absUrl("src") val videoType = source.attr("type") hanimeResolution.parseResolution(resolution, sourceUrl, videoType) } } else { val playerDivWrapper = parseBody.selectFirst("div[id=player-div-wrapper]") playerDivWrapper?.select("script")?.let { scripts -> for (script in scripts) { val data = script.data() if (data.isBlank()) continue val result = Regex.videoSource.find(data)?.groups?.get(1)?.value ?: continue hanimeResolution.parseResolution(null, result) break } } } val artistAvatarUrl = parseBody.selectFirst("#video-user-avatar + img")?.absUrl("src") val artistNameCSS = parseBody.getElementById("video-artist-name") val artistGenre = artistNameCSS?.nextElementSibling()?.text()?.trim() val artistName = artistNameCSS?.text()?.trim() val postCSS = parseBody.getElementById("video-subscribe-form") val post = postCSS?.let { val userId = it.selectFirst("input[name=subscribe-user-id]")?.attr("value") val artistId = it.selectFirst("input[name=subscribe-artist-id]")?.attr("value") val isSubscribed = it.selectFirst("input[name=subscribe-status]")?.attr("value") if (userId != null && artistId != null && isSubscribed != null) { HanimeVideo.Artist.POST( userId = userId, artistId = artistId, isSubscribed = isSubscribed == "1" ) } else null } val artist = if (artistAvatarUrl != null && artistName != null && artistGenre != null) { HanimeVideo.Artist( name = artistName, avatarUrl = artistAvatarUrl, genre = artistGenre, post = post, ) } else null return VideoLoadingState.Success( HanimeVideo( title = title, coverUrl = videoCoverUrl, chineseTitle = chineseTitle.logIfParseNull( Parser::hanimeVideoVer2.name, "chineseTitle" ), uploadTime = uploadTime.logIfParseNull(Parser::hanimeVideoVer2.name, "uploadTime"), views = views.logIfParseNull(Parser::hanimeVideoVer2.name, "views"), introduction = introduction.logIfParseNull( Parser::hanimeVideoVer2.name, "introduction" ), videoUrls = hanimeResolution.toResolutionLinkMap(), tags = tagList, myList = myList, playlist = playlist, relatedHanimes = relatedAnimeList, artist = artist.logIfParseNull(Parser::hanimeVideoVer2.name, "artist"), favTimes = likesCount, isFav = likeStatus != null, csrfToken = csrfToken, currentUserId = currentUserId ) ) } fun hanimePreview(body: String): WebsiteState { val parseBody = Jsoup.parse(body).body() // latest hanime val latestHanimeList = mutableListOf() val latestHanimeClass = parseBody.selectFirst("div[class$=owl-theme]") latestHanimeClass?.let { val latestHanimeItems = latestHanimeClass.select("div[class=home-rows-videos-div]") latestHanimeItems.forEach { latestHanimeItem -> val coverUrl = latestHanimeItem.selectFirst("img")?.absUrl("src") .throwIfParseNull(Parser::hanimePreview.name, "coverUrl") val title = latestHanimeItem.selectFirst("div[class$=title]")?.text() .throwIfParseNull(Parser::hanimePreview.name, "title") latestHanimeList.add( HanimeInfo( coverUrl = coverUrl, title = title, videoCode = EMPTY_STRING /* empty string here! */, itemType = HanimeInfo.SIMPLIFIED ) ) } } val contentPaddingClass = parseBody.select("div[class=content-padding] > div") val previewInfo = mutableListOf() for (i in 0 until contentPaddingClass.size / 2) { val firstPart = contentPaddingClass.getOrNull(i * 2) val secondPart = contentPaddingClass.getOrNull(i * 2 + 1) val videoCode = firstPart?.id() val title = firstPart?.selectFirst("h4")?.text() val coverUrl = firstPart?.selectFirst("div[class=preview-info-cover] > img")?.absUrl("src") val previewInfoContentClass = firstPart?.getElementsByClass("preview-info-content-padding")?.firstOrNull() val videoTitle = previewInfoContentClass?.selectFirst("h4")?.text() val brand = previewInfoContentClass?.selectFirst("h5")?.selectFirst("a")?.text() val releaseDate = previewInfoContentClass?.select("h5")?.getOrNull(1)?.ownText() val introduction = secondPart?.selectFirst("h5")?.text() val tagClass = secondPart?.select("div[class=single-video-tag] > a") val tags = mutableListOf() tagClass?.forEach { tag: Element? -> tag?.let { tags.add(tag.text()) } } val relatedPicClass = secondPart?.select("img[class=preview-image-modal-trigger]") val relatedPics = mutableListOf() relatedPicClass?.forEach { relatedPic: Element? -> relatedPic?.let { relatedPics.add(relatedPic.absUrl("src")) } } previewInfo.add( HanimePreview.PreviewInfo( title = title, videoTitle = videoTitle, coverUrl = coverUrl, introduction = introduction.logIfParseNull( Parser::hanimePreview.name, "$title introduction" ), brand = brand.logIfParseNull(Parser::hanimePreview.name, "$title brand"), releaseDate = releaseDate.logIfParseNull( Parser::hanimePreview.name, "$title releaseDate" ), videoCode = videoCode.logIfParseNull( Parser::hanimePreview.name, "$title videoCode" ), tags = tags, relatedPicsUrl = relatedPics ) ) } val header = parseBody.selectFirst("div[id=player-div-wrapper]") val headerPicUrl = header?.selectFirst("img")?.absUrl("src") val hasPrevious = parseBody.getElementsByClass("hidden-md hidden-lg").firstOrNull() ?.select("div[style*=left]")?.firstOrNull() != null val hasNext = parseBody.getElementsByClass("hidden-md hidden-lg").firstOrNull() ?.select("div[style*=right]")?.firstOrNull() != null return WebsiteState.Success( HanimePreview( headerPicUrl = headerPicUrl.logIfParseNull( Parser::hanimePreview.name, "headerPicUrl" ), hasPrevious = hasPrevious, hasNext = hasNext, latestHanime = latestHanimeList, previewInfo = previewInfo ) ) } fun myListItems(body: String): PageLoadingState> { val parseBody = Jsoup.parse(body).body() val csrfToken = parseBody.selectFirst("input[name=_token]")?.attr("value") val desc = parseBody.getElementById("playlist-show-description")?.ownText() val myListHanimeList = mutableListOf() val allHanimeClass = parseBody.getElementsByClass("home-rows-videos-wrapper").firstOrNull() allHanimeClass?.let { if (allHanimeClass.childrenSize() == 0) { return PageLoadingState.NoMoreData } allHanimeClass.children().forEach { videoElement -> val title = videoElement.getElementsByClass("home-rows-videos-title") .firstOrNull()?.text() .throwIfParseNull(Parser::myListItems.name, "title") val coverUrl = videoElement.select("img").let { it.getOrNull(1) ?: it.firstOrNull() }?.absUrl("src") .throwIfParseNull(Parser::myListItems.name, "coverUrl") val videoCode = videoElement.getElementsByClass("playlist-show-links") .firstOrNull()?.absUrl("href")?.toVideoCode() .throwIfParseNull(Parser::myListItems.name, "videoCode") myListHanimeList.add( HanimeInfo( title = title, coverUrl = coverUrl, videoCode = videoCode, itemType = HanimeInfo.SIMPLIFIED ) ) } }.logIfParseNull(Parser::myListItems.name, "allHanimeClass_CSS") return PageLoadingState.Success( MyListItems( myListHanimeList, desc = desc, csrfToken = csrfToken ) ) } fun subscriptionItems(body: String): PageLoadingState> { val parseBody = Jsoup.parse(body).body() val csrfToken = parseBody.selectFirst("input[name=_token]")?.attr("value") val subscriptionList = mutableListOf() val allArtistsClass = parseBody.getElementsByClass("home-rows-videos-wrapper").firstOrNull() allArtistsClass?.let { artistClass -> if (allArtistsClass.childrenSize() == 0) { return PageLoadingState.NoMoreData } allArtistsClass.children().forEach { artistElement -> val title = artistElement.selectFirst("div[class$=search-artist-title]")?.text() .logIfParseNull(Parser::subscriptionItems.name, "title", loginNeeded = true) val avatarUrl = artistElement.select("img").let { it.getOrNull(1) ?: it.firstOrNull() }?.absUrl("src") .logIfParseNull(Parser::subscriptionItems.name, "avatarUrl", loginNeeded = true) val artistId = artistElement.selectFirst("input[name=playlist-show-video-id]") ?.attr("value").logIfParseNull( Parser::subscriptionItems.name, "artistId", loginNeeded = true ) if (title != null) { subscriptionList += Subscription( name = title, avatarUrl = avatarUrl, artistId = artistId ) } } }.logIfParseNull(Parser::subscriptionItems.name, "allArtistsClass_CSS") return PageLoadingState.Success( MyListItems( subscriptionList, desc = null, csrfToken = csrfToken ) ) } fun playlists(body: String): WebsiteState { val parseBody = Jsoup.parse(body).body() val csrfToken = parseBody.selectFirst("input[name=_token]")?.attr("value") val lists = parseBody.select("div[class~=single-user-playlist]") val playlists = mutableListOf() lists.forEach { val listCode = it.childOrNull(0)?.absUrl("href")?.substringAfter('=') .throwIfParseNull(Parser::playlists.name, "listCode") val listTitle = it.selectFirst("div[class=card-mobile-title]")?.ownText() .throwIfParseNull(Parser::playlists.name, "listTitle") val listTotal = it.selectFirst("div[style]")?.text()?.toIntOrNull() .throwIfParseNull(Parser::playlists.name, "listName") playlists += Playlists.Playlist( listCode = listCode, title = listTitle, total = listTotal ) } return WebsiteState.Success(Playlists(playlists = playlists, csrfToken = csrfToken)) } @SuppressLint("BuildListAdds") fun comments(body: String): WebsiteState { val jsonObject = JSONObject(body) val commentBody = jsonObject.get("comments").toString() val parseBody = Jsoup.parse(commentBody).body() val csrfToken = parseBody.selectFirst("input[name=_token]")?.attr("value") val currentUserId = parseBody.selectFirst("input[name=comment-user-id]")?.attr("value") val commentList = mutableListOf() val allCommentsClass = parseBody.getElementById("comment-start") buildList { allCommentsClass?.children()?.chunked(4)?.forEach { elements -> this += Element("div").apply { appendChildren(elements) } } }.forEach { child: Element -> val avatarUrl = child.selectFirst("img")?.absUrl("src") .throwIfParseNull(Parser::comments.name, "avatarUrl") val textClass = child.getElementsByClass("comment-index-text") val nameAndDateClass = textClass.firstOrNull() val username = nameAndDateClass?.selectFirst("a")?.ownText()?.trim() .throwIfParseNull(Parser::comments.name, "username") val date = nameAndDateClass?.selectFirst("span")?.ownText()?.trim() .throwIfParseNull(Parser::comments.name, "date") val content = textClass.getOrNull(1)?.text() .throwIfParseNull(Parser::comments.name, "content") val hasMoreReplies = child.selectFirst("div[class^=load-replies-btn]") != null val thumbUp = child.getElementById("comment-like-form-wrapper") ?.select("span[style]")?.getOrNull(1) ?.text()?.toIntOrNull() val id = child.selectFirst("div[id^=reply-section-wrapper]") ?.id()?.substringAfterLast("-") val foreignId = child.getElementById("foreign_id")?.attr("value") val isPositive = child.getElementById("is_positive")?.attr("value") val likeUserId = child.selectFirst("input[name=comment-like-user-id]")?.attr("value") val commentLikesCount = child.selectFirst("input[name=comment-likes-count]")?.attr("value") val commentLikesSum = child.selectFirst("input[name=comment-likes-sum]")?.attr("value") val likeCommentStatus = child.selectFirst("input[name=like-comment-status]")?.attr("value") val unlikeCommentStatus = child.selectFirst("input[name=unlike-comment-status]")?.attr("value") val post = VideoComments.VideoComment.POST( foreignId.logIfParseNull(Parser::comments.name, "foreignId", loginNeeded = true), isPositive == "1", likeUserId.logIfParseNull(Parser::comments.name, "likeUserId", loginNeeded = true), commentLikesCount?.toIntOrNull().logIfParseNull( Parser::comments.name, "commentLikesCount", loginNeeded = true ), commentLikesSum?.toIntOrNull().logIfParseNull( Parser::comments.name, "commentLikesSum", loginNeeded = true ), likeCommentStatus == "1", unlikeCommentStatus == "1", ) commentList.add( VideoComments.VideoComment( avatar = avatarUrl, username = username, date = date, content = content, hasMoreReplies = hasMoreReplies, thumbUp = thumbUp.logIfParseNull(Parser::comments.name, "thumbUp"), id = id.logIfParseNull(Parser::comments.name, "id"), isChildComment = false, post = post ) ) } Log.d("commentList", commentList.toString()) return WebsiteState.Success( VideoComments( commentList, currentUserId, csrfToken ) ) } fun commentReply(body: String): WebsiteState { val jsonObject = JSONObject(body) val replyBody = jsonObject.get("replies").toString() val replyList = mutableListOf() val parseBody = Jsoup.parse(replyBody).body() val replyStart = parseBody.selectFirst("div[id^=reply-start]") replyStart?.let { val allRepliesClass = it.children() for (i in allRepliesClass.indices step 2) { val basicClass = allRepliesClass.getOrNull(i) val postClass = allRepliesClass.getOrNull(i + 1) val avatarUrl = basicClass?.selectFirst("img")?.absUrl("src") .throwIfParseNull(Parser::commentReply.name, "avatarUrl") val textClass = basicClass?.getElementsByClass("comment-index-text") val nameAndDateClass = textClass?.firstOrNull() val username = nameAndDateClass?.selectFirst("a")?.ownText()?.trim() .throwIfParseNull(Parser::commentReply.name, "name") val date = nameAndDateClass?.selectFirst("span")?.ownText()?.trim() .throwIfParseNull(Parser::commentReply.name, "date") val content = textClass?.getOrNull(1)?.text() .throwIfParseNull(Parser::commentReply.name, "content") val thumbUp = postClass ?.select("span[style]")?.getOrNull(1) ?.text()?.toIntOrNull() val foreignId = postClass?.getElementById("foreign_id")?.attr("value") val isPositive = postClass?.getElementById("is_positive")?.attr("value") val likeUserId = postClass?.selectFirst("input[name=comment-like-user-id]")?.attr("value") val commentLikesCount = postClass?.selectFirst("input[name=comment-likes-count]")?.attr("value") val commentLikesSum = postClass?.selectFirst("input[name=comment-likes-sum]")?.attr("value") val likeCommentStatus = postClass?.selectFirst("input[name=like-comment-status]")?.attr("value") val unlikeCommentStatus = postClass?.selectFirst("input[name=unlike-comment-status]")?.attr("value") val post = VideoComments.VideoComment.POST( foreignId.logIfParseNull( Parser::commentReply.name, "foreignId", loginNeeded = true ), isPositive == "1", likeUserId.logIfParseNull( Parser::commentReply.name, "likeUserId", loginNeeded = true ), commentLikesCount?.toIntOrNull().logIfParseNull( Parser::commentReply.name, "commentLikesCount", loginNeeded = true ), commentLikesSum?.toIntOrNull().logIfParseNull( Parser::commentReply.name, "commentLikesSum", loginNeeded = true ), likeCommentStatus == "1", unlikeCommentStatus == "1", ) replyList.add( VideoComments.VideoComment( avatar = avatarUrl, username = username, date = date, content = content, thumbUp = thumbUp.logIfParseNull(Parser::commentReply.name, "thumbUp"), id = null, isChildComment = true, post = post ) ) } } return WebsiteState.Success(VideoComments(replyList)) } /** * 這個網站的網頁結構真的很奇怪,所以我寫了一個 forEachStep2 來處理 */ private inline fun Elements.forEachStep2(action: (Element) -> Unit) { for (i in 0 until size step 2) { action(get(i)) } } /** * 得到 Element 的 child,如果 index 超出範圍,就返回 null */ private fun Element.childOrNull(index: Int): Element? { return try { child(index) } catch (_: IndexOutOfBoundsException) { null } } /** * 基本都是必需的參數,所以如果是 null,就直接丟出 [ParseException] * * @param funcName 這個參數是在哪個函數中被使用的 * @param varName 這個參數的名稱 * @return 如果 [this] 不是 null,就回傳 [this] * @throws ParseException 如果 [this] 是 null,就丟出 [ParseException] */ private fun T?.throwIfParseNull(funcName: String, varName: String): T = this ?: throw ParseException(funcName, varName) /** * 如果 [this] 是 null,就在 logcat 中顯示訊息 * * @param funcName 這個參數是在哪個函數中被使用的 * @param varName 這個參數的名稱 * @return 回傳 [this] */ private fun T?.logIfParseNull( funcName: String, varName: String, loginNeeded: Boolean = false, ): T? = also { if (it == null) { if (loginNeeded) { if (isAlreadyLogin) { Log.d("Parse::$funcName", "[$varName] is null. 而且處於登入狀態,這有點不正常") } } else { Log.d("Parse::$funcName", "[$varName] is null. 這有點不正常") } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/dao/DownloadDatabase.kt ================================================ package com.yenaly.han1meviewer.logic.dao import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase import com.yenaly.han1meviewer.logic.dao.download.DownloadCategoryDao import com.yenaly.han1meviewer.logic.dao.download.HUpdateDao import com.yenaly.han1meviewer.logic.dao.download.HanimeDownloadDao import com.yenaly.han1meviewer.logic.entity.download.DownloadCategoryEntity import com.yenaly.han1meviewer.logic.entity.download.HUpdateEntity import com.yenaly.han1meviewer.logic.entity.download.HanimeCategoryCrossRef import com.yenaly.han1meviewer.logic.entity.download.HanimeDownloadEntity import com.yenaly.han1meviewer.logic.state.DownloadState import com.yenaly.yenaly_libs.utils.applicationContext /** * @project Han1meViewer * @author Yenaly Liew * @time 2022/08/07 007 18:26 */ @Database( entities = [HanimeDownloadEntity::class, DownloadCategoryEntity::class, HanimeCategoryCrossRef::class, HUpdateEntity::class], version = 4, exportSchema = false ) abstract class DownloadDatabase : RoomDatabase() { abstract val hanimeDownloadDao: HanimeDownloadDao abstract val downloadCategoryDao: DownloadCategoryDao abstract val hUpdateDao: HUpdateDao companion object { val instance by lazy { Room.databaseBuilder( applicationContext, DownloadDatabase::class.java, "download.db" ).addMigrations(Migration1To2, Migration2To3, Migration3To4).build() } } object Migration1To2 : Migration(1, 2) { override fun migrate(db: SupportSQLiteDatabase) { db.execSQL( """CREATE TABLE IF NOT EXISTS `HanimeDownloadEntity`( `coverUrl` TEXT NOT NULL, `title` TEXT NOT NULL, `addDate` INTEGER NOT NULL, `videoCode` TEXT NOT NULL, `videoUri` TEXT NOT NULL, `quality` TEXT NOT NULL, `videoUrl` TEXT NOT NULL, `length` INTEGER NOT NULL, `downloadedLength` INTEGER NOT NULL, `isDownloading` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)""".trimIndent() ) db.execSQL( """INSERT INTO `HanimeDownloadEntity`( `coverUrl`, `title`, `addDate`, `videoCode`, `videoUri`, `quality`, `videoUrl`, `length`, `downloadedLength`, `isDownloading`, `id`) SELECT `coverUrl`, `title`, `addDate`, `videoCode`, `videoUri`, `quality`, '' AS `videoUrl`, 1 AS `length`, 1 AS `downloadedLength`, 0 AS `isDownloading`, `id` FROM `HanimeDownloadedEntity`""".trimIndent() ) db.execSQL("""DROP TABLE IF EXISTS HanimeDownloadedEntity""") } } object Migration2To3 : Migration(2, 3) { override fun migrate(db: SupportSQLiteDatabase) { db.execSQL( """CREATE TABLE IF NOT EXISTS `DownloadCategoryEntity` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL)""" ) db.execSQL( """CREATE TABLE IF NOT EXISTS `HanimeCategoryCrossRef` (`videoId` INTEGER NOT NULL, `categoryId` INTEGER NOT NULL, PRIMARY KEY(`videoId`, `categoryId`))""" ) // Add coverUri column db.execSQL("""ALTER TABLE `HanimeDownloadEntity` ADD COLUMN `coverUri` TEXT NULL""") // Add state column with default value (convert from isDownloading) db.execSQL("""ALTER TABLE `HanimeDownloadEntity` ADD COLUMN `state` INTEGER NOT NULL DEFAULT ${DownloadState.Mask.UNKNOWN}""") // Update state values based on isDownloading // If isDownloading=1, set state to DOWNLOADING (2) // If isDownloading=0, // if downloadedLength=length, set state to FINISHED (4) // else set state to PAUSED (3) db.execSQL( """UPDATE `HanimeDownloadEntity` SET `state` = |CASE WHEN `isDownloading` = 1 THEN ${DownloadState.Mask.DOWNLOADING} ELSE |CASE WHEN `downloadedLength` = `length` THEN ${DownloadState.Mask.FINISHED} |ELSE ${DownloadState.Mask.PAUSED} END END""".trimMargin() ) } } object Migration3To4 : Migration(3, 4) { override fun migrate(db: SupportSQLiteDatabase) { db.execSQL( """CREATE TABLE IF NOT EXISTS `HUpdateEntity`( `name` TEXT NOT NULL, `url` TEXT NOT NULL, `nodeId` TEXT NOT NULL, `length` INTEGER NOT NULL, `downloadedLength` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY NOT NULL)""".trimIndent() ) db.execSQL("""ALTER TABLE `HUpdateEntity` ADD COLUMN `state` INTEGER NOT NULL DEFAULT ${DownloadState.Mask.UNKNOWN}""") } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/dao/HKeyframeDao.kt ================================================ package com.yenaly.han1meviewer.logic.dao import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Update import com.yenaly.han1meviewer.logic.entity.HKeyframeEntity import kotlinx.coroutines.flow.Flow /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/12 012 12:39 */ @Dao abstract class HKeyframeDao { @Query("SELECT * FROM HKeyframeEntity ORDER BY createdTime DESC") abstract fun loadAll(): Flow> @Query("SELECT * FROM HKeyframeEntity WHERE `title` LIKE '%' || :keyword || '%' OR `videoCode` == :keyword ORDER BY createdTime DESC") abstract fun loadAll(keyword: String): Flow> @Insert(onConflict = OnConflictStrategy.REPLACE) abstract suspend fun insert(entity: HKeyframeEntity) @Update(onConflict = OnConflictStrategy.REPLACE) abstract suspend fun update(entity: HKeyframeEntity) @Delete abstract suspend fun delete(entity: HKeyframeEntity) @Query("SELECT * FROM HKeyframeEntity WHERE `videoCode` == :videoCode LIMIT 1") abstract suspend fun findBy(videoCode: String): HKeyframeEntity? @Query("SELECT * FROM HKeyframeEntity WHERE `videoCode` == :videoCode LIMIT 1") abstract fun observe(videoCode: String): Flow open suspend fun modifyKeyframe( videoCode: String, oldKeyframe: HKeyframeEntity.Keyframe, keyframe: HKeyframeEntity.Keyframe, ) { val entity = findBy(videoCode) entity?.let { // 按理説一定會有,如果沒有那就是出問題了 if (keyframe == oldKeyframe) return removeKeyframe(videoCode, oldKeyframe) appendKeyframe(videoCode, entity.title, keyframe) } } open suspend fun appendKeyframe( videoCode: String, title: String, keyframe: HKeyframeEntity.Keyframe, ) { val entity = findBy(videoCode) if (entity == null) { insert( HKeyframeEntity( videoCode, title, mutableListOf(keyframe), lastModifiedTime = System.currentTimeMillis(), createdTime = System.currentTimeMillis(), author = null ) ) } else { entity.keyframes += keyframe entity.keyframes.sortBy { it.position } update(entity.copy(lastModifiedTime = System.currentTimeMillis())) } } open suspend fun removeKeyframe( videoCode: String, keyframe: HKeyframeEntity.Keyframe, ) { val entity = findBy(videoCode) if (entity != null) { entity.keyframes -= keyframe if (entity.keyframes.isEmpty()) { delete(entity) return } update(entity.copy(lastModifiedTime = System.currentTimeMillis())) } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/dao/HistoryDatabase.kt ================================================ package com.yenaly.han1meviewer.logic.dao import android.database.sqlite.SQLiteDatabase import androidx.core.content.contentValuesOf import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase import com.yenaly.han1meviewer.logic.entity.SearchHistoryEntity import com.yenaly.han1meviewer.logic.entity.WatchHistoryEntity import com.yenaly.yenaly_libs.utils.applicationContext /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/22 022 22:46 */ @Database( entities = [SearchHistoryEntity::class, WatchHistoryEntity::class], version = 2, exportSchema = false ) abstract class HistoryDatabase : RoomDatabase() { abstract val searchHistory: SearchHistoryDao abstract val watchHistory: WatchHistoryDao companion object { val instance by lazy { Room.databaseBuilder( applicationContext, HistoryDatabase::class.java, "history.db" ).addMigrations(Migration1To2).build() } } object Migration1To2 : Migration(1, 2) { override fun migrate(db: SupportSQLiteDatabase) { val cursor = db.query( """SELECT id, redirectLink FROM WatchHistoryEntity""" ) while (cursor.moveToNext()) { val id = cursor.getInt(cursor.getColumnIndexOrThrow("id")) val url = cursor.getString(cursor.getColumnIndexOrThrow("redirectLink")) val videoCode = url.substringAfter("v=") // 不用 String.toVideoCode() 的原因是,防止該拓展函數因不可抗力改變導致 migrate 失敗 val values = contentValuesOf("redirectLink" to videoCode) db.update( "WatchHistoryEntity", SQLiteDatabase.CONFLICT_REPLACE, values, "id = ?", arrayOf(id) ) } db.execSQL( """ALTER TABLE WatchHistoryEntity RENAME COLUMN redirectLink TO videoCode""" ) } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/dao/MiscellanyDatabase.kt ================================================ package com.yenaly.han1meviewer.logic.dao import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import com.yenaly.han1meviewer.logic.entity.HKeyframeEntity import com.yenaly.yenaly_libs.utils.applicationContext /** * 这是各种 有数据库需求的小功能 的聚集地, * 如果这个功能需要数据库就放到这里。 * * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/12 012 12:28 */ @Database( entities = [HKeyframeEntity::class], version = 1, exportSchema = false ) abstract class MiscellanyDatabase : RoomDatabase() { abstract val hKeyframeDao: HKeyframeDao companion object { val instance by lazy { Room.databaseBuilder( applicationContext, MiscellanyDatabase::class.java, "miscellany.db" ).build() } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/dao/SearchHistoryDao.kt ================================================ package com.yenaly.han1meviewer.logic.dao import androidx.room.* import com.yenaly.han1meviewer.logic.entity.SearchHistoryEntity import kotlinx.coroutines.flow.Flow /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/22 022 17:53 */ @Dao abstract class SearchHistoryDao { @Query("SELECT * FROM SearchHistoryEntity ORDER BY id DESC") abstract fun loadAll(): Flow> @Query("SELECT * FROM SearchHistoryEntity WHERE `query` LIKE '%' || :keyword || '%' ORDER BY id DESC") abstract fun loadAll(keyword: String): Flow> @Delete abstract suspend fun delete(history: SearchHistoryEntity) @Insert(onConflict = OnConflictStrategy.REPLACE) abstract suspend fun insert(history: SearchHistoryEntity) @Query("SELECT * FROM SearchHistoryEntity WHERE (`query` = :query) LIMIT 1") abstract suspend fun find(query: String): SearchHistoryEntity? @Query("DELETE FROM SearchHistoryEntity WHERE (`query` = :query)") abstract suspend fun deleteByKeyword(query: String) @Transaction open suspend fun insertOrUpdate(entity: SearchHistoryEntity) { val dbEntity = find(entity.query) if (dbEntity != null) { delete(dbEntity) insert(entity) return } insert(entity) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/dao/WatchHistoryDao.kt ================================================ package com.yenaly.han1meviewer.logic.dao import androidx.room.* import com.yenaly.han1meviewer.logic.entity.WatchHistoryEntity import kotlinx.coroutines.flow.Flow /** * @project Han1meViewer * @author Yenaly Liew * @time 2022/07/02 002 16:47 */ @Dao abstract class WatchHistoryDao { @Query("SELECT * FROM WatchHistoryEntity ORDER BY id DESC") abstract fun loadAll(): Flow> @Delete abstract suspend fun delete(history: WatchHistoryEntity) @Query("DELETE FROM WatchHistoryEntity") abstract suspend fun deleteAll() @Insert(onConflict = OnConflictStrategy.REPLACE) abstract suspend fun insert(history: WatchHistoryEntity) @Update(onConflict = OnConflictStrategy.REPLACE) abstract suspend fun update(history: WatchHistoryEntity) @Query("SELECT * FROM WatchHistoryEntity WHERE (`videoCode` = :videoCode) LIMIT 1") abstract suspend fun findBy(videoCode: String): WatchHistoryEntity? @Transaction open suspend fun insertOrUpdate(history: WatchHistoryEntity) { val dbEntity = findBy(history.videoCode) if (dbEntity != null) { delete(dbEntity) insert(history) return } insert(history) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/dao/download/DownloadCategoryDao.kt ================================================ package com.yenaly.han1meviewer.logic.dao.download import androidx.room.Dao import androidx.room.Query import androidx.room.RewriteQueriesToDropUnusedColumns import androidx.room.Transaction import com.yenaly.han1meviewer.logic.entity.download.DownloadCategoryEntity import com.yenaly.han1meviewer.logic.entity.download.HanimeDownloadEntity import kotlinx.coroutines.flow.Flow @Dao abstract class DownloadCategoryDao { @RewriteQueriesToDropUnusedColumns @Transaction @Query( "SELECT * FROM HanimeDownloadEntity " + "INNER JOIN HanimeCategoryCrossRef ON HanimeDownloadEntity.id = HanimeCategoryCrossRef.videoId " + "WHERE HanimeCategoryCrossRef.categoryId = :categoryId AND HanimeDownloadEntity.downloadedLength == HanimeDownloadEntity.length" ) abstract fun getVideosForCategory(categoryId: Int): Flow> @Query("SELECT * FROM DownloadCategoryEntity") abstract fun getAllCategories(): Flow> } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/dao/download/HUpdateDao.kt ================================================ package com.yenaly.han1meviewer.logic.dao.download import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Update import com.yenaly.han1meviewer.logic.entity.download.HUpdateEntity import com.yenaly.han1meviewer.logic.state.DownloadState import kotlinx.coroutines.flow.Flow @Dao abstract class HUpdateDao { @Query("SELECT * FROM HUpdateEntity WHERE state != ${DownloadState.Mask.FINISHED} AND id = 1") abstract fun loadUpdating(): Flow @Query("DELETE FROM HUpdateEntity WHERE id = 1") abstract suspend fun delete() @Insert(onConflict = OnConflictStrategy.Companion.REPLACE) abstract suspend fun insert(entity: HUpdateEntity) @Update(onConflict = OnConflictStrategy.Companion.REPLACE) abstract suspend fun update(entity: HUpdateEntity): Int @Query("SELECT * FROM HUpdateEntity WHERE id = 1") abstract suspend fun get(): HUpdateEntity? @Query("UPDATE HUpdateEntity SET state = :state WHERE id = 1") abstract suspend fun updateState(state: DownloadState) } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/dao/download/HanimeDownloadDao.kt ================================================ package com.yenaly.han1meviewer.logic.dao.download import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Transaction import androidx.room.Update import com.yenaly.han1meviewer.logic.entity.download.HanimeDownloadEntity import com.yenaly.han1meviewer.logic.entity.download.VideoWithCategories import com.yenaly.han1meviewer.logic.state.DownloadState import kotlinx.coroutines.flow.Flow /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/08/18 018 23:07 */ @Dao abstract class HanimeDownloadDao { /** * 获取所有未下载完成的任务 * * 名字起得不好 */ @Query("SELECT * FROM HanimeDownloadEntity WHERE state != ${DownloadState.Mask.FINISHED} ORDER BY id DESC") abstract fun loadAllDownloadingHanime(): Flow> /** * 获取所有正在下载的任务,单次 */ //@Query("SELECT * FROM HanimeDownloadEntity WHERE isDownloading = 1 ORDER BY id DESC") @Query("SELECT * FROM HanimeDownloadEntity WHERE state != ${DownloadState.Mask.FINISHED} ORDER BY id DESC") abstract suspend fun loadAllDownloadingHanimeOnce(): MutableList /** * 获取部分正在下载的任务,单次 */ //@Query("SELECT * FROM HanimeDownloadEntity WHERE isDownloading = 1 ORDER BY id DESC LIMIT :limit") @Query("SELECT * FROM HanimeDownloadEntity WHERE state != ${DownloadState.Mask.FINISHED} ORDER BY id DESC LIMIT :limit") abstract suspend fun loadDownloadingHanimeOnce(limit: Int): MutableList @Query( "SELECT * FROM HanimeDownloadEntity WHERE state = ${DownloadState.Mask.FINISHED} ORDER BY " + "CASE WHEN :ascending THEN title END ASC, CASE WHEN NOT :ascending THEN title END DESC" ) @Transaction abstract fun loadAllDownloadedHanimeByTitle(ascending: Boolean): Flow> @Query( "SELECT * FROM HanimeDownloadEntity WHERE state = ${DownloadState.Mask.FINISHED} ORDER BY " + "CASE WHEN :ascending THEN id END ASC, CASE WHEN NOT :ascending THEN id END DESC" ) @Transaction abstract fun loadAllDownloadedHanimeById(ascending: Boolean): Flow> @Query("DELETE FROM HanimeDownloadEntity WHERE (`videoCode` = :videoCode AND `quality` = :quality)") @Deprecated("查屁") abstract suspend fun delete(videoCode: String, quality: String) @Query("DELETE FROM HanimeDownloadEntity WHERE (`videoCode` = :videoCode)") abstract suspend fun delete(videoCode: String) //@Query("UPDATE HanimeDownloadEntity SET `isDownloading` = 0") @Query("UPDATE HanimeDownloadEntity SET `state` = ${DownloadState.Mask.PAUSED}") abstract suspend fun pauseAll() @Delete abstract suspend fun delete(entity: HanimeDownloadEntity) @Insert(onConflict = OnConflictStrategy.Companion.REPLACE) abstract suspend fun insert(entity: HanimeDownloadEntity) @Update(onConflict = OnConflictStrategy.Companion.REPLACE) abstract suspend fun update(entity: HanimeDownloadEntity): Int @Query("SELECT * FROM HanimeDownloadEntity WHERE (`videoCode` = :videoCode AND `quality` = :quality) LIMIT 1") abstract suspend fun find(videoCode: String, quality: String): HanimeDownloadEntity? @Query("SELECT * FROM HanimeDownloadEntity WHERE (`videoCode` = :videoCode) LIMIT 1") abstract suspend fun find(videoCode: String): HanimeDownloadEntity? @Query("SELECT COUNT(*) FROM HanimeDownloadEntity WHERE (`videoCode` = :videoCode)") @Deprecated("查屁") abstract suspend fun countBy(videoCode: String): Int } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/entity/HKeyframeEntity.kt ================================================ @file:Suppress("PLUGIN_IS_NOT_ENABLED") package com.yenaly.han1meviewer.logic.entity import androidx.room.Entity import androidx.room.Ignore import androidx.room.PrimaryKey import androidx.room.TypeConverter import androidx.room.TypeConverters import com.yenaly.han1meviewer.logic.model.MultiItemEntity import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json /** * @project Han1meViewer * @author Yenaly Liew */ interface HKeyframeType : MultiItemEntity { companion object { const val H_KEYFRAME = 0 const val HEADER = 1 } } /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/12 012 12:14 */ @Serializable @Entity @TypeConverters(HKeyframeEntity.KeyframeTypeConverter::class) data class HKeyframeEntity( @PrimaryKey val videoCode: String, val title: String, /** * 关键帧列表 */ val keyframes: MutableList, /** * 最后修改时间 */ val lastModifiedTime: Long = -1, /** * 创建时间 */ val createdTime: Long = -1, /** * 作者,null 代表本地(自己创建的),非 null 代表共享 */ val author: String? = null, ) : HKeyframeType { /** * 分组,一个系列为一组 */ @Ignore val group: String? = null /** * 所在集数 */ @Ignore val episode: Int = -1 @Ignore override val itemType: Int = HKeyframeType.H_KEYFRAME @Serializable data class Keyframe( /** * 该关键帧的时间戳 */ val position: Long, /** * 该关键帧的提示 */ val prompt: String?, ) class KeyframeTypeConverter { @TypeConverter fun fromKeyframeList(keyframes: MutableList): String = Json.encodeToString(keyframes) @TypeConverter fun toKeyframeList(keyframes: String): MutableList = Json.decodeFromString(keyframes) } } /** * @project Han1meViewer * @author Yenaly Liew */ data class HKeyframeHeader( val title: String, /** * 附属的关键帧列表 */ val attached: List, override val itemType: Int = HKeyframeType.HEADER, ) : HKeyframeType ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/entity/SearchHistoryEntity.kt ================================================ package com.yenaly.han1meviewer.logic.entity import androidx.room.Entity import androidx.room.PrimaryKey /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/22 022 18:16 */ @Entity data class SearchHistoryEntity( val query: String, @PrimaryKey(autoGenerate = true) val id: Int = 0 ) ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/entity/WatchHistoryEntity.kt ================================================ package com.yenaly.han1meviewer.logic.entity import androidx.room.Entity import androidx.room.PrimaryKey /** * @project Han1meViewer * @author Yenaly Liew * @time 2022/07/02 002 13:13 */ @Entity data class WatchHistoryEntity( val coverUrl: String, val title: String, val releaseDate: Long, val watchDate: Long, val videoCode: String, @PrimaryKey(autoGenerate = true) val id: Int = 0, ) { val releaseDateDays: Int get() = (releaseDate / (24 * 60 * 60 * 1000)).toInt() } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/entity/download/DownloadCategoryEntity.kt ================================================ package com.yenaly.han1meviewer.logic.entity.download import androidx.room.Entity import androidx.room.PrimaryKey @Entity data class DownloadCategoryEntity( val name: String, @PrimaryKey(autoGenerate = true) val id: Int = 0, ) ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/entity/download/HUpdateEntity.kt ================================================ package com.yenaly.han1meviewer.logic.entity.download import androidx.annotation.IntRange import androidx.room.Entity import androidx.room.PrimaryKey import androidx.room.TypeConverter import androidx.room.TypeConverters import com.yenaly.han1meviewer.logic.state.DownloadState @Entity @TypeConverters(HUpdateEntity.StateTypeConverter::class) data class HUpdateEntity( @PrimaryKey() val id: Int = 1, val name: String, val url: String, val nodeId: String, /** * 安装包长度 */ val length: Long, /** * 安装包已下载长度 */ val downloadedLength: Long, /** * 当前状态 */ val state: DownloadState = DownloadState.Unknown, ) { /** * 下载进度 */ @get:IntRange(from = 0, to = 100) val progress get() = (downloadedLength * 100 / length).toInt() /** * 是否已下载完成 */ val isDownloaded get() = state == DownloadState.Finished val isDownloading get() = state == DownloadState.Downloading class StateTypeConverter { @TypeConverter fun from(state: DownloadState): Int = state.mask @TypeConverter fun to(state: Int): DownloadState = DownloadState.from(state) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/entity/download/HanimeCategoryCrossRef.kt ================================================ package com.yenaly.han1meviewer.logic.entity.download import androidx.room.Entity import androidx.room.Index @Entity( primaryKeys = ["videoId", "categoryId"], indices = [Index(value = ["categoryId"])], ) data class HanimeCategoryCrossRef( val videoId: Int, val categoryId: Int, ) ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/entity/download/HanimeDownloadEntity.kt ================================================ package com.yenaly.han1meviewer.logic.entity.download import androidx.annotation.IntRange import androidx.room.Entity import androidx.room.PrimaryKey import androidx.room.TypeConverter import androidx.room.TypeConverters import com.yenaly.han1meviewer.HFileManager import com.yenaly.han1meviewer.logic.state.DownloadState /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/08/18 018 21:50 */ @Entity @TypeConverters(HanimeDownloadEntity.StateTypeConverter::class) data class HanimeDownloadEntity( /** * 封面地址 */ val coverUrl: String, /** * 封面图片本地地址 */ var coverUri: String?, /** * 影片标题 */ val title: String, /** * 添加日期 */ val addDate: Long, /** * 影片代码 */ val videoCode: String, /** * 影片存储在本地的位置 */ val videoUri: String, /** * 影片质量 */ val quality: String, /** * 影片下载地址 */ val videoUrl: String, /** * 影片长度 */ val length: Long, /** * 影片已下载长度 */ val downloadedLength: Long, // /** // * 是否正在下载 // */ // val isDownloading: Boolean = false, /** * 当前状态 */ val state: DownloadState = DownloadState.Unknown, @PrimaryKey(autoGenerate = true) val id: Int = 0, ) { /** * 下载进度 */ @get:IntRange(from = 0, to = 100) val progress get() = (downloadedLength * 100 / length).toInt() /** * 是否已下载完成 */ val isDownloaded get() = state == DownloadState.Finished val isDownloading get() = state == DownloadState.Downloading val suffix get() = videoUri.substringAfterLast(".", HFileManager.DEF_VIDEO_TYPE) /** * 排序方式 */ enum class SortedBy { ID, TITLE } class StateTypeConverter { @TypeConverter fun from(state: DownloadState): Int = state.mask @TypeConverter fun to(state: Int): DownloadState = DownloadState.from(state) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/entity/download/VideoWithCategories.kt ================================================ package com.yenaly.han1meviewer.logic.entity.download import androidx.room.Embedded import androidx.room.Junction import androidx.room.Relation data class VideoWithCategories( @Embedded val video: HanimeDownloadEntity, @Relation( parentColumn = "id", entityColumn = "id", associateBy = Junction( value = HanimeCategoryCrossRef::class, parentColumn = "videoId", entityColumn = "categoryId" ) ) val categories: List, ) ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/exception/CloudFlareBlockedException.kt ================================================ package com.yenaly.han1meviewer.logic.exception import com.yenaly.han1meviewer.R /** * 检测到爬虫被封鎖 * * @project Han1meViewer * @author Yenaly Liew * @time 2023/08/07 007 12:45 */ open class CloudFlareBlockedException(reason: String) : RuntimeException(reason) { companion object { val localizedMessages = intArrayOf( R.string.website_blocked_msg, R.string.website_blocked_msg_2, R.string.website_blocked_msg_3, ) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/exception/HanimeNotFoundException.kt ================================================ package com.yenaly.han1meviewer.logic.exception /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/08/07 007 13:08 */ class HanimeNotFoundException(reason: String) : RuntimeException(reason) ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/exception/IPBlockedException.kt ================================================ package com.yenaly.han1meviewer.logic.exception /** * IP被封鎖 * * @project Han1meViewer * @author Yenaly Liew * @time 2023/08/07 007 12:40 */ class IPBlockedException(reason: String) : CloudFlareBlockedException(reason) ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/exception/ParseException.kt ================================================ package com.yenaly.han1meviewer.logic.exception /** * 解析錯誤 * * @project Han1meViewer * @author Yenaly Liew * @time 2023/08/05 005 16:20 */ class ParseException : RuntimeException { constructor( funcName: String, varName: String ) : super("[Parse::$funcName => $varName] parse error!") constructor(reason: String) : super(reason) } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/HanimeInfo.kt ================================================ package com.yenaly.han1meviewer.logic.model /** * @project Han1meViewer * @author Yenaly Liew */ interface HanimeInfoType : MultiItemEntity /** * @project Han1meViewer * @author Yenaly Liew * @time 2022/06/08 008 22:56 */ data class HanimeInfo( val title: String, val coverUrl: String, val videoCode: String, val duration: String? = null, val uploader: String? = null, val views: String? = null, val uploadTime: String? = null, val genre: String? = null, val isPlaying: Boolean = false, // for video playlist only. override var itemType: Int, ) : HanimeInfoType { companion object { const val NORMAL = 0 const val SIMPLIFIED = 1 } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/HanimePreview.kt ================================================ package com.yenaly.han1meviewer.logic.model /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/24 024 15:05 */ data class HanimePreview( val headerPicUrl: String?, val hasPrevious: Boolean = false, val hasNext: Boolean = false, val latestHanime: List, val previewInfo: List, ) { data class PreviewInfo( val title: String?, val videoTitle: String?, val coverUrl: String?, val introduction: String?, val brand: String?, val releaseDate: String?, val videoCode: String?, val tags: List, val relatedPicsUrl: List, ) } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/HanimeVideo.kt ================================================ package com.yenaly.han1meviewer.logic.model import com.yenaly.han1meviewer.ResolutionLinkMap import com.yenaly.yenaly_libs.utils.mapToArray import kotlinx.datetime.LocalDate import kotlinx.serialization.Serializable import kotlinx.serialization.Transient /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/11 011 20:30 */ @Serializable data class HanimeVideo( val title: String, val coverUrl: String, val chineseTitle: String?, val introduction: String?, val uploadTime: LocalDate?, @Transient val views: String? = null, // resolution to video url val videoUrls: ResolutionLinkMap, val tags: List, /** * 注意,這裏的myList是指用戶的播放清單playlist */ @Transient val myList: MyList? = null, /** * 注意,這裏的playlist是指該影片的系列影片,並非用戶的播放清單 */ @Transient val playlist: Playlist? = null, @Transient val relatedHanimes: List = emptyList(), val artist: Artist? = null, @Transient val favTimes: Int? = null, @Transient val isFav: Boolean = false, @Transient val csrfToken: String? = null, @Transient val currentUserId: String? = null, ) { fun incFavTime() = copy(favTimes = favTimes?.let { it + 1 }, isFav = true) fun decFavTime() = copy(favTimes = favTimes?.let { it - 1 }, isFav = false) // 為保證兼容性,不能直接用天數 val uploadTimeMillis: Long get() = uploadTime?.let { it.toEpochDays().toLong() * 24 * 60 * 60 * 1000 } ?: 0L data class MyList( var isWatchLater: Boolean, val myListInfo: List, ) { data class MyListInfo( val code: String, val title: String, var isSelected: Boolean, ) val titleArray get() = myListInfo.mapToArray(MyListInfo::title) val isSelectedArray get() = myListInfo.map(MyListInfo::isSelected).toBooleanArray() } data class Playlist( val playlistName: String?, val video: List, ) @Serializable data class Artist( val name: String, val avatarUrl: String, val genre: String, @Transient val post: POST? = null, ) { val isSubscribed: Boolean get() = post != null && post.isSubscribed data class POST( val userId: String, val artistId: String, val isSubscribed: Boolean, ) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/HomePage.kt ================================================ package com.yenaly.han1meviewer.logic.model /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/08 008 22:45 */ data class HomePage( val csrfToken: String?, val avatarUrl: String?, val username: String?, val banner: Banner?, val latestHanime: MutableList, val latestRelease: MutableList, val latestUpload: MutableList, val chineseSubtitle: MutableList, val hanimeTheyWatched: MutableList, val hanimeCurrent: MutableList, val hotHanimeMonthly: MutableList, // 首页TAG不想弄 ) { data class Banner( val title: String, val description: String?, val picUrl: String, // 目前网站的策略是,先你吗加载广告,然后再让你跳转 // 我不敢保证他会把 videoCode 放在哪里,所以暂时可以为空 val videoCode: String?, ) } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/MultiItemEntity.kt ================================================ package com.yenaly.han1meviewer.logic.model /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/26 026 17:40 */ interface MultiItemEntity { val itemType: Int } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/MyListItems.kt ================================================ package com.yenaly.han1meviewer.logic.model /** * @project Han1meViewer * @author Yenaly Liew * @time 2022/07/05 005 15:30 */ data class MyListItems( val hanimeInfo: List, /** * 清單的介紹,一般用於播放清單 */ var desc: String? = null, val csrfToken: String? = null, ) ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/ParamEnum.kt ================================================ package com.yenaly.han1meviewer.logic.model import com.yenaly.han1meviewer.EMPTY_STRING enum class MyListType(val value: String) { FAV_VIDEO("LL"), WATCH_LATER("WL"), SUBSCRIPTION("SL") } enum class FavStatus(val value: String) { ADD_FAV(EMPTY_STRING), CANCEL_FAV("1") } enum class CommentPlace(val value: String) { COMMENT("comment"), // 主評論 CHILD_COMMENT("reply") // 子評論 } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/Playlists.kt ================================================ package com.yenaly.han1meviewer.logic.model /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/08/26 026 17:47 */ data class Playlists( val playlists: List, val csrfToken: String? = null, ) { data class Playlist( val listCode: String, var title: String, var total: Int, ) } /** * 用於 修改播放清單 Flow 的返回值 */ data class ModifiedPlaylistArgs( var title: String, var desc: String, var isDeleted: Boolean, ) ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/SearchOption.kt ================================================ package com.yenaly.han1meviewer.logic.model import android.os.Parcelable import android.util.SparseArray import androidx.core.util.valueIterator import com.yenaly.han1meviewer.R import com.yenaly.yenaly_libs.utils.LanguageHelper import kotlinx.parcelize.Parcelize import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import java.util.Locale @Suppress("EqualsOrHashCode") @Serializable @Parcelize data class SearchOption( @SerialName("lang") val lang: Language? = null, @SerialName("name") val name: String? = null, @SerialName("search_key") val searchKey: String? = null, ) : Parcelable { companion object { fun SparseArray>.flatten(): Set = buildSet { valueIterator().forEach { options -> val res = options.mapNotNullTo(mutableSetOf()) { it.searchKey } addAll(res) } } operator fun Map>.get(scopeNameRes: Int): List { return when (scopeNameRes) { R.string.video_attr -> this["video_attributes"].orEmpty() R.string.relationship -> this["character_relationships"].orEmpty() R.string.characteristics -> this["characteristics"].orEmpty() R.string.appearance_and_figure -> this["appearance_and_figure"].orEmpty() R.string.story_plot -> this["story_plot"].orEmpty() R.string.sex_position -> this["sex_positions"].orEmpty() else -> error("Unknown scope name res: $scopeNameRes") } } fun toScopeKey(raw: String): Int = when (raw) { "video_attributes" -> R.string.video_attr "character_relationships" -> R.string.relationship "characteristics" -> R.string.characteristics "appearance_and_figure" -> R.string.appearance_and_figure "story_plot" -> R.string.story_plot "sex_positions" -> R.string.sex_position else -> error("Unknown scope name: $raw") } } @Serializable @Parcelize data class Language( @SerialName("zh-rCN") val zhrCN: String? = null, @SerialName("zh-rTW") val zhrTW: String? = null, @SerialName("en") val en: String? = null, ) : Parcelable override fun hashCode(): Int = searchKey.hashCode() val value: String get() = when { lang == null -> name.orEmpty() name == null -> LanguageHelper.preferredLanguage.let { pl -> when (pl.language) { Locale.CHINESE.language -> when (pl.country) { Locale.SIMPLIFIED_CHINESE.country -> lang.zhrCN else -> lang.zhrTW } Locale.ENGLISH.language -> lang.en else -> lang.zhrTW } } ?: lang.zhrTW.orEmpty() else -> throw IllegalArgumentException("Unknown lang type: ${lang.javaClass.name}") } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/SearchTag.kt ================================================ package com.yenaly.han1meviewer.logic.model /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/09 009 21:27 */ data class SearchTag( val genres: List, val tags: Map>, val sortOptions: List, val brands: List, val releaseDates: ReleaseDate, val durationOptions: List>, ) { data class ReleaseDate( val years: List>, val months: List>, ) } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/Subscription.kt ================================================ package com.yenaly.han1meviewer.logic.model /** * @since 2024/09/11 */ data class Subscription( val name: String, val avatarUrl: String?, val artistId: String?, // for adapter val isCheckBoxVisible: Boolean = false, val isDeleteVisible: Boolean = false, ) ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/VideoComments.kt ================================================ package com.yenaly.han1meviewer.logic.model /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/20 020 21:56 */ data class VideoComments( val videoComment: MutableList, val currentUserId: String? = null, val csrfToken: String? = null, ) { data class VideoComment( // 頭像 val avatar: String, // 作者 val username: String, // 發佈日期 val date: String, // 内容 val content: String, // 點讚數量,登入前不能憑藉post獲取 var thumbUp: Int? = null, // 是否为子评论 val isChildComment: Boolean, // 是否有更多回覆 val hasMoreReplies: Boolean = false, // 評論id,登入前不能憑藉post獲取 val id: String? = null, // post 相關 val post: POST, ) { val realReplyId get() = post.foreignId ?: checkNotNull(id) val realLikesCount get() = thumbUp fun incLikesCount(cancel: Boolean = false): VideoComment { return thumbUp?.let { copy( thumbUp = it + if (cancel) -1 else 1, post = post.copy( likeCommentStatus = !cancel, unlikeCommentStatus = false ) ) } ?: this } fun decLikesCount(cancel: Boolean = false): VideoComment { return thumbUp?.let { copy( thumbUp = it - if (cancel) -1 else 1, post = post.copy( likeCommentStatus = false, unlikeCommentStatus = !cancel ) ) } ?: this } data class POST( // 對方id val foreignId: String? = null, // 你點的 var isPositive: Boolean = false, // 你的id val likeUserId: String? = null, var commentLikesCount: Int? = null, var commentLikesSum: Int? = null, // 你之前有沒有點過讚 var likeCommentStatus: Boolean = false, // 你之前有沒有點過踩 var unlikeCommentStatus: Boolean = false, ) } } /** * 用於 評論交互 Flow 的返回值 */ data class VideoCommentArgs( // 當前評論所處adapter位置 val commentPosition: Int, // 你當前點擊的是讚還是踩,和comment裏的isPositive不一樣 val isPositive: Boolean, val comment: VideoComments.VideoComment, ) ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/github/Commit.kt ================================================ package com.yenaly.han1meviewer.logic.model.github import kotlinx.serialization.Serializable @Serializable data class CommitComparison(val commits: List) { @Serializable data class Commit(val commit: CommitDetail) { @Serializable data class CommitDetail(val author: CommitAuthor, val message: String) { @Serializable data class CommitAuthor(val name: String) } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/github/Latest.kt ================================================ package com.yenaly.han1meviewer.logic.model.github /** * @project Han1meViewer * @author Yenaly Liew * @time 2024/03/21 021 08:56 */ data class Latest( val version: String, val changelog: String, val downloadLink: String, /** * Node ID for the download link * * 其实就是个变相的 md5 验证 */ val nodeId: String, ) ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/github/Release.kt ================================================ package com.yenaly.han1meviewer.logic.model.github import android.os.Build import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable /** * @project Han1meViewer * @author Yenaly Liew * @time 2022/09/09 009 21:24 */ @Serializable data class Release( val url: String, @SerialName("assets_url") val assetsURL: String, @SerialName("upload_url") val uploadURL: String, @SerialName("html_url") val htmlURL: String, val id: Long, val author: Author, @SerialName("node_id") val nodeID: String, @SerialName("tag_name") val tagName: String, @SerialName("target_commitish") val targetCommitish: String, val name: String, val draft: Boolean, val prerelease: Boolean, @SerialName("created_at") val createdAt: String, @SerialName("published_at") val publishedAt: String, val assets: List, @SerialName("tarball_url") val tarballURL: String, @SerialName("zipball_url") val zipballURL: String, val body: String, ) { val asset get() = assets.firstOrNull { it.name.contains(Build.SUPPORTED_ABIS[0]) } ?: assets.first { it.name.contains("universal") } @Serializable data class Asset( val url: String, val id: Long, @SerialName("node_id") val nodeID: String, val name: String, val label: String? = null, val uploader: Author, @SerialName("content_type") val contentType: String, val state: String, val size: Long, @SerialName("download_count") val downloadCount: Long, @SerialName("created_at") val createdAt: String, @SerialName("updated_at") val updatedAt: String, @SerialName("browser_download_url") val browserDownloadURL: String, ) @Serializable data class Author( val login: String, val id: Long, @SerialName("node_id") val nodeID: String, @SerialName("avatar_url") val avatarURL: String, @SerialName("gravatar_id") val gravatarID: String, val url: String, @SerialName("html_url") val htmlURL: String, @SerialName("followers_url") val followersURL: String, @SerialName("following_url") val followingURL: String, @SerialName("gists_url") val gistsURL: String, @SerialName("starred_url") val starredURL: String, @SerialName("subscriptions_url") val subscriptionsURL: String, @SerialName("organizations_url") val organizationsURL: String, @SerialName("repos_url") val reposURL: String, @SerialName("events_url") val eventsURL: String, @SerialName("received_events_url") val receivedEventsURL: String, val type: String, @SerialName("site_admin") val siteAdmin: Boolean, ) } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/model/github/Workflow.kt ================================================ package com.yenaly.han1meviewer.logic.model.github import android.os.Build import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable /** * @project Han1meViewer * @author Yenaly Liew * @time 2024/03/21 021 09:03 */ @Serializable data class WorkflowRuns( @SerialName("workflow_runs") val workflowRuns: List, ) { @Serializable data class WorkflowRun( @SerialName("head_sha") val headSha: String, @SerialName("display_title") val title: String, @SerialName("artifacts_url") val artifactsUrl: String, ) } @Serializable data class Artifacts( @SerialName("artifacts") val artifacts: List, ) { val artifact get() = artifacts.firstOrNull { it.name.contains(Build.SUPPORTED_ABIS[0]) } ?: artifacts.first { it.name.contains("universal") } val downloadLink: String get() = artifact.downloadLink val nodeId: String get() = artifact.nodeId @Serializable data class Artifact( val name: String, @SerialName("archive_download_url") val downloadLink: String, @SerialName("node_id") val nodeId: String, ) } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/GitHubDns.kt ================================================ package com.yenaly.han1meviewer.logic.network import okhttp3.Dns import java.net.InetAddress /** * @project Han1meViewer * @author Yenaly Liew * @time 2024/03/29 029 17:14 */ object GitHubDns : Dns { override fun lookup(hostname: String): List { return when (hostname) { "api.github.com" -> listOf(InetAddress.getByName("140.82.121.6")) "github.com" -> listOf(InetAddress.getByName("140.82.121.4")) else -> Dns.SYSTEM.lookup(hostname) } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/HCookieJar.kt ================================================ package com.yenaly.han1meviewer.logic.network import com.yenaly.han1meviewer.Preferences import com.yenaly.han1meviewer.util.toLoginCookieList import okhttp3.Cookie import okhttp3.CookieJar import okhttp3.HttpUrl /** * 用於管理 Cookie。 * * #issue-71: 我竟然栽倒在 Cookie 管理上好幾年了!你去看我以前的管理方式, * 是完全錯誤的,竟然還能維持應用正常運行,太離譜了!怪不得切換簡體繁體一直不起作用! * * @project Han1meViewer * @author Yenaly Liew * @time 2024/03/13 013 15:20 */ class HCookieJar : CookieJar { companion object { @JvmStatic val cookieMap: MutableMap> = mutableMapOf() } override fun loadForRequest(url: HttpUrl): List { return cookieMap[url.host] ?: Preferences.loginCookieStateFlow.value.toLoginCookieList(url.host) } override fun saveFromResponse(url: HttpUrl, cookies: List) { cookieMap[url.host] = cookies.toMutableList().also { it += Preferences.loginCookieStateFlow.value.toLoginCookieList(url.host) } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/HDns.kt ================================================ package com.yenaly.han1meviewer.logic.network import android.util.Log import android.widget.Toast import com.yenaly.han1meviewer.HANIME_ALTER_HOSTNAME import com.yenaly.han1meviewer.HANIME_MAIN_HOSTNAME import com.yenaly.han1meviewer.Preferences import com.yenaly.han1meviewer.R import com.yenaly.yenaly_libs.utils.showShortToast import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import okhttp3.Dns import java.net.InetAddress import java.net.InetSocketAddress import java.net.Socket /** * @project Han1meViewer * @author Yenaly Liew * @time 2024/03/10 010 17:01 */ class HDns : Dns { private val scope = CoroutineScope(Dispatchers.IO) private val dnsMap = mutableMapOf>() private var sortedIpsCache = emptyList() private val useBuiltInHosts = Preferences.useBuiltInHosts private val isPingTest = Preferences.isPingTest init { if (useBuiltInHosts) { dnsMap[HANIME_MAIN_HOSTNAME] = listOf( "104.25.254.167", "172.67.75.184", "172.64.229.154", "2606:4700:8dd1::2a46:47f8" ) dnsMap[HANIME_ALTER_HOSTNAME] = listOf( "104.25.254.167", "172.67.75.184", "172.64.229.154", "2606:4700:8dd1::2a46:47f8" ) } } companion object { /** * 添加DNS */ private operator fun MutableMap>.set( host: String, ips: List, ) { this[host] = ips.map { InetAddress.getByAddress(host, InetAddress.getByName(it).address) } } } override fun lookup(hostname: String): List { if (sortedIpsCache.isNotEmpty()) return sortedIpsCache val dns = dnsMap[hostname] if (!useBuiltInHosts || dns.isNullOrEmpty()) return Dns.SYSTEM.lookup(hostname) if (!isPingTest) return dns CoroutineScope(Dispatchers.Main).launch { showShortToast(R.string.ping_test) } val ipLatencies = runBlocking { dns.map { ip -> scope.async { ip to pingTest(ip.hostAddress!!) } }.awaitAll() } val sortedIps = ipLatencies .sortedBy { (_, latency) -> latency } .map { (ip, _) -> ip } this.sortedIpsCache = sortedIps return sortedIps } private suspend fun pingTest(ip: String): Long { return withContext(Dispatchers.IO) { try { val startTime = System.currentTimeMillis() Socket().use { socket -> socket.connect(InetSocketAddress(ip, 80), 300) } System.currentTimeMillis() - startTime } catch (e: Exception) { Long.MAX_VALUE } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/HProxySelector.kt ================================================ package com.yenaly.han1meviewer.logic.network import com.yenaly.han1meviewer.Preferences import okhttp3.internal.proxy.NullProxySelector import java.io.IOException import java.net.InetAddress import java.net.InetSocketAddress import java.net.Proxy import java.net.ProxySelector import java.net.SocketAddress import java.net.URI /** * 受 [EhViewer_CN_SXJ 中 EhProxySelector](https://github.com/xiaojieonly/Ehviewer_CN_SXJ/blob/BiLi_PC_Gamer/app/src/main/java/com/hippo/ehviewer/EhProxySelector.java) * 的启发,Han1meViewer 也将使用 [HProxySelector] 来实现代理功能。 * * @project Han1meViewer * @author Yenaly Liew * @time 2023/10/07 007 17:32 */ // #issue-15: 添加系统代理功能 class HProxySelector : ProxySelector() { private var delegation: ProxySelector? = null private val alternative: ProxySelector = getDefault() ?: NullProxySelector init { updateProxy() } companion object { const val TYPE_DIRECT = 0 const val TYPE_SYSTEM = 1 const val TYPE_HTTP = 2 const val TYPE_SOCKS = 3 private val ipv4Regex = Regex("^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$") fun validateIp(ip: String): Boolean { return ipv4Regex.matches(ip) } fun validatePort(port: Int): Boolean { return port in 0..65535 } // #issue-39: 代理沒有應用到 WebView 上,只能通過此種方式來全局代理。 fun rebuildNetwork() { val properties = System.getProperties() when (Preferences.proxyType) { TYPE_HTTP, TYPE_SOCKS -> { properties["proxySet"] = true.toString() properties["proxyHost"] = Preferences.proxyIp properties["proxyPort"] = Preferences.proxyPort.toString() } else -> { properties["proxySet"] = false.toString() properties["proxyHost"] = "" properties["proxyPort"] = "" } } } } private fun updateProxy() { delegation = when (Preferences.proxyType) { TYPE_DIRECT -> NullProxySelector TYPE_SYSTEM -> alternative TYPE_HTTP, TYPE_SOCKS -> null else -> NullProxySelector } } override fun select(uri: URI?): MutableList { val type = Preferences.proxyType if (type == TYPE_HTTP || type == TYPE_SOCKS) { val ip = Preferences.proxyIp val port = Preferences.proxyPort if (ip.isNotBlank() && port != -1) { val inetAddress = InetAddress.getByName(ip) val socketAddress = InetSocketAddress(inetAddress, port) return mutableListOf( Proxy( if (type == TYPE_HTTP) Proxy.Type.HTTP else Proxy.Type.SOCKS, socketAddress ) ) } } return delegation?.select(uri) ?: alternative.select(uri) } override fun connectFailed(uri: URI?, sa: SocketAddress?, ioe: IOException?) { delegation?.select(uri) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/HUpdater.kt ================================================ package com.yenaly.han1meviewer.logic.network import android.util.Log import com.google.firebase.Firebase import com.google.firebase.remoteconfig.remoteConfig import com.yenaly.han1meviewer.BuildConfig import com.yenaly.han1meviewer.FirebaseConstants import com.yenaly.han1meviewer.Preferences import com.yenaly.han1meviewer.logic.dao.DownloadDatabase import com.yenaly.han1meviewer.logic.entity.download.HUpdateEntity import com.yenaly.han1meviewer.logic.model.github.CommitComparison import com.yenaly.han1meviewer.logic.model.github.Latest import com.yenaly.han1meviewer.logic.state.DownloadState import com.yenaly.han1meviewer.util.UPDATE_ZIP_PATH import com.yenaly.han1meviewer.util.checkNeedUpdate import com.yenaly.han1meviewer.util.copyTo import com.yenaly.han1meviewer.util.runSuspendCatching import com.yenaly.yenaly_libs.utils.applicationContext import okio.use import java.io.File import java.io.FileOutputStream import java.util.zip.ZipFile import java.util.zip.ZipInputStream /** * @project Han1meViewer * @author Yenaly Liew * @time 2024/03/21 021 08:28 */ object HUpdater { const val TAG = "HUpdater" const val DEFAULT_BRANCH = "master" /** * Regex to match multiple line feeds to a single line feed */ private val linefeedRegex = Regex("\\n{2,}") private val hUpdateDao = DownloadDatabase.instance.hUpdateDao /** * Check for update * * @param forceCheck force check */ suspend fun checkForUpdate(forceCheck: Boolean = false): Latest? { // 如果未设置HA1_GITHUB_TOKEN,则不检测版本更新 if (BuildConfig.HA1_GITHUB_TOKEN.isEmpty()) return null // debug模式不检测更新 // if (BuildConfig.DEBUG) return null if (forceCheck || Preferences.isUpdateDialogVisible) { if (Preferences.useCIUpdateChannel && Firebase.remoteConfig.getBoolean(FirebaseConstants.ENABLE_CI_UPDATE)) { val curSha = BuildConfig.COMMIT_SHA // 特殊情况下才用注释部分,一般情况下 branch 都是固定的,要不然多一次 // request 会对我的 API Token 造成负担。 // val apiReq = request(HA1_GITHUB_API_URL) // val branch = apiReq.body?.string()?.let(::JSONObject)?.getString("default_branch") // ?: return null val workflowRun = HanimeNetwork.githubService.getWorkflowRuns() .workflowRuns.firstOrNull() ?: return null val shortSha = workflowRun.headSha.take(7) if (shortSha != curSha) { val artifacts = HanimeNetwork.githubService.getArtifacts(workflowRun.artifactsUrl) val archiveUrl = artifacts.downloadLink val nodeId = artifacts.nodeId val changelog = runSuspendCatching { HanimeNetwork.githubService.getCommitComparison( curSha = curSha, latestSha = shortSha ).commits.toChangelogPrettyString() }.getOrNull() ?: workflowRun.title return Latest("$shortSha (CI)", changelog, archiveUrl, nodeId) } } else { val ver = HanimeNetwork.githubService.getLatestVersion() val isNeeded = checkNeedUpdate(ver.name) if (isNeeded) { return Latest( ver.tagName, ver.body, ver.asset.browserDownloadURL, ver.asset.nodeID ) } } } return null } suspend fun updateHUpdateLength(entity: HUpdateEntity, length: Long): HUpdateEntity { val newEntity = entity.copy( length = length ) hUpdateDao.update(newEntity) return newEntity } suspend fun updateHUpdateDownloadedLength(entity: HUpdateEntity, downloadedLength: Long) { hUpdateDao.update(entity.copy( downloadedLength = downloadedLength, state = DownloadState.Downloading )) } /** * Inject update to file * * @param url update url */ suspend fun File.injectUpdate(url: String, startOffset: Long = 0L, progress: (suspend (Int) -> Unit)? = null) { var entity = hUpdateDao.get() val res = HanimeNetwork.githubService.request(url, if (startOffset > 0) "bytes=$startOffset-" else null) if (url.endsWith("zip")) { Log.d(TAG, "Injecting update from zip ($url)") FileOutputStream(UPDATE_ZIP_PATH, true).use { res.body()?.use { body -> val len = body.contentLength() + startOffset entity?.let { it -> entity = updateHUpdateLength(it, len) } body.byteStream().copyTo( it, len, startOffset, progress = progress, downloadLength = { length -> entity?.let { it1 -> updateHUpdateDownloadedLength(it1, length) } } ) } } ZipFile(UPDATE_ZIP_PATH).use { zip -> zip.entries().asSequence().forEach { entry -> if (!entry.isDirectory) { zip.getInputStream(entry).use { input -> FileOutputStream(this, true).use { output -> input.copyTo(output) } } } } } } else { Log.d(TAG, "Injecting update from release ($url)") FileOutputStream(this, true).use { if (startOffset > 0) { it.channel.position(startOffset) } res.body()?.use { body -> val len = body.contentLength() + startOffset entity?.let { it -> entity = updateHUpdateLength(it, len) } body.byteStream().copyTo( it, len, startOffset, progress = progress, downloadLength = { length -> entity?.let { it1 -> updateHUpdateDownloadedLength(it1, length) } } ) } } } } /** * This function is used to filter out commits that are not authored by the user. */ private val CommitComparison.Commit.CommitDetail.CommitAuthor.isAuthorShouldIgnore: Boolean get() = name.contains("dependabot") private fun List.toChangelogPrettyString(): String { return filterNot { commit -> commit.commit.author.isAuthorShouldIgnore }.distinct().reversed().joinToString("\n\n") { commit -> val message = commit.commit.message.replace(linefeedRegex, "\n") "↓ (@${commit.commit.author.name})\n$message" } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/HanimeNetwork.kt ================================================ package com.yenaly.han1meviewer.logic.network import com.yenaly.han1meviewer.HANIME_BASE_URL import com.yenaly.han1meviewer.logic.network.service.HGitHubService import com.yenaly.han1meviewer.logic.network.service.HanimeBaseService import com.yenaly.han1meviewer.logic.network.service.HanimeCommentService import com.yenaly.han1meviewer.logic.network.service.HanimeMyListService import com.yenaly.han1meviewer.logic.network.service.HanimeSubscriptionService /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/08 008 22:35 */ object HanimeNetwork { var hanimeService = _hanimeService private set var githubService = _githubService private set var commentService = _commentService private set var myListService = _myListService private set var subscriptionService = _subscriptionService private set private val _hanimeService get() = ServiceCreator.create(HANIME_BASE_URL) private val _githubService get() = ServiceCreator.createGitHubApi() private val _commentService get() = ServiceCreator.create(HANIME_BASE_URL) private val _myListService get() = ServiceCreator.create(HANIME_BASE_URL) private val _subscriptionService get() = ServiceCreator.create(HANIME_BASE_URL) fun rebuildNetwork() { ServiceCreator.rebuildOkHttpClient() hanimeService = _hanimeService commentService = _commentService myListService = _myListService } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/ServiceCreator.kt ================================================ package com.yenaly.han1meviewer.logic.network import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import com.yenaly.han1meviewer.BuildConfig import com.yenaly.han1meviewer.HA1_GITHUB_API_URL import com.yenaly.han1meviewer.HJson import com.yenaly.han1meviewer.Preferences import com.yenaly.han1meviewer.logic.network.interceptor.SpeedLimitInterceptor import com.yenaly.han1meviewer.logic.network.interceptor.UserAgentInterceptor import com.yenaly.yenaly_libs.utils.applicationContext import com.yenaly.yenaly_libs.utils.unsafeLazy import okhttp3.Cache import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import retrofit2.Retrofit import java.io.File import java.util.concurrent.TimeUnit /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/08 008 22:35 */ object ServiceCreator { val cache = Cache( directory = File(applicationContext.cacheDir, "http_cache"), maxSize = 10 * 1024 * 1024 ) private val downloadSpeedLimitInterceptor by unsafeLazy { SpeedLimitInterceptor(maxSpeed = Preferences.downloadSpeedLimit) } inline fun create(baseUrl: String): T = Retrofit.Builder() .baseUrl(baseUrl) .client(hClient) .build() .create(T::class.java) inline fun createGitHubApi(): T = Retrofit.Builder() .baseUrl(HA1_GITHUB_API_URL) .client(githubClient) .addConverterFactory(HJson.asConverterFactory("application/json".toMediaType())) .build() .create(T::class.java) /** * OkHttpClient */ var hClient: OkHttpClient = buildHClient() private set var githubClient: OkHttpClient = buildGithubClient() private set var downloadClient: OkHttpClient = buildDownloadClient() private set /** * Rebuild OkHttpClient */ fun rebuildOkHttpClient() { hClient = buildHClient() } private fun buildDownloadClient(): OkHttpClient { return OkHttpClient.Builder() .connectTimeout(5, TimeUnit.SECONDS) .addInterceptor(UserAgentInterceptor) .addInterceptor(downloadSpeedLimitInterceptor) .build() } /** * Build OkHttpClient */ private fun buildHClient(): OkHttpClient { return OkHttpClient.Builder() .connectTimeout(15, TimeUnit.SECONDS) .addInterceptor(UserAgentInterceptor) .cache(cache) .cookieJar(HCookieJar()) .proxySelector(HProxySelector()) .dns(HDns()) .build() } private fun buildGithubClient(): OkHttpClient { return OkHttpClient.Builder() .dns(GitHubDns) .addInterceptor { chain -> val request = chain.request().newBuilder().addHeader( "Authorization", "Bearer ${BuildConfig.HA1_GITHUB_TOKEN}" ).build() return@addInterceptor chain.proceed(request) } .build() } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/interceptor/SpeedLimitInterceptor.kt ================================================ package com.yenaly.han1meviewer.logic.network.interceptor import okhttp3.Interceptor import okhttp3.Response class SpeedLimitInterceptor(var maxSpeed: Long) : Interceptor { companion object { const val NO_LIMIT = 0L const val NO_LIMIT_INDEX = 0 @JvmField val SPEED_BYTES = longArrayOf( /* 不限速 */ 0L, 128 * 1024L, 256 * 1024L, 512 * 1024L, 1024 * 1024L, 2048 * 1024L, 4096 * 1024L, 8192 * 1024L, 10240 * 1024L ) } override fun intercept(chain: Interceptor.Chain): Response { val response = chain.proceed(chain.request()) return response.newBuilder() .body(response.body?.let { SpeedLimitResponseBody(it, maxSpeed) }).build() } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/interceptor/SpeedLimitResponseBody.kt ================================================ package com.yenaly.han1meviewer.logic.network.interceptor import com.yenaly.yenaly_libs.utils.unsafeLazy import okhttp3.ResponseBody import okio.Throttler import okio.buffer class SpeedLimitResponseBody( private val responseBody: ResponseBody, /** * 0 means no limit */ private val maxSpeed: Long ) : ResponseBody() { private val throttler by unsafeLazy { Throttler().apply { bytesPerSecond(maxSpeed) } } override fun contentLength(): Long = responseBody.contentLength() override fun contentType() = responseBody.contentType() override fun source() = throttler.source(responseBody.source()).buffer() } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/interceptor/UserAgentInterceptor.kt ================================================ package com.yenaly.han1meviewer.logic.network.interceptor import com.yenaly.han1meviewer.USER_AGENT import okhttp3.Interceptor import okhttp3.Response object UserAgentInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request().newBuilder().addHeader( "User-Agent", USER_AGENT ).build() return chain.proceed(request) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/service/HGitHubService.kt ================================================ package com.yenaly.han1meviewer.logic.network.service import com.yenaly.han1meviewer.logic.model.github.Artifacts import com.yenaly.han1meviewer.logic.model.github.CommitComparison import com.yenaly.han1meviewer.logic.model.github.Release import com.yenaly.han1meviewer.logic.model.github.WorkflowRuns import com.yenaly.han1meviewer.logic.network.HUpdater import okhttp3.ResponseBody import retrofit2.Response import retrofit2.http.GET import retrofit2.http.Header import retrofit2.http.Path import retrofit2.http.Query import retrofit2.http.Url /** * @project Han1meViewer * @author Yenaly Liew * @time 2022/09/09 009 20:04 */ interface HGitHubService { @GET("releases/latest") suspend fun getLatestVersion(): Release /** * What is Workflow Runs? * * List all workflow runs for a repository. You can use parameters to filter the list of results. For example, you * can get a list of workflow runs for a specific branch, or you can get a list of workflow runs that used a specific * workflow file. */ @GET("actions/workflows/ci.yml/runs?event=push&status=success&per_page=1") suspend fun getWorkflowRuns( @Query("branch") branch: String = HUpdater.DEFAULT_BRANCH, ): WorkflowRuns /** * What is Commit Comparison? * * Compare two commits in a repository. The response will include a comparison of the two commits. The response can * include difference in various aspects such as files, commits, and comments. */ @GET("compare/{curSha}...{latestSha}") suspend fun getCommitComparison( @Path("curSha") curSha: String, @Path("latestSha") latestSha: String, ): CommitComparison /** * What is Artifacts? * * Artifacts are the files produced by a workflow run. They are associated with the run during the execution of the * job that produces them. Artifacts are available for 90 days after the run is completed. */ @GET suspend fun getArtifacts( @Url url: String, ): Artifacts /** * Typical request */ @GET suspend fun request( @Url url: String, @Header("Range") range: String? = null ): Response } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/service/HanimeBaseService.kt ================================================ package com.yenaly.han1meviewer.logic.network.service import androidx.annotation.IntRange import okhttp3.ResponseBody import retrofit2.Response import retrofit2.http.* /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/08 008 22:10 */ interface HanimeBaseService { @GET("/") suspend fun getHomePage(): Response @GET("search") suspend fun getHanimeSearchResult( @Query("page") @IntRange(from = 1) page: Int = 1, @Query("query") query: String? = null, @Query("genre") genre: String? = null, @Query("sort") sort: String? = null, @Query("broad") broad: String? = null, @Query("date") date: String? = null, @Query("duration") duration: String? = null, @Query("tags[]") tags: Set = emptySet(), @Query("brands[]") brands: Set = emptySet(), ): Response @GET("watch") suspend fun getHanimeVideo( @Query("v") videoCode: String, ): Response @GET("previews/{date}") suspend fun getHanimePreview( @Path("date") date: String, // 类似 202206. 202012 ): Response @FormUrlEncoded @POST("login") suspend fun login( @Field("_token") csrfToken: String?, @Field("email") email: String, @Field("password") password: String, @Header("X-CSRF-TOKEN") csrfToken_1: String? = csrfToken, ): Response @GET("login") suspend fun getLoginPage(): Response } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/service/HanimeCommentService.kt ================================================ package com.yenaly.han1meviewer.logic.network.service import okhttp3.ResponseBody import retrofit2.Response import retrofit2.http.* /** * @project Han1meViewer * @author Yenaly Liew * @time 2022/09/19 019 17:44 */ interface HanimeCommentService { @GET("loadComment") suspend fun getComments( @Query("type") type: String, // 類似 "video", "preview" @Query("id") code: String, ): Response @GET("loadReplies") suspend fun getCommentReply( @Query("id") commentId: String, ): Response @FormUrlEncoded @POST("createComment") suspend fun postComment( @Field("_token") csrfToken: String?, @Field("comment-user-id") currentUserId: String, @Field("comment-type") type: String, // 類似 "video", "preview" @Field("comment-foreign-id") targetUserId: String, @Field("comment-text") text: String, @Field("comment-count") count: Int = 1, // 感觉没什么用,仅前端用 @Field("comment-is-political") isPolitical: Int = 0, // 感觉没什么用,仅前端用 @Header("X-CSRF-TOKEN") csrfToken_1: String? = csrfToken, ): Response @FormUrlEncoded @POST("replyComment") suspend fun postCommentReply( @Field("_token") csrfToken: String?, @Field("reply-comment-id") replyCommentId: String, @Field("reply-comment-text") text: String, @Header("X-CSRF-TOKEN") csrfToken_1: String? = csrfToken, ): Response @FormUrlEncoded @POST("commentLike") suspend fun likeComment( @Field("_token") csrfToken: String?, @Field("foreign_type") foreignType: String, @Field("foreign_id") foreignId: String?, @Field("is_positive") isPositive: Int, // 你選擇的是讚還是踩,1是讚,0是踩 @Field("comment-like-user-id") likeUserId: String?, @Field("comment-likes-count") commentLikesCount: Int, @Field("comment-likes-sum") commentLikesSum: Int, @Field("like-comment-status") likeCommentStatus: Int, // 你之前有沒有點過讚,1是0否 @Field("unlike-comment-status") unlikeCommentStatus: Int, // 你之前有沒有點過踩,1是0否 @Header("X-CSRF-TOKEN") csrfToken_1: String? = csrfToken, ): Response } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/service/HanimeMyListService.kt ================================================ package com.yenaly.han1meviewer.logic.network.service import androidx.annotation.IntRange import okhttp3.ResponseBody import retrofit2.Response import retrofit2.http.Field import retrofit2.http.FormUrlEncoded import retrofit2.http.GET import retrofit2.http.Header import retrofit2.http.POST import retrofit2.http.Path import retrofit2.http.Query /** * MyList 是指 喜欢的影片 + 稍后再看 * * Playlist 是指 自定义的播放列表 * * @project Han1meViewer * @author Yenaly Liew * @time 2023/08/26 026 16:30 */ interface HanimeMyListService { @GET("playlist") suspend fun getMyListItems( @Query("page") @IntRange(from = 1) page: Int, @Query("list") typeOrCode: String, // WL, LL, SL, 12534.. ): Response @FormUrlEncoded @POST("deletePlayitem") suspend fun deleteMyListItems( @Field("playlist_id") listType: String, @Field("video_id") videoCode: String, @Field("count") count: Int = 1, // 隨便傳一個就行 @Header("X-CSRF-TOKEN") csrfToken: String?, ): Response @FormUrlEncoded @POST("like") suspend fun addToMyFavVideo( @Field("like-foreign-id") videoCode: String, @Field("like-status") likeStatus: String, @Field("_token") csrfToken: String?, @Field("like-user-id") userId: String?, @Field("like-is-positive") isPositive: Int = 1, @Header("X-CSRF-TOKEN") csrfToken_1: String? = csrfToken, ): Response @GET("playlists") suspend fun getPlaylists(): Response @FormUrlEncoded @POST("createPlaylist") suspend fun createPlaylist( @Field("_token") csrfToken: String?, @Field("create-playlist-video-id") videoCode: String, @Field("playlist-title") title: String, @Field("playlist-description") description: String, @Header("X-CSRF-TOKEN") csrfToken_1: String? = csrfToken, ): Response @FormUrlEncoded @POST("save") suspend fun addToMyList( @Field("_token") csrfToken: String?, @Field("input_id") listCode: String, @Field("video_id") videoCode: String, @Field("is_checked") isChecked: Boolean, @Field("user_id") userId: String = "", @Header("X-CSRF-TOKEN") csrfToken_1: String? = csrfToken, ): Response @FormUrlEncoded @POST("playlist/{list_code}") suspend fun modifyPlaylist( @Path("list_code") listCode: String, @Field("playlist-title") title: String, @Field("playlist-description") description: String, @Field("playlist-delete") delete: String?, // 删除 "on",不删除 null @Field("_token") csrfToken: String?, @Field("_method") method: String? = "PUT", @Header("X-CSRF-TOKEN") csrfToken_1: String? = csrfToken, ): Response } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/network/service/HanimeSubscriptionService.kt ================================================ package com.yenaly.han1meviewer.logic.network.service import okhttp3.ResponseBody import retrofit2.Response import retrofit2.http.Field import retrofit2.http.FormUrlEncoded import retrofit2.http.Header import retrofit2.http.POST interface HanimeSubscriptionService { @FormUrlEncoded @POST("subscribe") suspend fun subscribeArtist( @Field("_token") csrfToken: String?, @Field("subscribe-user-id") userId: String, @Field("subscribe-artist-id") artistId: String, // 如果当前未订阅会发送空字符串,否则发1 @Field("subscribe-status") status: String, @Header("X-CSRF-TOKEN") csrfToken_1: String? = csrfToken, ): Response } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/state/DownloadState.kt ================================================ package com.yenaly.han1meviewer.logic.state import androidx.annotation.IntDef /** * 下载任务状态 * @project Han1meViewer * @author Yenaly Liew * @time 2025/3/3 21:11 */ enum class DownloadState(@Mask val mask: Int) { // 未知状态(刚添加进来的状态),队列中,下载中,暂停,已完成,失败 Unknown(Mask.UNKNOWN), Queued(Mask.QUEUED), Downloading(Mask.DOWNLOADING), Paused(Mask.PAUSED), Finished(Mask.FINISHED), Failed(Mask.FAILED); companion object { const val STATE = "state" fun from(@Mask mask: Int): DownloadState = when (mask) { Mask.QUEUED -> Queued Mask.DOWNLOADING -> Downloading Mask.PAUSED -> Paused Mask.FINISHED -> Finished Mask.FAILED -> Failed else -> Unknown } } @IntDef( Mask.UNKNOWN, Mask.QUEUED, Mask.DOWNLOADING, Mask.PAUSED, Mask.FINISHED, Mask.FAILED ) annotation class Mask { companion object { const val UNKNOWN = 0 const val QUEUED = 1 const val DOWNLOADING = 2 const val PAUSED = 3 const val FINISHED = 4 const val FAILED = 5 } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/state/PageLoadingState.kt ================================================ package com.yenaly.han1meviewer.logic.state /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/10 010 16:30 */ sealed class PageLoadingState { data class Success(val info: T) : PageLoadingState() data object Loading : PageLoadingState() data object NoMoreData : PageLoadingState() data class Error(val throwable: Throwable) : PageLoadingState() } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/state/VideoLoadingState.kt ================================================ package com.yenaly.han1meviewer.logic.state /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/18 018 18:14 */ sealed class VideoLoadingState { data class Success(val info: T) : VideoLoadingState() data class Error(val throwable: Throwable) : VideoLoadingState() data object Loading : VideoLoadingState() data object NoContent : VideoLoadingState() } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/logic/state/WebsiteState.kt ================================================ package com.yenaly.han1meviewer.logic.state /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/08 008 22:20 */ sealed class WebsiteState { data class Success(val info: T) : WebsiteState() data object Loading : WebsiteState() data class Error(val throwable: Throwable) : WebsiteState() } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/StateLayoutMixin.kt ================================================ package com.yenaly.han1meviewer.ui import android.annotation.SuppressLint import android.widget.TextView import com.drake.statelayout.StateLayout import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.pienization /** * 用於初始化 StateLayout。 * * 但是不是説實現了這個接口就代表有 StateLayout 了,有些我還是直接用的 BRVAH 自帶的 StateLayoutVH, * 因爲用 StateLayout 稍稍有點麻煩。 * * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/30 030 15:24 */ @JvmDefaultWithoutCompatibility interface StateLayoutMixin { /** * 初始化 StateLayout */ @SuppressLint("SetTextI18n") fun StateLayout.init(apply: StateLayout.() -> Unit = {}) { errorLayout = R.layout.layout_empty_view emptyLayout = R.layout.layout_empty_view onError { val err = it as Throwable findViewById(R.id.tv_empty).text = err.pienization } apply() } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/activity/DownloadActivity.kt ================================================ package com.yenaly.han1meviewer.ui.activity import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View import androidx.core.text.parseAsHtml import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.databinding.ActivityDownloadBinding import com.yenaly.han1meviewer.ui.fragment.home.download.DownloadedFragment import com.yenaly.han1meviewer.ui.fragment.home.download.DownloadingFragment import com.yenaly.han1meviewer.ui.view.funcbar.Hanidokitem import com.yenaly.yenaly_libs.base.YenalyActivity import com.yenaly.yenaly_libs.utils.showShortToast import com.yenaly.yenaly_libs.utils.view.attach import com.yenaly.yenaly_libs.utils.view.setUpFragmentStateAdapter class DownloadActivity : YenalyActivity() { companion object { const val TAG = "HoppinByte" private const val HB = """HoppinByte""" val hbSpannedTitle = HB.parseAsHtml() } private val tabNameArray = intArrayOf(R.string.downloading, R.string.downloaded) override fun getViewBinding(layoutInflater: LayoutInflater): ActivityDownloadBinding { return ActivityDownloadBinding.inflate(layoutInflater) } override fun initData(savedInstanceState: Bundle?) { setSupportActionBar(binding.toolbar) binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() } supportActionBar?.let { it.title = hbSpannedTitle it.setDisplayHomeAsUpEnabled(true) it.setHomeActionContentDescription(R.string.back) } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { overrideActivityTransition( OVERRIDE_TRANSITION_OPEN, R.anim.slide_in_from_bottom, R.anim.fade_out ) overrideActivityTransition( OVERRIDE_TRANSITION_CLOSE, R.anim.fade_in, R.anim.slide_out_to_bottom ) } binding.viewPager.setUpFragmentStateAdapter(this) { addFragment { DownloadingFragment() } addFragment { DownloadedFragment() } } binding.tabLayout.attach(binding.viewPager) { tab, position -> tab.setText(tabNameArray[position]) } binding.hanidock.hanidokitems = listOf( Hanidokitem.create { icon = R.drawable.ic_baseline_access_time_24 text = R.string.title viewAction = View.OnClickListener { showShortToast("test") } }, Hanidokitem.create { icon = R.drawable.baseline_add_24 text = R.string.add subitems = listOf( Hanidokitem.create { icon = R.drawable.ic_baseline_access_time_24 text = R.string.title } ) } ) } override fun finish() { super.finish() if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { @Suppress("DEPRECATION") overridePendingTransition(R.anim.fade_in, R.anim.slide_out_to_bottom) } } override fun bindDataObservers() { } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/activity/LoginActivity.kt ================================================ package com.yenaly.han1meviewer.ui.activity import android.annotation.SuppressLint import android.graphics.Color import android.os.Bundle import android.util.Log import android.view.KeyEvent import android.view.View import android.webkit.CookieManager import android.webkit.WebResourceRequest import android.webkit.WebView import android.webkit.WebViewClient import androidx.activity.SystemBarStyle import androidx.activity.enableEdgeToEdge import androidx.annotation.LayoutRes import androidx.appcompat.app.AlertDialog import androidx.core.text.parseAsHtml import androidx.databinding.DataBindingUtil import androidx.lifecycle.lifecycleScope import com.google.android.material.textfield.TextInputEditText import com.yenaly.han1meviewer.HANIME_ALTER_BASE_URL import com.yenaly.han1meviewer.HANIME_LOGIN_URL import com.yenaly.han1meviewer.HANIME_MAIN_BASE_URL import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.USER_AGENT import com.yenaly.han1meviewer.databinding.ActivityLoginBinding import com.yenaly.han1meviewer.logic.NetworkRepo import com.yenaly.han1meviewer.logic.state.WebsiteState import com.yenaly.han1meviewer.login import com.yenaly.han1meviewer.util.createAlertDialog import com.yenaly.han1meviewer.util.showWithBlurEffect import com.yenaly.yenaly_libs.base.frame.FrameActivity import com.yenaly.yenaly_libs.utils.showShortToast import com.yenaly.yenaly_libs.utils.unsafeLazy import kotlinx.coroutines.launch class LoginActivity : FrameActivity() { companion object { const val TAG = "LoginActivity" private const val HL = """Ha1ogin""" // val hlSpannedTitle = HL.parseAsHtml() } private lateinit var binding: ActivityLoginBinding private val dialog = unsafeLazy { LoginDialog(R.layout.dialog_login) } override fun setUiStyle() { enableEdgeToEdge( statusBarStyle = SystemBarStyle.dark(Color.TRANSPARENT), navigationBarStyle = SystemBarStyle.dark(Color.TRANSPARENT) ) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.activity_login) setSupportActionBar(binding.toolbar) binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() } supportActionBar?.let { it.title = HL.parseAsHtml() it.setDisplayHomeAsUpEnabled(true) it.setHomeActionContentDescription(R.string.back) } initWebView() binding.srlLogin.setOnRefreshListener { binding.wvLogin.loadUrl(HANIME_LOGIN_URL) } binding.srlLogin.autoRefresh() } override fun onDestroy() { super.onDestroy() if (dialog.isInitialized()) { dialog.value.dismiss() } binding.wvLogin.removeAllViews() binding.wvLogin.destroy() binding.unbind() } override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { if (keyCode == KeyEvent.KEYCODE_BACK && binding.wvLogin.canGoBack()) { binding.wvLogin.goBack() return true } return super.onKeyDown(keyCode, event) } @SuppressLint("SetJavaScriptEnabled") private fun initWebView() { binding.wvLogin.apply { // #issue-17: 谷歌登录需要开启JavaScript,但是谷歌拒絕這種登錄方式,遂放棄 settings.javaScriptEnabled = true settings.domStorageEnabled = true settings.userAgentString = USER_AGENT webViewClient = object : WebViewClient() { override fun onPageFinished(view: WebView, url: String) { binding.srlLogin.finishRefresh() } override fun shouldOverrideUrlLoading( view: WebView, request: WebResourceRequest, ): Boolean { val isSameUrl = request.url.toString() == HANIME_MAIN_BASE_URL || request.url.toString() == HANIME_ALTER_BASE_URL if (request.isRedirect && isSameUrl) { val url = request.url val cookieManager = CookieManager.getInstance().getCookie(url.host) Log.d("login_cookie", cookieManager.toString()) login(cookieManager) setResult(RESULT_OK) finish() return true } return super.shouldOverrideUrlLoading(view, request) } override fun onReceivedError( view: WebView?, errorCode: Int, description: String?, failingUrl: String?, ) { // #issue-146 // #issue-160: 修复字段销毁后调用引发的错误 if (!isDestroyed && !isFinishing) { binding.srlLogin.finishRefresh() dialog.value.show() } } } } } inner class LoginDialog(@LayoutRes layoutRes: Int) { private val etUsername: TextInputEditText private val etPassword: TextInputEditText private val dialog: AlertDialog private val username get() = etUsername.text?.toString().orEmpty() private val password get() = etPassword.text?.toString().orEmpty() init { val view = View.inflate(this@LoginActivity, layoutRes, null) etUsername = view.findViewById(R.id.et_username) etPassword = view.findViewById(R.id.et_password) dialog = createAlertDialog { setView(view) setCancelable(false) setTitle(R.string.try_login_here) setPositiveButton(R.string.login, null) setNegativeButton(R.string.cancel, null) } dialog.setOnShowListener { dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { handleLogin() } } } private fun handleLogin() { lifecycleScope.launch { NetworkRepo.login(username, password).collect { state -> dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = state !is WebsiteState.Loading dialog.getButton(AlertDialog.BUTTON_NEGATIVE).isEnabled = state !is WebsiteState.Loading when (state) { WebsiteState.Loading -> Unit is WebsiteState.Error -> { state.throwable.printStackTrace() if (state.throwable is IllegalStateException) { showShortToast(R.string.account_or_password_wrong) } else { showShortToast(R.string.login_failed) } } is WebsiteState.Success -> { login(state.info) setResult(RESULT_OK) dialog.dismiss() showShortToast(R.string.login_success) finish() } } } } } fun show() { dialog.showWithBlurEffect() } fun dismiss() { dialog.dismiss() } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/activity/MainActivity.kt ================================================ package com.yenaly.han1meviewer.ui.activity import android.annotation.SuppressLint import android.content.Intent import android.graphics.Color import android.graphics.RenderEffect import android.graphics.Shader import android.os.Build import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.widget.ImageView import android.widget.TextView import androidx.activity.SystemBarStyle import androidx.activity.enableEdgeToEdge import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.appcompat.widget.Toolbar import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.isVisible import androidx.customview.widget.Openable import androidx.drawerlayout.widget.DrawerLayout import androidx.drawerlayout.widget.DrawerLayout.DrawerListener import androidx.fragment.app.Fragment import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.NavController import androidx.navigation.fragment.NavHostFragment import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.setupWithNavController import coil.load import coil.transform.CircleCropTransformation import com.google.android.material.navigation.NavigationBarView.ACTIVE_INDICATOR_WIDTH_MATCH_PARENT import com.google.android.material.navigation.NavigationView import com.google.android.material.navigationrail.NavigationRailView import com.google.android.material.snackbar.Snackbar import com.yenaly.han1meviewer.Preferences import com.yenaly.han1meviewer.Preferences.isAlreadyLogin import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.VIDEO_CODE import com.yenaly.han1meviewer.databinding.ActivityMainBinding import com.yenaly.han1meviewer.hanimeSpannedTitle import com.yenaly.han1meviewer.logic.exception.CloudFlareBlockedException import com.yenaly.han1meviewer.logic.state.WebsiteState import com.yenaly.han1meviewer.logout import com.yenaly.han1meviewer.ui.viewmodel.AppViewModel import com.yenaly.han1meviewer.ui.viewmodel.MainViewModel import com.yenaly.han1meviewer.util.dpToPx import com.yenaly.han1meviewer.util.logScreenViewEvent import com.yenaly.han1meviewer.util.showAlertDialog import com.yenaly.han1meviewer.util.showUpdateDialog import com.yenaly.han1meviewer.videoUrlRegex import com.yenaly.yenaly_libs.base.YenalyActivity import com.yenaly.yenaly_libs.utils.dp import com.yenaly.yenaly_libs.utils.showShortToast import com.yenaly.yenaly_libs.utils.showSnackBar import com.yenaly.yenaly_libs.utils.startActivity import com.yenaly.yenaly_libs.utils.textFromClipboard import kotlinx.coroutines.launch import kotlinx.datetime.Clock /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/08 008 17:35 */ class MainActivity : YenalyActivity(), DrawerListener { val viewModel by viewModels() lateinit var navHostFragment: NavHostFragment lateinit var navController: NavController val currentFragment get() = navHostFragment.childFragmentManager.primaryNavigationFragment // 登錄完了後讓activity刷新主頁 private val loginDataLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == RESULT_OK) { viewModel.getHomePage() initHeaderView() initMenu() } } override fun getViewBinding(layoutInflater: LayoutInflater): ActivityMainBinding = ActivityMainBinding.inflate(layoutInflater) override fun setUiStyle() { enableEdgeToEdge( statusBarStyle = SystemBarStyle.dark(Color.TRANSPARENT), navigationBarStyle = SystemBarStyle.dark(Color.TRANSPARENT) ) } override val onFragmentResumedListener: (Fragment) -> Unit = { fragment -> logScreenViewEvent(fragment) } /** * 初始化数据 */ override fun initData(savedInstanceState: Bundle?) { navHostFragment = supportFragmentManager.findFragmentById(R.id.fcv_main) as NavHostFragment navController = navHostFragment.navController if (binding.nvMain is NavigationView) { (binding.nvMain as NavigationView).setupWithNavController(navController) } if (binding.nvMain is NavigationRailView) { val nvMain = binding.nvMain as NavigationRailView nvMain.labelVisibilityMode = NavigationRailView.LABEL_VISIBILITY_LABELED nvMain.itemActiveIndicatorExpandedWidth = ACTIVE_INDICATOR_WIDTH_MATCH_PARENT } if (binding.dlMain is DrawerLayout) { (binding.dlMain as DrawerLayout).addDrawerListener(this) } initHeaderView() initNavActivity() initMenu() ViewCompat.setOnApplyWindowInsetsListener(binding.nvMain) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) WindowInsetsCompat.CONSUMED } } override fun onStart() { super.onStart() binding.root.post { textFromClipboard?.let { videoUrlRegex.find(it)?.groupValues?.get(1)?.let { videoCode -> showFindRelatedLinkSnackBar(videoCode) } } } } override fun bindDataObservers() { lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.CREATED) { AppViewModel.versionFlow.collect { state -> if (state is WebsiteState.Success && Preferences.isUpdateDialogVisible) { state.info?.let { release -> Preferences.lastUpdatePopupTime = Clock.System.now().epochSeconds showUpdateDialog(release) } } } } } lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.CREATED) { viewModel.homePageFlow.collect { state -> if (state is WebsiteState.Error) { if (state.throwable is CloudFlareBlockedException) { // TODO: 被屏蔽时的处理 } } } } } fun setAvatar(header: View) { val headerAvatar = header.findViewById(R.id.header_avatar) val headerUsername = header.findViewById(R.id.header_username) lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.CREATED) { viewModel.homePageFlow.collect { state -> if (state is WebsiteState.Success) { if (isAlreadyLogin) { if (state.info.username == null) { headerAvatar.load(R.mipmap.ic_launcher) { crossfade(true) transformations(CircleCropTransformation()) } headerUsername.setText(R.string.refresh_page_or_login_expired) } else { headerAvatar.load(state.info.avatarUrl) { crossfade(true) transformations(CircleCropTransformation()) } headerUsername.text = state.info.username } } else { initHeaderView() } } else { headerAvatar.load(R.mipmap.ic_launcher) { crossfade(true) transformations(CircleCropTransformation()) } headerUsername.setText(R.string.loading) } } } } } if (binding.nvMain is NavigationView) { (binding.nvMain as NavigationView).getHeaderView(0)?.let { header -> setAvatar(header) val collapse = header.findViewById(R.id.collapse) collapse.isVisible = false } } if (binding.nvMain is NavigationRailView) { val nvMain = binding.nvMain as NavigationRailView nvMain.headerView?.let { header -> val headerAvatar = header.findViewById(R.id.header_avatar) setAvatar(header) setHeaderAvatarSize(headerAvatar, false) } } } override fun onSupportNavigateUp(): Boolean { return navController.navigateUp() || super.onSupportNavigateUp() } override fun onDrawerSlide(drawerView: View, slideOffset: Float) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (slideOffset > 0f) { binding.fcvMain.setRenderEffect( RenderEffect.createBlurEffect( 6.dp * slideOffset, 6.dp * slideOffset, Shader.TileMode.CLAMP ) ) } } } override fun onDrawerClosed(drawerView: View) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { binding.fcvMain.setRenderEffect(null) } } override fun onDrawerOpened(drawerView: View) { } override fun onDrawerStateChanged(newState: Int) { } private fun showFindRelatedLinkSnackBar(videoCode: String) { showSnackBar(R.string.detect_ha1_related_link_in_clipboard, Snackbar.LENGTH_LONG) { setAction(R.string.enter) { startActivity(VIDEO_CODE to videoCode) } } } fun setHeaderAvatarSize(headerAvatar: ImageView, isExpanded: Boolean) { if (isExpanded) { val widthInPx = resources.getDimensionPixelSize(R.dimen.main_expanded_avatar_size) val params = headerAvatar.layoutParams params.width = widthInPx params.height = widthInPx headerAvatar.layoutParams = params } else { val widthInPx = resources.getDimensionPixelSize(R.dimen.main_avatar_size) val params = headerAvatar.layoutParams params.width = widthInPx params.height = widthInPx headerAvatar.layoutParams = params } } @SuppressLint("SetTextI18n") private fun initHeaderView() { fun setAvatar(view: View) { val headerAvatar = view.findViewById(R.id.header_avatar) val headerUsername = view.findViewById(R.id.header_username) if (isAlreadyLogin) { headerAvatar.setOnClickListener { showAlertDialog { setTitle(R.string.sure_to_logout) setPositiveButton(R.string.sure) { _, _ -> logoutWithRefresh() } setNegativeButton(R.string.no, null) } } } else { headerAvatar.load(R.mipmap.ic_launcher) { crossfade(true) transformations(CircleCropTransformation()) } headerUsername.setText(R.string.not_logged_in) headerAvatar.setOnClickListener { gotoLoginActivity() } } } if (binding.nvMain is NavigationView) { (binding.nvMain as NavigationView).getHeaderView(0)?.let { view -> setAvatar(view) } } if (binding.nvMain is NavigationRailView) { val nvMain = (binding.nvMain as NavigationRailView) nvMain.headerView?.let { view -> setAvatar(view) val collapse = view.findViewById(R.id.collapse) val headerAvatar = view.findViewById(R.id.header_avatar) collapse.setOnClickListener { setHeaderAvatarSize(headerAvatar, !nvMain.isExpanded) if (nvMain.isExpanded) { nvMain.collapse() val params = nvMain.layoutParams params.width = 80.dpToPx() nvMain.layoutParams = params } else { nvMain.expand() val params = nvMain.layoutParams params.width = 300.dpToPx() nvMain.layoutParams = params } } } } } // #issue-225: 侧滑选单双重点击异常,不能从 xml 里直接定义 activity 块,需要在代码里初始化 private fun initNavActivity() { val menu = when (binding.nvMain) { is NavigationView -> { (binding.nvMain as NavigationView).menu } else -> { (binding.nvMain as NavigationRailView).menu } } menu.apply { findItem(R.id.nv_settings).setOnMenuItemClickListener { SettingsRouter.with(navController).toSettingsActivity() return@setOnMenuItemClickListener false } findItem(R.id.nv_h_keyframe_settings).setOnMenuItemClickListener { SettingsRouter.with(navController) .toSettingsActivity(R.id.hKeyframeSettingsFragment) return@setOnMenuItemClickListener false } findItem(R.id.nv_download).setOnMenuItemClickListener { startActivity() if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { @Suppress("DEPRECATION") overridePendingTransition(R.anim.slide_in_from_bottom, R.anim.fade_out) } return@setOnMenuItemClickListener false } } } private val loginNeededFragmentList = intArrayOf(R.id.nv_fav_video, R.id.nv_watch_later, R.id.nv_playlist) private fun initMenu() { val menu = when (binding.nvMain) { is NavigationView -> { (binding.nvMain as NavigationView).menu } else -> { (binding.nvMain as NavigationRailView).menu } } if (isAlreadyLogin) { loginNeededFragmentList.forEach { menu.findItem(it).setOnMenuItemClickListener(null) } } else { loginNeededFragmentList.forEach { menu.findItem(it).setOnMenuItemClickListener { showShortToast(R.string.login_first) return@setOnMenuItemClickListener false } } } } private fun gotoLoginActivity() { val intent = Intent(this, LoginActivity::class.java) loginDataLauncher.launch(intent) } private fun logoutWithRefresh() { logout() initHeaderView() initMenu() } /** * 设置toolbar与navController关联 * * 必须最后调用!先设置好toolbar! */ fun Toolbar.setupWithMainNavController() { supportActionBar!!.title = hanimeSpannedTitle if (binding.dlMain is DrawerLayout) { val appBarConfiguration = AppBarConfiguration(setOf(R.id.nv_home_page), binding.dlMain as Openable? ) this.setupWithNavController(navController, appBarConfiguration) } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/activity/PreviewActivity.kt ================================================ package com.yenaly.han1meviewer.ui.activity import android.annotation.SuppressLint import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.LayoutInflater import android.view.Menu import android.view.MenuItem import androidx.activity.SystemBarStyle import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.annotation.OptIn import androidx.core.graphics.ColorUtils import androidx.core.graphics.drawable.toBitmapOrNull import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.core.view.updatePadding import androidx.interpolator.view.animation.FastOutSlowInInterpolator import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.palette.graphics.Palette import androidx.recyclerview.widget.LinearSnapHelper import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 import coil.imageLoader import coil.load import coil.request.ImageRequest import com.google.android.material.appbar.AppBarLayout import com.google.android.material.badge.BadgeDrawable import com.google.android.material.badge.BadgeUtils import com.google.android.material.badge.ExperimentalBadgeUtils import com.yenaly.han1meviewer.DATE_CODE import com.yenaly.han1meviewer.PREVIEW_COMMENT_PREFIX import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.databinding.ActivityPreviewBinding import com.yenaly.han1meviewer.logic.state.WebsiteState import com.yenaly.han1meviewer.pienization import com.yenaly.han1meviewer.ui.adapter.HanimePreviewNewsRvAdapter import com.yenaly.han1meviewer.ui.adapter.HanimePreviewTourRvAdapter import com.yenaly.han1meviewer.ui.view.CenterLinearLayoutManager import com.yenaly.han1meviewer.ui.viewmodel.PreviewCommentPrefetcher import com.yenaly.han1meviewer.ui.viewmodel.PreviewViewModel import com.yenaly.han1meviewer.util.addUpdateListener import com.yenaly.han1meviewer.util.colorTransition import com.yenaly.han1meviewer.util.toColorStateList import com.yenaly.yenaly_libs.base.YenalyActivity import com.yenaly.yenaly_libs.utils.appScreenWidth import com.yenaly.yenaly_libs.utils.getThemeColor import com.yenaly.yenaly_libs.utils.startActivity import com.yenaly.yenaly_libs.utils.unsafeLazy import com.yenaly.yenaly_libs.utils.view.AppBarLayoutStateChangeListener import com.yenaly.yenaly_libs.utils.view.innerRecyclerView import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch import kotlinx.datetime.Clock import kotlinx.datetime.DateTimeUnit import kotlinx.datetime.LocalDateTime import kotlinx.datetime.TimeZone import kotlinx.datetime.format import kotlinx.datetime.format.Padding import kotlinx.datetime.format.char import kotlinx.datetime.minus import kotlinx.datetime.plus import kotlinx.datetime.toInstant import kotlinx.datetime.toLocalDateTime /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/23 023 16:46 */ class PreviewActivity : YenalyActivity() { companion object { private const val ANIM_DURATION = 300L private val animInterpolator = FastOutSlowInInterpolator() } val viewModel by viewModels() private val dateUtils = DateUtils() private val badgeDrawable by unsafeLazy { BadgeDrawable.create(this@PreviewActivity) } /** * 左右滑动 VP 时,不触发 onScrollStateChanged,防止触发两次 binding.vpNews.setCurrentItem * 导致滑动不流畅。 */ private var shouldTriggerScroll = false private val tourSimplifiedAdapter = HanimePreviewTourRvAdapter() private val linearSnapHelper = LinearSnapHelper() private val newsAdapter = HanimePreviewNewsRvAdapter() private val tourLayoutManager by unsafeLazy { object : CenterLinearLayoutManager(this@PreviewActivity) { init { orientation = HORIZONTAL reverseLayout = false } override fun scrollVerticallyBy( dy: Int, recycler: RecyclerView.Recycler?, state: RecyclerView.State?, ): Int { if (!binding.vpNews.isInTouchMode) { onScrollWhenInNonTouchMode(dy) } return super.scrollVerticallyBy(dy, recycler, state) } private fun onScrollWhenInNonTouchMode(dy: Int) { if (dy > 0) { binding.appBar.setExpanded(false, true) } else binding.appBar.setExpanded(true, true) } } } override fun getViewBinding(layoutInflater: LayoutInflater): ActivityPreviewBinding = ActivityPreviewBinding.inflate(layoutInflater) override fun setUiStyle() { enableEdgeToEdge( statusBarStyle = SystemBarStyle.dark(Color.TRANSPARENT), navigationBarStyle = SystemBarStyle.dark(Color.TRANSPARENT) ) } override fun initData(savedInstanceState: Bundle?) { setSupportActionBar(binding.toolbar) binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() } supportActionBar?.let { it.title = null it.setDisplayHomeAsUpEnabled(true) it.setHomeActionContentDescription(R.string.back) } PreviewCommentPrefetcher.here().tag(PreviewCommentPrefetcher.Scope.PREVIEW_ACTIVITY) // binding.newsTitle.findViewById(R.id.title).setText(R.string.latest_hanime_news) // binding.newsTitle.findViewById(R.id.sub_title).setText(R.string.introduction) dateUtils.current.format(DateUtils.FORMATTED_FORMAT).let { format -> viewModel.getHanimePreview(format) loadComments(format) } binding.fabPrevious.setOnClickListener { dateUtils.toPrevDate().format(DateUtils.FORMATTED_FORMAT).let { format -> viewModel.getHanimePreview(format) loadComments(format) } } binding.fabNext.setOnClickListener { dateUtils.toNextDate().format(DateUtils.FORMATTED_FORMAT).let { format -> viewModel.getHanimePreview(format) loadComments(format) } } binding.vpNews.adapter = newsAdapter binding.rvTourSimplified.apply { layoutManager = tourLayoutManager adapter = tourSimplifiedAdapter clipToPadding = false ViewCompat.setOnApplyWindowInsetsListener(this) { view, _ -> val elementWidth = view.resources.getDimension( R.dimen.video_cover_simplified_width_small ) val padding = appScreenWidth / 2f - elementWidth / 2f view.updatePadding(left = padding.toInt(), right = padding.toInt()) WindowInsetsCompat.CONSUMED } linearSnapHelper.attachToRecyclerView(this) addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { super.onScrollStateChanged(recyclerView, newState) if (newState == RecyclerView.SCROLL_STATE_IDLE) { if (shouldTriggerScroll) { val view = linearSnapHelper.findSnapView(tourLayoutManager) val position = view?.let(::getChildAdapterPosition) ?: RecyclerView.NO_POSITION binding.vpNews.setCurrentItem(position, false) } shouldTriggerScroll = true } } }) } tourSimplifiedAdapter.setOnItemClickListener { _, _, position -> binding.vpNews.setCurrentItem(position, false) binding.appBar.setExpanded(false, true) } binding.vpNews.innerRecyclerView?.apply { isNestedScrollingEnabled = false clipToPadding = false ViewCompat.setOnApplyWindowInsetsListener(this) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.navigationBars()) v.updatePadding(bottom = systemBars.bottom) WindowInsetsCompat.CONSUMED } } binding.vpNews.offscreenPageLimit = 1 binding.vpNews.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { shouldTriggerScroll = false binding.rvTourSimplified.smoothScrollToPosition(position) handleToolbarColor(position) } }) initAnimation() //binding.srlPreview.setOnRefreshListener { // viewModel.getHanimePreview(dateUtils.current.second) //} } @OptIn(ExperimentalBadgeUtils::class) @SuppressLint("SetTextI18n") override fun bindDataObservers() { lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.CREATED) { viewModel.previewFlow.collect { state -> binding.nsvPreview.isGone = state !is WebsiteState.Success binding.appBar.setExpanded(state is WebsiteState.Success, true) when (state) { is WebsiteState.Error -> { //binding.srlPreview.finishRefresh() supportActionBar?.title = state.throwable.pienization } is WebsiteState.Loading -> { //binding.srlPreview.autoRefresh() binding.fabPrevious.isEnabled = false binding.fabNext.isEnabled = false } is WebsiteState.Success -> { //binding.srlPreview.finishRefresh() binding.vpNews.setCurrentItem(0, false) supportActionBar?.title = getString( R.string.latest_hanime_list_monthly, dateUtils.current.format(DateUtils.NORMAL_FORMAT) ) binding.fabPrevious.apply { isVisible = state.info.hasPrevious isEnabled = state.info.hasPrevious text = dateUtils.prevDate.format(DateUtils.NORMAL_FORMAT) } binding.fabNext.apply { isVisible = state.info.hasNext isEnabled = state.info.hasNext text = dateUtils.nextDate.format(DateUtils.NORMAL_FORMAT) } binding.cover.load(state.info.headerPicUrl) { crossfade(true) allowHardware(false) target( onStart = binding.cover::setImageDrawable, onError = binding.cover::setImageDrawable, onSuccess = { binding.cover.setImageDrawable(it) it.toBitmapOrNull()?.let(Palette::Builder)?.generate { p -> p?.let(::handleHeaderPalette) } } ) } tourSimplifiedAdapter.submitList(state.info.latestHanime) // 有時候 tour 無法順利加載出來,加點延遲反而就好了,哈哈 delay(100) handleToolbarColor(0) newsAdapter.submitList(state.info.previewInfo) } } } } } lifecycleScope.launch { PreviewCommentPrefetcher.here().commentFlow.collectLatest { comments -> badgeDrawable.apply { isVisible = comments.isNotEmpty() number = comments.size badgeGravity = BadgeDrawable.TOP_START } BadgeUtils.attachBadgeDrawable(badgeDrawable, binding.toolbar, R.id.tb_comment) } } } override fun onDestroy() { super.onDestroy() PreviewCommentPrefetcher.bye(PreviewCommentPrefetcher.Scope.PREVIEW_ACTIVITY) } override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_preview_toolbar, menu) return super.onCreateOptionsMenu(menu) } override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.tb_comment -> { startActivity( "date" to dateUtils.current.format(DateUtils.NORMAL_FORMAT), DATE_CODE to dateUtils.current.format(DateUtils.FORMATTED_FORMAT) ) } } return super.onOptionsItemSelected(item) } private fun loadComments(currentFormat: String) { PreviewCommentPrefetcher.here() .fetch(PREVIEW_COMMENT_PREFIX, currentFormat) } private fun handleToolbarColor(index: Int) { val data = tourSimplifiedAdapter.getItem(index)?.coverUrl val request = ImageRequest.Builder(this) .data(data) .allowHardware(false) .target( onError = { }, onSuccess = { it.toBitmapOrNull()?.let(Palette::Builder)?.generate { p -> p?.let(::handleToolbarPalette) } } ) .build() this.imageLoader.enqueue(request) } private fun handleToolbarPalette(p: Palette) { val darkMuted = p.darkMutedSwatch?.rgb ?: p.darkVibrantSwatch?.rgb ?: p.lightVibrantSwatch?.rgb ?: p.lightMutedSwatch?.rgb ?: Color.BLACK colorTransition( fromColor = (binding.collapsingToolbar.contentScrim as ColorDrawable).color, toColor = ColorUtils.blendARGB(darkMuted, Color.BLACK, 0.3f) ) { duration = ANIM_DURATION interpolator = animInterpolator addUpdateListener(lifecycle) { val value = it.animatedValue as Int binding.collapsingToolbar.setContentScrimColor(value) } } colorTransition( fromColor = (binding.llTour.background as? ColorDrawable)?.color ?: Color.TRANSPARENT, toColor = darkMuted ) { duration = ANIM_DURATION interpolator = animInterpolator addUpdateListener(lifecycle) { val value = it.animatedValue as Int binding.llTour.setBackgroundColor(value) } } } private fun handleHeaderPalette(p: Palette) { val colorPrimary = getThemeColor(com.google.android.material.R.attr.colorPrimaryFixed) val lightVibrant = p.getLightVibrantColor(colorPrimary) val per70lightVibrantStateList = ColorUtils.setAlphaComponent(lightVibrant, 0xB3).toColorStateList() binding.fabPrevious.backgroundTintList = per70lightVibrantStateList binding.fabNext.backgroundTintList = per70lightVibrantStateList val titleTextColorStateList = (p.lightVibrantSwatch?.titleTextColor ?: Color.BLACK).toColorStateList() binding.fabPrevious.iconTint = titleTextColorStateList binding.fabNext.iconTint = titleTextColorStateList binding.fabPrevious.setTextColor(titleTextColorStateList) binding.fabNext.setTextColor(titleTextColorStateList) } private fun initAnimation() { binding.appBar.addOnOffsetChangedListener(object : AppBarLayoutStateChangeListener() { override fun onStateChanged(appBarLayout: AppBarLayout, state: State) { when (state) { State.EXPANDED -> { binding.fabPrevious.animate().translationX(0F).setDuration(ANIM_DURATION) .setInterpolator(animInterpolator).start() binding.fabNext.animate().translationX(0F).setDuration(ANIM_DURATION) .setInterpolator(animInterpolator).start() } State.INTERMEDIATE -> { binding.fabPrevious.animate().translationX(-500F).setDuration(ANIM_DURATION) .setInterpolator(animInterpolator).start() binding.fabNext.animate().translationX(500F).setDuration(ANIM_DURATION) .setInterpolator(animInterpolator).start() } State.COLLAPSED -> { } } } }) } /** * 单纯给这个用的DateUtils */ private class DateUtils { companion object { /** * 2022/2 */ val NORMAL_FORMAT = LocalDateTime.Format { year(); char('/'); monthNumber(Padding.NONE) } /** * 202202 */ val FORMATTED_FORMAT = LocalDateTime.Format { year(); monthNumber() } } // 當前顯示的日期 var current: LocalDateTime = currentDate private set val currentDate: LocalDateTime get() = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()) val prevDate: LocalDateTime get() { val instant = current.toInstant(TimeZone.currentSystemDefault()) return instant.minus(1, DateTimeUnit.MONTH, TimeZone.currentSystemDefault()) .toLocalDateTime(TimeZone.currentSystemDefault()) } val nextDate: LocalDateTime get() { val instant = current.toInstant(TimeZone.currentSystemDefault()) return instant.plus(1, DateTimeUnit.MONTH, TimeZone.currentSystemDefault()) .toLocalDateTime(TimeZone.currentSystemDefault()) } fun toPrevDate(): LocalDateTime { current = prevDate return current } fun toNextDate(): LocalDateTime { current = nextDate return current } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/activity/PreviewCommentActivity.kt ================================================ package com.yenaly.han1meviewer.ui.activity import android.graphics.Color import android.os.Bundle import android.view.LayoutInflater import androidx.activity.SystemBarStyle import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import com.yenaly.han1meviewer.COMMENT_TYPE import com.yenaly.han1meviewer.DATE_CODE import com.yenaly.han1meviewer.PREVIEW_COMMENT_PREFIX import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.databinding.ActivityPreviewCommentBinding import com.yenaly.han1meviewer.ui.fragment.video.CommentFragment import com.yenaly.han1meviewer.ui.viewmodel.CommentViewModel import com.yenaly.han1meviewer.ui.viewmodel.PreviewCommentPrefetcher import com.yenaly.yenaly_libs.base.YenalyActivity import com.yenaly.yenaly_libs.utils.makeBundle import com.yenaly.yenaly_libs.utils.safeIntentExtra /** * @project Han1meViewer * @author Yenaly Liew * @time 2022/06/28 028 12:03 */ class PreviewCommentActivity : YenalyActivity() { val viewModel by viewModels() private val date by safeIntentExtra("date") // 感覺沒必要弄成個常量 private val dateCode by safeIntentExtra(DATE_CODE) override fun getViewBinding(layoutInflater: LayoutInflater): ActivityPreviewCommentBinding = ActivityPreviewCommentBinding.inflate(layoutInflater) override fun setUiStyle() { enableEdgeToEdge( statusBarStyle = SystemBarStyle.dark(Color.TRANSPARENT), navigationBarStyle = SystemBarStyle.dark(Color.TRANSPARENT) ) } override fun initData(savedInstanceState: Bundle?) { setSupportActionBar(binding.toolbar) binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() } supportActionBar?.let { it.setDisplayHomeAsUpEnabled(true) it.setHomeActionContentDescription(R.string.back) it.title = getString(R.string.latest_hanime_comment, date) } viewModel.code = dateCode PreviewCommentPrefetcher.here().tag(PreviewCommentPrefetcher.Scope.PREVIEW_COMMENT_ACTIVITY) val commentFragment = CommentFragment().makeBundle(COMMENT_TYPE to PREVIEW_COMMENT_PREFIX) supportFragmentManager.beginTransaction().apply { add(R.id.fcv_pre_comment, commentFragment) }.commit() } override fun onDestroy() { super.onDestroy() PreviewCommentPrefetcher.bye(PreviewCommentPrefetcher.Scope.PREVIEW_COMMENT_ACTIVITY) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/activity/SearchActivity.kt ================================================ package com.yenaly.han1meviewer.ui.activity import android.annotation.SuppressLint import android.content.res.Configuration import android.graphics.Color import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup.MarginLayoutParams import androidx.activity.SystemBarStyle import androidx.activity.addCallback import androidx.activity.enableEdgeToEdge import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.core.util.size import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.core.view.updateLayoutParams import androidx.core.view.updatePadding import androidx.fragment.app.Fragment import androidx.lifecycle.Lifecycle import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.OnScrollListener import com.yenaly.han1meviewer.ADVANCED_SEARCH_MAP import com.yenaly.han1meviewer.AdvancedSearchMap import com.yenaly.han1meviewer.HAdvancedSearch import com.yenaly.han1meviewer.VideoCoverSize import com.yenaly.han1meviewer.databinding.ActivitySearchBinding import com.yenaly.han1meviewer.logic.entity.SearchHistoryEntity import com.yenaly.han1meviewer.logic.model.HanimeInfo import com.yenaly.han1meviewer.logic.model.SearchOption import com.yenaly.han1meviewer.logic.model.SearchOption.Companion.flatten import com.yenaly.han1meviewer.logic.model.SearchOption.Companion.get import com.yenaly.han1meviewer.logic.state.PageLoadingState import com.yenaly.han1meviewer.ui.StateLayoutMixin import com.yenaly.han1meviewer.ui.adapter.FixedGridLayoutManager import com.yenaly.han1meviewer.ui.adapter.HanimeSearchHistoryRvAdapter import com.yenaly.han1meviewer.ui.adapter.HanimeVideoRvAdapter import com.yenaly.han1meviewer.ui.fragment.search.HMultiChoicesDialog import com.yenaly.han1meviewer.ui.fragment.search.SearchOptionsPopupFragment import com.yenaly.han1meviewer.ui.viewmodel.MyListViewModel import com.yenaly.han1meviewer.ui.viewmodel.SearchViewModel import com.yenaly.han1meviewer.util.logScreenViewEvent import com.yenaly.yenaly_libs.base.YenalyActivity import com.yenaly.yenaly_libs.utils.dp import com.yenaly.yenaly_libs.utils.intentExtra import com.yenaly.yenaly_libs.utils.unsafeLazy import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch /** * @project Hanime1 * @author Yenaly Liew * @time 2022/06/13 013 22:29 */ class SearchActivity : YenalyActivity(), StateLayoutMixin { val viewModel by viewModels() val myListViewModel by viewModels() val subscribeLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == RESULT_OK) { initSubscription() } } /** * 判断adapter是否已经加载,防止多次加载导致滑动浏览总是跳到顶部。 */ private var hasAdapterLoaded = false private val searchAdapter by unsafeLazy { HanimeVideoRvAdapter() } private val historyAdapter by unsafeLazy { HanimeSearchHistoryRvAdapter() } private val advancedSearchMap by intentExtra(ADVANCED_SEARCH_MAP) private val optionsPopupFragment by unsafeLazy { SearchOptionsPopupFragment() } override fun getViewBinding(layoutInflater: LayoutInflater): ActivitySearchBinding = ActivitySearchBinding.inflate(layoutInflater) override val onFragmentResumedListener: (Fragment) -> Unit = { fragment -> logScreenViewEvent(fragment) } override fun setUiStyle() { enableEdgeToEdge( statusBarStyle = SystemBarStyle.dark(Color.TRANSPARENT), navigationBarStyle = SystemBarStyle.dark(Color.TRANSPARENT) ) } /** * 初始化数据 */ override fun initData(savedInstanceState: Bundle?) { advancedSearchMap?.let(::loadAdvancedSearch) initSearchBar() initSubscription() binding.state.init() binding.searchRv.apply { layoutManager = FixedGridLayoutManager( this@SearchActivity, VideoCoverSize.Normal.videoInOneLine ) adapter = searchAdapter clipToPadding = false addOnScrollListener(object : OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { if (newState != RecyclerView.SCROLL_STATE_IDLE) { binding.searchBar.hideHistory() } } }) } binding.searchSrl.apply { setOnLoadMoreListener { getHanimeSearchResult() } setOnRefreshListener { // will enter here firstly. cuz the flow's def value is Loading. getNewHanimeSearchResult() } setDisableContentWhenRefresh(true) } ViewCompat.setOnApplyWindowInsetsListener(binding.searchBar) { v, insets -> v.updatePadding(top = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top) WindowInsetsCompat.CONSUMED } ViewCompat.setOnApplyWindowInsetsListener(binding.searchRv) { v, insets -> val sysBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.updatePadding(bottom = sysBars.bottom, top = sysBars.top + 68.dp) WindowInsetsCompat.CONSUMED } ViewCompat.setOnApplyWindowInsetsListener(binding.searchHeader) { v, insets -> val sysBars = insets.getInsets(WindowInsetsCompat.Type.statusBars()) v.updateLayoutParams { topMargin = sysBars.top + 68.dp } WindowInsetsCompat.CONSUMED } } @SuppressLint("SetTextI18n") override fun bindDataObservers() { lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.CREATED) { viewModel.searchStateFlow.collect { state -> binding.searchRv.isGone = state is PageLoadingState.Error when (state) { is PageLoadingState.Loading -> { if (viewModel.searchFlow.value.isEmpty()) binding.searchSrl.autoRefresh() } is PageLoadingState.Success -> { viewModel.page++ binding.searchSrl.finishRefresh() binding.searchSrl.finishLoadMore(true) if (!hasAdapterLoaded) { binding.searchRv.layoutManager = state.info.buildFlexibleGridLayoutManager() hasAdapterLoaded = true } binding.state.showContent() } is PageLoadingState.NoMoreData -> { binding.searchSrl.finishLoadMoreWithNoMoreData() if (viewModel.searchFlow.value.isEmpty()) { binding.state.showEmpty() binding.searchRv.isGone = true } } is PageLoadingState.Error -> { binding.searchSrl.finishRefresh() binding.searchSrl.finishLoadMore(false) // set error view binding.state.showError(state.throwable) } } } } } lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.CREATED) { viewModel.searchFlow.collectLatest { searchAdapter.submitList(it) } } } } override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) val dataState = viewModel.searchStateFlow.value binding.searchRv.layoutManager = if (dataState is PageLoadingState.Success) { dataState.info.buildFlexibleGridLayoutManager() } else FixedGridLayoutManager(this, VideoCoverSize.Normal.videoInOneLine) } private fun getHanimeSearchResult() { Log.d("SearchActivity", buildString { appendLine("page: ${viewModel.page}, query: ${viewModel.query}, genre: ${viewModel.genre}, ") appendLine("sort: ${viewModel.sort}, broad: ${viewModel.broad}, year: ${viewModel.year}, ") appendLine("month: ${viewModel.month}, duration: ${viewModel.duration}, ") appendLine("tagMap: ${viewModel.tagMap}, brandMap: ${viewModel.brandMap}") }) viewModel.getHanimeSearchResult( viewModel.page, viewModel.query, viewModel.genre, viewModel.sort, viewModel.broad, viewModel.year, viewModel.month, viewModel.duration, viewModel.tagMap.flatten(), viewModel.brandMap.flatten() ) } /** * 獲取最新結果,清除之前保存的所有數據 */ private fun getNewHanimeSearchResult() { viewModel.page = 1 hasAdapterLoaded = false viewModel.clearHanimeSearchResult() getHanimeSearchResult() } @OptIn(FlowPreview::class, ExperimentalCoroutinesApi::class) private fun initSearchBar() { onBackPressedDispatcher.addCallback(this) { if (binding.searchBar.hideHistory()) { return@addCallback } finish() } historyAdapter.listener = object : HanimeSearchHistoryRvAdapter.OnItemViewClickListener { override fun onItemClickListener(v: View, history: SearchHistoryEntity?) { binding.searchBar.searchText = history?.query } override fun onItemRemoveListener(v: View, history: SearchHistoryEntity?) { history?.let(viewModel::deleteSearchHistory) } } binding.searchBar.apply hsb@{ historyAdapter = this@SearchActivity.historyAdapter onTagClickListener = { optionsPopupFragment.showIn(this@SearchActivity) } onBackClickListener = { finish() } onSearchClickListener = { _, text -> viewModel.query = text if (text.isNotBlank()) { viewModel.insertSearchHistory(SearchHistoryEntity(text)) } // getNewHanimeSearchResult() 下面那個方法自動幫你執行這個方法了 binding.searchSrl.autoRefresh() } // 搜索框文字改变走这里 textChangeFlow() .debounce(300) .flatMapLatest { viewModel.loadAllSearchHistories(it) }.flowOn(Dispatchers.IO).onEach { this@SearchActivity.historyAdapter.submitList(it) }.flowWithLifecycle(lifecycle).launchIn(lifecycleScope) } optionsPopupFragment.onSearchListener = { optionsPopupFragment.dismiss() binding.searchSrl.autoRefresh() } } private fun initSubscription() { myListViewModel.subscription.getSubscriptionsWithSinglePage() } private fun List.buildFlexibleGridLayoutManager(): GridLayoutManager { val counts = if (any { it.itemType == HanimeInfo.NORMAL }) VideoCoverSize.Normal.videoInOneLine else VideoCoverSize.Simplified.videoInOneLine return FixedGridLayoutManager(this@SearchActivity, counts) } fun setSearchText(text: String?, canTextChange: Boolean = true) { viewModel.query = text binding.searchBar.searchText = text binding.searchBar.canTextChange = canTextChange } val searchText: String? get() = binding.searchBar.searchText /** * 分析该 any 并加载给相应 ViewModel 中的参数 * * any 可以爲 [AdvancedSearchMap] 或者 [String] * * 若为 [String],则默认给 query 处理 */ @Suppress("UNCHECKED_CAST") private fun loadAdvancedSearch(any: Any) { if (any is String) { setSearchText(any) return } val map = any as AdvancedSearchMap (map[HAdvancedSearch.QUERY] as? String)?.let { setSearchText(it) } viewModel.genre = map[HAdvancedSearch.GENRE] as? String viewModel.sort = map[HAdvancedSearch.SORT] as? String viewModel.year = map[HAdvancedSearch.YEAR] as? Int viewModel.month = map[HAdvancedSearch.MONTH] as? Int viewModel.duration = map[HAdvancedSearch.DURATION] as? String when (val tags = map[HAdvancedSearch.TAGS]) { is Map<*, *> -> { val tagMap = tags as Map tagMap.forEach { (k, v) -> val scope = viewModel.tags[k] when (v) { is String -> { val option = scope.find { it.searchKey == v } viewModel.tagMap[k] = option?.let(::setOf) ?: emptySet() } is Set<*> -> { val keySet = scope.filterTo(mutableSetOf()) { it.searchKey in v } viewModel.tagMap[k] = keySet } } } } // 不推荐使用 is String -> { kotlin.run t@{ viewModel.tags.forEach { (k, v) -> v.find { it.searchKey == tags }?.let { so -> val scopeKey = SearchOption.toScopeKey(k) viewModel.tagMap[scopeKey] = setOf(so) return@t } } } } // 不推荐使用 is Set<*> -> { viewModel.tags.forEach { (k, v) -> val keySet = v.filterTo(mutableSetOf()) { it.searchKey in tags } viewModel.tagMap[SearchOption.toScopeKey(k)] = keySet } } } when (val brands = map[HAdvancedSearch.BRANDS]) { is String -> { val brand = viewModel.brands.find { it.searchKey == brands } viewModel.brandMap[HMultiChoicesDialog.UNKNOWN_ADAPTER] = brand?.let(::setOf) ?: emptySet() } is Set<*> -> { val keySet = viewModel.brands.filterTo(mutableSetOf()) { it.searchKey in brands } viewModel.brandMap[HMultiChoicesDialog.UNKNOWN_ADAPTER] = keySet } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/activity/SettingsActivity.kt ================================================ package com.yenaly.han1meviewer.ui.activity import android.graphics.Color import android.os.Build import android.os.Bundle import android.view.LayoutInflater import androidx.activity.SystemBarStyle import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.updatePadding import androidx.fragment.app.Fragment import androidx.navigation.NavController import androidx.navigation.fragment.NavHostFragment import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.databinding.ActivitySettingsBinding import com.yenaly.han1meviewer.ui.viewmodel.SettingsViewModel import com.yenaly.han1meviewer.util.logScreenViewEvent import com.yenaly.yenaly_libs.base.YenalyActivity /** * @project Han1meViewer * @author Yenaly Liew * @time 2022/07/01 001 13:40 */ class SettingsActivity : YenalyActivity() { val viewModel by viewModels() private lateinit var navHostFragment: NavHostFragment private lateinit var navController: NavController val currentFragment get() = navHostFragment.childFragmentManager.primaryNavigationFragment override fun getViewBinding(layoutInflater: LayoutInflater): ActivitySettingsBinding = ActivitySettingsBinding.inflate(layoutInflater) override val onFragmentResumedListener: (Fragment) -> Unit = { fragment -> logScreenViewEvent(fragment) } override fun setUiStyle() { enableEdgeToEdge( statusBarStyle = SystemBarStyle.dark(Color.TRANSPARENT), navigationBarStyle = SystemBarStyle.dark(Color.TRANSPARENT) ) } override fun initData(savedInstanceState: Bundle?) { setSupportActionBar(binding.toolbar) supportActionBar?.let { it.setDisplayHomeAsUpEnabled(true) it.setHomeActionContentDescription(R.string.back) } navHostFragment = supportFragmentManager.findFragmentById(R.id.fcv_settings) as NavHostFragment navController = navHostFragment.navController SettingsRouter.with(navController).navigateFromActivity(inclusive = true) binding.toolbar.setNavigationOnClickListener { if (!navController.popBackStack()) { onBackPressedDispatcher.onBackPressed() } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { overrideActivityTransition( OVERRIDE_TRANSITION_OPEN, R.anim.fade_in, R.anim.fade_out ) overrideActivityTransition( OVERRIDE_TRANSITION_CLOSE, R.anim.fade_in, R.anim.fade_out ) } ViewCompat.setOnApplyWindowInsetsListener(binding.fcvSettings) { v, insets -> val navBar = insets.getInsets(WindowInsetsCompat.Type.navigationBars()) v.updatePadding(bottom = navBar.bottom) WindowInsetsCompat.CONSUMED } } @Suppress("DEPRECATION") override fun finish() { super.finish() if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { overridePendingTransition(R.anim.fade_in, R.anim.fade_out) } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/activity/SettingsRouter.kt ================================================ package com.yenaly.han1meviewer.ui.activity import android.content.Context import android.content.Intent import android.os.Build import android.os.Bundle import androidx.annotation.IdRes import androidx.fragment.app.Fragment import androidx.navigation.NavController import androidx.navigation.fragment.findNavController import androidx.navigation.navOptions import com.yenaly.han1meviewer.R import com.yenaly.yenaly_libs.utils.activity /** * 极其简易的路由器,用于从任何地方跳转到设置界面 */ class SettingsRouter private constructor( private val context: Context, private val navController: NavController ) { companion object { const val DESTINATION = "destination" const val BUNDLE = "bundle" /** * 适用于 fragment 内部跳转 */ @JvmStatic fun with(fragment: Fragment) = SettingsRouter( fragment.requireContext(), fragment.findNavController() ) /** * 适用于 activity 跳转 */ @JvmStatic fun with(navController: NavController) = SettingsRouter( navController.context, navController ) } /** * 依靠 intent extra 运作,只适用于其他 activity 打开设置界面 */ fun navigateFromActivity( args: Bundle? = null, inclusive: Boolean = false ) { val activity = context.activity ?: return val id = activity.intent.getIntExtra(DESTINATION, 0) if (id == 0) return navController.navigate(id, args, navOptions { popUpTo(R.id.homeSettingsFragment) { this.inclusive = true } anim { enter = R.anim.fade_in exit = R.anim.fade_out popEnter = R.anim.fade_in popExit = R.anim.fade_out } }.takeIf { inclusive }) } fun toSettingsActivity(@IdRes id: Int = 0, bundle: Bundle? = null) { val activity = context.activity ?: return val intent = Intent(activity, SettingsActivity::class.java).apply { putExtra(DESTINATION, id) bundle?.let { putExtra(BUNDLE, it) } } activity.startActivity(intent) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { @Suppress("DEPRECATION") activity.overridePendingTransition(R.anim.fade_in, R.anim.fade_out) } } /** * 适用于 Settings 内不同设置页面跳转 */ fun navigateWithinSettings( @IdRes to: Int, args: Bundle? = null, inclusive: Boolean = false ) { val from = navController.currentDestination?.id ?: return navController.navigate(to, args, navOptions { popUpTo(from) { this.inclusive = inclusive } anim { enter = R.anim.fade_in exit = R.anim.fade_out popEnter = R.anim.fade_in popExit = R.anim.fade_out } }) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/activity/VideoActivity.kt ================================================ package com.yenaly.han1meviewer.ui.activity import android.app.PendingIntent import android.app.PictureInPictureParams import android.app.RemoteAction import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter import android.content.pm.ActivityInfo import android.graphics.Color import android.graphics.Rect import android.graphics.drawable.Icon import android.os.Build import android.os.Bundle import android.util.Log import android.util.Rational import android.view.Gravity import android.view.LayoutInflater import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.MarginLayoutParams import android.widget.LinearLayout import androidx.activity.SystemBarStyle import androidx.activity.addCallback import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.annotation.RequiresApi import androidx.core.content.ContextCompat import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams import androidx.fragment.app.Fragment import androidx.lifecycle.Lifecycle import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import cn.jzvd.JZMediaInterface import cn.jzvd.Jzvd import cn.jzvd.Jzvd.goOnPlayOnPause import coil.load import com.google.firebase.Firebase import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.analytics.analytics import com.google.firebase.analytics.logEvent import com.yenaly.han1meviewer.COMMENT_TYPE import com.yenaly.han1meviewer.FROM_DOWNLOAD import com.yenaly.han1meviewer.FirebaseConstants import com.yenaly.han1meviewer.Preferences import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.VIDEO_CODE import com.yenaly.han1meviewer.VIDEO_COMMENT_PREFIX import com.yenaly.han1meviewer.databinding.ActivityVideoBinding import com.yenaly.han1meviewer.getHanimeVideoLink import com.yenaly.han1meviewer.logic.entity.HKeyframeEntity import com.yenaly.han1meviewer.logic.entity.WatchHistoryEntity import com.yenaly.han1meviewer.logic.exception.ParseException import com.yenaly.han1meviewer.logic.state.VideoLoadingState import com.yenaly.han1meviewer.ui.fragment.video.CommentFragment import com.yenaly.han1meviewer.ui.fragment.video.VideoIntroductionFragment import com.yenaly.han1meviewer.ui.view.video.HMediaKernel import com.yenaly.han1meviewer.ui.view.video.HanimeDataSource import com.yenaly.han1meviewer.ui.viewmodel.CommentViewModel import com.yenaly.han1meviewer.ui.viewmodel.VideoViewModel import com.yenaly.han1meviewer.util.getOrCreateBadgeOnTextViewAt import com.yenaly.han1meviewer.util.logScreenViewEvent import com.yenaly.han1meviewer.util.showAlertDialog import com.yenaly.yenaly_libs.base.YenalyActivity import com.yenaly.yenaly_libs.utils.OrientationManager import com.yenaly.yenaly_libs.utils.activity import com.yenaly.yenaly_libs.utils.browse import com.yenaly.yenaly_libs.utils.dp import com.yenaly.yenaly_libs.utils.intentExtra import com.yenaly.yenaly_libs.utils.makeBundle import com.yenaly.yenaly_libs.utils.showShortToast import com.yenaly.yenaly_libs.utils.startActivity import com.yenaly.yenaly_libs.utils.view.attach import com.yenaly.yenaly_libs.utils.view.setUpFragmentStateAdapter import kotlinx.coroutines.launch import kotlinx.datetime.Clock class VideoActivity : YenalyActivity(), OrientationManager.OrientationChangeListener { companion object { private const val ACTION_PLAY = "com.yenaly.han1meviewer.ACTION_PLAY" private const val ACTION_PAUSE = "com.yenaly.han1meviewer.ACTION_PAUSE" } val viewModel by viewModels() private val commentViewModel by viewModels() private val kernel = HMediaKernel.Type.fromString(Preferences.switchPlayerKernel) private val fromDownload by intentExtra(FROM_DOWNLOAD, false) private val videoCode by intentExtra(VIDEO_CODE) private var videoTitle: String? = null private var videoCodeByWebsite: String? = null private var builder: PictureInPictureParams.Builder? = null private val tabNameArray = intArrayOf(R.string.introduction, R.string.comment) override fun getViewBinding(layoutInflater: LayoutInflater): ActivityVideoBinding = ActivityVideoBinding.inflate(layoutInflater) override val onFragmentResumedListener: (Fragment) -> Unit = { fragment -> logScreenViewEvent(fragment) } override fun setUiStyle() { enableEdgeToEdge( statusBarStyle = SystemBarStyle.dark(Color.TRANSPARENT), navigationBarStyle = SystemBarStyle.dark(Color.TRANSPARENT) ) } override fun initData(savedInstanceState: Bundle?) { if (intent.action == Intent.ACTION_VIEW) { val uri = intent.data uri?.let { videoCodeByWebsite = it.getQueryParameter("v") } } onBackPressedDispatcher.addCallback(this) { if (Jzvd.backPress()) { return@addCallback } finish() } // 必须 fromDownload 在前,videoCode 在后 viewModel.fromDownload = fromDownload requireNotNull(videoCodeByWebsite ?: videoCode).let { viewModel.videoCode = it commentViewModel.code = it binding.videoPlayer.videoCode = it } ViewCompat.setOnApplyWindowInsetsListener(binding.videoPlayer) { v, insets -> val navBar = insets.getInsets(WindowInsetsCompat.Type.statusBars()) v.updateLayoutParams { topMargin = navBar.top } WindowInsetsCompat.CONSUMED } lifecycle.addObserver(OrientationManager(this)) initViewPager() initHKeyframe() if (Preferences.isPipAllowed) initPIP() } override fun bindDataObservers() { lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.CREATED) { viewModel.hanimeVideoStateFlow.collect { state -> when (state) { is VideoLoadingState.Error -> { showShortToast(state.throwable.localizedMessage) if (state.throwable is ParseException) { browse(getHanimeVideoLink(viewModel.videoCode)) } finish() } is VideoLoadingState.Loading -> { } is VideoLoadingState.Success -> { videoTitle = state.info.title if (state.info.videoUrls.isEmpty()) { binding.videoPlayer.startButton.setOnClickListener { showShortToast(R.string.fail_to_get_video_link) browse(getHanimeVideoLink(viewModel.videoCode)) } } else { binding.videoPlayer.setUp( HanimeDataSource(state.info.title, state.info.videoUrls), Jzvd.SCREEN_NORMAL, kernel ) } binding.videoPlayer.posterImageView.load(state.info.coverUrl) { crossfade(true) } // 將觀看記錄保存數據庫 if (!fromDownload) { val entity = WatchHistoryEntity( state.info.coverUrl, state.info.title, state.info.uploadTimeMillis, Clock.System.now().toEpochMilliseconds(), viewModel.videoCode ) viewModel.insertWatchHistoryWithCover(entity) } } is VideoLoadingState.NoContent -> { showShortToast(R.string.video_might_not_exist) finish() } } } } } lifecycleScope.launch { viewModel.observeKeyframe(viewModel.videoCode)?.flowWithLifecycle(lifecycle)?.collect { binding.videoPlayer.hKeyframe = it viewModel.hKeyframes = it } } lifecycleScope.launch { viewModel.modifyHKeyframeFlow.collect { (_, reason) -> showShortToast(reason) } } } override fun onStop() { super.onStop() goOnPlayOnPause() } override fun onDestroy() { super.onDestroy() Jzvd.releaseAllVideos() unregisterReceiver() } override fun onOrientationChanged(orientation: OrientationManager.ScreenOrientation) { if (Jzvd.CURRENT_JZVD != null && (binding.videoPlayer.state == Jzvd.STATE_PLAYING || binding.videoPlayer.state == Jzvd.STATE_PAUSE) && binding.videoPlayer.screen != Jzvd.SCREEN_TINY && Jzvd.FULLSCREEN_ORIENTATION != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ) { if (orientation.isLandscape && binding.videoPlayer.screen == Jzvd.SCREEN_NORMAL) { changeScreenFullLandscape(orientation) } else if (orientation === OrientationManager.ScreenOrientation.PORTRAIT && binding.videoPlayer.screen == Jzvd.SCREEN_FULLSCREEN ) { changeScreenNormal() } } } /** * 竖屏并退出全屏 */ private fun changeScreenNormal() { if (binding.videoPlayer.screen == Jzvd.SCREEN_FULLSCREEN) { binding.videoPlayer.gotoNormalScreen() } } /** * 横屏 */ private fun changeScreenFullLandscape(orientation: OrientationManager.ScreenOrientation) { //从竖屏状态进入横屏 if (binding.videoPlayer.screen != Jzvd.SCREEN_FULLSCREEN) { if (System.currentTimeMillis() - Jzvd.lastAutoFullscreenTime > 2000) { binding.videoPlayer.autoFullscreen(orientation) Jzvd.lastAutoFullscreenTime = System.currentTimeMillis() } } } private fun initViewPager() { binding.videoVp.offscreenPageLimit = 1 binding.videoVp.setUpFragmentStateAdapter(this) { addFragment { VideoIntroductionFragment() } if (!fromDownload) { addFragment { CommentFragment().makeBundle(COMMENT_TYPE to VIDEO_COMMENT_PREFIX) } } } binding.videoTl.attach(binding.videoVp) { tab, position -> tab.setText(tabNameArray[position]) } } private fun initHKeyframe() { binding.videoPlayer.onGoHomeClickListener = { _ -> // singleTask 直接把所有 VideoActivity 都 finish 掉 startActivity() } binding.videoPlayer.onKeyframeClickListener = { v -> binding.videoPlayer.clickHKeyframe(v) } binding.videoPlayer.onKeyframeLongClickListener = { val mi: JZMediaInterface? = binding.videoPlayer.mediaInterface if (mi != null && !mi.isPlaying) { val currentPosition = binding.videoPlayer.currentPositionWhenPlaying it.context.showAlertDialog { setTitle(R.string.add_to_h_keyframe) setMessage(buildString { appendLine(getString(R.string.sure_to_add_to_h_keyframe)) append(getString(R.string.current_position_d_ms, currentPosition)) }) setPositiveButton(R.string.confirm) { _, _ -> viewModel.appendHKeyframe( viewModel.videoCode, videoTitle ?: "Untitled", HKeyframeEntity.Keyframe( position = currentPosition, prompt = null // 這裏不要給太多負擔,保存就行了沒必要寫comment ) ) // 使用到这里说明用户可能是关键H帧目标用户 Firebase.analytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT) { param( FirebaseAnalytics.Param.ITEM_ID, FirebaseConstants.H_KEYFRAMES ) param( FirebaseAnalytics.Param.CONTENT_TYPE, FirebaseConstants.H_KEYFRAMES ) } } setNegativeButton(R.string.cancel, null) } } else { showShortToast(R.string.pause_then_long_press) } } } fun updateVideoPlayerSize(isInPictureInPictureMode: Boolean) { if (binding.videoPlayer.layoutParams !is LinearLayout.LayoutParams) return if (isInPictureInPictureMode) { // 进入画中画模式时,设置视频播放器的布局参数为全屏 // 避免画中画只显示部分画面. val params = binding.videoPlayer.layoutParams as LinearLayout.LayoutParams params.width = MATCH_PARENT params.height = MATCH_PARENT binding.videoPlayer.layoutParams = params } else { // 恢复原来的布局参数 val params = binding.videoPlayer.layoutParams as LinearLayout.LayoutParams params.width = MATCH_PARENT params.height = 250.dp binding.videoPlayer.layoutParams = params } } @Deprecated("Deprecated in android.app.Activity") override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) { super.onPictureInPictureModeChanged(isInPictureInPictureMode) // 当全屏状态进入画中画时 videoPlayer.layoutParams 为 FrameLayout.LayoutParams updateVideoPlayerSize(isInPictureInPictureMode) } private val playbackReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { when (intent.action) { ACTION_PLAY -> binding.videoPlayer.startButton.performClick() ACTION_PAUSE -> goOnPlayOnPause() } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { updatePIPAction() } // 暂停时隐藏UI binding.videoPlayer.topContainer.isVisible = false binding.videoPlayer.bottomContainer.isVisible = false } } private fun registerReceiver() { val filter = IntentFilter().apply { addAction(ACTION_PLAY) addAction(ACTION_PAUSE) } activity?.let { ContextCompat.registerReceiver( it, playbackReceiver, filter, ContextCompat.RECEIVER_EXPORTED ) } } private fun unregisterReceiver() { try { unregisterReceiver(playbackReceiver) } catch (e: IllegalArgumentException) { Log.w("VideoActivity", "Receiver not registered: $e") } } @RequiresApi(Build.VERSION_CODES.O) private fun updatePIPAction() { val (iconRes, titleRes, actionRes) = if (binding.videoPlayer.state == Jzvd.STATE_PLAYING) { Triple(R.drawable.pause_circle_24px, R.string.pause, ACTION_PAUSE) } else { Triple(R.drawable.play_circle_24px, R.string.continues, ACTION_PLAY) } val pauseIntent = PendingIntent.getBroadcast( activity, 0, Intent(actionRes).setPackage(activity?.packageName), PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) val action = RemoteAction( Icon.createWithResource(activity, iconRes), getString(titleRes), getString(titleRes), pauseIntent ) builder?.setActions(listOf(action)) } private fun initPIP() { registerReceiver() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val aspectRatio = Rational(16, 9) binding.videoPlayer.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> val sourceRectHint = Rect() binding.videoPlayer.getGlobalVisibleRect(sourceRectHint) builder = PictureInPictureParams.Builder() .setAspectRatio(aspectRatio) .setSourceRectHint(sourceRectHint) updatePIPAction() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { builder?.setAutoEnterEnabled(true) } setPictureInPictureParams(builder!!.build()) } } } override fun onUserLeaveHint() { super.onUserLeaveHint() if (Preferences.isPipAllowed) { enterPictureInPictureMode() } } fun showRedDotCount(count: Int) { binding.videoTl.getOrCreateBadgeOnTextViewAt( tabNameArray.indexOf(R.string.comment), null, Gravity.START, 2.dp ) { isVisible = count > 0 number = count } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/AdapterLikeDataBindingPage.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import androidx.databinding.ViewDataBinding /** * 利用 Adapter 性质的页面,同时运用 DataBinding */ interface AdapterLikeDataBindingPage { var binding: DB? } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/BaseSingleDifferAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import androidx.recyclerview.widget.AsyncDifferConfig import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import com.chad.library.adapter4.BaseDifferAdapter import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine /** * @project Han1meViewer * @author Yenaly Liew * @time 2024/04/05 005 20:44 */ abstract class BaseSingleDifferAdapter : BaseDifferAdapter { private constructor(config: AsyncDifferConfig, items: List) : super(config, items) constructor(diffCallback: DiffUtil.ItemCallback) : this( AsyncDifferConfig.Builder(diffCallback).build(), emptyList() ) constructor(diffCallback: DiffUtil.ItemCallback, item: T) : this( AsyncDifferConfig.Builder(diffCallback).build(), listOf(item) ) constructor(config: AsyncDifferConfig) : this(config, emptyList()) constructor(config: AsyncDifferConfig, item: T) : this(config, listOf(item)) var item: T? get() = items.firstOrNull() set(value) { items = if (value != null) listOf(value) else emptyList() } suspend fun submit(item: T?) = suspendCoroutine { cont -> val list = item?.let(::listOf).orEmpty() submitList(list) { cont.resume(Unit) } } protected abstract fun onBindViewHolder(holder: VH, item: T?) open fun onBindViewHolder(holder: VH, item: T?, payloads: List) { onBindViewHolder(holder, item) } final override fun onBindViewHolder(holder: VH, position: Int, item: T?) { onBindViewHolder(holder, item) } final override fun onBindViewHolder(holder: VH, position: Int, item: T?, payloads: List) { onBindViewHolder(holder, item, payloads) } override fun add(data: T) { throw RuntimeException("Please use setItem()") } override fun add(position: Int, data: T) { throw RuntimeException("Please use setItem()") } override fun addAll(collection: Collection) { throw RuntimeException("Please use setItem()") } override fun addAll(position: Int, collection: Collection) { throw RuntimeException("Please use setItem()") } override fun remove(data: T) { throw RuntimeException("Please use setItem()") } override fun removeAtRange(range: IntRange) { throw RuntimeException("Please use setItem()") } override fun removeAt(position: Int) { throw RuntimeException("Please use setItem()") } override fun set(position: Int, data: T) { throw RuntimeException("Please use setItem()") } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/FixedGridLayoutManager.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import androidx.recyclerview.widget.GridLayoutManager /** * @project Han1meViewer * @author Yenaly Liew * @time 2022/09/10 010 00:24 */ class FixedGridLayoutManager( context: Context?, spanCount: Int ) : GridLayoutManager(context, spanCount) { override fun supportsPredictiveItemAnimations(): Boolean { return false } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HKeyframesRvAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import android.util.Base64 import android.view.View import android.view.ViewGroup import android.widget.ImageButton import android.widget.TextView import androidx.core.text.method.LinkMovementMethodCompat import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import cn.jzvd.JZUtils import com.chad.library.adapter4.BaseDifferAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.google.android.material.button.MaterialButton import com.itxca.spannablex.spannable import com.lxj.xpopup.XPopup import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.VIDEO_CODE import com.yenaly.han1meviewer.logic.entity.HKeyframeEntity import com.yenaly.han1meviewer.ui.activity.SettingsActivity import com.yenaly.han1meviewer.ui.activity.VideoActivity import com.yenaly.han1meviewer.util.showAlertDialog import com.yenaly.yenaly_libs.utils.activity import com.yenaly.yenaly_libs.utils.copyToClipboard import com.yenaly.yenaly_libs.utils.encodeToStringByBase64 import com.yenaly.yenaly_libs.utils.showShortToast import com.yenaly.yenaly_libs.utils.startActivity import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/26 026 17:42 */ class HKeyframesRvAdapter : BaseDifferAdapter(COMPARATOR) { init { isStateViewEnable = true } companion object { val COMPARATOR = object : DiffUtil.ItemCallback() { override fun areItemsTheSame( oldItem: HKeyframeEntity, newItem: HKeyframeEntity, ) = oldItem.videoCode == newItem.videoCode override fun areContentsTheSame( oldItem: HKeyframeEntity, newItem: HKeyframeEntity, ) = oldItem == newItem } private val editResArray = intArrayOf(R.string.edit, R.string.delete, R.string.share) private val editResIconArray = intArrayOf( R.drawable.baseline_edit_24, R.drawable.ic_baseline_delete_24, R.drawable.ic_baseline_share_24 ) } override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: HKeyframeEntity?) { item ?: return holder.setText(R.id.tv_title, item.title) holder.setGone(R.id.btn_edit, item.author != null) holder.getView(R.id.tv_video_code).apply { movementMethod = LinkMovementMethodCompat.getInstance() text = spannable { context.getString(R.string.h_keyframe_title_prefix).text() item.videoCode.span { clickable(color = context.getColor(R.color.video_code_link_text_color)) { _, videoCode -> context.activity?.startActivity(VIDEO_CODE to videoCode) } underline() } } } holder.getView(R.id.rv_h_keyframe).apply { layoutManager = LinearLayoutManager(context) adapter = HKeyframeRvAdapter(item.videoCode, item).apply { isLocal = item.author == null } } } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): QuickViewHolder { return QuickViewHolder(R.layout.item_h_keyframes, parent).also { viewHolder -> viewHolder.getView(R.id.btn_edit).apply { setOnClickListener { view -> val position = viewHolder.bindingAdapterPosition val item = getItem(position) ?: return@setOnClickListener XPopup.Builder(view.context).atView(view).isDarkTheme(true).asAttachList( editResArray.map(view.context::getString).toTypedArray(), editResIconArray ) { pos, _ -> when (pos) { 0 -> modify(item) // 修改 1 -> delete(item) // 刪除 2 -> share(item) // 分享 } }.show() } } } } private fun share(item: HKeyframeEntity) { val toJson = Json.encodeToString(item) val toBase64 = toJson.encodeToStringByBase64(flag = Base64.NO_WRAP) val toContent = buildString { append(">>>") append(toBase64) append("<<<") } context.showAlertDialog { setTitle(R.string.share_to_others) setMessage(context.getString(R.string.share_to_others_tip, toContent)) setPositiveButton(R.string.copy_) { _, _ -> toContent.copyToClipboard() showShortToast(R.string.copy_to_clipboard) } setNegativeButton(R.string.cancel, null) } } private fun delete(item: HKeyframeEntity) { val activity = context if (activity is SettingsActivity) { activity.showAlertDialog { setTitle(R.string.sure_to_delete) setMessage(item.title) setPositiveButton(R.string.confirm) { _, _ -> activity.viewModel.deleteHKeyframes(item) } setNegativeButton(R.string.cancel, null) } } } private fun modify(item: HKeyframeEntity) { val activity = context if (activity is SettingsActivity) { val view = View.inflate(activity, R.layout.dialog_modify_h_keyframes, null) val etTitle = view.findViewById(R.id.et_title) val etVideoCode = view.findViewById(R.id.et_video_code) etTitle.text = item.title etVideoCode.text = item.videoCode activity.showAlertDialog { setTitle(R.string.modify_h_keyframe) setView(view) setPositiveButton(R.string.confirm) { _, _ -> val title = etTitle.text.toString() activity.viewModel.updateHKeyframes(item.copy(title = title)) } setNegativeButton(R.string.cancel, null) } } } } /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/26 026 17:42 */ class HKeyframeRvAdapter( private val videoCode: String, keyframe: HKeyframeEntity? = null, ) : BaseDifferAdapter( COMPARATOR, keyframe?.keyframes.orEmpty() ) { init { isStateViewEnable = true } /** * 是否是本地关键帧 * * @return false if is shared, true otherwise. */ var isLocal: Boolean = true var isShared: Boolean = false companion object { val COMPARATOR = object : DiffUtil.ItemCallback() { override fun areItemsTheSame( oldItem: HKeyframeEntity.Keyframe, newItem: HKeyframeEntity.Keyframe, ) = oldItem.position == newItem.position override fun areContentsTheSame( oldItem: HKeyframeEntity.Keyframe, newItem: HKeyframeEntity.Keyframe, ) = oldItem == newItem } } override fun onBindViewHolder( holder: QuickViewHolder, position: Int, item: HKeyframeEntity.Keyframe?, ) { item ?: return holder.setText(R.id.tv_keyframe, JZUtils.stringForTime(item.position)) holder.setText(R.id.tv_index, "#${holder.bindingAdapterPosition + 1}") holder.setGone(R.id.btn_delete, !isLocal) holder.setGone(R.id.btn_edit, !isLocal) if (!item.prompt.isNullOrBlank()) { holder.setGone(R.id.tv_prompt, false) holder.setText(R.id.tv_prompt, "➥ " + item.prompt) } else { holder.setGone(R.id.tv_prompt, true) } } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): QuickViewHolder { return QuickViewHolder(R.layout.item_h_keyframe, parent).also { viewHolder -> if (isShared) return@also viewHolder.getView(R.id.btn_edit).apply { setOnClickListener { val position = viewHolder.bindingAdapterPosition val item = getItem(position) ?: return@setOnClickListener val view = View.inflate(context, R.layout.dialog_modify_h_keyframe, null) val etPrompt = view.findViewById(R.id.et_prompt) val etPosition = view.findViewById(R.id.et_position) etPrompt.text = item.prompt etPosition.text = item.position.toString() context.showAlertDialog { setTitle(R.string.modify_h_keyframe) setView(view) setPositiveButton(R.string.confirm) { _, _ -> val prompt = etPrompt.text.toString() val pos = etPosition.text.toString().toLong() when (context) { is SettingsActivity -> { context.viewModel.modifyHKeyframe( videoCode, item, HKeyframeEntity.Keyframe( position = pos, prompt = prompt ) ) showShortToast(R.string.modify_success) } is VideoActivity -> { context.viewModel.modifyHKeyframe( videoCode, item, HKeyframeEntity.Keyframe( position = pos, prompt = prompt ) ) // showShortToast("修改成功") // 這裏不用提示,因為 VideoActivity 有 Flow 操控 } } } setNegativeButton(R.string.cancel, null) } } } viewHolder.getView(R.id.btn_delete).apply { setOnClickListener { val position = viewHolder.bindingAdapterPosition val item = getItem(position) ?: return@setOnClickListener it.context.showAlertDialog { setTitle(R.string.sure_to_delete) setMessage(JZUtils.stringForTime(item.position)) setPositiveButton(R.string.confirm) { _, _ -> when (context) { is SettingsActivity -> { context.viewModel.removeHKeyframe(videoCode, item) showShortToast(R.string.delete_success) } is VideoActivity -> { context.viewModel.removeHKeyframe(videoCode, item) // showShortToast("刪除成功") // 這裏不用提示,因為 VideoActivity 有 Flow 操控 } } } setNegativeButton(R.string.cancel, null) } } } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HRvItemAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.view.View import android.view.ViewGroup import android.widget.LinearLayout import androidx.annotation.StringRes import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.ViewHolder import com.yenaly.han1meviewer.ui.adapter.RvWrapper.Companion.wrappedWith class HRvItemAdapter( private val titleAdapter: VideoColumnTitleAdapter, private val contentAdapter: RvWrapper, ): RecyclerView.Adapter() { class HLinearLayoutViewHolder(val linearLayout: LinearLayout) : ViewHolder(linearLayout) companion object { fun RecyclerView.Adapter<*>.withTitleSection( @StringRes titleResId: Int, onMoreListener: (View) -> Unit ): HRvItemAdapter { val titleAdapter = VideoColumnTitleAdapter(titleResId).apply { onMoreHanimeListener = onMoreListener } val contentAdapter = this.wrappedWith { LinearLayoutManager(null, LinearLayoutManager.HORIZONTAL, false) } return HRvItemAdapter(titleAdapter, contentAdapter) } } override fun onCreateViewHolder( parent: ViewGroup, viewType: Int ): ViewHolder { val linearLayout = LinearLayout(parent.context).apply { layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT ) orientation = LinearLayout.VERTICAL isNestedScrollingEnabled = false } return HLinearLayoutViewHolder(linearLayout) } override fun onBindViewHolder( holder: ViewHolder, position: Int ) { val linearLayout = (holder as HLinearLayoutViewHolder).linearLayout linearLayout.removeAllViews() val titleRecyclerView = RecyclerView(linearLayout.context).apply { layoutParams = LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT ) adapter = titleAdapter layoutManager = LinearLayoutManager(context) isNestedScrollingEnabled = false } linearLayout.addView(titleRecyclerView) val contentRecyclerView = RecyclerView(linearLayout.context).apply { layoutParams = LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT ) adapter = contentAdapter layoutManager = LinearLayoutManager(context) isNestedScrollingEnabled = false } linearLayout.addView(contentRecyclerView) } override fun getItemCount(): Int = 1 } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HSearchTagAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import android.text.TextUtils import android.view.ViewGroup import com.chad.library.adapter4.BaseQuickAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.google.android.material.checkbox.MaterialCheckBox import com.yenaly.han1meviewer.logic.model.SearchOption class HSearchTagAdapter : BaseQuickAdapter() { val checkedSet = mutableSetOf() override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: SearchOption?) { item ?: return val chip = holder.itemView as MaterialCheckBox chip.isChecked = item in checkedSet chip.text = item.value } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int ): QuickViewHolder { val checkBox = MaterialCheckBox(context).apply { maxLines = 2 ellipsize = TextUtils.TruncateAt.END } return QuickViewHolder(checkBox).apply { checkBox.setOnCheckedChangeListener { _, isChecked -> val position = bindingAdapterPosition getItem(position)?.let { item -> if (isChecked) { checkedSet += item } else { checkedSet -= item } } } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HSubscriptionAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import android.view.View import android.view.ViewGroup import android.widget.CheckBox import android.widget.ImageView import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.recyclerview.widget.DiffUtil import coil.load import coil.transform.CircleCropTransformation import com.chad.library.adapter4.BaseDifferAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.logic.model.Subscription import com.yenaly.han1meviewer.ui.activity.SearchActivity import com.yenaly.han1meviewer.util.showAlertDialog class HSubscriptionAdapter : BaseDifferAdapter(COMPARATOR) { companion object { const val DELETE = 1 const val CHECK = 1 shl 1 } private object COMPARATOR : DiffUtil.ItemCallback() { override fun areItemsTheSame(oldItem: Subscription, newItem: Subscription): Boolean { return oldItem.name == newItem.name } override fun areContentsTheSame(oldItem: Subscription, newItem: Subscription): Boolean { return oldItem == newItem } override fun getChangePayload(oldItem: Subscription, newItem: Subscription): Int { var bitmap = 0 if (oldItem.isDeleteVisible != newItem.isDeleteVisible) { bitmap = bitmap or DELETE } return bitmap } } override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: Subscription?) { item ?: return val context = this.context if (context is SearchActivity) { holder.getView(R.id.cb_select).apply { isVisible = item.name == context.viewModel.subscriptionBrand isChecked = isVisible } holder.getView(R.id.btn_delete).isVisible = item.isDeleteVisible } holder.setText(R.id.tv_artist, item.name) holder.getView(R.id.iv_artist).apply { load(item.avatarUrl) { crossfade(true) transformations(CircleCropTransformation()) } } } override fun onBindViewHolder( holder: QuickViewHolder, position: Int, item: Subscription?, payloads: List ) { item ?: return if (payloads.isEmpty()) { onBindViewHolder(holder, position, item) return } val payload = payloads.first() as Int if (payload and DELETE != 0) { holder.getView(R.id.btn_delete).isVisible = item.isDeleteVisible holder.getView(R.id.cb_select).isVisible = item.isCheckBoxVisible } if (payload and CHECK != 0) { val context = this.context if (context is SearchActivity) { holder.getView(R.id.cb_select).apply { isVisible = item.name == context.viewModel.subscriptionBrand isChecked = isVisible } } } } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int ): QuickViewHolder { return QuickViewHolder(R.layout.item_h_subscription, parent).apply { itemView.setOnClickListener { val position = bindingAdapterPosition val item = getItem(position) ?: return@setOnClickListener if (item.isDeleteVisible) return@setOnClickListener getView(R.id.cb_select).apply { if (isChecked) { isVisible = false isChecked = false if (context is SearchActivity) { context.viewModel.subscriptionBrand = null context.setSearchText(null) notifyItemChanged(position, CHECK) } } else { isVisible = true isChecked = true if (context is SearchActivity) { context.viewModel.subscriptionBrand = item.name context.setSearchText(item.name, canTextChange = false) notifyItemRangeChanged(0, itemCount, CHECK) } } } } itemView.setOnLongClickListener { if (context is SearchActivity) { val btnDelete = getView(R.id.btn_delete) if (btnDelete.isGone) { submitList(items.map { it.copy( isDeleteVisible = true, isCheckBoxVisible = false ) }) } else { submitList(items.map { it.copy( isDeleteVisible = false, isCheckBoxVisible = it.name == context.viewModel.subscriptionBrand ) }) } } true } getView(R.id.btn_delete).setOnClickListener { val position = bindingAdapterPosition val item = getItem(position) ?: return@setOnClickListener context.showAlertDialog { setTitle(R.string.sure_to_delete) setMessage(context.getString(R.string.sure_to_delete_s, item.name)) setPositiveButton(R.string.confirm) { _, _ -> if (context is SearchActivity) { context.myListViewModel.subscription.deleteSubscription( item.artistId, position ) } } setNegativeButton(R.string.cancel, null) } } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HanimeDownloadedRvAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import android.graphics.RenderEffect import android.graphics.Shader import android.os.Build import android.view.LayoutInflater import android.view.ViewGroup import androidx.core.net.toFile import androidx.core.net.toUri import androidx.core.view.updateLayoutParams import androidx.recyclerview.widget.DiffUtil import com.chad.library.adapter4.BaseDifferAdapter import com.chad.library.adapter4.viewholder.DataBindingHolder import com.yenaly.han1meviewer.HFileManager import com.yenaly.han1meviewer.LOCAL_DATE_TIME_FORMAT import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.VIDEO_CODE import com.yenaly.han1meviewer.databinding.ItemHanimeDownloadedBinding import com.yenaly.han1meviewer.logic.entity.download.VideoWithCategories import com.yenaly.han1meviewer.ui.activity.VideoActivity import com.yenaly.han1meviewer.ui.fragment.home.download.DownloadedFragment import com.yenaly.han1meviewer.util.HImageMeower.loadUnhappily import com.yenaly.han1meviewer.util.MediaUtils import com.yenaly.han1meviewer.util.openDownloadedHanimeVideoInActivity import com.yenaly.han1meviewer.util.showAlertDialog import com.yenaly.yenaly_libs.utils.activity import com.yenaly.yenaly_libs.utils.dpF import com.yenaly.yenaly_libs.utils.formatFileSizeV2 import com.yenaly.yenaly_libs.utils.startActivity import kotlinx.datetime.Instant import kotlinx.datetime.TimeZone import kotlinx.datetime.format import kotlinx.datetime.toLocalDateTime /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/26 026 16:57 */ class HanimeDownloadedRvAdapter(private val fragment: DownloadedFragment) : BaseDifferAdapter>( COMPARATOR ) { init { isStateViewEnable = true } companion object { val COMPARATOR = object : DiffUtil.ItemCallback() { override fun areContentsTheSame( oldItem: VideoWithCategories, newItem: VideoWithCategories, ): Boolean { return oldItem == newItem } override fun areItemsTheSame( oldItem: VideoWithCategories, newItem: VideoWithCategories, ): Boolean { return oldItem.video.id == newItem.video.id } } } override fun onBindViewHolder( holder: DataBindingHolder, position: Int, item: VideoWithCategories?, ) { item ?: return holder.binding.tvTitle.text = item.video.title holder.binding.tvVideoCode.text = item.video.videoCode holder.binding.ivCover.loadUnhappily(item.video.coverUri, item.video.coverUrl) holder.itemView.post { // fast path if (holder.itemView.height == holder.binding.vCoverBg.height) return@post holder.binding.vCoverBg.updateLayoutParams { height = holder.itemView.height } holder.binding.ivCoverBg.updateLayoutParams { height = holder.itemView.height } } holder.binding.ivCoverBg.apply { loadUnhappily(item.video.coverUri, item.video.coverUrl) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { setRenderEffect( RenderEffect.createBlurEffect( 8.dpF, 8.dpF, Shader.TileMode.CLAMP ) ) } } holder.binding.tvAddedTime.text = Instant.fromEpochMilliseconds(item.video.addDate).toLocalDateTime( TimeZone.currentSystemDefault() ).format(LOCAL_DATE_TIME_FORMAT) val realSize = item.video.videoUri.toUri().toFile().length() holder.binding.tvSize.text = if (realSize == 0L) { "???" } else { item.video.length.formatFileSizeV2() } holder.binding.tvQuality.text = item.video.quality } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): DataBindingHolder { return DataBindingHolder( ItemHanimeDownloadedBinding.inflate( LayoutInflater.from(context), parent, false ) ).also { viewHolder -> viewHolder.itemView.setOnClickListener { val position = viewHolder.bindingAdapterPosition val item = getItem(position) ?: return@setOnClickListener context.activity?.startActivity(VIDEO_CODE to item.video.videoCode) } viewHolder.binding.btnDelete.setOnClickListener { val position = viewHolder.bindingAdapterPosition // #issue-158: 这里可能为空 val item = getItem(position) item?.let { context.showAlertDialog { setTitle(R.string.sure_to_delete) setMessage(context.getString(R.string.prepare_to_delete_s, it.video.title)) setPositiveButton(R.string.confirm) { _, _ -> // if (file.exists()) file.delete() HFileManager.getDownloadVideoFolder( it.video.videoCode ).deleteRecursively() fragment.viewModel.deleteDownloadHanimeBy( it.video.videoCode, it.video.quality ) } setNegativeButton(R.string.cancel, null) } } } viewHolder.binding.btnLocalPlayback.setOnClickListener { val position = viewHolder.bindingAdapterPosition val item = getItem(position) ?: return@setOnClickListener // context.openDownloadedHanimeVideoLocally(item.video.videoUri, onFileNotFound = { // context.showAlertDialog { // setTitle(R.string.video_not_exist) // setMessage(R.string.video_deleted_sure_to_delete_item) // setPositiveButton(R.string.delete) { _, _ -> // fragment.viewModel.deleteDownloadHanimeBy( // item.video.videoCode, // item.video.quality // ) // } // setNegativeButton(R.string.cancel, null) // } // }) context.openDownloadedHanimeVideoInActivity(item.video.videoCode) } viewHolder.binding.btnExternalPlayback.setOnClickListener { val position = viewHolder.bindingAdapterPosition val item = getItem(position) ?: return@setOnClickListener MediaUtils.playMedia(context, item.video.videoUri) } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HanimeDownloadingRvAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.animation.ValueAnimator import android.annotation.SuppressLint import android.content.Context import android.graphics.RenderEffect import android.graphics.Shader import android.os.Build import android.util.Log import android.view.LayoutInflater import android.view.ViewGroup import androidx.annotation.RequiresApi import androidx.core.view.updateLayoutParams import androidx.interpolator.view.animation.FastOutSlowInInterpolator import androidx.recyclerview.widget.DiffUtil import com.chad.library.adapter4.BaseDifferAdapter import com.chad.library.adapter4.viewholder.DataBindingHolder import com.google.android.material.button.MaterialButton import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.databinding.ItemHanimeDownloadingBinding import com.yenaly.han1meviewer.logic.entity.download.HanimeDownloadEntity import com.yenaly.han1meviewer.logic.state.DownloadState import com.yenaly.han1meviewer.ui.fragment.home.download.DownloadingFragment import com.yenaly.han1meviewer.util.HImageMeower.loadUnhappily import com.yenaly.han1meviewer.util.addUpdateListener import com.yenaly.han1meviewer.util.setStateViewLayout import com.yenaly.han1meviewer.util.showAlertDialog import com.yenaly.han1meviewer.worker.HanimeDownloadManagerV2 import com.yenaly.han1meviewer.worker.HanimeDownloadWorker import com.yenaly.yenaly_libs.utils.dpF import com.yenaly.yenaly_libs.utils.formatFileSizeV2 import com.yenaly.yenaly_libs.utils.logFieldsChange import java.lang.ref.WeakReference /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/26 026 17:05 */ class HanimeDownloadingRvAdapter(private val fragment: DownloadingFragment) : BaseDifferAdapter>( COMPARATOR ) { init { isStateViewEnable = true } companion object { const val TAG = "HanimeDownloadingRvAdapter" private val interpolator = FastOutSlowInInterpolator() private const val DOWNLOADING = 1 private const val STATE = 1 shl 1 private const val PROGRESS = 1 shl 2 val COMPARATOR = object : DiffUtil.ItemCallback() { override fun areContentsTheSame( oldItem: HanimeDownloadEntity, newItem: HanimeDownloadEntity, ): Boolean { return oldItem == newItem } override fun areItemsTheSame( oldItem: HanimeDownloadEntity, newItem: HanimeDownloadEntity, ): Boolean { return oldItem.id == newItem.id } override fun getChangePayload( oldItem: HanimeDownloadEntity, newItem: HanimeDownloadEntity, ): Any { logFieldsChange(TAG, oldItem, newItem) var bitset = 0 if (oldItem.downloadedLength != newItem.downloadedLength) bitset = bitset or DOWNLOADING if (oldItem.state != newItem.state) bitset = bitset or STATE if (oldItem.progress != newItem.progress) bitset = bitset or PROGRESS return bitset } } } @SuppressLint("SetTextI18n") override fun onBindViewHolder( holder: DataBindingHolder, position: Int, item: HanimeDownloadEntity?, ) { item ?: return holder.binding.tvTitle.text = item.title holder.binding.ivCover.loadUnhappily(item.coverUri, item.coverUrl) Log.d(TAG, "调用 load") holder.itemView.post { holder.binding.vCoverBg.updateLayoutParams { height = holder.itemView.height } holder.binding.ivCoverBg.updateLayoutParams { height = holder.itemView.height } } holder.binding.clProgress.post { holder.binding.vProgress.updateLayoutParams { width = holder.binding.clProgress.width * item.progress / 100 } } holder.binding.ivCoverBg.apply { loadUnhappily(item.coverUri, item.coverUrl) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { val renderEffect = RenderEffect.createBlurEffect( 8.dpF, 8.dpF, Shader.TileMode.CLAMP ) setRenderEffect(renderEffect) } } holder.binding.tvDownloadedSize.text = item.downloadedLength.formatFileSizeV2() holder.binding.tvSize.text = item.length.formatFileSizeV2() holder.binding.tvQuality.text = item.quality // holder.binding.tvProgress.text = "${item.progress}%" // holder.binding.pbProgress.setProgress(item.progress, true) holder.binding.btnStart.handleStartButton(item) } @SuppressLint("SetTextI18n") override fun onBindViewHolder( holder: DataBindingHolder, position: Int, item: HanimeDownloadEntity?, payloads: List, ) { if (payloads.isEmpty() || payloads.first() == 0) return super.onBindViewHolder(holder, position, item, payloads) item ?: return val bitset = payloads.first() as Int if (bitset and DOWNLOADING != 0) { holder.binding.btnStart.handleStartButton(item) holder.binding.tvDownloadedSize.text = item.downloadedLength.formatFileSizeV2() } if (bitset and STATE != 0) { holder.binding.btnStart.handleStartButton(item) } if (bitset and PROGRESS != 0) { // holder.binding.tvProgress.text = "${item.progress}%" // holder.binding.pbProgress.setProgress(item.progress, true) // 根据百分比,设置 vProgress 的宽度,比如 50% 就设置成 itemView 50% 的宽度 val weakViewProgress = WeakReference(holder.binding.vProgress) ValueAnimator.ofInt( holder.binding.vProgress.width, holder.itemView.width * item.progress / 100 ).apply { // must be less than HanimeDownloadWorker.RESPONSE_INTERVAL duration = 300L.coerceAtMost(HanimeDownloadWorker.RESPONSE_INTERVAL) interpolator = HanimeDownloadingRvAdapter.interpolator addUpdateListener(fragment) { weakViewProgress.get()?.updateLayoutParams { width = it.animatedValue as Int } } }.start() } } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): DataBindingHolder { return DataBindingHolder( ItemHanimeDownloadingBinding.inflate( LayoutInflater.from(context), parent, false ) ).also { viewHolder -> viewHolder.binding.btnStart.setOnClickListener { val pos = viewHolder.bindingAdapterPosition val item = getItem(pos) ?: return@setOnClickListener // val isDownloading: Boolean if (item.isDownloading) { // isDownloading = false // cancelUniqueWorkAndPause(item.copy(isDownloading = false)) HanimeDownloadManagerV2.stopTask(item) } else { // isDownloading = true // continueWork(item.copy(isDownloading = true)) HanimeDownloadManagerV2.resumeTask(item) } viewHolder.binding.btnStart.handleStartButton(item, rotate = true) } viewHolder.binding.btnCancel.setOnClickListener { val pos = viewHolder.bindingAdapterPosition val item = getItem(pos) ?: return@setOnClickListener context.showAlertDialog { setTitle(R.string.sure_to_delete) setMessage( context.getString(R.string.prepare_to_delete_s, item.title) ) setPositiveButton(R.string.confirm) { _, _ -> // cancelUniqueWorkAndDelete(item) HanimeDownloadManagerV2.deleteTask(item) } setNegativeButton(R.string.cancel, null) } } } } @SuppressLint("SetTextI18n") private fun MaterialButton.handleStartButton( item: HanimeDownloadEntity, rotate: Boolean = false ) { val state = if (rotate) { when (item.state) { DownloadState.Unknown, DownloadState.Queued, DownloadState.Paused -> DownloadState.Downloading DownloadState.Downloading -> DownloadState.Paused DownloadState.Finished, DownloadState.Failed -> DownloadState.Unknown } } else { item.state } when (state) { DownloadState.Queued -> { setText(R.string.already_in_queue) setIconResource(R.drawable.ic_baseline_play_arrow_24) } DownloadState.Downloading -> { // setText(R.string.pause) // setIconResource(R.drawable.ic_baseline_pause_24) text = "${item.progress}%" setIconResource(R.drawable.ic_baseline_pause_24) } DownloadState.Paused -> { setText(R.string.continues) setIconResource(R.drawable.ic_baseline_play_arrow_24) } DownloadState.Failed -> { setText(R.string.retry) setIconResource(R.drawable.baseline_error_outline_24) } DownloadState.Finished, DownloadState.Unknown -> {} // do nothing } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HanimeMyListVideoAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import coil.load import com.chad.library.adapter4.BaseDifferAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.VIDEO_CODE import com.yenaly.han1meviewer.VideoCoverSize import com.yenaly.han1meviewer.logic.model.HanimeInfo import com.yenaly.han1meviewer.ui.activity.VideoActivity import com.yenaly.yenaly_libs.utils.activity import com.yenaly.yenaly_libs.utils.startActivity /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/26 026 16:38 */ class HanimeMyListVideoAdapter : BaseDifferAdapter(COMPARATOR) { init { isStateViewEnable = true } companion object { val COMPARATOR = object : DiffUtil.ItemCallback() { override fun areItemsTheSame( oldItem: HanimeInfo, newItem: HanimeInfo, ): Boolean { return oldItem.videoCode == newItem.videoCode } override fun areContentsTheSame( oldItem: HanimeInfo, newItem: HanimeInfo, ): Boolean { return oldItem == newItem } } } override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: HanimeInfo?) { item ?: return holder.getView(R.id.title).text = item.title holder.getView(R.id.cover).load(item.coverUrl) { crossfade(true) } } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): QuickViewHolder { return QuickViewHolder(R.layout.item_hanime_video_simplified, parent).also { viewHolder -> viewHolder.getView(R.id.frame).layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT ) viewHolder.getView(R.id.cover).scaleType = ImageView.ScaleType.CENTER_CROP viewHolder.itemView.apply { setOnClickListener { val position = viewHolder.bindingAdapterPosition val item = getItem(position) ?: return@setOnClickListener val videoCode = item.videoCode context.activity?.startActivity(VIDEO_CODE to videoCode) } // setOnLongClickListener 由各自的 Fragment 实现 } with(VideoCoverSize.Simplified) { viewHolder.getView(R.id.cover_wrapper).resizeForVideoCover() } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HanimePreviewNewsRvAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import android.view.LayoutInflater import android.view.ViewGroup import android.widget.ImageView import androidx.recyclerview.widget.LinearLayoutManager import coil.load import com.chad.library.adapter4.BaseQuickAdapter import com.chad.library.adapter4.viewholder.DataBindingHolder import com.chad.library.adapter4.viewholder.QuickViewHolder import com.lxj.xpopup.XPopup import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.VIDEO_CODE import com.yenaly.han1meviewer.databinding.ItemHanimePreviewNewsV2Binding import com.yenaly.han1meviewer.logic.model.HanimePreview import com.yenaly.han1meviewer.ui.activity.PreviewActivity import com.yenaly.han1meviewer.ui.activity.VideoActivity import com.yenaly.han1meviewer.ui.popup.CoilImageLoader import com.yenaly.han1meviewer.ui.view.BlurTransformation import com.yenaly.yenaly_libs.utils.startActivity /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/26 026 16:48 */ class HanimePreviewNewsRvAdapter : BaseQuickAdapter>() { init { isStateViewEnable = true } private val imageLoader = CoilImageLoader() override fun onBindViewHolder( holder: DataBindingHolder, position: Int, item: HanimePreview.PreviewInfo?, ) { item ?: return holder.binding.ivCoverBig.load(item.coverUrl) { crossfade(true) transformations(BlurTransformation(context)) } holder.binding.tvTitle.text = item.title holder.binding.tvIntroduction.text = item.introduction holder.binding.tvBrand.text = item.brand holder.binding.tvReleaseDate.text = item.releaseDate holder.binding.tvVideoTitle.text = item.videoTitle holder.binding.tags.tags = item.tags holder.binding.rvPreview.apply { layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) adapter = PreviewPicRvAdapter(item) } } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): DataBindingHolder { return DataBindingHolder( ItemHanimePreviewNewsV2Binding.inflate( LayoutInflater.from(context), parent, false ) ).also { viewHolder -> viewHolder.binding.tags.lifecycle = (context as? PreviewActivity)?.lifecycle viewHolder.binding.tags.isCollapsedEnabled = true viewHolder.itemView.apply { setOnClickListener { val position = viewHolder.bindingAdapterPosition val item = getItem(position) ?: return@setOnClickListener if (context is PreviewActivity) { context.startActivity(VIDEO_CODE to item.videoCode) } } } } } private inner class PreviewPicRvAdapter(private val item: HanimePreview.PreviewInfo) : BaseQuickAdapter(item.relatedPicsUrl) { override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: String?) { holder.getView(R.id.iv_preview_news_pic).load(item) { crossfade(true) } } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): QuickViewHolder { return QuickViewHolder( R.layout.item_hanime_preview_news_pic, parent ).also { viewHolder -> viewHolder.itemView.setOnClickListener { val position = viewHolder.bindingAdapterPosition XPopup.Builder(context).asImageViewer( it as? ImageView, position, item.relatedPicsUrl, { popupView, pos -> popupView.updateSrcView(recyclerView.getChildAt(pos) as? ImageView) }, imageLoader ).show() } } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HanimePreviewTourRvAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import android.view.ViewGroup import android.widget.ImageView import coil.load import com.chad.library.adapter4.BaseDifferAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.lxj.xpopup.XPopup import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.logic.model.HanimeInfo import com.yenaly.han1meviewer.ui.popup.CoilImageLoader /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/29 029 20:11 */ class HanimePreviewTourRvAdapter : BaseDifferAdapter( HanimeVideoRvAdapter.COMPARATOR ) { private val imageLoader = CoilImageLoader() override fun onBindViewHolder( holder: QuickViewHolder, position: Int, item: HanimeInfo?, ) { holder.getView(R.id.cover).load(item?.coverUrl) { crossfade(true) } } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): QuickViewHolder { return QuickViewHolder(R.layout.item_preview_tour_simplified, parent).also { viewHolder -> viewHolder.itemView.setOnLongClickListener { val position = viewHolder.bindingAdapterPosition val urlList = items.map { it.coverUrl } XPopup.Builder(context).asImageViewer( viewHolder.getView(R.id.cover), position, urlList, { popupView, pos -> popupView.updateSrcView(recyclerView.getChildAt(pos) as? ImageView) }, imageLoader ).show() return@setOnLongClickListener true } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HanimeSearchHistoryRvAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import com.chad.library.adapter4.BaseDifferAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.logic.entity.SearchHistoryEntity /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/26 026 16:42 */ class HanimeSearchHistoryRvAdapter : BaseDifferAdapter(COMPARATOR) { init { isStateViewEnable = true } companion object { val COMPARATOR = object : DiffUtil.ItemCallback() { override fun areItemsTheSame( oldItem: SearchHistoryEntity, newItem: SearchHistoryEntity, ): Boolean { return oldItem.id == newItem.id } override fun areContentsTheSame( oldItem: SearchHistoryEntity, newItem: SearchHistoryEntity, ): Boolean { return oldItem == newItem } } } var listener: OnItemViewClickListener? = null override fun onBindViewHolder( holder: QuickViewHolder, position: Int, item: SearchHistoryEntity?, ) { item ?: return holder.setText(R.id.tv_text, item.query) } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): QuickViewHolder { return QuickViewHolder(R.layout.item_search_history, parent).also { viewHolder -> viewHolder.getView(R.id.btn_remove).setOnClickListener { // #issue-142: 部分机型调用 getItem().notNull() 可能会报错 listener?.onItemRemoveListener( it, getItem(viewHolder.bindingAdapterPosition) ) } viewHolder.getView(R.id.root).setOnClickListener { listener?.onItemClickListener( it, getItem(viewHolder.bindingAdapterPosition) ) } } } interface OnItemViewClickListener { fun onItemClickListener(v: View, history: SearchHistoryEntity?) fun onItemRemoveListener(v: View, history: SearchHistoryEntity?) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HanimeUpdateRvAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.animation.ValueAnimator import android.annotation.SuppressLint import android.content.Context import android.util.Log import android.view.LayoutInflater import android.view.ViewGroup import androidx.core.view.updateLayoutParams import androidx.interpolator.view.animation.FastOutSlowInInterpolator import androidx.recyclerview.widget.DiffUtil import com.chad.library.adapter4.BaseDifferAdapter import com.chad.library.adapter4.viewholder.DataBindingHolder import com.google.android.material.button.MaterialButton import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.databinding.ItemHanimeUpdatingBinding import com.yenaly.han1meviewer.logic.entity.download.HUpdateEntity import com.yenaly.han1meviewer.logic.state.DownloadState import com.yenaly.han1meviewer.ui.fragment.home.download.DownloadingFragment import com.yenaly.han1meviewer.util.addUpdateListener import com.yenaly.han1meviewer.util.showAlertDialog import com.yenaly.han1meviewer.worker.HUpdateWorker import com.yenaly.han1meviewer.worker.HanimeDownloadWorker import com.yenaly.yenaly_libs.utils.formatFileSizeV2 import com.yenaly.yenaly_libs.utils.logFieldsChange import java.lang.ref.WeakReference /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/26 026 17:05 */ class HanimeUpdateRvAdapter(private val fragment: DownloadingFragment) : BaseDifferAdapter>( COMPARATOR ) { init { isStateViewEnable = true } companion object { const val TAG = "HanimeUpdateRvAdapter" private val interpolator = FastOutSlowInInterpolator() private const val DOWNLOADING = 1 private const val STATE = 1 shl 1 private const val PROGRESS = 1 shl 2 val COMPARATOR = object : DiffUtil.ItemCallback() { override fun areContentsTheSame( oldItem: HUpdateEntity, newItem: HUpdateEntity, ): Boolean { return oldItem == newItem } override fun areItemsTheSame( oldItem: HUpdateEntity, newItem: HUpdateEntity, ): Boolean { return oldItem.id == newItem.id } override fun getChangePayload( oldItem: HUpdateEntity, newItem: HUpdateEntity, ): Any { logFieldsChange(TAG, oldItem, newItem) var bitset = 0 if (oldItem.downloadedLength != newItem.downloadedLength) bitset = bitset or DOWNLOADING if (oldItem.state != newItem.state) bitset = bitset or STATE if (oldItem.progress != newItem.progress) bitset = bitset or PROGRESS return bitset } } } @SuppressLint("SetTextI18n") override fun onBindViewHolder( holder: DataBindingHolder, position: Int, item: HUpdateEntity?, ) { item ?: return holder.binding.tvTitle.text = item.name Log.d(TAG, "调用 load") holder.itemView.post { holder.binding.vCoverBg.updateLayoutParams { height = holder.itemView.height } holder.binding.ivCoverBg.updateLayoutParams { height = holder.itemView.height } } holder.binding.clProgress.post { holder.binding.vProgress.updateLayoutParams { width = holder.binding.clProgress.width * item.progress / 100 } } holder.binding.tvDownloadedSize.text = item.downloadedLength.formatFileSizeV2() holder.binding.tvSize.text = item.length.formatFileSizeV2() holder.binding.btnStart.handleStartButton(item) } @SuppressLint("SetTextI18n") override fun onBindViewHolder( holder: DataBindingHolder, position: Int, item: HUpdateEntity?, payloads: List, ) { if (payloads.isEmpty() || payloads.first() == 0) return super.onBindViewHolder(holder, position, item, payloads) item ?: return val bitset = payloads.first() as Int if (bitset and DOWNLOADING != 0) { holder.binding.btnStart.handleStartButton(item) holder.binding.tvDownloadedSize.text = item.downloadedLength.formatFileSizeV2() } if (bitset and STATE != 0) { holder.binding.btnStart.handleStartButton(item) } if (bitset and PROGRESS != 0) { // 根据百分比,设置 vProgress 的宽度,比如 50% 就设置成 itemView 50% 的宽度 val weakViewProgress = WeakReference(holder.binding.vProgress) ValueAnimator.ofInt( holder.binding.vProgress.width, holder.itemView.width * item.progress / 100 ).apply { // must be less than HanimeDownloadWorker.RESPONSE_INTERVAL duration = 300L.coerceAtMost(HanimeDownloadWorker.RESPONSE_INTERVAL) interpolator = interpolator addUpdateListener(fragment) { weakViewProgress.get()?.updateLayoutParams { width = it.animatedValue as Int } } }.start() } } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): DataBindingHolder { return DataBindingHolder( ItemHanimeUpdatingBinding.inflate( LayoutInflater.from(context), parent, false ) ).also { viewHolder -> viewHolder.binding.btnStart.setOnClickListener { val pos = viewHolder.bindingAdapterPosition val item = getItem(pos) ?: return@setOnClickListener if (item.isDownloading) { HUpdateWorker.stop() } else { HUpdateWorker.resume() } viewHolder.binding.btnStart.handleStartButton(item, rotate = true) } viewHolder.binding.btnCancel.setOnClickListener { val pos = viewHolder.bindingAdapterPosition val item = getItem(pos) ?: return@setOnClickListener context.showAlertDialog { setTitle(R.string.sure_to_delete) setMessage( context.getString(R.string.prepare_to_delete_s, item.name) ) setPositiveButton(R.string.confirm) { _, _ -> HUpdateWorker.deleteUpdate(context) } setNegativeButton(R.string.cancel, null) } } } } @SuppressLint("SetTextI18n") private fun MaterialButton.handleStartButton( item: HUpdateEntity, rotate: Boolean = false ) { val state = if (rotate) { when (item.state) { DownloadState.Unknown, DownloadState.Queued, DownloadState.Paused -> DownloadState.Downloading DownloadState.Downloading -> DownloadState.Paused DownloadState.Finished, DownloadState.Failed -> DownloadState.Unknown } } else { item.state } when (state) { DownloadState.Queued -> { setText(R.string.already_in_queue) setIconResource(R.drawable.ic_baseline_play_arrow_24) } DownloadState.Downloading -> { // setText(R.string.pause) // setIconResource(R.drawable.ic_baseline_pause_24) text = "${item.progress}%" setIconResource(R.drawable.ic_baseline_pause_24) } DownloadState.Paused -> { setText(R.string.continues) setIconResource(R.drawable.ic_baseline_play_arrow_24) } DownloadState.Failed -> { setText(R.string.retry) setIconResource(R.drawable.baseline_error_outline_24) } DownloadState.Finished, DownloadState.Unknown -> {} // do nothing } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HanimeUpdatedRvAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import android.graphics.RenderEffect import android.graphics.Shader import android.os.Build import android.view.LayoutInflater import android.view.ViewGroup import androidx.core.net.toFile import androidx.core.net.toUri import androidx.core.view.updateLayoutParams import androidx.recyclerview.widget.DiffUtil import com.chad.library.adapter4.BaseDifferAdapter import com.chad.library.adapter4.viewholder.DataBindingHolder import com.yenaly.han1meviewer.HFileManager import com.yenaly.han1meviewer.LOCAL_DATE_TIME_FORMAT import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.VIDEO_CODE import com.yenaly.han1meviewer.databinding.ItemHanimeUpdatedBinding import com.yenaly.han1meviewer.logic.entity.download.HUpdateEntity import com.yenaly.han1meviewer.ui.activity.VideoActivity import com.yenaly.han1meviewer.ui.fragment.home.download.DownloadedFragment import com.yenaly.han1meviewer.util.HImageMeower.loadUnhappily import com.yenaly.han1meviewer.util.MediaUtils import com.yenaly.han1meviewer.util.installApkPackage import com.yenaly.han1meviewer.util.openDownloadedHanimeVideoInActivity import com.yenaly.han1meviewer.util.showAlertDialog import com.yenaly.han1meviewer.util.updateFile import com.yenaly.han1meviewer.worker.HUpdateWorker import com.yenaly.yenaly_libs.utils.activity import com.yenaly.yenaly_libs.utils.dpF import com.yenaly.yenaly_libs.utils.formatFileSizeV2 import com.yenaly.yenaly_libs.utils.startActivity import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.datetime.Instant import kotlinx.datetime.TimeZone import kotlinx.datetime.format import kotlinx.datetime.toLocalDateTime /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/26 026 16:57 */ class HanimeUpdatedRvAdapter(private val fragment: DownloadedFragment) : BaseDifferAdapter>( COMPARATOR ) { init { isStateViewEnable = true } companion object { val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) val COMPARATOR = object : DiffUtil.ItemCallback() { override fun areContentsTheSame( oldItem: HUpdateEntity, newItem: HUpdateEntity, ): Boolean { return oldItem == newItem } override fun areItemsTheSame( oldItem: HUpdateEntity, newItem: HUpdateEntity, ): Boolean { return oldItem.id == newItem.id } } } override fun onBindViewHolder( holder: DataBindingHolder, position: Int, item: HUpdateEntity?, ) { item ?: return holder.binding.tvTitle.text = item.name holder.itemView.post { // fast path if (holder.itemView.height == holder.binding.vCoverBg.height) return@post holder.binding.vCoverBg.updateLayoutParams { height = holder.itemView.height } holder.binding.ivCoverBg.updateLayoutParams { height = holder.itemView.height } } val realSize = context.updateFile.length() holder.binding.tvSize.text = if (realSize == 0L) { "???" } else { item.length.formatFileSizeV2() } } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): DataBindingHolder { return DataBindingHolder( ItemHanimeUpdatedBinding.inflate( LayoutInflater.from(context), parent, false ) ).also { viewHolder -> viewHolder.binding.btnDelete.setOnClickListener { val position = viewHolder.bindingAdapterPosition // #issue-158: 这里可能为空 val item = getItem(position) item?.let { context.showAlertDialog { setTitle(R.string.sure_to_delete) setMessage(context.getString(R.string.prepare_to_delete_s, it.name)) setPositiveButton(R.string.confirm) { _, _ -> HUpdateWorker.deleteUpdate(context) } setNegativeButton(R.string.cancel, null) } } } viewHolder.binding.btnInstall.setOnClickListener { scope.launch { context.installApkPackage(context.updateFile) } } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/HanimeVideoRvAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import android.content.Intent import android.graphics.Color import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.recyclerview.widget.DiffUtil import coil.load import com.chad.library.adapter4.BaseDifferAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.itxca.spannablex.spannable import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.VIDEO_CODE import com.yenaly.han1meviewer.VIDEO_LAYOUT_MATCH_PARENT import com.yenaly.han1meviewer.VIDEO_LAYOUT_WRAP_CONTENT import com.yenaly.han1meviewer.VideoCoverSize import com.yenaly.han1meviewer.getHanimeShareText import com.yenaly.han1meviewer.logic.model.HanimeInfo import com.yenaly.han1meviewer.ui.activity.MainActivity import com.yenaly.han1meviewer.ui.activity.PreviewActivity import com.yenaly.han1meviewer.ui.activity.SearchActivity import com.yenaly.han1meviewer.ui.activity.VideoActivity import com.yenaly.han1meviewer.ui.fragment.home.HomePageFragment import com.yenaly.yenaly_libs.utils.activity import com.yenaly.yenaly_libs.utils.copyTextToClipboard import com.yenaly.yenaly_libs.utils.dp import com.yenaly.yenaly_libs.utils.showShortToast import com.yenaly.yenaly_libs.utils.startActivity /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/26 026 17:15 */ class HanimeVideoRvAdapter(private val videoWidthType: Int = -1) : // videoWidthType is VIDEO_LAYOUT_MATCH_PARENT or VIDEO_LAYOUT_WRAP_CONTENT or nothing BaseDifferAdapter(COMPARATOR) { init { isStateViewEnable = true } companion object { val COMPARATOR = object : DiffUtil.ItemCallback() { override fun areItemsTheSame( oldItem: HanimeInfo, newItem: HanimeInfo, ): Boolean { return oldItem.videoCode == newItem.videoCode } override fun areContentsTheSame( oldItem: HanimeInfo, newItem: HanimeInfo, ): Boolean { return oldItem == newItem } } } override fun getItemViewType(position: Int, list: List): Int { return list[position].itemType } override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: HanimeInfo?) { item ?: return // stackoverflow-64362192 when (getItemViewType(position)) { HanimeInfo.SIMPLIFIED -> { holder.getView(R.id.cover).load(item.coverUrl) { crossfade(true) } holder.getView(R.id.title).text = item.title } HanimeInfo.NORMAL -> { holder.getView(R.id.title).text = item.title holder.getView(R.id.cover).load(item.coverUrl) { crossfade(true) } holder.getView(R.id.is_playing).isVisible = item.isPlaying holder.getView(R.id.duration).text = item.duration holder.getView(R.id.time).apply { if (item.uploadTime != null) { holder.getView(R.id.icon_time).isGone = false text = item.uploadTime } else { holder.getView(R.id.icon_time).isGone = true } } holder.getView(R.id.views).apply { if (item.views != null) { holder.getView(R.id.icon_views).isGone = false text = item.views } else { holder.getView(R.id.icon_views).isGone = true } } holder.getView(R.id.genre_and_uploader).apply { if (item.genre == null && item.uploader == null) { isGone = true return@apply } isGone = false text = spannable { item.genre.span { margin(4.dp) when (item.genre) { "3D" -> color(Color.rgb(245, 171, 53)) "COS" -> color(Color.rgb(165, 55, 253)) "同人" -> color(Color.rgb(241, 130, 141)) else -> color(Color.RED) } } item.uploader.text() } } } } } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): QuickViewHolder { return if (viewType == HanimeInfo.NORMAL) { QuickViewHolder(R.layout.item_hanime_video, parent) } else { QuickViewHolder(R.layout.item_hanime_video_simplified, parent) }.also { viewHolder -> when (viewType) { HanimeInfo.SIMPLIFIED -> { when (context) { is SearchActivity -> { viewHolder.getView(R.id.frame).widthMatchParent() } is VideoActivity -> when (videoWidthType) { VIDEO_LAYOUT_MATCH_PARENT -> viewHolder.getView(R.id.frame).widthMatchParent() VIDEO_LAYOUT_WRAP_CONTENT -> viewHolder.getView(R.id.frame).widthWrapContent() } } with(VideoCoverSize.Simplified) { viewHolder.getView(R.id.cover_wrapper).resizeForVideoCover() } } HanimeInfo.NORMAL -> { when (context) { is VideoActivity -> when (videoWidthType) { VIDEO_LAYOUT_MATCH_PARENT -> viewHolder.getView(R.id.frame).widthMatchParent() VIDEO_LAYOUT_WRAP_CONTENT -> viewHolder.getView(R.id.frame).widthWrapContent() } is MainActivity -> { val activity = context val fragment = activity.currentFragment if (fragment is HomePageFragment) { viewHolder.getView(R.id.frame).widthWrapContent() } } } with(VideoCoverSize.Normal) { viewHolder.getView(R.id.cover_wrapper).resizeForVideoCover() } } } viewHolder.itemView.apply { if (context !is PreviewActivity) { setOnClickListener { val position = viewHolder.bindingAdapterPosition val item = getItem(position) ?: return@setOnClickListener if (item.isPlaying) { showShortToast(R.string.watching_this_video_now) } else { val videoCode = item.videoCode context.startVideoActivity(videoCode) } } setOnLongClickListener { val position = viewHolder.bindingAdapterPosition val item = getItem(position) ?: return@setOnLongClickListener true copyTextToClipboard(getHanimeShareText(item.title, item.videoCode)) showShortToast(R.string.copy_to_clipboard) return@setOnLongClickListener true } } } } } private fun View.widthMatchParent() = apply { layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT ) } private fun View.widthWrapContent() = apply { layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT ) } private fun Context.startVideoActivity(videoCode: String) { if (this is SearchActivity) { val intent = Intent(this, VideoActivity::class.java).apply { putExtra(VIDEO_CODE, videoCode) } this.subscribeLauncher.launch(intent) return } activity?.startActivity(VIDEO_CODE to videoCode) } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/PlaylistRvAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import android.view.ViewGroup import androidx.fragment.app.Fragment import com.chad.library.adapter4.BaseQuickAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.logic.model.Playlists import com.yenaly.han1meviewer.ui.fragment.home.MyPlaylistFragment /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/26 026 16:30 */ class PlaylistRvAdapter(private val fragment: Fragment) : BaseQuickAdapter() { init { isStateViewEnable = true } override fun onBindViewHolder( holder: QuickViewHolder, position: Int, item: Playlists.Playlist?, ) { item ?: return holder.setText(R.id.tv_title, item.title) holder.setText(R.id.tv_count, item.total.toString()) } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): QuickViewHolder { return QuickViewHolder(R.layout.item_playlist, parent).also { viewHolder -> check(fragment is MyPlaylistFragment) viewHolder.itemView.setOnClickListener { val position = viewHolder.bindingAdapterPosition val item = getItem(position) ?: return@setOnClickListener fragment.listCode = item.listCode fragment.listTitle = item.title fragment.getNewPlaylistItems() fragment.binding.dlPlaylist.closeDrawers() } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/RvWrapper.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import android.graphics.Outline import android.view.View import android.view.ViewGroup import android.view.ViewOutlineProvider import androidx.annotation.StringRes import androidx.core.view.minusAssign import androidx.core.view.plusAssign import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.LayoutManager import androidx.recyclerview.widget.RecyclerView.ViewHolder import com.chad.library.adapter4.BaseSingleItemAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.util.dpToPx /** * RecyclerView Wrapper,为了让多 LayoutManager 布局能够在 ConcatAdapter 中使用。 * * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/27 027 17:00 */ class RvWrapper( private val adapter: RecyclerView.Adapter, private val customRv: ((Context) -> RecyclerView)?, private val layoutManager: () -> LayoutManager, ) : BaseSingleItemAdapter() { companion object { fun RecyclerView.Adapter.wrappedWith( customRv: ((Context) -> RecyclerView)? = null, layoutManager: () -> LayoutManager, ) = RvWrapper(this, customRv, layoutManager) } var wrapper: RecyclerView? = null private set private var onWrap: (RecyclerView.() -> Unit)? = null fun doOnWrap(block: RecyclerView.() -> Unit) { onWrap = block } override fun onBindViewHolder(holder: QuickViewHolder, item: Unit?) = Unit override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): QuickViewHolder { return QuickViewHolder(R.layout.item_rv_wrapper, parent).also { viewHolder -> val frame = viewHolder.itemView as ViewGroup var rv = this@RvWrapper.customRv?.invoke(context)?.apply { id = R.id.rv isNestedScrollingEnabled = false } val prevRv = viewHolder.getView(R.id.rv) if (rv != null) { frame -= prevRv rv.layoutParams = prevRv.layoutParams frame += rv } else { rv = prevRv } rv.apply wr@{ this@wr.layoutManager = this@RvWrapper.layoutManager() this@wr.adapter = this@RvWrapper.adapter this@RvWrapper.wrapper = this@wr onWrap?.invoke(this@wr) outlineProvider = object : ViewOutlineProvider() { override fun getOutline(view: View, outline: Outline) { outline.setRoundRect(0, 0, view.width, view.height, 8f.dpToPx()) } } clipToOutline = true } } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/SharedHKeyframesRvAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.annotation.SuppressLint import android.content.Context import android.view.ViewGroup import android.widget.TextView import androidx.core.text.method.LinkMovementMethodCompat import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.chad.library.adapter4.BaseDifferAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.itxca.spannablex.spannable import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.VIDEO_CODE import com.yenaly.han1meviewer.logic.entity.HKeyframeEntity import com.yenaly.han1meviewer.logic.entity.HKeyframeHeader import com.yenaly.han1meviewer.logic.entity.HKeyframeType import com.yenaly.han1meviewer.ui.activity.VideoActivity import com.yenaly.yenaly_libs.utils.activity import com.yenaly.yenaly_libs.utils.startActivity /** * @project Han1meViewer * @author Yenaly Liew * @time 2024/04/03 003 21:40 */ class SharedHKeyframesRvAdapter : BaseDifferAdapter(COMPARATOR) { init { isStateViewEnable = true } companion object { val COMPARATOR = object : DiffUtil.ItemCallback() { override fun areItemsTheSame( oldItem: HKeyframeType, newItem: HKeyframeType, ) = when { oldItem is HKeyframeEntity && newItem is HKeyframeEntity -> { oldItem.videoCode == newItem.videoCode } oldItem is HKeyframeHeader && newItem is HKeyframeHeader -> { oldItem.title == newItem.title } else -> false } @SuppressLint("DiffUtilEquals") override fun areContentsTheSame( oldItem: HKeyframeType, newItem: HKeyframeType, ) = when { oldItem is HKeyframeEntity && newItem is HKeyframeEntity -> { oldItem == newItem } oldItem is HKeyframeHeader && newItem is HKeyframeHeader -> { oldItem == newItem } else -> false } } } override fun getItemViewType(position: Int, list: List): Int { return list[position].itemType } override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: HKeyframeType?) { when (getItemViewType(position)) { HKeyframeType.H_KEYFRAME -> { require(item is HKeyframeEntity) holder.setText(R.id.tv_title, item.title) holder.getView(R.id.tv_video_code).apply { movementMethod = LinkMovementMethodCompat.getInstance() text = spannable { context.getString(R.string.h_keyframe_title_prefix).text() item.videoCode.span { clickable(color = context.getColor(R.color.video_code_link_text_color)) { _, videoCode -> context.activity?.startActivity(VIDEO_CODE to videoCode) } underline() } } } holder.getView(R.id.rv_h_keyframe).apply { layoutManager = LinearLayoutManager(context) adapter = HKeyframeRvAdapter(item.videoCode, item).apply { isLocal = item.author == null isShared = true } } holder.setText(R.id.tv_author, "@${item.author}") } HKeyframeType.HEADER -> { require(item is HKeyframeHeader) holder.setText(R.id.tv_title, item.title) } } } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): QuickViewHolder { return when (viewType) { HKeyframeType.H_KEYFRAME -> { QuickViewHolder(R.layout.item_shared_h_keyframes, parent) } HKeyframeType.HEADER -> { QuickViewHolder(R.layout.layout_header_h_keyframes, parent) } else -> throw IllegalArgumentException("Unknown viewType: $viewType") } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/SuperResolutionAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.R import android.content.Context import android.graphics.Color import android.view.Gravity import android.view.ViewGroup import android.widget.TextView import com.chad.library.adapter4.BaseQuickAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.yenaly.han1meviewer.ui.view.video.HJzvdStd /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/26 026 16:09 */ class SuperResolutionAdapter(private var currentIndex: Int) : BaseQuickAdapter( HJzvdStd.superResolutionArray.toMutableList() ) { init { isStateViewEnable = true } override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: String?) { holder.setText(R.id.text1, item) holder.setTextColor( R.id.text1, if (currentIndex == holder.bindingAdapterPosition) Color.parseColor("#fff85959") else Color.parseColor("#ffffff") ) } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): QuickViewHolder { return QuickViewHolder(R.layout.simple_list_item_1, parent).also { viewHolder -> viewHolder.getView(R.id.text1).gravity = Gravity.CENTER } } } ================================================ FILE: app/src/main/java/com/yenaly/han1meviewer/ui/adapter/VideoColumnTitleAdapter.kt ================================================ package com.yenaly.han1meviewer.ui.adapter import android.content.Context import android.view.View import android.view.ViewGroup import android.widget.Button import androidx.annotation.StringRes import com.chad.library.adapter4.BaseSingleItemAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.yenaly.han1meviewer.EMPTY_STRING import com.yenaly.han1meviewer.R import com.yenaly.han1meviewer.ui.activity.MainActivity import com.yenaly.yenaly_libs.utils.applicationContext /** * @project Han1meViewer * @author Yenaly Liew * @time 2023/11/27 027 12:55 */ class VideoColumnTitleAdapter : BaseSingleItemAdapter { private val notifyWhenSet: Boolean var title: String = EMPTY_STRING set(value) = if (notifyWhenSet) { field = value notifyItemChanged(0) } else field = value var subtitle: String? = null set(value) = if (notifyWhenSet) { field = value notifyItemChanged(0) } else field = value var onMoreHanimeListener: ((View) -> Unit)? = null constructor() : super() { notifyWhenSet = true title = EMPTY_STRING subtitle = null } constructor(title: String, subtitle: String? = null, notifyWhenSet: Boolean = false) : super() { this.title = title this.subtitle = subtitle this.notifyWhenSet = notifyWhenSet } constructor( @StringRes title: Int, @StringRes subtitle: Int = 0, notifyWhenSet: Boolean = false, ) : this( applicationContext.getString(title), if (subtitle != 0) applicationContext.getString(subtitle) else null, notifyWhenSet ) override fun onBindViewHolder(holder: QuickViewHolder, item: Unit?) { holder.setGone(R.id.sub_title, subtitle == null) holder.setText(R.id.title, title) holder.setText(R.id.sub_title, subtitle) } override fun onCreateViewHolder( context: Context, parent: ViewGroup, viewType: Int, ): QuickViewHolder { return QuickViewHolder(R.layout.item_video_column_title, parent).also { viewHolder -> viewHolder.setGone(R.id.more, context !is MainActivity) viewHolder.getView