diff --git a/lib/src/reverse_engineering/responses/channel_upload_page.dart b/lib/src/reverse_engineering/responses/channel_upload_page.dart index 7c8c6b5..a92dc0a 100644 --- a/lib/src/reverse_engineering/responses/channel_upload_page.dart +++ b/lib/src/reverse_engineering/responses/channel_upload_page.dart @@ -5,10 +5,10 @@ import 'package:html/parser.dart' as parser; import '../../channels/channel_video.dart'; import '../../exceptions/exceptions.dart'; -import '../../extensions/helpers_extension.dart'; import '../../retry.dart'; import '../../videos/videos.dart'; import '../youtube_http_client.dart'; +import 'generated/channel_upload_page_id.g.dart'; /// class ChannelUploadPage { @@ -19,8 +19,8 @@ class ChannelUploadPage { _InitialData _initialData; /// - _InitialData get initialData => - _initialData ??= _InitialData(json.decode(_matchJson(_extractJson( + _InitialData get initialData => _initialData ??= _InitialData( + ChannelUploadPageId.fromJson(json.decode(_extractJson( _root .querySelectorAll('script') .map((e) => e.text) @@ -64,8 +64,8 @@ class ChannelUploadPage { 'https://www.youtube.com/browse_ajax?ctoken=${initialData.continuation}&continuation=${initialData.continuation}&itct=${initialData.clickTrackingParams}'; return retry(() async { var raw = await httpClient.getString(url); - return ChannelUploadPage( - null, channelId, _InitialData(json.decode(raw)[1])); + return ChannelUploadPage(null, channelId, + _InitialData(ChannelUploadPageId.fromJson(json.decode(raw)[1]))); }); } @@ -86,11 +86,30 @@ class ChannelUploadPage { : _root = parser.parse(raw); } +void x() { + ChannelUploadPageId _id; + // @getContentContext + var x = _id.contents.twoColumnBrowseResultsRenderer.tabs + .map((e) => e.tabRenderer) + .firstWhere((e) => e.selected) + .content + .sectionListRenderer + .contents + .first + .itemSectionRenderer + .contents + .first + .gridRenderer + .items; + + _id.response.continuationContents.gridContinuation.items; +} + class _InitialData { // Json parsed map - final Map _root; + final ChannelUploadPageId root; - _InitialData(this._root); + _InitialData(this.root); /* Cache results */ @@ -98,64 +117,68 @@ class _InitialData { String _continuation; String _clickTrackingParams; - List> getContentContext(Map root) { - if (root['contents'] != null) { - return (_root['contents']['twoColumnBrowseResultsRenderer']['tabs'] - as List) - .map((e) => e['tabRenderer']) - .firstWhere((e) => e['selected'] == true)['content'] - ['sectionListRenderer']['contents'] - .first['itemSectionRenderer']['contents'] - .first['gridRenderer']['items'] - .cast>(); + List getContentContext() { + if (root.contents != null) { + return root.contents.twoColumnBrowseResultsRenderer.tabs + .map((e) => e.tabRenderer) + .firstWhere((e) => e.selected) + .content + .sectionListRenderer + .contents + .first + .itemSectionRenderer + .contents + .first + .gridRenderer + .items; } - if (root['response'] != null) { - return _root['response']['continuationContents']['gridContinuation'] - ['items'] - .cast>(); + if (root.response != null) { + return root.response.continuationContents.gridContinuation.items; } throw FatalFailureException('Failed to get initial data context.'); } - Map getContinuationContext(Map root) { - if (_root['contents'] != null) { - return (_root['contents']['twoColumnBrowseResultsRenderer']['tabs'] - as List) - ?.map((e) => e['tabRenderer']) - ?.firstWhere((e) => e['selected'] == true)['content'] - ['sectionListRenderer']['contents'] - ?.first['itemSectionRenderer']['contents'] - ?.first['gridRenderer']['continuations'] - ?.first['nextContinuationData'] - ?.cast(); + NextContinuationData getContinuationContext() { + if (root.contents != null) { + return root.contents.twoColumnBrowseResultsRenderer.tabs + .map((e) => e.tabRenderer) + .firstWhere((e) => e.selected) + .content + .sectionListRenderer + .contents + .first + .itemSectionRenderer + .contents + .first + .gridRenderer + .continuations + .first + .nextContinuationData; } - if (_root['response'] != null) { - return _root['response']['continuationContents']['gridContinuation'] - ['continuations'] - ?.first - ?.cast(); + if (root.response != null) { + return root.response.continuationContents.gridContinuation.continuations + .first.nextContinuationData; } return null; } - List get uploads => _uploads ??= getContentContext(_root) + List get uploads => _uploads ??= getContentContext() ?.map(_parseContent) ?.where((e) => e != null) ?.toList() ?.cast(); - String get continuation => _continuation ??= - getContinuationContext(_root)?.getValue('continuation') ?? ''; + String get continuation => + _continuation ??= getContinuationContext().continuation ?? ''; String get clickTrackingParams => _clickTrackingParams ??= - getContinuationContext(_root)?.getValue('clickTrackingParams') ?? ''; + getContinuationContext()?.clickTrackingParams ?? ''; - dynamic _parseContent(content) { - if (content == null || content['gridVideoRenderer'] == null) { + dynamic _parseContent(GridContinuationItem content) { + if (content == null || content.gridVideoRenderer == null) { return null; } - var video = content['gridVideoRenderer'] as Map; - return ChannelVideo( - VideoId(video['videoId']), video['title']['simpleText']); + var video = content.gridVideoRenderer; + return ChannelVideo(VideoId(video.videoId), video.title.simpleText); } } diff --git a/lib/src/reverse_engineering/responses/generated/channel_upload_page_id.g.dart b/lib/src/reverse_engineering/responses/generated/channel_upload_page_id.g.dart new file mode 100644 index 0000000..0b30c81 --- /dev/null +++ b/lib/src/reverse_engineering/responses/generated/channel_upload_page_id.g.dart @@ -0,0 +1,5426 @@ +// To parse this JSON data, do +// +// final channelUploadPageId = channelUploadPageIdFromJson(jsonString); + +import 'dart:convert'; + +class ChannelUploadPageId { + ChannelUploadPageId({ + this.page, + this.xsrfToken, + this.endpoint, + this.response, + this.timing, + this.responseContext, + this.contents, + this.header, + this.metadata, + this.trackingParams, + this.topbar, + this.microformat, + }); + + final String page; + final String xsrfToken; + final ChannelUploadPageIdEndpoint endpoint; + final Response response; + final Timing timing; + final ChannelUploadPageIdResponseContext responseContext; + final Contents contents; + final Header header; + final Metadata metadata; + final String trackingParams; + final Topbar topbar; + final Microformat microformat; + + factory ChannelUploadPageId.fromRawJson(String str) => + ChannelUploadPageId.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ChannelUploadPageId.fromJson(Map json) => + ChannelUploadPageId( + page: json["page"] == null ? null : json["page"], + xsrfToken: json["xsrf_token"] == null ? null : json["xsrf_token"], + endpoint: json["endpoint"] == null + ? null + : ChannelUploadPageIdEndpoint.fromJson(json["endpoint"]), + response: json["response"] == null + ? null + : Response.fromJson(json["response"]), + timing: json["timing"] == null ? null : Timing.fromJson(json["timing"]), + responseContext: json["responseContext"] == null + ? null + : ChannelUploadPageIdResponseContext.fromJson( + json["responseContext"]), + contents: json["contents"] == null + ? null + : Contents.fromJson(json["contents"]), + header: json["header"] == null ? null : Header.fromJson(json["header"]), + metadata: json["metadata"] == null + ? null + : Metadata.fromJson(json["metadata"]), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + topbar: json["topbar"] == null ? null : Topbar.fromJson(json["topbar"]), + microformat: json["microformat"] == null + ? null + : Microformat.fromJson(json["microformat"]), + ); + + Map toJson() => { + "page": page == null ? null : page, + "xsrf_token": xsrfToken == null ? null : xsrfToken, + "endpoint": endpoint == null ? null : endpoint.toJson(), + "response": response == null ? null : response.toJson(), + "timing": timing == null ? null : timing.toJson(), + "responseContext": + responseContext == null ? null : responseContext.toJson(), + "contents": contents == null ? null : contents.toJson(), + "header": header == null ? null : header.toJson(), + "metadata": metadata == null ? null : metadata.toJson(), + "trackingParams": trackingParams == null ? null : trackingParams, + "topbar": topbar == null ? null : topbar.toJson(), + "microformat": microformat == null ? null : microformat.toJson(), + }; +} + +class Contents { + Contents({ + this.twoColumnBrowseResultsRenderer, + }); + + final TwoColumnBrowseResultsRenderer twoColumnBrowseResultsRenderer; + + factory Contents.fromRawJson(String str) => + Contents.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Contents.fromJson(Map json) => Contents( + twoColumnBrowseResultsRenderer: + json["twoColumnBrowseResultsRenderer"] == null + ? null + : TwoColumnBrowseResultsRenderer.fromJson( + json["twoColumnBrowseResultsRenderer"]), + ); + + Map toJson() => { + "twoColumnBrowseResultsRenderer": twoColumnBrowseResultsRenderer == null + ? null + : twoColumnBrowseResultsRenderer.toJson(), + }; +} + +class TwoColumnBrowseResultsRenderer { + TwoColumnBrowseResultsRenderer({ + this.tabs, + }); + + final List tabs; + + factory TwoColumnBrowseResultsRenderer.fromRawJson(String str) => + TwoColumnBrowseResultsRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory TwoColumnBrowseResultsRenderer.fromJson(Map json) => + TwoColumnBrowseResultsRenderer( + tabs: json["tabs"] == null + ? null + : List.from(json["tabs"].map((x) => Tab.fromJson(x))), + ); + + Map toJson() => { + "tabs": tabs == null + ? null + : List.from(tabs.map((x) => x.toJson())), + }; +} + +class Tab { + Tab({ + this.tabRenderer, + this.expandableTabRenderer, + }); + + final TabRenderer tabRenderer; + final ExpandableTabRenderer expandableTabRenderer; + + factory Tab.fromRawJson(String str) => Tab.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Tab.fromJson(Map json) => Tab( + tabRenderer: json["tabRenderer"] == null + ? null + : TabRenderer.fromJson(json["tabRenderer"]), + expandableTabRenderer: json["expandableTabRenderer"] == null + ? null + : ExpandableTabRenderer.fromJson(json["expandableTabRenderer"]), + ); + + Map toJson() => { + "tabRenderer": tabRenderer == null ? null : tabRenderer.toJson(), + "expandableTabRenderer": expandableTabRenderer == null + ? null + : expandableTabRenderer.toJson(), + }; +} + +class ExpandableTabRenderer { + ExpandableTabRenderer({ + this.endpoint, + this.title, + this.selected, + }); + + final NavigationEndpointClass endpoint; + final String title; + final bool selected; + + factory ExpandableTabRenderer.fromRawJson(String str) => + ExpandableTabRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ExpandableTabRenderer.fromJson(Map json) => + ExpandableTabRenderer( + endpoint: json["endpoint"] == null + ? null + : NavigationEndpointClass.fromJson(json["endpoint"]), + title: json["title"] == null ? null : json["title"], + selected: json["selected"] == null ? null : json["selected"], + ); + + Map toJson() => { + "endpoint": endpoint == null ? null : endpoint.toJson(), + "title": title == null ? null : title, + "selected": selected == null ? null : selected, + }; +} + +class NavigationEndpointClass { + NavigationEndpointClass({ + this.clickTrackingParams, + this.commandMetadata, + this.browseEndpoint, + }); + + final String clickTrackingParams; + final NextEndpointCommandMetadata commandMetadata; + final PurpleBrowseEndpoint browseEndpoint; + + factory NavigationEndpointClass.fromRawJson(String str) => + NavigationEndpointClass.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory NavigationEndpointClass.fromJson(Map json) => + NavigationEndpointClass( + clickTrackingParams: json["clickTrackingParams"] == null + ? null + : json["clickTrackingParams"], + commandMetadata: json["commandMetadata"] == null + ? null + : NextEndpointCommandMetadata.fromJson(json["commandMetadata"]), + browseEndpoint: json["browseEndpoint"] == null + ? null + : PurpleBrowseEndpoint.fromJson(json["browseEndpoint"]), + ); + + Map toJson() => { + "clickTrackingParams": + clickTrackingParams == null ? null : clickTrackingParams, + "commandMetadata": + commandMetadata == null ? null : commandMetadata.toJson(), + "browseEndpoint": + browseEndpoint == null ? null : browseEndpoint.toJson(), + }; +} + +class PurpleBrowseEndpoint { + PurpleBrowseEndpoint({ + this.browseId, + this.params, + this.canonicalBaseUrl, + }); + + final Id browseId; + final String params; + final CanonicalBaseUrl canonicalBaseUrl; + + factory PurpleBrowseEndpoint.fromRawJson(String str) => + PurpleBrowseEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory PurpleBrowseEndpoint.fromJson(Map json) => + PurpleBrowseEndpoint( + browseId: + json["browseId"] == null ? null : idValues.map[json["browseId"]], + params: json["params"] == null ? null : json["params"], + canonicalBaseUrl: json["canonicalBaseUrl"] == null + ? null + : canonicalBaseUrlValues.map[json["canonicalBaseUrl"]], + ); + + Map toJson() => { + "browseId": browseId == null ? null : idValues.reverse[browseId], + "params": params == null ? null : params, + "canonicalBaseUrl": canonicalBaseUrl == null + ? null + : canonicalBaseUrlValues.reverse[canonicalBaseUrl], + }; +} + +enum Id { U_CS7_O9_S_OU_QI_BG_BXAA_AGU_IWIG } + +final idValues = EnumValues( + {"UCs7O9sOUQiBGBxaaAguIwig": Id.U_CS7_O9_S_OU_QI_BG_BXAA_AGU_IWIG}); + +enum CanonicalBaseUrl { C_PATRIK_PIETSCHMANN } + +final canonicalBaseUrlValues = + EnumValues({"/c/PatrikPietschmann": CanonicalBaseUrl.C_PATRIK_PIETSCHMANN}); + +class NextEndpointCommandMetadata { + NextEndpointCommandMetadata({ + this.webCommandMetadata, + }); + + final PurpleWebCommandMetadata webCommandMetadata; + + factory NextEndpointCommandMetadata.fromRawJson(String str) => + NextEndpointCommandMetadata.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory NextEndpointCommandMetadata.fromJson(Map json) => + NextEndpointCommandMetadata( + webCommandMetadata: json["webCommandMetadata"] == null + ? null + : PurpleWebCommandMetadata.fromJson(json["webCommandMetadata"]), + ); + + Map toJson() => { + "webCommandMetadata": + webCommandMetadata == null ? null : webCommandMetadata.toJson(), + }; +} + +class PurpleWebCommandMetadata { + PurpleWebCommandMetadata({ + this.url, + this.webPageType, + this.rootVe, + }); + + final String url; + final WebPageType webPageType; + final int rootVe; + + factory PurpleWebCommandMetadata.fromRawJson(String str) => + PurpleWebCommandMetadata.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory PurpleWebCommandMetadata.fromJson(Map json) => + PurpleWebCommandMetadata( + url: json["url"] == null ? null : json["url"], + webPageType: json["webPageType"] == null + ? null + : webPageTypeValues.map[json["webPageType"]], + rootVe: json["rootVe"] == null ? null : json["rootVe"], + ); + + Map toJson() => { + "url": url == null ? null : url, + "webPageType": + webPageType == null ? null : webPageTypeValues.reverse[webPageType], + "rootVe": rootVe == null ? null : rootVe, + }; +} + +enum WebPageType { + WEB_PAGE_TYPE_CHANNEL, + WEB_PAGE_TYPE_WATCH, + WEB_PAGE_TYPE_UNKNOWN, + WEB_PAGE_TYPE_BROWSE, + WEB_PAGE_TYPE_SEARCH +} + +final webPageTypeValues = EnumValues({ + "WEB_PAGE_TYPE_BROWSE": WebPageType.WEB_PAGE_TYPE_BROWSE, + "WEB_PAGE_TYPE_CHANNEL": WebPageType.WEB_PAGE_TYPE_CHANNEL, + "WEB_PAGE_TYPE_SEARCH": WebPageType.WEB_PAGE_TYPE_SEARCH, + "WEB_PAGE_TYPE_UNKNOWN": WebPageType.WEB_PAGE_TYPE_UNKNOWN, + "WEB_PAGE_TYPE_WATCH": WebPageType.WEB_PAGE_TYPE_WATCH +}); + +class TabRenderer { + TabRenderer({ + this.endpoint, + this.title, + this.selected, + this.trackingParams, + this.content, + }); + + final NavigationEndpointClass endpoint; + final String title; + final bool selected; + final String trackingParams; + final TabRendererContent content; + + factory TabRenderer.fromRawJson(String str) => + TabRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory TabRenderer.fromJson(Map json) => TabRenderer( + endpoint: json["endpoint"] == null + ? null + : NavigationEndpointClass.fromJson(json["endpoint"]), + title: json["title"] == null ? null : json["title"], + selected: json["selected"] == null ? null : json["selected"], + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + content: json["content"] == null + ? null + : TabRendererContent.fromJson(json["content"]), + ); + + Map toJson() => { + "endpoint": endpoint == null ? null : endpoint.toJson(), + "title": title == null ? null : title, + "selected": selected == null ? null : selected, + "trackingParams": trackingParams == null ? null : trackingParams, + "content": content == null ? null : content.toJson(), + }; +} + +class TabRendererContent { + TabRendererContent({ + this.sectionListRenderer, + }); + + final SectionListRenderer sectionListRenderer; + + factory TabRendererContent.fromRawJson(String str) => + TabRendererContent.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory TabRendererContent.fromJson(Map json) => + TabRendererContent( + sectionListRenderer: json["sectionListRenderer"] == null + ? null + : SectionListRenderer.fromJson(json["sectionListRenderer"]), + ); + + Map toJson() => { + "sectionListRenderer": + sectionListRenderer == null ? null : sectionListRenderer.toJson(), + }; +} + +class SectionListRenderer { + SectionListRenderer({ + this.contents, + this.trackingParams, + this.subMenu, + }); + + final List contents; + final String trackingParams; + final SubMenu subMenu; + + factory SectionListRenderer.fromRawJson(String str) => + SectionListRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory SectionListRenderer.fromJson(Map json) => + SectionListRenderer( + contents: json["contents"] == null + ? null + : List.from(json["contents"] + .map((x) => SectionListRendererContent.fromJson(x))), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + subMenu: + json["subMenu"] == null ? null : SubMenu.fromJson(json["subMenu"]), + ); + + Map toJson() => { + "contents": contents == null + ? null + : List.from(contents.map((x) => x.toJson())), + "trackingParams": trackingParams == null ? null : trackingParams, + "subMenu": subMenu == null ? null : subMenu.toJson(), + }; +} + +class SectionListRendererContent { + SectionListRendererContent({ + this.itemSectionRenderer, + }); + + final ItemSectionRenderer itemSectionRenderer; + + factory SectionListRendererContent.fromRawJson(String str) => + SectionListRendererContent.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory SectionListRendererContent.fromJson(Map json) => + SectionListRendererContent( + itemSectionRenderer: json["itemSectionRenderer"] == null + ? null + : ItemSectionRenderer.fromJson(json["itemSectionRenderer"]), + ); + + Map toJson() => { + "itemSectionRenderer": + itemSectionRenderer == null ? null : itemSectionRenderer.toJson(), + }; +} + +class ItemSectionRenderer { + ItemSectionRenderer({ + this.contents, + this.trackingParams, + }); + + final List contents; + final String trackingParams; + + factory ItemSectionRenderer.fromRawJson(String str) => + ItemSectionRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ItemSectionRenderer.fromJson(Map json) => + ItemSectionRenderer( + contents: json["contents"] == null + ? null + : List.from(json["contents"] + .map((x) => ItemSectionRendererContent.fromJson(x))), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + ); + + Map toJson() => { + "contents": contents == null + ? null + : List.from(contents.map((x) => x.toJson())), + "trackingParams": trackingParams == null ? null : trackingParams, + }; +} + +class ItemSectionRendererContent { + ItemSectionRendererContent({ + this.gridRenderer, + }); + + final Grid gridRenderer; + + factory ItemSectionRendererContent.fromRawJson(String str) => + ItemSectionRendererContent.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ItemSectionRendererContent.fromJson(Map json) => + ItemSectionRendererContent( + gridRenderer: json["gridRenderer"] == null + ? null + : Grid.fromJson(json["gridRenderer"]), + ); + + Map toJson() => { + "gridRenderer": gridRenderer == null ? null : gridRenderer.toJson(), + }; +} + +class Grid { + Grid({ + this.items, + this.continuations, + this.trackingParams, + }); + + final List items; + final List continuations; + final String trackingParams; + + factory Grid.fromRawJson(String str) => Grid.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Grid.fromJson(Map json) => Grid( + items: json["items"] == null + ? null + : List.from( + json["items"].map((x) => GridContinuationItem.fromJson(x))), + continuations: json["continuations"] == null + ? null + : List.from( + json["continuations"].map((x) => Continuation.fromJson(x))), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + ); + + Map toJson() => { + "items": items == null + ? null + : List.from(items.map((x) => x.toJson())), + "continuations": continuations == null + ? null + : List.from(continuations.map((x) => x.toJson())), + "trackingParams": trackingParams == null ? null : trackingParams, + }; +} + +class Continuation { + Continuation({ + this.nextContinuationData, + }); + + final NextContinuationData nextContinuationData; + + factory Continuation.fromRawJson(String str) => + Continuation.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Continuation.fromJson(Map json) => Continuation( + nextContinuationData: json["nextContinuationData"] == null + ? null + : NextContinuationData.fromJson(json["nextContinuationData"]), + ); + + Map toJson() => { + "nextContinuationData": + nextContinuationData == null ? null : nextContinuationData.toJson(), + }; +} + +class NextContinuationData { + NextContinuationData({ + this.continuation, + this.clickTrackingParams, + }); + + final String continuation; + final String clickTrackingParams; + + factory NextContinuationData.fromRawJson(String str) => + NextContinuationData.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory NextContinuationData.fromJson(Map json) => + NextContinuationData( + continuation: + json["continuation"] == null ? null : json["continuation"], + clickTrackingParams: json["clickTrackingParams"] == null + ? null + : json["clickTrackingParams"], + ); + + Map toJson() => { + "continuation": continuation == null ? null : continuation, + "clickTrackingParams": + clickTrackingParams == null ? null : clickTrackingParams, + }; +} + +class GridContinuationItem { + GridContinuationItem({ + this.gridVideoRenderer, + }); + + final GridVideoRenderer gridVideoRenderer; + + factory GridContinuationItem.fromRawJson(String str) => + GridContinuationItem.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory GridContinuationItem.fromJson(Map json) => + GridContinuationItem( + gridVideoRenderer: json["gridVideoRenderer"] == null + ? null + : GridVideoRenderer.fromJson(json["gridVideoRenderer"]), + ); + + Map toJson() => { + "gridVideoRenderer": + gridVideoRenderer == null ? null : gridVideoRenderer.toJson(), + }; +} + +class GridVideoRenderer { + GridVideoRenderer({ + this.videoId, + this.thumbnail, + this.title, + this.publishedTimeText, + this.viewCountText, + this.navigationEndpoint, + this.ownerBadges, + this.trackingParams, + this.shortViewCountText, + this.menu, + this.thumbnailOverlays, + }); + + final String videoId; + final Avatar thumbnail; + final Title title; + final Text publishedTimeText; + final Text viewCountText; + final GridVideoRendererNavigationEndpoint navigationEndpoint; + final List ownerBadges; + final String trackingParams; + final Text shortViewCountText; + final Menu menu; + final List thumbnailOverlays; + + factory GridVideoRenderer.fromRawJson(String str) => + GridVideoRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory GridVideoRenderer.fromJson(Map json) => + GridVideoRenderer( + videoId: json["videoId"] == null ? null : json["videoId"], + thumbnail: json["thumbnail"] == null + ? null + : Avatar.fromJson(json["thumbnail"]), + title: json["title"] == null ? null : Title.fromJson(json["title"]), + publishedTimeText: json["publishedTimeText"] == null + ? null + : Text.fromJson(json["publishedTimeText"]), + viewCountText: json["viewCountText"] == null + ? null + : Text.fromJson(json["viewCountText"]), + navigationEndpoint: json["navigationEndpoint"] == null + ? null + : GridVideoRendererNavigationEndpoint.fromJson( + json["navigationEndpoint"]), + ownerBadges: json["ownerBadges"] == null + ? null + : List.from( + json["ownerBadges"].map((x) => Badge.fromJson(x))), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + shortViewCountText: json["shortViewCountText"] == null + ? null + : Text.fromJson(json["shortViewCountText"]), + menu: json["menu"] == null ? null : Menu.fromJson(json["menu"]), + thumbnailOverlays: json["thumbnailOverlays"] == null + ? null + : List.from(json["thumbnailOverlays"] + .map((x) => ThumbnailOverlay.fromJson(x))), + ); + + Map toJson() => { + "videoId": videoId == null ? null : videoId, + "thumbnail": thumbnail == null ? null : thumbnail.toJson(), + "title": title == null ? null : title.toJson(), + "publishedTimeText": + publishedTimeText == null ? null : publishedTimeText.toJson(), + "viewCountText": viewCountText == null ? null : viewCountText.toJson(), + "navigationEndpoint": + navigationEndpoint == null ? null : navigationEndpoint.toJson(), + "ownerBadges": ownerBadges == null + ? null + : List.from(ownerBadges.map((x) => x.toJson())), + "trackingParams": trackingParams == null ? null : trackingParams, + "shortViewCountText": + shortViewCountText == null ? null : shortViewCountText.toJson(), + "menu": menu == null ? null : menu.toJson(), + "thumbnailOverlays": thumbnailOverlays == null + ? null + : List.from(thumbnailOverlays.map((x) => x.toJson())), + }; +} + +class Menu { + Menu({ + this.menuRenderer, + }); + + final MenuMenuRenderer menuRenderer; + + factory Menu.fromRawJson(String str) => Menu.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Menu.fromJson(Map json) => Menu( + menuRenderer: json["menuRenderer"] == null + ? null + : MenuMenuRenderer.fromJson(json["menuRenderer"]), + ); + + Map toJson() => { + "menuRenderer": menuRenderer == null ? null : menuRenderer.toJson(), + }; +} + +class MenuMenuRenderer { + MenuMenuRenderer({ + this.items, + this.trackingParams, + this.accessibility, + }); + + final List items; + final String trackingParams; + final Accessibility accessibility; + + factory MenuMenuRenderer.fromRawJson(String str) => + MenuMenuRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory MenuMenuRenderer.fromJson(Map json) => + MenuMenuRenderer( + items: json["items"] == null + ? null + : List.from( + json["items"].map((x) => MenuRendererItem.fromJson(x))), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + accessibility: json["accessibility"] == null + ? null + : Accessibility.fromJson(json["accessibility"]), + ); + + Map toJson() => { + "items": items == null + ? null + : List.from(items.map((x) => x.toJson())), + "trackingParams": trackingParams == null ? null : trackingParams, + "accessibility": accessibility == null ? null : accessibility.toJson(), + }; +} + +class Accessibility { + Accessibility({ + this.accessibilityData, + }); + + final AccessibilityData accessibilityData; + + factory Accessibility.fromRawJson(String str) => + Accessibility.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Accessibility.fromJson(Map json) => Accessibility( + accessibilityData: json["accessibilityData"] == null + ? null + : AccessibilityData.fromJson(json["accessibilityData"]), + ); + + Map toJson() => { + "accessibilityData": + accessibilityData == null ? null : accessibilityData.toJson(), + }; +} + +class AccessibilityData { + AccessibilityData({ + this.label, + }); + + final String label; + + factory AccessibilityData.fromRawJson(String str) => + AccessibilityData.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory AccessibilityData.fromJson(Map json) => + AccessibilityData( + label: json["label"] == null ? null : json["label"], + ); + + Map toJson() => { + "label": label == null ? null : label, + }; +} + +class MenuRendererItem { + MenuRendererItem({ + this.menuServiceItemRenderer, + }); + + final MenuServiceItemRenderer menuServiceItemRenderer; + + factory MenuRendererItem.fromRawJson(String str) => + MenuRendererItem.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory MenuRendererItem.fromJson(Map json) => + MenuRendererItem( + menuServiceItemRenderer: json["menuServiceItemRenderer"] == null + ? null + : MenuServiceItemRenderer.fromJson(json["menuServiceItemRenderer"]), + ); + + Map toJson() => { + "menuServiceItemRenderer": menuServiceItemRenderer == null + ? null + : menuServiceItemRenderer.toJson(), + }; +} + +class MenuServiceItemRenderer { + MenuServiceItemRenderer({ + this.text, + this.icon, + this.serviceEndpoint, + this.trackingParams, + }); + + final SubscriberCountText text; + final IconImage icon; + final ServiceEndpoint serviceEndpoint; + final String trackingParams; + + factory MenuServiceItemRenderer.fromRawJson(String str) => + MenuServiceItemRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory MenuServiceItemRenderer.fromJson(Map json) => + MenuServiceItemRenderer( + text: json["text"] == null + ? null + : SubscriberCountText.fromJson(json["text"]), + icon: json["icon"] == null ? null : IconImage.fromJson(json["icon"]), + serviceEndpoint: json["serviceEndpoint"] == null + ? null + : ServiceEndpoint.fromJson(json["serviceEndpoint"]), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + ); + + Map toJson() => { + "text": text == null ? null : text.toJson(), + "icon": icon == null ? null : icon.toJson(), + "serviceEndpoint": + serviceEndpoint == null ? null : serviceEndpoint.toJson(), + "trackingParams": trackingParams == null ? null : trackingParams, + }; +} + +class IconImage { + IconImage({ + this.iconType, + }); + + final IconType iconType; + + factory IconImage.fromRawJson(String str) => + IconImage.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory IconImage.fromJson(Map json) => IconImage( + iconType: json["iconType"] == null + ? null + : iconTypeValues.map[json["iconType"]], + ); + + Map toJson() => { + "iconType": iconType == null ? null : iconTypeValues.reverse[iconType], + }; +} + +enum IconType { + ADD_TO_QUEUE_TAIL, + OFFICIAL_ARTIST_BADGE, + CHECK, + PLAYLIST_ADD_CHECK, + WATCH_LATER, + SORT, + YOUTUBE_LOGO, + SEARCH, + AVATAR_LOGGED_OUT, + VIDEO_CALL, + APPS, + MORE_VERT, + CREATION_UPLOAD, + CREATION_LIVE, + UNPLUGGED_LOGO, + YOUTUBE_MUSIC, + YOUTUBE_KIDS_ROUND, + YOUTUBE_ROUND +} + +final iconTypeValues = EnumValues({ + "ADD_TO_QUEUE_TAIL": IconType.ADD_TO_QUEUE_TAIL, + "APPS": IconType.APPS, + "AVATAR_LOGGED_OUT": IconType.AVATAR_LOGGED_OUT, + "CHECK": IconType.CHECK, + "CREATION_LIVE": IconType.CREATION_LIVE, + "CREATION_UPLOAD": IconType.CREATION_UPLOAD, + "MORE_VERT": IconType.MORE_VERT, + "OFFICIAL_ARTIST_BADGE": IconType.OFFICIAL_ARTIST_BADGE, + "PLAYLIST_ADD_CHECK": IconType.PLAYLIST_ADD_CHECK, + "SEARCH": IconType.SEARCH, + "SORT": IconType.SORT, + "UNPLUGGED_LOGO": IconType.UNPLUGGED_LOGO, + "VIDEO_CALL": IconType.VIDEO_CALL, + "WATCH_LATER": IconType.WATCH_LATER, + "YOUTUBE_KIDS_ROUND": IconType.YOUTUBE_KIDS_ROUND, + "YOUTUBE_LOGO": IconType.YOUTUBE_LOGO, + "YOUTUBE_MUSIC": IconType.YOUTUBE_MUSIC, + "YOUTUBE_ROUND": IconType.YOUTUBE_ROUND +}); + +class ServiceEndpoint { + ServiceEndpoint({ + this.clickTrackingParams, + this.commandMetadata, + this.signalServiceEndpoint, + }); + + final String clickTrackingParams; + final ServiceEndpointCommandMetadata commandMetadata; + final ServiceEndpointSignalServiceEndpoint signalServiceEndpoint; + + factory ServiceEndpoint.fromRawJson(String str) => + ServiceEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ServiceEndpoint.fromJson(Map json) => + ServiceEndpoint( + clickTrackingParams: json["clickTrackingParams"] == null + ? null + : json["clickTrackingParams"], + commandMetadata: json["commandMetadata"] == null + ? null + : ServiceEndpointCommandMetadata.fromJson(json["commandMetadata"]), + signalServiceEndpoint: json["signalServiceEndpoint"] == null + ? null + : ServiceEndpointSignalServiceEndpoint.fromJson( + json["signalServiceEndpoint"]), + ); + + Map toJson() => { + "clickTrackingParams": + clickTrackingParams == null ? null : clickTrackingParams, + "commandMetadata": + commandMetadata == null ? null : commandMetadata.toJson(), + "signalServiceEndpoint": signalServiceEndpoint == null + ? null + : signalServiceEndpoint.toJson(), + }; +} + +class ServiceEndpointCommandMetadata { + ServiceEndpointCommandMetadata({ + this.webCommandMetadata, + }); + + final FluffyWebCommandMetadata webCommandMetadata; + + factory ServiceEndpointCommandMetadata.fromRawJson(String str) => + ServiceEndpointCommandMetadata.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ServiceEndpointCommandMetadata.fromJson(Map json) => + ServiceEndpointCommandMetadata( + webCommandMetadata: json["webCommandMetadata"] == null + ? null + : FluffyWebCommandMetadata.fromJson(json["webCommandMetadata"]), + ); + + Map toJson() => { + "webCommandMetadata": + webCommandMetadata == null ? null : webCommandMetadata.toJson(), + }; +} + +class FluffyWebCommandMetadata { + FluffyWebCommandMetadata({ + this.url, + this.sendPost, + }); + + final Url url; + final bool sendPost; + + factory FluffyWebCommandMetadata.fromRawJson(String str) => + FluffyWebCommandMetadata.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory FluffyWebCommandMetadata.fromJson(Map json) => + FluffyWebCommandMetadata( + url: json["url"] == null ? null : urlValues.map[json["url"]], + sendPost: json["sendPost"] == null ? null : json["sendPost"], + ); + + Map toJson() => { + "url": url == null ? null : urlValues.reverse[url], + "sendPost": sendPost == null ? null : sendPost, + }; +} + +enum Url { SERVICE_AJAX } + +final urlValues = EnumValues({"/service_ajax": Url.SERVICE_AJAX}); + +class ServiceEndpointSignalServiceEndpoint { + ServiceEndpointSignalServiceEndpoint({ + this.signal, + this.actions, + }); + + final Signal signal; + final List actions; + + factory ServiceEndpointSignalServiceEndpoint.fromRawJson(String str) => + ServiceEndpointSignalServiceEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ServiceEndpointSignalServiceEndpoint.fromJson( + Map json) => + ServiceEndpointSignalServiceEndpoint( + signal: + json["signal"] == null ? null : signalValues.map[json["signal"]], + actions: json["actions"] == null + ? null + : List.from( + json["actions"].map((x) => PurpleAction.fromJson(x))), + ); + + Map toJson() => { + "signal": signal == null ? null : signalValues.reverse[signal], + "actions": actions == null + ? null + : List.from(actions.map((x) => x.toJson())), + }; +} + +class PurpleAction { + PurpleAction({ + this.addToPlaylistCommand, + }); + + final AddToPlaylistCommand addToPlaylistCommand; + + factory PurpleAction.fromRawJson(String str) => + PurpleAction.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory PurpleAction.fromJson(Map json) => PurpleAction( + addToPlaylistCommand: json["addToPlaylistCommand"] == null + ? null + : AddToPlaylistCommand.fromJson(json["addToPlaylistCommand"]), + ); + + Map toJson() => { + "addToPlaylistCommand": + addToPlaylistCommand == null ? null : addToPlaylistCommand.toJson(), + }; +} + +class AddToPlaylistCommand { + AddToPlaylistCommand({ + this.openMiniplayer, + this.openListPanel, + this.videoId, + this.listType, + this.onCreateListCommand, + this.videoIds, + }); + + final bool openMiniplayer; + final bool openListPanel; + final String videoId; + final ListType listType; + final OnCreateListCommand onCreateListCommand; + final List videoIds; + + factory AddToPlaylistCommand.fromRawJson(String str) => + AddToPlaylistCommand.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory AddToPlaylistCommand.fromJson(Map json) => + AddToPlaylistCommand( + openMiniplayer: + json["openMiniplayer"] == null ? null : json["openMiniplayer"], + openListPanel: + json["openListPanel"] == null ? null : json["openListPanel"], + videoId: json["videoId"] == null ? null : json["videoId"], + listType: json["listType"] == null + ? null + : listTypeValues.map[json["listType"]], + onCreateListCommand: json["onCreateListCommand"] == null + ? null + : OnCreateListCommand.fromJson(json["onCreateListCommand"]), + videoIds: json["videoIds"] == null + ? null + : List.from(json["videoIds"].map((x) => x)), + ); + + Map toJson() => { + "openMiniplayer": openMiniplayer == null ? null : openMiniplayer, + "openListPanel": openListPanel == null ? null : openListPanel, + "videoId": videoId == null ? null : videoId, + "listType": listType == null ? null : listTypeValues.reverse[listType], + "onCreateListCommand": + onCreateListCommand == null ? null : onCreateListCommand.toJson(), + "videoIds": videoIds == null + ? null + : List.from(videoIds.map((x) => x)), + }; +} + +enum ListType { PLAYLIST_EDIT_LIST_TYPE_QUEUE } + +final listTypeValues = EnumValues( + {"PLAYLIST_EDIT_LIST_TYPE_QUEUE": ListType.PLAYLIST_EDIT_LIST_TYPE_QUEUE}); + +class OnCreateListCommand { + OnCreateListCommand({ + this.clickTrackingParams, + this.commandMetadata, + this.createPlaylistServiceEndpoint, + }); + + final String clickTrackingParams; + final OnCreateListCommandCommandMetadata commandMetadata; + final CreatePlaylistServiceEndpoint createPlaylistServiceEndpoint; + + factory OnCreateListCommand.fromRawJson(String str) => + OnCreateListCommand.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory OnCreateListCommand.fromJson(Map json) => + OnCreateListCommand( + clickTrackingParams: json["clickTrackingParams"] == null + ? null + : json["clickTrackingParams"], + commandMetadata: json["commandMetadata"] == null + ? null + : OnCreateListCommandCommandMetadata.fromJson( + json["commandMetadata"]), + createPlaylistServiceEndpoint: + json["createPlaylistServiceEndpoint"] == null + ? null + : CreatePlaylistServiceEndpoint.fromJson( + json["createPlaylistServiceEndpoint"]), + ); + + Map toJson() => { + "clickTrackingParams": + clickTrackingParams == null ? null : clickTrackingParams, + "commandMetadata": + commandMetadata == null ? null : commandMetadata.toJson(), + "createPlaylistServiceEndpoint": createPlaylistServiceEndpoint == null + ? null + : createPlaylistServiceEndpoint.toJson(), + }; +} + +class OnCreateListCommandCommandMetadata { + OnCreateListCommandCommandMetadata({ + this.webCommandMetadata, + }); + + final TentacledWebCommandMetadata webCommandMetadata; + + factory OnCreateListCommandCommandMetadata.fromRawJson(String str) => + OnCreateListCommandCommandMetadata.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory OnCreateListCommandCommandMetadata.fromJson( + Map json) => + OnCreateListCommandCommandMetadata( + webCommandMetadata: json["webCommandMetadata"] == null + ? null + : TentacledWebCommandMetadata.fromJson(json["webCommandMetadata"]), + ); + + Map toJson() => { + "webCommandMetadata": + webCommandMetadata == null ? null : webCommandMetadata.toJson(), + }; +} + +class TentacledWebCommandMetadata { + TentacledWebCommandMetadata({ + this.url, + this.sendPost, + this.apiUrl, + }); + + final Url url; + final bool sendPost; + final ApiUrl apiUrl; + + factory TentacledWebCommandMetadata.fromRawJson(String str) => + TentacledWebCommandMetadata.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory TentacledWebCommandMetadata.fromJson(Map json) => + TentacledWebCommandMetadata( + url: json["url"] == null ? null : urlValues.map[json["url"]], + sendPost: json["sendPost"] == null ? null : json["sendPost"], + apiUrl: + json["apiUrl"] == null ? null : apiUrlValues.map[json["apiUrl"]], + ); + + Map toJson() => { + "url": url == null ? null : urlValues.reverse[url], + "sendPost": sendPost == null ? null : sendPost, + "apiUrl": apiUrl == null ? null : apiUrlValues.reverse[apiUrl], + }; +} + +enum ApiUrl { + YOUTUBEI_V1_PLAYLIST_CREATE, + YOUTUBEI_V1_BROWSE_EDIT_PLAYLIST, + YOUTUBEI_V1_ACCOUNT_ACCOUNT_MENU +} + +final apiUrlValues = EnumValues({ + "/youtubei/v1/account/account_menu": ApiUrl.YOUTUBEI_V1_ACCOUNT_ACCOUNT_MENU, + "/youtubei/v1/browse/edit_playlist": ApiUrl.YOUTUBEI_V1_BROWSE_EDIT_PLAYLIST, + "/youtubei/v1/playlist/create": ApiUrl.YOUTUBEI_V1_PLAYLIST_CREATE +}); + +class CreatePlaylistServiceEndpoint { + CreatePlaylistServiceEndpoint({ + this.videoIds, + this.hack, + this.params, + }); + + final List videoIds; + final bool hack; + final Params params; + + factory CreatePlaylistServiceEndpoint.fromRawJson(String str) => + CreatePlaylistServiceEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory CreatePlaylistServiceEndpoint.fromJson(Map json) => + CreatePlaylistServiceEndpoint( + videoIds: json["videoIds"] == null + ? null + : List.from(json["videoIds"].map((x) => x)), + hack: json["hack"] == null ? null : json["hack"], + params: + json["params"] == null ? null : paramsValues.map[json["params"]], + ); + + Map toJson() => { + "videoIds": videoIds == null + ? null + : List.from(videoIds.map((x) => x)), + "hack": hack == null ? null : hack, + "params": params == null ? null : paramsValues.reverse[params], + }; +} + +enum Params { CAQ_3_D } + +final paramsValues = EnumValues({"CAQ%3D": Params.CAQ_3_D}); + +enum Signal { CLIENT_SIGNAL } + +final signalValues = EnumValues({"CLIENT_SIGNAL": Signal.CLIENT_SIGNAL}); + +class SubscriberCountText { + SubscriberCountText({ + this.runs, + }); + + final List runs; + + factory SubscriberCountText.fromRawJson(String str) => + SubscriberCountText.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory SubscriberCountText.fromJson(Map json) => + SubscriberCountText( + runs: json["runs"] == null + ? null + : List.from(json["runs"].map((x) => Run.fromJson(x))), + ); + + Map toJson() => { + "runs": runs == null + ? null + : List.from(runs.map((x) => x.toJson())), + }; +} + +class Run { + Run({ + this.text, + }); + + final String text; + + factory Run.fromRawJson(String str) => Run.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Run.fromJson(Map json) => Run( + text: json["text"] == null ? null : json["text"], + ); + + Map toJson() => { + "text": text == null ? null : text, + }; +} + +class GridVideoRendererNavigationEndpoint { + GridVideoRendererNavigationEndpoint({ + this.clickTrackingParams, + this.commandMetadata, + this.watchEndpoint, + }); + + final String clickTrackingParams; + final NextEndpointCommandMetadata commandMetadata; + final WatchEndpoint watchEndpoint; + + factory GridVideoRendererNavigationEndpoint.fromRawJson(String str) => + GridVideoRendererNavigationEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory GridVideoRendererNavigationEndpoint.fromJson( + Map json) => + GridVideoRendererNavigationEndpoint( + clickTrackingParams: json["clickTrackingParams"] == null + ? null + : json["clickTrackingParams"], + commandMetadata: json["commandMetadata"] == null + ? null + : NextEndpointCommandMetadata.fromJson(json["commandMetadata"]), + watchEndpoint: json["watchEndpoint"] == null + ? null + : WatchEndpoint.fromJson(json["watchEndpoint"]), + ); + + Map toJson() => { + "clickTrackingParams": + clickTrackingParams == null ? null : clickTrackingParams, + "commandMetadata": + commandMetadata == null ? null : commandMetadata.toJson(), + "watchEndpoint": watchEndpoint == null ? null : watchEndpoint.toJson(), + }; +} + +class WatchEndpoint { + WatchEndpoint({ + this.videoId, + }); + + final String videoId; + + factory WatchEndpoint.fromRawJson(String str) => + WatchEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory WatchEndpoint.fromJson(Map json) => WatchEndpoint( + videoId: json["videoId"] == null ? null : json["videoId"], + ); + + Map toJson() => { + "videoId": videoId == null ? null : videoId, + }; +} + +class Badge { + Badge({ + this.metadataBadgeRenderer, + }); + + final MetadataBadgeRenderer metadataBadgeRenderer; + + factory Badge.fromRawJson(String str) => Badge.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Badge.fromJson(Map json) => Badge( + metadataBadgeRenderer: json["metadataBadgeRenderer"] == null + ? null + : MetadataBadgeRenderer.fromJson(json["metadataBadgeRenderer"]), + ); + + Map toJson() => { + "metadataBadgeRenderer": metadataBadgeRenderer == null + ? null + : metadataBadgeRenderer.toJson(), + }; +} + +class MetadataBadgeRenderer { + MetadataBadgeRenderer({ + this.icon, + this.style, + this.tooltip, + this.trackingParams, + }); + + final IconImage icon; + final MetadataBadgeRendererStyle style; + final Tooltip tooltip; + final String trackingParams; + + factory MetadataBadgeRenderer.fromRawJson(String str) => + MetadataBadgeRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory MetadataBadgeRenderer.fromJson(Map json) => + MetadataBadgeRenderer( + icon: json["icon"] == null ? null : IconImage.fromJson(json["icon"]), + style: json["style"] == null + ? null + : metadataBadgeRendererStyleValues.map[json["style"]], + tooltip: + json["tooltip"] == null ? null : tooltipValues.map[json["tooltip"]], + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + ); + + Map toJson() => { + "icon": icon == null ? null : icon.toJson(), + "style": style == null + ? null + : metadataBadgeRendererStyleValues.reverse[style], + "tooltip": tooltip == null ? null : tooltipValues.reverse[tooltip], + "trackingParams": trackingParams == null ? null : trackingParams, + }; +} + +enum MetadataBadgeRendererStyle { BADGE_STYLE_TYPE_VERIFIED_ARTIST } + +final metadataBadgeRendererStyleValues = EnumValues({ + "BADGE_STYLE_TYPE_VERIFIED_ARTIST": + MetadataBadgeRendererStyle.BADGE_STYLE_TYPE_VERIFIED_ARTIST +}); + +enum Tooltip { OFFICIAL_ARTIST_CHANNEL } + +final tooltipValues = + EnumValues({"Official Artist Channel": Tooltip.OFFICIAL_ARTIST_CHANNEL}); + +class Text { + Text({ + this.simpleText, + }); + + final String simpleText; + + factory Text.fromRawJson(String str) => Text.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Text.fromJson(Map json) => Text( + simpleText: json["simpleText"] == null ? null : json["simpleText"], + ); + + Map toJson() => { + "simpleText": simpleText == null ? null : simpleText, + }; +} + +class Avatar { + Avatar({ + this.thumbnails, + }); + + final List thumbnails; + + factory Avatar.fromRawJson(String str) => Avatar.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Avatar.fromJson(Map json) => Avatar( + thumbnails: json["thumbnails"] == null + ? null + : List.from( + json["thumbnails"].map((x) => Thumbnail.fromJson(x))), + ); + + Map toJson() => { + "thumbnails": thumbnails == null + ? null + : List.from(thumbnails.map((x) => x.toJson())), + }; +} + +class Thumbnail { + Thumbnail({ + this.url, + this.width, + this.height, + }); + + final String url; + final int width; + final int height; + + factory Thumbnail.fromRawJson(String str) => + Thumbnail.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Thumbnail.fromJson(Map json) => Thumbnail( + url: json["url"] == null ? null : json["url"], + width: json["width"] == null ? null : json["width"], + height: json["height"] == null ? null : json["height"], + ); + + Map toJson() => { + "url": url == null ? null : url, + "width": width == null ? null : width, + "height": height == null ? null : height, + }; +} + +class ThumbnailOverlay { + ThumbnailOverlay({ + this.thumbnailOverlayTimeStatusRenderer, + this.thumbnailOverlayToggleButtonRenderer, + this.thumbnailOverlayNowPlayingRenderer, + }); + + final ThumbnailOverlayTimeStatusRenderer thumbnailOverlayTimeStatusRenderer; + final ThumbnailOverlayToggleButtonRenderer + thumbnailOverlayToggleButtonRenderer; + final ThumbnailOverlayNowPlayingRenderer thumbnailOverlayNowPlayingRenderer; + + factory ThumbnailOverlay.fromRawJson(String str) => + ThumbnailOverlay.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ThumbnailOverlay.fromJson(Map json) => + ThumbnailOverlay( + thumbnailOverlayTimeStatusRenderer: + json["thumbnailOverlayTimeStatusRenderer"] == null + ? null + : ThumbnailOverlayTimeStatusRenderer.fromJson( + json["thumbnailOverlayTimeStatusRenderer"]), + thumbnailOverlayToggleButtonRenderer: + json["thumbnailOverlayToggleButtonRenderer"] == null + ? null + : ThumbnailOverlayToggleButtonRenderer.fromJson( + json["thumbnailOverlayToggleButtonRenderer"]), + thumbnailOverlayNowPlayingRenderer: + json["thumbnailOverlayNowPlayingRenderer"] == null + ? null + : ThumbnailOverlayNowPlayingRenderer.fromJson( + json["thumbnailOverlayNowPlayingRenderer"]), + ); + + Map toJson() => { + "thumbnailOverlayTimeStatusRenderer": + thumbnailOverlayTimeStatusRenderer == null + ? null + : thumbnailOverlayTimeStatusRenderer.toJson(), + "thumbnailOverlayToggleButtonRenderer": + thumbnailOverlayToggleButtonRenderer == null + ? null + : thumbnailOverlayToggleButtonRenderer.toJson(), + "thumbnailOverlayNowPlayingRenderer": + thumbnailOverlayNowPlayingRenderer == null + ? null + : thumbnailOverlayNowPlayingRenderer.toJson(), + }; +} + +class ThumbnailOverlayNowPlayingRenderer { + ThumbnailOverlayNowPlayingRenderer({ + this.text, + }); + + final SubscriberCountText text; + + factory ThumbnailOverlayNowPlayingRenderer.fromRawJson(String str) => + ThumbnailOverlayNowPlayingRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ThumbnailOverlayNowPlayingRenderer.fromJson( + Map json) => + ThumbnailOverlayNowPlayingRenderer( + text: json["text"] == null + ? null + : SubscriberCountText.fromJson(json["text"]), + ); + + Map toJson() => { + "text": text == null ? null : text.toJson(), + }; +} + +class ThumbnailOverlayTimeStatusRenderer { + ThumbnailOverlayTimeStatusRenderer({ + this.text, + this.style, + }); + + final Title text; + final ThumbnailOverlayTimeStatusRendererStyle style; + + factory ThumbnailOverlayTimeStatusRenderer.fromRawJson(String str) => + ThumbnailOverlayTimeStatusRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ThumbnailOverlayTimeStatusRenderer.fromJson( + Map json) => + ThumbnailOverlayTimeStatusRenderer( + text: json["text"] == null ? null : Title.fromJson(json["text"]), + style: json["style"] == null + ? null + : thumbnailOverlayTimeStatusRendererStyleValues.map[json["style"]], + ); + + Map toJson() => { + "text": text == null ? null : text.toJson(), + "style": style == null + ? null + : thumbnailOverlayTimeStatusRendererStyleValues.reverse[style], + }; +} + +enum ThumbnailOverlayTimeStatusRendererStyle { DEFAULT } + +final thumbnailOverlayTimeStatusRendererStyleValues = + EnumValues({"DEFAULT": ThumbnailOverlayTimeStatusRendererStyle.DEFAULT}); + +class Title { + Title({ + this.accessibility, + this.simpleText, + }); + + final Accessibility accessibility; + final String simpleText; + + factory Title.fromRawJson(String str) => Title.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Title.fromJson(Map json) => Title( + accessibility: json["accessibility"] == null + ? null + : Accessibility.fromJson(json["accessibility"]), + simpleText: json["simpleText"] == null ? null : json["simpleText"], + ); + + Map toJson() => { + "accessibility": accessibility == null ? null : accessibility.toJson(), + "simpleText": simpleText == null ? null : simpleText, + }; +} + +class ThumbnailOverlayToggleButtonRenderer { + ThumbnailOverlayToggleButtonRenderer({ + this.isToggled, + this.untoggledIcon, + this.toggledIcon, + this.untoggledTooltip, + this.toggledTooltip, + this.untoggledServiceEndpoint, + this.toggledServiceEndpoint, + this.untoggledAccessibility, + this.toggledAccessibility, + this.trackingParams, + }); + + final bool isToggled; + final IconImage untoggledIcon; + final IconImage toggledIcon; + final UntoggledTooltip untoggledTooltip; + final ToggledTooltip toggledTooltip; + final UntoggledServiceEndpoint untoggledServiceEndpoint; + final ToggledServiceEndpoint toggledServiceEndpoint; + final Accessibility untoggledAccessibility; + final Accessibility toggledAccessibility; + final String trackingParams; + + factory ThumbnailOverlayToggleButtonRenderer.fromRawJson(String str) => + ThumbnailOverlayToggleButtonRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ThumbnailOverlayToggleButtonRenderer.fromJson( + Map json) => + ThumbnailOverlayToggleButtonRenderer( + isToggled: json["isToggled"] == null ? null : json["isToggled"], + untoggledIcon: json["untoggledIcon"] == null + ? null + : IconImage.fromJson(json["untoggledIcon"]), + toggledIcon: json["toggledIcon"] == null + ? null + : IconImage.fromJson(json["toggledIcon"]), + untoggledTooltip: json["untoggledTooltip"] == null + ? null + : untoggledTooltipValues.map[json["untoggledTooltip"]], + toggledTooltip: json["toggledTooltip"] == null + ? null + : toggledTooltipValues.map[json["toggledTooltip"]], + untoggledServiceEndpoint: json["untoggledServiceEndpoint"] == null + ? null + : UntoggledServiceEndpoint.fromJson( + json["untoggledServiceEndpoint"]), + toggledServiceEndpoint: json["toggledServiceEndpoint"] == null + ? null + : ToggledServiceEndpoint.fromJson(json["toggledServiceEndpoint"]), + untoggledAccessibility: json["untoggledAccessibility"] == null + ? null + : Accessibility.fromJson(json["untoggledAccessibility"]), + toggledAccessibility: json["toggledAccessibility"] == null + ? null + : Accessibility.fromJson(json["toggledAccessibility"]), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + ); + + Map toJson() => { + "isToggled": isToggled == null ? null : isToggled, + "untoggledIcon": untoggledIcon == null ? null : untoggledIcon.toJson(), + "toggledIcon": toggledIcon == null ? null : toggledIcon.toJson(), + "untoggledTooltip": untoggledTooltip == null + ? null + : untoggledTooltipValues.reverse[untoggledTooltip], + "toggledTooltip": toggledTooltip == null + ? null + : toggledTooltipValues.reverse[toggledTooltip], + "untoggledServiceEndpoint": untoggledServiceEndpoint == null + ? null + : untoggledServiceEndpoint.toJson(), + "toggledServiceEndpoint": toggledServiceEndpoint == null + ? null + : toggledServiceEndpoint.toJson(), + "untoggledAccessibility": untoggledAccessibility == null + ? null + : untoggledAccessibility.toJson(), + "toggledAccessibility": + toggledAccessibility == null ? null : toggledAccessibility.toJson(), + "trackingParams": trackingParams == null ? null : trackingParams, + }; +} + +class ToggledServiceEndpoint { + ToggledServiceEndpoint({ + this.clickTrackingParams, + this.commandMetadata, + this.playlistEditEndpoint, + }); + + final String clickTrackingParams; + final OnCreateListCommandCommandMetadata commandMetadata; + final ToggledServiceEndpointPlaylistEditEndpoint playlistEditEndpoint; + + factory ToggledServiceEndpoint.fromRawJson(String str) => + ToggledServiceEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ToggledServiceEndpoint.fromJson(Map json) => + ToggledServiceEndpoint( + clickTrackingParams: json["clickTrackingParams"] == null + ? null + : json["clickTrackingParams"], + commandMetadata: json["commandMetadata"] == null + ? null + : OnCreateListCommandCommandMetadata.fromJson( + json["commandMetadata"]), + playlistEditEndpoint: json["playlistEditEndpoint"] == null + ? null + : ToggledServiceEndpointPlaylistEditEndpoint.fromJson( + json["playlistEditEndpoint"]), + ); + + Map toJson() => { + "clickTrackingParams": + clickTrackingParams == null ? null : clickTrackingParams, + "commandMetadata": + commandMetadata == null ? null : commandMetadata.toJson(), + "playlistEditEndpoint": + playlistEditEndpoint == null ? null : playlistEditEndpoint.toJson(), + }; +} + +class ToggledServiceEndpointPlaylistEditEndpoint { + ToggledServiceEndpointPlaylistEditEndpoint({ + this.playlistId, + this.actions, + }); + + final PlaylistId playlistId; + final List actions; + + factory ToggledServiceEndpointPlaylistEditEndpoint.fromRawJson(String str) => + ToggledServiceEndpointPlaylistEditEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ToggledServiceEndpointPlaylistEditEndpoint.fromJson( + Map json) => + ToggledServiceEndpointPlaylistEditEndpoint( + playlistId: json["playlistId"] == null + ? null + : playlistIdValues.map[json["playlistId"]], + actions: json["actions"] == null + ? null + : List.from( + json["actions"].map((x) => FluffyAction.fromJson(x))), + ); + + Map toJson() => { + "playlistId": + playlistId == null ? null : playlistIdValues.reverse[playlistId], + "actions": actions == null + ? null + : List.from(actions.map((x) => x.toJson())), + }; +} + +class FluffyAction { + FluffyAction({ + this.action, + this.removedVideoId, + }); + + final IndecentAction action; + final String removedVideoId; + + factory FluffyAction.fromRawJson(String str) => + FluffyAction.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory FluffyAction.fromJson(Map json) => FluffyAction( + action: json["action"] == null + ? null + : indecentActionValues.map[json["action"]], + removedVideoId: + json["removedVideoId"] == null ? null : json["removedVideoId"], + ); + + Map toJson() => { + "action": action == null ? null : indecentActionValues.reverse[action], + "removedVideoId": removedVideoId == null ? null : removedVideoId, + }; +} + +enum IndecentAction { ACTION_REMOVE_VIDEO_BY_VIDEO_ID } + +final indecentActionValues = EnumValues({ + "ACTION_REMOVE_VIDEO_BY_VIDEO_ID": + IndecentAction.ACTION_REMOVE_VIDEO_BY_VIDEO_ID +}); + +enum PlaylistId { WL } + +final playlistIdValues = EnumValues({"WL": PlaylistId.WL}); + +enum ToggledTooltip { ADDED } + +final toggledTooltipValues = EnumValues({"Added": ToggledTooltip.ADDED}); + +class UntoggledServiceEndpoint { + UntoggledServiceEndpoint({ + this.clickTrackingParams, + this.commandMetadata, + this.playlistEditEndpoint, + this.signalServiceEndpoint, + }); + + final String clickTrackingParams; + final OnCreateListCommandCommandMetadata commandMetadata; + final UntoggledServiceEndpointPlaylistEditEndpoint playlistEditEndpoint; + final ServiceEndpointSignalServiceEndpoint signalServiceEndpoint; + + factory UntoggledServiceEndpoint.fromRawJson(String str) => + UntoggledServiceEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory UntoggledServiceEndpoint.fromJson(Map json) => + UntoggledServiceEndpoint( + clickTrackingParams: json["clickTrackingParams"] == null + ? null + : json["clickTrackingParams"], + commandMetadata: json["commandMetadata"] == null + ? null + : OnCreateListCommandCommandMetadata.fromJson( + json["commandMetadata"]), + playlistEditEndpoint: json["playlistEditEndpoint"] == null + ? null + : UntoggledServiceEndpointPlaylistEditEndpoint.fromJson( + json["playlistEditEndpoint"]), + signalServiceEndpoint: json["signalServiceEndpoint"] == null + ? null + : ServiceEndpointSignalServiceEndpoint.fromJson( + json["signalServiceEndpoint"]), + ); + + Map toJson() => { + "clickTrackingParams": + clickTrackingParams == null ? null : clickTrackingParams, + "commandMetadata": + commandMetadata == null ? null : commandMetadata.toJson(), + "playlistEditEndpoint": + playlistEditEndpoint == null ? null : playlistEditEndpoint.toJson(), + "signalServiceEndpoint": signalServiceEndpoint == null + ? null + : signalServiceEndpoint.toJson(), + }; +} + +class UntoggledServiceEndpointPlaylistEditEndpoint { + UntoggledServiceEndpointPlaylistEditEndpoint({ + this.playlistId, + this.actions, + }); + + final PlaylistId playlistId; + final List actions; + + factory UntoggledServiceEndpointPlaylistEditEndpoint.fromRawJson( + String str) => + UntoggledServiceEndpointPlaylistEditEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory UntoggledServiceEndpointPlaylistEditEndpoint.fromJson( + Map json) => + UntoggledServiceEndpointPlaylistEditEndpoint( + playlistId: json["playlistId"] == null + ? null + : playlistIdValues.map[json["playlistId"]], + actions: json["actions"] == null + ? null + : List.from( + json["actions"].map((x) => TentacledAction.fromJson(x))), + ); + + Map toJson() => { + "playlistId": + playlistId == null ? null : playlistIdValues.reverse[playlistId], + "actions": actions == null + ? null + : List.from(actions.map((x) => x.toJson())), + }; +} + +class TentacledAction { + TentacledAction({ + this.addedVideoId, + this.action, + }); + + final String addedVideoId; + final HilariousAction action; + + factory TentacledAction.fromRawJson(String str) => + TentacledAction.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory TentacledAction.fromJson(Map json) => + TentacledAction( + addedVideoId: + json["addedVideoId"] == null ? null : json["addedVideoId"], + action: json["action"] == null + ? null + : hilariousActionValues.map[json["action"]], + ); + + Map toJson() => { + "addedVideoId": addedVideoId == null ? null : addedVideoId, + "action": action == null ? null : hilariousActionValues.reverse[action], + }; +} + +enum HilariousAction { ACTION_ADD_VIDEO } + +final hilariousActionValues = + EnumValues({"ACTION_ADD_VIDEO": HilariousAction.ACTION_ADD_VIDEO}); + +enum UntoggledTooltip { WATCH_LATER, ADD_TO_QUEUE } + +final untoggledTooltipValues = EnumValues({ + "Add to queue": UntoggledTooltip.ADD_TO_QUEUE, + "Watch later": UntoggledTooltip.WATCH_LATER +}); + +class SubMenu { + SubMenu({ + this.channelSubMenuRenderer, + }); + + final ChannelSubMenuRenderer channelSubMenuRenderer; + + factory SubMenu.fromRawJson(String str) => SubMenu.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory SubMenu.fromJson(Map json) => SubMenu( + channelSubMenuRenderer: json["channelSubMenuRenderer"] == null + ? null + : ChannelSubMenuRenderer.fromJson(json["channelSubMenuRenderer"]), + ); + + Map toJson() => { + "channelSubMenuRenderer": channelSubMenuRenderer == null + ? null + : channelSubMenuRenderer.toJson(), + }; +} + +class ChannelSubMenuRenderer { + ChannelSubMenuRenderer({ + this.contentTypeSubMenuItems, + this.flowSubMenuItems, + this.playAllButton, + this.sortSetting, + }); + + final List contentTypeSubMenuItems; + final List flowSubMenuItems; + final DismissButtonClass playAllButton; + final SortSetting sortSetting; + + factory ChannelSubMenuRenderer.fromRawJson(String str) => + ChannelSubMenuRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ChannelSubMenuRenderer.fromJson(Map json) => + ChannelSubMenuRenderer( + contentTypeSubMenuItems: json["contentTypeSubMenuItems"] == null + ? null + : List.from(json["contentTypeSubMenuItems"] + .map((x) => ExpandableTabRenderer.fromJson(x))), + flowSubMenuItems: json["flowSubMenuItems"] == null + ? null + : List.from(json["flowSubMenuItems"] + .map((x) => ExpandableTabRenderer.fromJson(x))), + playAllButton: json["playAllButton"] == null + ? null + : DismissButtonClass.fromJson(json["playAllButton"]), + sortSetting: json["sortSetting"] == null + ? null + : SortSetting.fromJson(json["sortSetting"]), + ); + + Map toJson() => { + "contentTypeSubMenuItems": contentTypeSubMenuItems == null + ? null + : List.from( + contentTypeSubMenuItems.map((x) => x.toJson())), + "flowSubMenuItems": flowSubMenuItems == null + ? null + : List.from(flowSubMenuItems.map((x) => x.toJson())), + "playAllButton": playAllButton == null ? null : playAllButton.toJson(), + "sortSetting": sortSetting == null ? null : sortSetting.toJson(), + }; +} + +class DismissButtonClass { + DismissButtonClass({ + this.buttonRenderer, + }); + + final DismissButtonButtonRenderer buttonRenderer; + + factory DismissButtonClass.fromRawJson(String str) => + DismissButtonClass.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory DismissButtonClass.fromJson(Map json) => + DismissButtonClass( + buttonRenderer: json["buttonRenderer"] == null + ? null + : DismissButtonButtonRenderer.fromJson(json["buttonRenderer"]), + ); + + Map toJson() => { + "buttonRenderer": + buttonRenderer == null ? null : buttonRenderer.toJson(), + }; +} + +class DismissButtonButtonRenderer { + DismissButtonButtonRenderer({ + this.style, + this.size, + this.isDisabled, + this.text, + this.navigationEndpoint, + this.trackingParams, + }); + + final String style; + final String size; + final bool isDisabled; + final Text text; + final PurpleNavigationEndpoint navigationEndpoint; + final String trackingParams; + + factory DismissButtonButtonRenderer.fromRawJson(String str) => + DismissButtonButtonRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory DismissButtonButtonRenderer.fromJson(Map json) => + DismissButtonButtonRenderer( + style: json["style"] == null ? null : json["style"], + size: json["size"] == null ? null : json["size"], + isDisabled: json["isDisabled"] == null ? null : json["isDisabled"], + text: json["text"] == null ? null : Text.fromJson(json["text"]), + navigationEndpoint: json["navigationEndpoint"] == null + ? null + : PurpleNavigationEndpoint.fromJson(json["navigationEndpoint"]), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + ); + + Map toJson() => { + "style": style == null ? null : style, + "size": size == null ? null : size, + "isDisabled": isDisabled == null ? null : isDisabled, + "text": text == null ? null : text.toJson(), + "navigationEndpoint": + navigationEndpoint == null ? null : navigationEndpoint.toJson(), + "trackingParams": trackingParams == null ? null : trackingParams, + }; +} + +class PurpleNavigationEndpoint { + PurpleNavigationEndpoint({ + this.clickTrackingParams, + this.commandMetadata, + this.watchPlaylistEndpoint, + }); + + final String clickTrackingParams; + final NextEndpointCommandMetadata commandMetadata; + final WatchPlaylistEndpoint watchPlaylistEndpoint; + + factory PurpleNavigationEndpoint.fromRawJson(String str) => + PurpleNavigationEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory PurpleNavigationEndpoint.fromJson(Map json) => + PurpleNavigationEndpoint( + clickTrackingParams: json["clickTrackingParams"] == null + ? null + : json["clickTrackingParams"], + commandMetadata: json["commandMetadata"] == null + ? null + : NextEndpointCommandMetadata.fromJson(json["commandMetadata"]), + watchPlaylistEndpoint: json["watchPlaylistEndpoint"] == null + ? null + : WatchPlaylistEndpoint.fromJson(json["watchPlaylistEndpoint"]), + ); + + Map toJson() => { + "clickTrackingParams": + clickTrackingParams == null ? null : clickTrackingParams, + "commandMetadata": + commandMetadata == null ? null : commandMetadata.toJson(), + "watchPlaylistEndpoint": watchPlaylistEndpoint == null + ? null + : watchPlaylistEndpoint.toJson(), + }; +} + +class WatchPlaylistEndpoint { + WatchPlaylistEndpoint({ + this.playlistId, + }); + + final String playlistId; + + factory WatchPlaylistEndpoint.fromRawJson(String str) => + WatchPlaylistEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory WatchPlaylistEndpoint.fromJson(Map json) => + WatchPlaylistEndpoint( + playlistId: json["playlistId"] == null ? null : json["playlistId"], + ); + + Map toJson() => { + "playlistId": playlistId == null ? null : playlistId, + }; +} + +class SortSetting { + SortSetting({ + this.sortFilterSubMenuRenderer, + }); + + final SortFilterSubMenuRenderer sortFilterSubMenuRenderer; + + factory SortSetting.fromRawJson(String str) => + SortSetting.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory SortSetting.fromJson(Map json) => SortSetting( + sortFilterSubMenuRenderer: json["sortFilterSubMenuRenderer"] == null + ? null + : SortFilterSubMenuRenderer.fromJson( + json["sortFilterSubMenuRenderer"]), + ); + + Map toJson() => { + "sortFilterSubMenuRenderer": sortFilterSubMenuRenderer == null + ? null + : sortFilterSubMenuRenderer.toJson(), + }; +} + +class SortFilterSubMenuRenderer { + SortFilterSubMenuRenderer({ + this.subMenuItems, + this.title, + this.icon, + this.accessibility, + this.trackingParams, + }); + + final List subMenuItems; + final String title; + final IconImage icon; + final Accessibility accessibility; + final String trackingParams; + + factory SortFilterSubMenuRenderer.fromRawJson(String str) => + SortFilterSubMenuRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory SortFilterSubMenuRenderer.fromJson(Map json) => + SortFilterSubMenuRenderer( + subMenuItems: json["subMenuItems"] == null + ? null + : List.from( + json["subMenuItems"].map((x) => SubMenuItem.fromJson(x))), + title: json["title"] == null ? null : json["title"], + icon: json["icon"] == null ? null : IconImage.fromJson(json["icon"]), + accessibility: json["accessibility"] == null + ? null + : Accessibility.fromJson(json["accessibility"]), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + ); + + Map toJson() => { + "subMenuItems": subMenuItems == null + ? null + : List.from(subMenuItems.map((x) => x.toJson())), + "title": title == null ? null : title, + "icon": icon == null ? null : icon.toJson(), + "accessibility": accessibility == null ? null : accessibility.toJson(), + "trackingParams": trackingParams == null ? null : trackingParams, + }; +} + +class SubMenuItem { + SubMenuItem({ + this.title, + this.selected, + this.navigationEndpoint, + }); + + final String title; + final bool selected; + final NavigationEndpointClass navigationEndpoint; + + factory SubMenuItem.fromRawJson(String str) => + SubMenuItem.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory SubMenuItem.fromJson(Map json) => SubMenuItem( + title: json["title"] == null ? null : json["title"], + selected: json["selected"] == null ? null : json["selected"], + navigationEndpoint: json["navigationEndpoint"] == null + ? null + : NavigationEndpointClass.fromJson(json["navigationEndpoint"]), + ); + + Map toJson() => { + "title": title == null ? null : title, + "selected": selected == null ? null : selected, + "navigationEndpoint": + navigationEndpoint == null ? null : navigationEndpoint.toJson(), + }; +} + +class ChannelUploadPageIdEndpoint { + ChannelUploadPageIdEndpoint({ + this.commandMetadata, + this.urlEndpoint, + }); + + final PurpleCommandMetadata commandMetadata; + final EndpointUrlEndpoint urlEndpoint; + + factory ChannelUploadPageIdEndpoint.fromRawJson(String str) => + ChannelUploadPageIdEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ChannelUploadPageIdEndpoint.fromJson(Map json) => + ChannelUploadPageIdEndpoint( + commandMetadata: json["commandMetadata"] == null + ? null + : PurpleCommandMetadata.fromJson(json["commandMetadata"]), + urlEndpoint: json["urlEndpoint"] == null + ? null + : EndpointUrlEndpoint.fromJson(json["urlEndpoint"]), + ); + + Map toJson() => { + "commandMetadata": + commandMetadata == null ? null : commandMetadata.toJson(), + "urlEndpoint": urlEndpoint == null ? null : urlEndpoint.toJson(), + }; +} + +class PurpleCommandMetadata { + PurpleCommandMetadata({ + this.webCommandMetadata, + }); + + final StickyWebCommandMetadata webCommandMetadata; + + factory PurpleCommandMetadata.fromRawJson(String str) => + PurpleCommandMetadata.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory PurpleCommandMetadata.fromJson(Map json) => + PurpleCommandMetadata( + webCommandMetadata: json["webCommandMetadata"] == null + ? null + : StickyWebCommandMetadata.fromJson(json["webCommandMetadata"]), + ); + + Map toJson() => { + "webCommandMetadata": + webCommandMetadata == null ? null : webCommandMetadata.toJson(), + }; +} + +class StickyWebCommandMetadata { + StickyWebCommandMetadata({ + this.url, + this.webPageType, + }); + + final String url; + final WebPageType webPageType; + + factory StickyWebCommandMetadata.fromRawJson(String str) => + StickyWebCommandMetadata.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory StickyWebCommandMetadata.fromJson(Map json) => + StickyWebCommandMetadata( + url: json["url"] == null ? null : json["url"], + webPageType: json["webPageType"] == null + ? null + : webPageTypeValues.map[json["webPageType"]], + ); + + Map toJson() => { + "url": url == null ? null : url, + "webPageType": + webPageType == null ? null : webPageTypeValues.reverse[webPageType], + }; +} + +class EndpointUrlEndpoint { + EndpointUrlEndpoint({ + this.url, + }); + + final String url; + + factory EndpointUrlEndpoint.fromRawJson(String str) => + EndpointUrlEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory EndpointUrlEndpoint.fromJson(Map json) => + EndpointUrlEndpoint( + url: json["url"] == null ? null : json["url"], + ); + + Map toJson() => { + "url": url == null ? null : url, + }; +} + +class Header { + Header({ + this.c4TabbedHeaderRenderer, + }); + + final C4TabbedHeaderRenderer c4TabbedHeaderRenderer; + + factory Header.fromRawJson(String str) => Header.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Header.fromJson(Map json) => Header( + c4TabbedHeaderRenderer: json["c4TabbedHeaderRenderer"] == null + ? null + : C4TabbedHeaderRenderer.fromJson(json["c4TabbedHeaderRenderer"]), + ); + + Map toJson() => { + "c4TabbedHeaderRenderer": c4TabbedHeaderRenderer == null + ? null + : c4TabbedHeaderRenderer.toJson(), + }; +} + +class C4TabbedHeaderRenderer { + C4TabbedHeaderRenderer({ + this.channelId, + this.title, + this.navigationEndpoint, + this.avatar, + this.banner, + this.badges, + this.headerLinks, + this.subscribeButton, + this.subscriberCountText, + this.tvBanner, + this.mobileBanner, + this.trackingParams, + }); + + final Id channelId; + final String title; + final C4TabbedHeaderRendererNavigationEndpoint navigationEndpoint; + final Avatar avatar; + final Avatar banner; + final List badges; + final HeaderLinks headerLinks; + final SubscribeButton subscribeButton; + final SubscriberCountText subscriberCountText; + final Avatar tvBanner; + final Avatar mobileBanner; + final String trackingParams; + + factory C4TabbedHeaderRenderer.fromRawJson(String str) => + C4TabbedHeaderRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory C4TabbedHeaderRenderer.fromJson(Map json) => + C4TabbedHeaderRenderer( + channelId: + json["channelId"] == null ? null : idValues.map[json["channelId"]], + title: json["title"] == null ? null : json["title"], + navigationEndpoint: json["navigationEndpoint"] == null + ? null + : C4TabbedHeaderRendererNavigationEndpoint.fromJson( + json["navigationEndpoint"]), + avatar: json["avatar"] == null ? null : Avatar.fromJson(json["avatar"]), + banner: json["banner"] == null ? null : Avatar.fromJson(json["banner"]), + badges: json["badges"] == null + ? null + : List.from(json["badges"].map((x) => Badge.fromJson(x))), + headerLinks: json["headerLinks"] == null + ? null + : HeaderLinks.fromJson(json["headerLinks"]), + subscribeButton: json["subscribeButton"] == null + ? null + : SubscribeButton.fromJson(json["subscribeButton"]), + subscriberCountText: json["subscriberCountText"] == null + ? null + : SubscriberCountText.fromJson(json["subscriberCountText"]), + tvBanner: + json["tvBanner"] == null ? null : Avatar.fromJson(json["tvBanner"]), + mobileBanner: json["mobileBanner"] == null + ? null + : Avatar.fromJson(json["mobileBanner"]), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + ); + + Map toJson() => { + "channelId": channelId == null ? null : idValues.reverse[channelId], + "title": title == null ? null : title, + "navigationEndpoint": + navigationEndpoint == null ? null : navigationEndpoint.toJson(), + "avatar": avatar == null ? null : avatar.toJson(), + "banner": banner == null ? null : banner.toJson(), + "badges": badges == null + ? null + : List.from(badges.map((x) => x.toJson())), + "headerLinks": headerLinks == null ? null : headerLinks.toJson(), + "subscribeButton": + subscribeButton == null ? null : subscribeButton.toJson(), + "subscriberCountText": + subscriberCountText == null ? null : subscriberCountText.toJson(), + "tvBanner": tvBanner == null ? null : tvBanner.toJson(), + "mobileBanner": mobileBanner == null ? null : mobileBanner.toJson(), + "trackingParams": trackingParams == null ? null : trackingParams, + }; +} + +class HeaderLinks { + HeaderLinks({ + this.channelHeaderLinksRenderer, + }); + + final ChannelHeaderLinksRenderer channelHeaderLinksRenderer; + + factory HeaderLinks.fromRawJson(String str) => + HeaderLinks.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory HeaderLinks.fromJson(Map json) => HeaderLinks( + channelHeaderLinksRenderer: json["channelHeaderLinksRenderer"] == null + ? null + : ChannelHeaderLinksRenderer.fromJson( + json["channelHeaderLinksRenderer"]), + ); + + Map toJson() => { + "channelHeaderLinksRenderer": channelHeaderLinksRenderer == null + ? null + : channelHeaderLinksRenderer.toJson(), + }; +} + +class ChannelHeaderLinksRenderer { + ChannelHeaderLinksRenderer({ + this.hack, + }); + + final bool hack; + + factory ChannelHeaderLinksRenderer.fromRawJson(String str) => + ChannelHeaderLinksRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ChannelHeaderLinksRenderer.fromJson(Map json) => + ChannelHeaderLinksRenderer( + hack: json["hack"] == null ? null : json["hack"], + ); + + Map toJson() => { + "hack": hack == null ? null : hack, + }; +} + +class C4TabbedHeaderRendererNavigationEndpoint { + C4TabbedHeaderRendererNavigationEndpoint({ + this.clickTrackingParams, + this.commandMetadata, + this.browseEndpoint, + }); + + final String clickTrackingParams; + final NextEndpointCommandMetadata commandMetadata; + final FluffyBrowseEndpoint browseEndpoint; + + factory C4TabbedHeaderRendererNavigationEndpoint.fromRawJson(String str) => + C4TabbedHeaderRendererNavigationEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory C4TabbedHeaderRendererNavigationEndpoint.fromJson( + Map json) => + C4TabbedHeaderRendererNavigationEndpoint( + clickTrackingParams: json["clickTrackingParams"] == null + ? null + : json["clickTrackingParams"], + commandMetadata: json["commandMetadata"] == null + ? null + : NextEndpointCommandMetadata.fromJson(json["commandMetadata"]), + browseEndpoint: json["browseEndpoint"] == null + ? null + : FluffyBrowseEndpoint.fromJson(json["browseEndpoint"]), + ); + + Map toJson() => { + "clickTrackingParams": + clickTrackingParams == null ? null : clickTrackingParams, + "commandMetadata": + commandMetadata == null ? null : commandMetadata.toJson(), + "browseEndpoint": + browseEndpoint == null ? null : browseEndpoint.toJson(), + }; +} + +class FluffyBrowseEndpoint { + FluffyBrowseEndpoint({ + this.browseId, + this.canonicalBaseUrl, + }); + + final Id browseId; + final CanonicalBaseUrl canonicalBaseUrl; + + factory FluffyBrowseEndpoint.fromRawJson(String str) => + FluffyBrowseEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory FluffyBrowseEndpoint.fromJson(Map json) => + FluffyBrowseEndpoint( + browseId: + json["browseId"] == null ? null : idValues.map[json["browseId"]], + canonicalBaseUrl: json["canonicalBaseUrl"] == null + ? null + : canonicalBaseUrlValues.map[json["canonicalBaseUrl"]], + ); + + Map toJson() => { + "browseId": browseId == null ? null : idValues.reverse[browseId], + "canonicalBaseUrl": canonicalBaseUrl == null + ? null + : canonicalBaseUrlValues.reverse[canonicalBaseUrl], + }; +} + +class SubscribeButton { + SubscribeButton({ + this.buttonRenderer, + }); + + final SubscribeButtonButtonRenderer buttonRenderer; + + factory SubscribeButton.fromRawJson(String str) => + SubscribeButton.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory SubscribeButton.fromJson(Map json) => + SubscribeButton( + buttonRenderer: json["buttonRenderer"] == null + ? null + : SubscribeButtonButtonRenderer.fromJson(json["buttonRenderer"]), + ); + + Map toJson() => { + "buttonRenderer": + buttonRenderer == null ? null : buttonRenderer.toJson(), + }; +} + +class SubscribeButtonButtonRenderer { + SubscribeButtonButtonRenderer({ + this.style, + this.size, + this.isDisabled, + this.text, + this.navigationEndpoint, + this.trackingParams, + }); + + final String style; + final String size; + final bool isDisabled; + final Text text; + final FluffyNavigationEndpoint navigationEndpoint; + final String trackingParams; + + factory SubscribeButtonButtonRenderer.fromRawJson(String str) => + SubscribeButtonButtonRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory SubscribeButtonButtonRenderer.fromJson(Map json) => + SubscribeButtonButtonRenderer( + style: json["style"] == null ? null : json["style"], + size: json["size"] == null ? null : json["size"], + isDisabled: json["isDisabled"] == null ? null : json["isDisabled"], + text: json["text"] == null ? null : Text.fromJson(json["text"]), + navigationEndpoint: json["navigationEndpoint"] == null + ? null + : FluffyNavigationEndpoint.fromJson(json["navigationEndpoint"]), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + ); + + Map toJson() => { + "style": style == null ? null : style, + "size": size == null ? null : size, + "isDisabled": isDisabled == null ? null : isDisabled, + "text": text == null ? null : text.toJson(), + "navigationEndpoint": + navigationEndpoint == null ? null : navigationEndpoint.toJson(), + "trackingParams": trackingParams == null ? null : trackingParams, + }; +} + +class FluffyNavigationEndpoint { + FluffyNavigationEndpoint({ + this.clickTrackingParams, + this.commandMetadata, + this.modalEndpoint, + }); + + final String clickTrackingParams; + final FluffyCommandMetadata commandMetadata; + final ModalEndpoint modalEndpoint; + + factory FluffyNavigationEndpoint.fromRawJson(String str) => + FluffyNavigationEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory FluffyNavigationEndpoint.fromJson(Map json) => + FluffyNavigationEndpoint( + clickTrackingParams: json["clickTrackingParams"] == null + ? null + : json["clickTrackingParams"], + commandMetadata: json["commandMetadata"] == null + ? null + : FluffyCommandMetadata.fromJson(json["commandMetadata"]), + modalEndpoint: json["modalEndpoint"] == null + ? null + : ModalEndpoint.fromJson(json["modalEndpoint"]), + ); + + Map toJson() => { + "clickTrackingParams": + clickTrackingParams == null ? null : clickTrackingParams, + "commandMetadata": + commandMetadata == null ? null : commandMetadata.toJson(), + "modalEndpoint": modalEndpoint == null ? null : modalEndpoint.toJson(), + }; +} + +class FluffyCommandMetadata { + FluffyCommandMetadata({ + this.webCommandMetadata, + }); + + final IndigoWebCommandMetadata webCommandMetadata; + + factory FluffyCommandMetadata.fromRawJson(String str) => + FluffyCommandMetadata.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory FluffyCommandMetadata.fromJson(Map json) => + FluffyCommandMetadata( + webCommandMetadata: json["webCommandMetadata"] == null + ? null + : IndigoWebCommandMetadata.fromJson(json["webCommandMetadata"]), + ); + + Map toJson() => { + "webCommandMetadata": + webCommandMetadata == null ? null : webCommandMetadata.toJson(), + }; +} + +class IndigoWebCommandMetadata { + IndigoWebCommandMetadata({ + this.ignoreNavigation, + }); + + final bool ignoreNavigation; + + factory IndigoWebCommandMetadata.fromRawJson(String str) => + IndigoWebCommandMetadata.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory IndigoWebCommandMetadata.fromJson(Map json) => + IndigoWebCommandMetadata( + ignoreNavigation: + json["ignoreNavigation"] == null ? null : json["ignoreNavigation"], + ); + + Map toJson() => { + "ignoreNavigation": ignoreNavigation == null ? null : ignoreNavigation, + }; +} + +class ModalEndpoint { + ModalEndpoint({ + this.modal, + }); + + final Modal modal; + + factory ModalEndpoint.fromRawJson(String str) => + ModalEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ModalEndpoint.fromJson(Map json) => ModalEndpoint( + modal: json["modal"] == null ? null : Modal.fromJson(json["modal"]), + ); + + Map toJson() => { + "modal": modal == null ? null : modal.toJson(), + }; +} + +class Modal { + Modal({ + this.modalWithTitleAndButtonRenderer, + }); + + final ModalWithTitleAndButtonRenderer modalWithTitleAndButtonRenderer; + + factory Modal.fromRawJson(String str) => Modal.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Modal.fromJson(Map json) => Modal( + modalWithTitleAndButtonRenderer: + json["modalWithTitleAndButtonRenderer"] == null + ? null + : ModalWithTitleAndButtonRenderer.fromJson( + json["modalWithTitleAndButtonRenderer"]), + ); + + Map toJson() => { + "modalWithTitleAndButtonRenderer": + modalWithTitleAndButtonRenderer == null + ? null + : modalWithTitleAndButtonRenderer.toJson(), + }; +} + +class ModalWithTitleAndButtonRenderer { + ModalWithTitleAndButtonRenderer({ + this.title, + this.content, + this.button, + }); + + final Text title; + final Text content; + final Button button; + + factory ModalWithTitleAndButtonRenderer.fromRawJson(String str) => + ModalWithTitleAndButtonRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ModalWithTitleAndButtonRenderer.fromJson(Map json) => + ModalWithTitleAndButtonRenderer( + title: json["title"] == null ? null : Text.fromJson(json["title"]), + content: + json["content"] == null ? null : Text.fromJson(json["content"]), + button: json["button"] == null ? null : Button.fromJson(json["button"]), + ); + + Map toJson() => { + "title": title == null ? null : title.toJson(), + "content": content == null ? null : content.toJson(), + "button": button == null ? null : button.toJson(), + }; +} + +class Button { + Button({ + this.buttonRenderer, + }); + + final ButtonButtonRenderer buttonRenderer; + + factory Button.fromRawJson(String str) => Button.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Button.fromJson(Map json) => Button( + buttonRenderer: json["buttonRenderer"] == null + ? null + : ButtonButtonRenderer.fromJson(json["buttonRenderer"]), + ); + + Map toJson() => { + "buttonRenderer": + buttonRenderer == null ? null : buttonRenderer.toJson(), + }; +} + +class ButtonButtonRenderer { + ButtonButtonRenderer({ + this.style, + this.size, + this.isDisabled, + this.text, + this.navigationEndpoint, + this.trackingParams, + }); + + final String style; + final String size; + final bool isDisabled; + final Text text; + final TentacledNavigationEndpoint navigationEndpoint; + final String trackingParams; + + factory ButtonButtonRenderer.fromRawJson(String str) => + ButtonButtonRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ButtonButtonRenderer.fromJson(Map json) => + ButtonButtonRenderer( + style: json["style"] == null ? null : json["style"], + size: json["size"] == null ? null : json["size"], + isDisabled: json["isDisabled"] == null ? null : json["isDisabled"], + text: json["text"] == null ? null : Text.fromJson(json["text"]), + navigationEndpoint: json["navigationEndpoint"] == null + ? null + : TentacledNavigationEndpoint.fromJson(json["navigationEndpoint"]), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + ); + + Map toJson() => { + "style": style == null ? null : style, + "size": size == null ? null : size, + "isDisabled": isDisabled == null ? null : isDisabled, + "text": text == null ? null : text.toJson(), + "navigationEndpoint": + navigationEndpoint == null ? null : navigationEndpoint.toJson(), + "trackingParams": trackingParams == null ? null : trackingParams, + }; +} + +class TentacledNavigationEndpoint { + TentacledNavigationEndpoint({ + this.clickTrackingParams, + this.commandMetadata, + this.signInEndpoint, + }); + + final String clickTrackingParams; + final NextEndpointCommandMetadata commandMetadata; + final PurpleSignInEndpoint signInEndpoint; + + factory TentacledNavigationEndpoint.fromRawJson(String str) => + TentacledNavigationEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory TentacledNavigationEndpoint.fromJson(Map json) => + TentacledNavigationEndpoint( + clickTrackingParams: json["clickTrackingParams"] == null + ? null + : json["clickTrackingParams"], + commandMetadata: json["commandMetadata"] == null + ? null + : NextEndpointCommandMetadata.fromJson(json["commandMetadata"]), + signInEndpoint: json["signInEndpoint"] == null + ? null + : PurpleSignInEndpoint.fromJson(json["signInEndpoint"]), + ); + + Map toJson() => { + "clickTrackingParams": + clickTrackingParams == null ? null : clickTrackingParams, + "commandMetadata": + commandMetadata == null ? null : commandMetadata.toJson(), + "signInEndpoint": + signInEndpoint == null ? null : signInEndpoint.toJson(), + }; +} + +class PurpleSignInEndpoint { + PurpleSignInEndpoint({ + this.nextEndpoint, + this.continueAction, + this.idamTag, + }); + + final PurpleNextEndpoint nextEndpoint; + final String continueAction; + final String idamTag; + + factory PurpleSignInEndpoint.fromRawJson(String str) => + PurpleSignInEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory PurpleSignInEndpoint.fromJson(Map json) => + PurpleSignInEndpoint( + nextEndpoint: json["nextEndpoint"] == null + ? null + : PurpleNextEndpoint.fromJson(json["nextEndpoint"]), + continueAction: + json["continueAction"] == null ? null : json["continueAction"], + idamTag: json["idamTag"] == null ? null : json["idamTag"], + ); + + Map toJson() => { + "nextEndpoint": nextEndpoint == null ? null : nextEndpoint.toJson(), + "continueAction": continueAction == null ? null : continueAction, + "idamTag": idamTag == null ? null : idamTag, + }; +} + +class PurpleNextEndpoint { + PurpleNextEndpoint({ + this.clickTrackingParams, + this.commandMetadata, + this.browseEndpoint, + }); + + final String clickTrackingParams; + final NextEndpointCommandMetadata commandMetadata; + final NextEndpointBrowseEndpoint browseEndpoint; + + factory PurpleNextEndpoint.fromRawJson(String str) => + PurpleNextEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory PurpleNextEndpoint.fromJson(Map json) => + PurpleNextEndpoint( + clickTrackingParams: json["clickTrackingParams"] == null + ? null + : json["clickTrackingParams"], + commandMetadata: json["commandMetadata"] == null + ? null + : NextEndpointCommandMetadata.fromJson(json["commandMetadata"]), + browseEndpoint: json["browseEndpoint"] == null + ? null + : NextEndpointBrowseEndpoint.fromJson(json["browseEndpoint"]), + ); + + Map toJson() => { + "clickTrackingParams": + clickTrackingParams == null ? null : clickTrackingParams, + "commandMetadata": + commandMetadata == null ? null : commandMetadata.toJson(), + "browseEndpoint": + browseEndpoint == null ? null : browseEndpoint.toJson(), + }; +} + +class NextEndpointBrowseEndpoint { + NextEndpointBrowseEndpoint({ + this.browseId, + this.params, + }); + + final Id browseId; + final String params; + + factory NextEndpointBrowseEndpoint.fromRawJson(String str) => + NextEndpointBrowseEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory NextEndpointBrowseEndpoint.fromJson(Map json) => + NextEndpointBrowseEndpoint( + browseId: + json["browseId"] == null ? null : idValues.map[json["browseId"]], + params: json["params"] == null ? null : json["params"], + ); + + Map toJson() => { + "browseId": browseId == null ? null : idValues.reverse[browseId], + "params": params == null ? null : params, + }; +} + +class Metadata { + Metadata({ + this.channelMetadataRenderer, + }); + + final ChannelMetadataRenderer channelMetadataRenderer; + + factory Metadata.fromRawJson(String str) => + Metadata.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Metadata.fromJson(Map json) => Metadata( + channelMetadataRenderer: json["channelMetadataRenderer"] == null + ? null + : ChannelMetadataRenderer.fromJson(json["channelMetadataRenderer"]), + ); + + Map toJson() => { + "channelMetadataRenderer": channelMetadataRenderer == null + ? null + : channelMetadataRenderer.toJson(), + }; +} + +class ChannelMetadataRenderer { + ChannelMetadataRenderer({ + this.title, + this.description, + this.externalId, + this.keywords, + this.ownerUrls, + this.avatar, + this.channelUrl, + this.isFamilySafe, + this.availableCountryCodes, + this.musicArtistName, + this.androidDeepLink, + this.androidAppindexingLink, + this.iosAppindexingLink, + this.tabPath, + this.vanityChannelUrl, + }); + + final String title; + final String description; + final Id externalId; + final String keywords; + final List ownerUrls; + final Avatar avatar; + final String channelUrl; + final bool isFamilySafe; + final List availableCountryCodes; + final String musicArtistName; + final String androidDeepLink; + final String androidAppindexingLink; + final String iosAppindexingLink; + final String tabPath; + final String vanityChannelUrl; + + factory ChannelMetadataRenderer.fromRawJson(String str) => + ChannelMetadataRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ChannelMetadataRenderer.fromJson(Map json) => + ChannelMetadataRenderer( + title: json["title"] == null ? null : json["title"], + description: json["description"] == null ? null : json["description"], + externalId: json["externalId"] == null + ? null + : idValues.map[json["externalId"]], + keywords: json["keywords"] == null ? null : json["keywords"], + ownerUrls: json["ownerUrls"] == null + ? null + : List.from(json["ownerUrls"].map((x) => x)), + avatar: json["avatar"] == null ? null : Avatar.fromJson(json["avatar"]), + channelUrl: json["channelUrl"] == null ? null : json["channelUrl"], + isFamilySafe: + json["isFamilySafe"] == null ? null : json["isFamilySafe"], + availableCountryCodes: json["availableCountryCodes"] == null + ? null + : List.from(json["availableCountryCodes"].map((x) => x)), + musicArtistName: + json["musicArtistName"] == null ? null : json["musicArtistName"], + androidDeepLink: + json["androidDeepLink"] == null ? null : json["androidDeepLink"], + androidAppindexingLink: json["androidAppindexingLink"] == null + ? null + : json["androidAppindexingLink"], + iosAppindexingLink: json["iosAppindexingLink"] == null + ? null + : json["iosAppindexingLink"], + tabPath: json["tabPath"] == null ? null : json["tabPath"], + vanityChannelUrl: + json["vanityChannelUrl"] == null ? null : json["vanityChannelUrl"], + ); + + Map toJson() => { + "title": title == null ? null : title, + "description": description == null ? null : description, + "externalId": externalId == null ? null : idValues.reverse[externalId], + "keywords": keywords == null ? null : keywords, + "ownerUrls": ownerUrls == null + ? null + : List.from(ownerUrls.map((x) => x)), + "avatar": avatar == null ? null : avatar.toJson(), + "channelUrl": channelUrl == null ? null : channelUrl, + "isFamilySafe": isFamilySafe == null ? null : isFamilySafe, + "availableCountryCodes": availableCountryCodes == null + ? null + : List.from(availableCountryCodes.map((x) => x)), + "musicArtistName": musicArtistName == null ? null : musicArtistName, + "androidDeepLink": androidDeepLink == null ? null : androidDeepLink, + "androidAppindexingLink": + androidAppindexingLink == null ? null : androidAppindexingLink, + "iosAppindexingLink": + iosAppindexingLink == null ? null : iosAppindexingLink, + "tabPath": tabPath == null ? null : tabPath, + "vanityChannelUrl": vanityChannelUrl == null ? null : vanityChannelUrl, + }; +} + +class Microformat { + Microformat({ + this.microformatDataRenderer, + }); + + final MicroformatDataRenderer microformatDataRenderer; + + factory Microformat.fromRawJson(String str) => + Microformat.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Microformat.fromJson(Map json) => Microformat( + microformatDataRenderer: json["microformatDataRenderer"] == null + ? null + : MicroformatDataRenderer.fromJson(json["microformatDataRenderer"]), + ); + + Map toJson() => { + "microformatDataRenderer": microformatDataRenderer == null + ? null + : microformatDataRenderer.toJson(), + }; +} + +class MicroformatDataRenderer { + MicroformatDataRenderer({ + this.urlCanonical, + this.title, + this.description, + this.thumbnail, + this.siteName, + this.appName, + this.androidPackage, + this.iosAppStoreId, + this.iosAppArguments, + this.ogType, + this.urlApplinksWeb, + this.urlApplinksIos, + this.urlApplinksAndroid, + this.urlTwitterIos, + this.urlTwitterAndroid, + this.twitterCardType, + this.twitterSiteHandle, + this.schemaDotOrgType, + this.noindex, + this.unlisted, + this.linkAlternates, + }); + + final String urlCanonical; + final String title; + final String description; + final Avatar thumbnail; + final String siteName; + final String appName; + final String androidPackage; + final String iosAppStoreId; + final String iosAppArguments; + final String ogType; + final String urlApplinksWeb; + final String urlApplinksIos; + final String urlApplinksAndroid; + final String urlTwitterIos; + final String urlTwitterAndroid; + final String twitterCardType; + final String twitterSiteHandle; + final String schemaDotOrgType; + final bool noindex; + final bool unlisted; + final List linkAlternates; + + factory MicroformatDataRenderer.fromRawJson(String str) => + MicroformatDataRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory MicroformatDataRenderer.fromJson(Map json) => + MicroformatDataRenderer( + urlCanonical: + json["urlCanonical"] == null ? null : json["urlCanonical"], + title: json["title"] == null ? null : json["title"], + description: json["description"] == null ? null : json["description"], + thumbnail: json["thumbnail"] == null + ? null + : Avatar.fromJson(json["thumbnail"]), + siteName: json["siteName"] == null ? null : json["siteName"], + appName: json["appName"] == null ? null : json["appName"], + androidPackage: + json["androidPackage"] == null ? null : json["androidPackage"], + iosAppStoreId: + json["iosAppStoreId"] == null ? null : json["iosAppStoreId"], + iosAppArguments: + json["iosAppArguments"] == null ? null : json["iosAppArguments"], + ogType: json["ogType"] == null ? null : json["ogType"], + urlApplinksWeb: + json["urlApplinksWeb"] == null ? null : json["urlApplinksWeb"], + urlApplinksIos: + json["urlApplinksIos"] == null ? null : json["urlApplinksIos"], + urlApplinksAndroid: json["urlApplinksAndroid"] == null + ? null + : json["urlApplinksAndroid"], + urlTwitterIos: + json["urlTwitterIos"] == null ? null : json["urlTwitterIos"], + urlTwitterAndroid: json["urlTwitterAndroid"] == null + ? null + : json["urlTwitterAndroid"], + twitterCardType: + json["twitterCardType"] == null ? null : json["twitterCardType"], + twitterSiteHandle: json["twitterSiteHandle"] == null + ? null + : json["twitterSiteHandle"], + schemaDotOrgType: + json["schemaDotOrgType"] == null ? null : json["schemaDotOrgType"], + noindex: json["noindex"] == null ? null : json["noindex"], + unlisted: json["unlisted"] == null ? null : json["unlisted"], + linkAlternates: json["linkAlternates"] == null + ? null + : List.from( + json["linkAlternates"].map((x) => LinkAlternate.fromJson(x))), + ); + + Map toJson() => { + "urlCanonical": urlCanonical == null ? null : urlCanonical, + "title": title == null ? null : title, + "description": description == null ? null : description, + "thumbnail": thumbnail == null ? null : thumbnail.toJson(), + "siteName": siteName == null ? null : siteName, + "appName": appName == null ? null : appName, + "androidPackage": androidPackage == null ? null : androidPackage, + "iosAppStoreId": iosAppStoreId == null ? null : iosAppStoreId, + "iosAppArguments": iosAppArguments == null ? null : iosAppArguments, + "ogType": ogType == null ? null : ogType, + "urlApplinksWeb": urlApplinksWeb == null ? null : urlApplinksWeb, + "urlApplinksIos": urlApplinksIos == null ? null : urlApplinksIos, + "urlApplinksAndroid": + urlApplinksAndroid == null ? null : urlApplinksAndroid, + "urlTwitterIos": urlTwitterIos == null ? null : urlTwitterIos, + "urlTwitterAndroid": + urlTwitterAndroid == null ? null : urlTwitterAndroid, + "twitterCardType": twitterCardType == null ? null : twitterCardType, + "twitterSiteHandle": + twitterSiteHandle == null ? null : twitterSiteHandle, + "schemaDotOrgType": schemaDotOrgType == null ? null : schemaDotOrgType, + "noindex": noindex == null ? null : noindex, + "unlisted": unlisted == null ? null : unlisted, + "linkAlternates": linkAlternates == null + ? null + : List.from(linkAlternates.map((x) => x.toJson())), + }; +} + +class LinkAlternate { + LinkAlternate({ + this.hrefUrl, + }); + + final String hrefUrl; + + factory LinkAlternate.fromRawJson(String str) => + LinkAlternate.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory LinkAlternate.fromJson(Map json) => LinkAlternate( + hrefUrl: json["hrefUrl"] == null ? null : json["hrefUrl"], + ); + + Map toJson() => { + "hrefUrl": hrefUrl == null ? null : hrefUrl, + }; +} + +class Response { + Response({ + this.responseContext, + this.continuationContents, + this.metadata, + this.trackingParams, + this.microformat, + }); + + final ResponseResponseContext responseContext; + final ContinuationContents continuationContents; + final Metadata metadata; + final String trackingParams; + final Microformat microformat; + + factory Response.fromRawJson(String str) => + Response.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Response.fromJson(Map json) => Response( + responseContext: json["responseContext"] == null + ? null + : ResponseResponseContext.fromJson(json["responseContext"]), + continuationContents: json["continuationContents"] == null + ? null + : ContinuationContents.fromJson(json["continuationContents"]), + metadata: json["metadata"] == null + ? null + : Metadata.fromJson(json["metadata"]), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + microformat: json["microformat"] == null + ? null + : Microformat.fromJson(json["microformat"]), + ); + + Map toJson() => { + "responseContext": + responseContext == null ? null : responseContext.toJson(), + "continuationContents": + continuationContents == null ? null : continuationContents.toJson(), + "metadata": metadata == null ? null : metadata.toJson(), + "trackingParams": trackingParams == null ? null : trackingParams, + "microformat": microformat == null ? null : microformat.toJson(), + }; +} + +class ContinuationContents { + ContinuationContents({ + this.gridContinuation, + }); + + final Grid gridContinuation; + + factory ContinuationContents.fromRawJson(String str) => + ContinuationContents.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ContinuationContents.fromJson(Map json) => + ContinuationContents( + gridContinuation: json["gridContinuation"] == null + ? null + : Grid.fromJson(json["gridContinuation"]), + ); + + Map toJson() => { + "gridContinuation": + gridContinuation == null ? null : gridContinuation.toJson(), + }; +} + +class ResponseResponseContext { + ResponseResponseContext({ + this.serviceTrackingParams, + this.maxAgeSeconds, + this.webResponseContextExtensionData, + }); + + final List serviceTrackingParams; + final int maxAgeSeconds; + final PurpleWebResponseContextExtensionData webResponseContextExtensionData; + + factory ResponseResponseContext.fromRawJson(String str) => + ResponseResponseContext.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ResponseResponseContext.fromJson(Map json) => + ResponseResponseContext( + serviceTrackingParams: json["serviceTrackingParams"] == null + ? null + : List.from(json["serviceTrackingParams"] + .map((x) => ServiceTrackingParam.fromJson(x))), + maxAgeSeconds: + json["maxAgeSeconds"] == null ? null : json["maxAgeSeconds"], + webResponseContextExtensionData: + json["webResponseContextExtensionData"] == null + ? null + : PurpleWebResponseContextExtensionData.fromJson( + json["webResponseContextExtensionData"]), + ); + + Map toJson() => { + "serviceTrackingParams": serviceTrackingParams == null + ? null + : List.from(serviceTrackingParams.map((x) => x.toJson())), + "maxAgeSeconds": maxAgeSeconds == null ? null : maxAgeSeconds, + "webResponseContextExtensionData": + webResponseContextExtensionData == null + ? null + : webResponseContextExtensionData.toJson(), + }; +} + +class ServiceTrackingParam { + ServiceTrackingParam({ + this.service, + this.params, + }); + + final String service; + final List params; + + factory ServiceTrackingParam.fromRawJson(String str) => + ServiceTrackingParam.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ServiceTrackingParam.fromJson(Map json) => + ServiceTrackingParam( + service: json["service"] == null ? null : json["service"], + params: json["params"] == null + ? null + : List.from(json["params"].map((x) => Param.fromJson(x))), + ); + + Map toJson() => { + "service": service == null ? null : service, + "params": params == null + ? null + : List.from(params.map((x) => x.toJson())), + }; +} + +class Param { + Param({ + this.key, + this.value, + }); + + final String key; + final String value; + + factory Param.fromRawJson(String str) => Param.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Param.fromJson(Map json) => Param( + key: json["key"] == null ? null : json["key"], + value: json["value"] == null ? null : json["value"], + ); + + Map toJson() => { + "key": key == null ? null : key, + "value": value == null ? null : value, + }; +} + +class PurpleWebResponseContextExtensionData { + PurpleWebResponseContextExtensionData({ + this.ytConfigData, + this.hasDecorated, + }); + + final PurpleYtConfigData ytConfigData; + final bool hasDecorated; + + factory PurpleWebResponseContextExtensionData.fromRawJson(String str) => + PurpleWebResponseContextExtensionData.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory PurpleWebResponseContextExtensionData.fromJson( + Map json) => + PurpleWebResponseContextExtensionData( + ytConfigData: json["ytConfigData"] == null + ? null + : PurpleYtConfigData.fromJson(json["ytConfigData"]), + hasDecorated: + json["hasDecorated"] == null ? null : json["hasDecorated"], + ); + + Map toJson() => { + "ytConfigData": ytConfigData == null ? null : ytConfigData.toJson(), + "hasDecorated": hasDecorated == null ? null : hasDecorated, + }; +} + +class PurpleYtConfigData { + PurpleYtConfigData({ + this.csn, + this.visitorData, + }); + + final String csn; + final String visitorData; + + factory PurpleYtConfigData.fromRawJson(String str) => + PurpleYtConfigData.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory PurpleYtConfigData.fromJson(Map json) => + PurpleYtConfigData( + csn: json["csn"] == null ? null : json["csn"], + visitorData: json["visitorData"] == null ? null : json["visitorData"], + ); + + Map toJson() => { + "csn": csn == null ? null : csn, + "visitorData": visitorData == null ? null : visitorData, + }; +} + +class ChannelUploadPageIdResponseContext { + ChannelUploadPageIdResponseContext({ + this.serviceTrackingParams, + this.maxAgeSeconds, + this.webResponseContextExtensionData, + }); + + final List serviceTrackingParams; + final int maxAgeSeconds; + final FluffyWebResponseContextExtensionData webResponseContextExtensionData; + + factory ChannelUploadPageIdResponseContext.fromRawJson(String str) => + ChannelUploadPageIdResponseContext.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ChannelUploadPageIdResponseContext.fromJson( + Map json) => + ChannelUploadPageIdResponseContext( + serviceTrackingParams: json["serviceTrackingParams"] == null + ? null + : List.from(json["serviceTrackingParams"] + .map((x) => ServiceTrackingParam.fromJson(x))), + maxAgeSeconds: + json["maxAgeSeconds"] == null ? null : json["maxAgeSeconds"], + webResponseContextExtensionData: + json["webResponseContextExtensionData"] == null + ? null + : FluffyWebResponseContextExtensionData.fromJson( + json["webResponseContextExtensionData"]), + ); + + Map toJson() => { + "serviceTrackingParams": serviceTrackingParams == null + ? null + : List.from(serviceTrackingParams.map((x) => x.toJson())), + "maxAgeSeconds": maxAgeSeconds == null ? null : maxAgeSeconds, + "webResponseContextExtensionData": + webResponseContextExtensionData == null + ? null + : webResponseContextExtensionData.toJson(), + }; +} + +class FluffyWebResponseContextExtensionData { + FluffyWebResponseContextExtensionData({ + this.ytConfigData, + this.hasDecorated, + }); + + final FluffyYtConfigData ytConfigData; + final bool hasDecorated; + + factory FluffyWebResponseContextExtensionData.fromRawJson(String str) => + FluffyWebResponseContextExtensionData.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory FluffyWebResponseContextExtensionData.fromJson( + Map json) => + FluffyWebResponseContextExtensionData( + ytConfigData: json["ytConfigData"] == null + ? null + : FluffyYtConfigData.fromJson(json["ytConfigData"]), + hasDecorated: + json["hasDecorated"] == null ? null : json["hasDecorated"], + ); + + Map toJson() => { + "ytConfigData": ytConfigData == null ? null : ytConfigData.toJson(), + "hasDecorated": hasDecorated == null ? null : hasDecorated, + }; +} + +class FluffyYtConfigData { + FluffyYtConfigData({ + this.csn, + this.visitorData, + this.rootVisualElementType, + }); + + final String csn; + final String visitorData; + final int rootVisualElementType; + + factory FluffyYtConfigData.fromRawJson(String str) => + FluffyYtConfigData.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory FluffyYtConfigData.fromJson(Map json) => + FluffyYtConfigData( + csn: json["csn"] == null ? null : json["csn"], + visitorData: json["visitorData"] == null ? null : json["visitorData"], + rootVisualElementType: json["rootVisualElementType"] == null + ? null + : json["rootVisualElementType"], + ); + + Map toJson() => { + "csn": csn == null ? null : csn, + "visitorData": visitorData == null ? null : visitorData, + "rootVisualElementType": + rootVisualElementType == null ? null : rootVisualElementType, + }; +} + +class Timing { + Timing({ + this.info, + }); + + final Info info; + + factory Timing.fromRawJson(String str) => Timing.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Timing.fromJson(Map json) => Timing( + info: json["info"] == null ? null : Info.fromJson(json["info"]), + ); + + Map toJson() => { + "info": info == null ? null : info.toJson(), + }; +} + +class Info { + Info({ + this.st, + }); + + final int st; + + factory Info.fromRawJson(String str) => Info.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Info.fromJson(Map json) => Info( + st: json["st"] == null ? null : json["st"], + ); + + Map toJson() => { + "st": st == null ? null : st, + }; +} + +class Topbar { + Topbar({ + this.desktopTopbarRenderer, + }); + + final DesktopTopbarRenderer desktopTopbarRenderer; + + factory Topbar.fromRawJson(String str) => Topbar.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Topbar.fromJson(Map json) => Topbar( + desktopTopbarRenderer: json["desktopTopbarRenderer"] == null + ? null + : DesktopTopbarRenderer.fromJson(json["desktopTopbarRenderer"]), + ); + + Map toJson() => { + "desktopTopbarRenderer": desktopTopbarRenderer == null + ? null + : desktopTopbarRenderer.toJson(), + }; +} + +class DesktopTopbarRenderer { + DesktopTopbarRenderer({ + this.logo, + this.searchbox, + this.trackingParams, + this.countryCode, + this.topbarButtons, + this.hotkeyDialog, + this.backButton, + this.forwardButton, + this.a11YSkipNavigationButton, + }); + + final Logo logo; + final Searchbox searchbox; + final String trackingParams; + final String countryCode; + final List topbarButtons; + final HotkeyDialog hotkeyDialog; + final BackButtonClass backButton; + final BackButtonClass forwardButton; + final A11YSkipNavigationButton a11YSkipNavigationButton; + + factory DesktopTopbarRenderer.fromRawJson(String str) => + DesktopTopbarRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory DesktopTopbarRenderer.fromJson(Map json) => + DesktopTopbarRenderer( + logo: json["logo"] == null ? null : Logo.fromJson(json["logo"]), + searchbox: json["searchbox"] == null + ? null + : Searchbox.fromJson(json["searchbox"]), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + countryCode: json["countryCode"] == null ? null : json["countryCode"], + topbarButtons: json["topbarButtons"] == null + ? null + : List.from( + json["topbarButtons"].map((x) => TopbarButton.fromJson(x))), + hotkeyDialog: json["hotkeyDialog"] == null + ? null + : HotkeyDialog.fromJson(json["hotkeyDialog"]), + backButton: json["backButton"] == null + ? null + : BackButtonClass.fromJson(json["backButton"]), + forwardButton: json["forwardButton"] == null + ? null + : BackButtonClass.fromJson(json["forwardButton"]), + a11YSkipNavigationButton: json["a11ySkipNavigationButton"] == null + ? null + : A11YSkipNavigationButton.fromJson( + json["a11ySkipNavigationButton"]), + ); + + Map toJson() => { + "logo": logo == null ? null : logo.toJson(), + "searchbox": searchbox == null ? null : searchbox.toJson(), + "trackingParams": trackingParams == null ? null : trackingParams, + "countryCode": countryCode == null ? null : countryCode, + "topbarButtons": topbarButtons == null + ? null + : List.from(topbarButtons.map((x) => x.toJson())), + "hotkeyDialog": hotkeyDialog == null ? null : hotkeyDialog.toJson(), + "backButton": backButton == null ? null : backButton.toJson(), + "forwardButton": forwardButton == null ? null : forwardButton.toJson(), + "a11ySkipNavigationButton": a11YSkipNavigationButton == null + ? null + : a11YSkipNavigationButton.toJson(), + }; +} + +class A11YSkipNavigationButton { + A11YSkipNavigationButton({ + this.buttonRenderer, + }); + + final A11YSkipNavigationButtonButtonRenderer buttonRenderer; + + factory A11YSkipNavigationButton.fromRawJson(String str) => + A11YSkipNavigationButton.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory A11YSkipNavigationButton.fromJson(Map json) => + A11YSkipNavigationButton( + buttonRenderer: json["buttonRenderer"] == null + ? null + : A11YSkipNavigationButtonButtonRenderer.fromJson( + json["buttonRenderer"]), + ); + + Map toJson() => { + "buttonRenderer": + buttonRenderer == null ? null : buttonRenderer.toJson(), + }; +} + +class A11YSkipNavigationButtonButtonRenderer { + A11YSkipNavigationButtonButtonRenderer({ + this.style, + this.size, + this.isDisabled, + this.text, + this.trackingParams, + this.command, + }); + + final String style; + final String size; + final bool isDisabled; + final SubscriberCountText text; + final String trackingParams; + final Command command; + + factory A11YSkipNavigationButtonButtonRenderer.fromRawJson(String str) => + A11YSkipNavigationButtonButtonRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory A11YSkipNavigationButtonButtonRenderer.fromJson( + Map json) => + A11YSkipNavigationButtonButtonRenderer( + style: json["style"] == null ? null : json["style"], + size: json["size"] == null ? null : json["size"], + isDisabled: json["isDisabled"] == null ? null : json["isDisabled"], + text: json["text"] == null + ? null + : SubscriberCountText.fromJson(json["text"]), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + command: + json["command"] == null ? null : Command.fromJson(json["command"]), + ); + + Map toJson() => { + "style": style == null ? null : style, + "size": size == null ? null : size, + "isDisabled": isDisabled == null ? null : isDisabled, + "text": text == null ? null : text.toJson(), + "trackingParams": trackingParams == null ? null : trackingParams, + "command": command == null ? null : command.toJson(), + }; +} + +class Command { + Command({ + this.clickTrackingParams, + this.commandMetadata, + this.signalServiceEndpoint, + }); + + final String clickTrackingParams; + final ServiceEndpointCommandMetadata commandMetadata; + final CommandSignalServiceEndpoint signalServiceEndpoint; + + factory Command.fromRawJson(String str) => Command.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Command.fromJson(Map json) => Command( + clickTrackingParams: json["clickTrackingParams"] == null + ? null + : json["clickTrackingParams"], + commandMetadata: json["commandMetadata"] == null + ? null + : ServiceEndpointCommandMetadata.fromJson(json["commandMetadata"]), + signalServiceEndpoint: json["signalServiceEndpoint"] == null + ? null + : CommandSignalServiceEndpoint.fromJson( + json["signalServiceEndpoint"]), + ); + + Map toJson() => { + "clickTrackingParams": + clickTrackingParams == null ? null : clickTrackingParams, + "commandMetadata": + commandMetadata == null ? null : commandMetadata.toJson(), + "signalServiceEndpoint": signalServiceEndpoint == null + ? null + : signalServiceEndpoint.toJson(), + }; +} + +class CommandSignalServiceEndpoint { + CommandSignalServiceEndpoint({ + this.signal, + this.actions, + }); + + final Signal signal; + final List actions; + + factory CommandSignalServiceEndpoint.fromRawJson(String str) => + CommandSignalServiceEndpoint.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory CommandSignalServiceEndpoint.fromJson(Map json) => + CommandSignalServiceEndpoint( + signal: + json["signal"] == null ? null : signalValues.map[json["signal"]], + actions: json["actions"] == null + ? null + : List.from( + json["actions"].map((x) => StickyAction.fromJson(x))), + ); + + Map toJson() => { + "signal": signal == null ? null : signalValues.reverse[signal], + "actions": actions == null + ? null + : List.from(actions.map((x) => x.toJson())), + }; +} + +class StickyAction { + StickyAction({ + this.signalAction, + }); + + final SignalAction signalAction; + + factory StickyAction.fromRawJson(String str) => + StickyAction.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory StickyAction.fromJson(Map json) => StickyAction( + signalAction: json["signalAction"] == null + ? null + : SignalAction.fromJson(json["signalAction"]), + ); + + Map toJson() => { + "signalAction": signalAction == null ? null : signalAction.toJson(), + }; +} + +class SignalAction { + SignalAction({ + this.signal, + }); + + final String signal; + + factory SignalAction.fromRawJson(String str) => + SignalAction.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory SignalAction.fromJson(Map json) => SignalAction( + signal: json["signal"] == null ? null : json["signal"], + ); + + Map toJson() => { + "signal": signal == null ? null : signal, + }; +} + +class BackButtonClass { + BackButtonClass({ + this.buttonRenderer, + }); + + final BackButtonButtonRenderer buttonRenderer; + + factory BackButtonClass.fromRawJson(String str) => + BackButtonClass.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory BackButtonClass.fromJson(Map json) => + BackButtonClass( + buttonRenderer: json["buttonRenderer"] == null + ? null + : BackButtonButtonRenderer.fromJson(json["buttonRenderer"]), + ); + + Map toJson() => { + "buttonRenderer": + buttonRenderer == null ? null : buttonRenderer.toJson(), + }; +} + +class BackButtonButtonRenderer { + BackButtonButtonRenderer({ + this.trackingParams, + this.command, + }); + + final String trackingParams; + final Command command; + + factory BackButtonButtonRenderer.fromRawJson(String str) => + BackButtonButtonRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory BackButtonButtonRenderer.fromJson(Map json) => + BackButtonButtonRenderer( + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + command: + json["command"] == null ? null : Command.fromJson(json["command"]), + ); + + Map toJson() => { + "trackingParams": trackingParams == null ? null : trackingParams, + "command": command == null ? null : command.toJson(), + }; +} + +class HotkeyDialog { + HotkeyDialog({ + this.hotkeyDialogRenderer, + }); + + final HotkeyDialogRenderer hotkeyDialogRenderer; + + factory HotkeyDialog.fromRawJson(String str) => + HotkeyDialog.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory HotkeyDialog.fromJson(Map json) => HotkeyDialog( + hotkeyDialogRenderer: json["hotkeyDialogRenderer"] == null + ? null + : HotkeyDialogRenderer.fromJson(json["hotkeyDialogRenderer"]), + ); + + Map toJson() => { + "hotkeyDialogRenderer": + hotkeyDialogRenderer == null ? null : hotkeyDialogRenderer.toJson(), + }; +} + +class HotkeyDialogRenderer { + HotkeyDialogRenderer({ + this.title, + this.sections, + this.dismissButton, + this.trackingParams, + }); + + final SubscriberCountText title; + final List sections; + final DismissButtonClass dismissButton; + final String trackingParams; + + factory HotkeyDialogRenderer.fromRawJson(String str) => + HotkeyDialogRenderer.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory HotkeyDialogRenderer.fromJson(Map json) => + HotkeyDialogRenderer( + title: json["title"] == null + ? null + : SubscriberCountText.fromJson(json["title"]), + sections: json["sections"] == null + ? null + : List.from(json["sections"] + .map((x) => HotkeyDialogRendererSection.fromJson(x))), + dismissButton: json["dismissButton"] == null + ? null + : DismissButtonClass.fromJson(json["dismissButton"]), + trackingParams: + json["trackingParams"] == null ? null : json["trackingParams"], + ); + + Map toJson() => { + "title": title == null ? null : title.toJson(), + "sections": sections == null + ? null + : List.from(sections.map((x) => x.toJson())), + "dismissButton": dismissButton == null ? null : dismissButton.toJson(), + "trackingParams": trackingParams == null ? null : trackingParams, + }; +} + +class HotkeyDialogRendererSection { + HotkeyDialogRendererSection({ + this.hotkeyDialogSectionRenderer, + }); + + final HotkeyDialogSectionRenderer hotkeyDialogSectionRenderer; + + factory HotkeyDialogRendererSection.fromRawJson(String str) => + HotkeyDialogRendererSection.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory HotkeyDialogRendererSection.fromJson(Map json) => + HotkeyDialogRendererSection( + hotkeyDialogSectionRenderer: json["hotkeyDialogSectionRenderer"] == null + ? null + : HotkeyDialogSectionRenderer.fromJson( + json["hotkeyDialogSectionRenderer"]), + ); + + Map toJson() => { + "hotkeyDialogSectionRenderer": hotkeyDialogSectionRenderer == null + ? null + : hotkeyDialogSectionRenderer.toJson(), + }; +} + +class HotkeyDialogSectionRenderer { + HotkeyDialogSectionRenderer({ + this.title, + this.options, + }); + + final SubscriberCountText title; + final List