  

import Foundation
///预览结构体
struct JsonBrowses: Codable {
    ///获取访问数据
    let responseContext:ResponseContext?
    ///抓取的数据_预览首次（无额外参数）获取会调用这个
    let contents:Contents?
    ///抓取的数据_预览再（有额外参数）获取会调用这个
    let continuationContents:ContinuationContents?
    enum CodingKeys: String, CodingKey {
        case responseContext = "responseContext"
        case contents = "contents"
        case continuationContents = "continuationContents"

    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        responseContext = try values.decodeIfPresent(ResponseContext.self, forKey: .responseContext)
        contents = try values.decodeIfPresent(Contents.self, forKey: .contents)
        continuationContents = try values.decodeIfPresent(ContinuationContents.self, forKey: .continuationContents)
    }
    
    //MARK: - 内容结构
    ///访问数据
    struct ResponseContext: Codable {
        let visitorData:String?
        enum CodingKeys: String, CodingKey {
            case visitorData = "visitorData"

        }

        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            visitorData = try values.decodeIfPresent(String.self, forKey: .visitorData)
        }
    }
    ///内容结构一
    struct Contents: Codable {
        let singleColumnBrowseResultsRenderer : SingleColumnBrowseResultsRenderer?
        enum CodingKeys: String, CodingKey {

            case singleColumnBrowseResultsRenderer = "singleColumnBrowseResultsRenderer"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            singleColumnBrowseResultsRenderer = try values.decodeIfPresent(SingleColumnBrowseResultsRenderer.self, forKey: .singleColumnBrowseResultsRenderer)
        }
        struct SingleColumnBrowseResultsRenderer: Codable {
            ///通常只有1位数据
            let tabs : [Tab]?
            enum CodingKeys: String, CodingKey {
                case tabs = "tabs"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                tabs = try values.decodeIfPresent([Tab].self, forKey: .tabs)
            }
            struct Tab : Codable {
                let tabRenderer : TabRenderer?
                enum CodingKeys: String, CodingKey {
                    case tabRenderer = "tabRenderer"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    tabRenderer = try values.decodeIfPresent(TabRenderer.self, forKey: .tabRenderer)
                }
                struct TabRenderer : Codable {
                    ///内容总汇（包含content以及第一阶段ctoke吗）
                    let content : Content?
                    enum CodingKeys: String, CodingKey {
                        case content = "content"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        content = try values.decodeIfPresent(Content.self, forKey: .content)
                    }
                    struct Content : Codable {
                        let sectionListRenderer : SectionListRenderer?
                        enum CodingKeys: String, CodingKey {
                            case sectionListRenderer = "sectionListRenderer"
                        }
                        init(from decoder: Decoder) throws {
                            let values = try decoder.container(keyedBy: CodingKeys.self)
                            sectionListRenderer = try values.decodeIfPresent(SectionListRenderer.self, forKey: .sectionListRenderer)
                        }
                        //MARK: - 核心内容，从此往上代码无意义
                        struct SectionListRenderer : Codable {
                            ///指向图像数据内容
                            let contents : [Content]?
                            ///指向续页编码
                            let continuations : [Continuation]?
                            let trackingParams : String?

                            enum CodingKeys: String, CodingKey {
                                case contents = "contents"
                                case continuations = "continuations"
                                case trackingParams = "trackingParams"
                            }

                            init(from decoder: Decoder) throws {
                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                contents = try values.decodeIfPresent([Content].self, forKey: .contents)
                                continuations = try values.decodeIfPresent([Continuation].self, forKey: .continuations)
                                trackingParams = try values.decodeIfPresent(String.self, forKey: .trackingParams)
                            }
                            ///图像数据内容
                            struct Content: Codable {
                                let musicCarouselShelfRenderer:MusicCarouselShelfRenderer?
                                
                                enum CodingKeys: String, CodingKey {
                                    case musicCarouselShelfRenderer = "musicCarouselShelfRenderer"
                                }

                                init(from decoder: Decoder) throws {
                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                    musicCarouselShelfRenderer = try values.decodeIfPresent(MusicCarouselShelfRenderer.self, forKey: .musicCarouselShelfRenderer)
                                }
                                struct MusicCarouselShelfRenderer: Codable {
                                    ///指向模块标题
                                    let header:Header?
                                    ///指向模块内容
                                    let contents:[Content]?
                                    enum CodingKeys: String, CodingKey {
                                        case header = "header"
                                        case contents = "contents"
                                    }
                                    init(from decoder: Decoder) throws {
                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                        header = try values.decodeIfPresent(Header.self, forKey: .header)
                                        contents = try values.decodeIfPresent([Content].self, forKey: .contents)
                                    }
                                    ///模块标题
                                    struct Header: Codable {
                                        let musicCarouselShelfBasicHeaderRenderer:MusicCarouselShelfBasicHeaderRenderer?
                                        enum CodingKeys: String, CodingKey {
                                            case musicCarouselShelfBasicHeaderRenderer = "musicCarouselShelfBasicHeaderRenderer"
                                        }
                                        init(from decoder: Decoder) throws {
                                            let values = try decoder.container(keyedBy: CodingKeys.self)
                                            musicCarouselShelfBasicHeaderRenderer = try values.decodeIfPresent(MusicCarouselShelfBasicHeaderRenderer.self, forKey: .musicCarouselShelfBasicHeaderRenderer)
                                        }
                                        struct MusicCarouselShelfBasicHeaderRenderer: Codable {
                                            let title:Title?
                                            enum CodingKeys: String, CodingKey {
                                                case title = "title"
                                            }
                                            init(from decoder: Decoder) throws {
                                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                                title = try values.decodeIfPresent(Title.self, forKey: .title)
                                            }
                                            struct Title: Codable {
                                                ///一般是第0位
                                                let runs:[Run]?
                                                enum CodingKeys: String, CodingKey {
                                                    case runs = "runs"
                                                }
                                                init(from decoder: Decoder) throws {
                                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                                    runs = try values.decodeIfPresent([Run].self, forKey: .runs)
                                                }
                                                
                                                //MARK: - 文本内容，标题/作者/专辑
                                                struct Run: Codable {
                                                    ///关键文本内容（代表各级标题）
                                                    let text:String?
                                                    ///指向预览ID
                                                    let navigationEndpoint: NavigationEndpoint?
                                                    enum CodingKeys: String, CodingKey {
                                                        case text = "text"
                                                        case navigationEndpoint = "navigationEndpoint"
                                                    }
                                                    init(from decoder: Decoder) throws {
                                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                                        text = try values.decodeIfPresent(String.self, forKey: .text)
                                                        navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
                                                    }
                                                    struct NavigationEndpoint: Codable {
                                                        let browseEndpoint:BrowseEndpoint?
                                                        
                                                        enum CodingKeys: String, CodingKey {
                                                            case browseEndpoint = "browseEndpoint"
                                                        }
                                                        init(from decoder: Decoder) throws {
                                                            let values = try decoder.container(keyedBy: CodingKeys.self)
                                                            browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
                                                            
                                                        }
                                                        //MARK: - 展示内容块的预览内容
                                                        struct BrowseEndpoint: Codable {
                                                            ///预览ID（作者/歌单/专辑都有，关键内容）
                                                            let browseId:String?
                                                            ///预览参数（作者/歌单/专辑具备，关键内容）
                                                            let params:String?
                                                            ///指向预览类型
                                                            let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs?
                                                            enum CodingKeys: String, CodingKey {
                                                                case browseId = "browseId"
                                                                case params = "params"
                                                                case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs"
                                                            }
                                                            init(from decoder: Decoder) throws {
                                                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                                                browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
                                                                params = try values.decodeIfPresent(String.self, forKey: .params)
                                                                browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs)
                                                            }
                                                            struct BrowseEndpointContextSupportedConfigs: Codable {
                                                                let browseEndpointContextMusicConfig:BrowseEndpointContextMusicConfig?
                                                                enum CodingKeys: String, CodingKey {
                                                                    case browseEndpointContextMusicConfig = "browseEndpointContextMusicConfig"
                                                                }
                                                                init(from decoder: Decoder) throws {
                                                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                                                    browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig)
                                                                }
                                                                //MARK: - Browse类型 作者/歌单/专辑
                                                                struct BrowseEndpointContextMusicConfig: Codable {
                                                                    let pageType:String?
                                                                    enum CodingKeys: String, CodingKey {
                                                                        case pageType = "pageType"
                                                                    }
                                                                    init(from decoder: Decoder) throws {
                                                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                                                        pageType = try values.decodeIfPresent(String.self, forKey: .pageType)
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    ///音乐内容
                                    struct Content: Codable {
                                        ///常规列表(通常是四组件构成，封面，一级标题，二级标题，三级标题，额外包含ID内容，通常是单曲)
                                        let musicResponsiveListItemRenderer:RootMusicResponsiveListItemRenderer?
                                        ///两行式列表(通常是三组件构成，封面，一级标题，二级标题，额外包含ID内容，通常是歌单)
                                        let musicTwoRowItemRenderer:RootMusicTwoRowItemRenderer?
                                        enum CodingKeys: String, CodingKey {
                                            case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer"
                                            case musicTwoRowItemRenderer = "musicTwoRowItemRenderer"
                                        }
                                        init(from decoder: Decoder) throws {
                                            let values = try decoder.container(keyedBy: CodingKeys.self)
                                            musicResponsiveListItemRenderer = try values.decodeIfPresent(RootMusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer)
                                            musicTwoRowItemRenderer = try values.decodeIfPresent(RootMusicTwoRowItemRenderer.self, forKey: .musicTwoRowItemRenderer)
                                        }
                                    }
                                }
                            }
                            ///续页编码
                            struct Continuation: Codable {
                                let nextContinuationData:NextContinuationData?
                                enum CodingKeys: String, CodingKey {
                                    case nextContinuationData = "nextContinuationData"
                                }

                                init(from decoder: Decoder) throws {
                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                    nextContinuationData = try values.decodeIfPresent(NextContinuationData.self, forKey: .nextContinuationData)
                                }
                                //MARK: - 续页编码
                                struct NextContinuationData: Codable {
                                    let continuation:String?
                                    let clickTrackingParams:String?
                                    enum CodingKeys: String, CodingKey {
                                        case continuation = "continuation"
                                        case clickTrackingParams = "clickTrackingParams"
                                    }

                                    init(from decoder: Decoder) throws {
                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                        continuation = try values.decodeIfPresent(String.self, forKey: .continuation)
                                        clickTrackingParams = try values.decodeIfPresent(String.self, forKey: .clickTrackingParams)
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    ///内容结构二
    struct ContinuationContents: Codable {
        let sectionListContinuation:SectionListContinuation?
        enum CodingKeys: String, CodingKey {
            case sectionListContinuation = "sectionListContinuation"
        }

        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            sectionListContinuation = try values.decodeIfPresent(SectionListContinuation.self, forKey: .sectionListContinuation)
        }
        //MARK: - 核心内容，从此往上代码无意义
        struct SectionListContinuation : Codable {
            ///指向图像数据内容
            let contents : [Content]?
            ///指向续页编码
            let continuations : [Continuation]?
            let trackingParams : String?

            enum CodingKeys: String, CodingKey {
                case contents = "contents"
                case continuations = "continuations"
                case trackingParams = "trackingParams"
            }

            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                contents = try values.decodeIfPresent([Content].self, forKey: .contents)
                continuations = try values.decodeIfPresent([Continuation].self, forKey: .continuations)
                trackingParams = try values.decodeIfPresent(String.self, forKey: .trackingParams)
            }
            ///图像数据内容
            struct Content: Codable {
                let musicCarouselShelfRenderer:MusicCarouselShelfRenderer?
                
                enum CodingKeys: String, CodingKey {
                    case musicCarouselShelfRenderer = "musicCarouselShelfRenderer"
                }

                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    musicCarouselShelfRenderer = try values.decodeIfPresent(MusicCarouselShelfRenderer.self, forKey: .musicCarouselShelfRenderer)
                }
                struct MusicCarouselShelfRenderer: Codable {
                    ///指向模块标题
                    let header:Header?
                    ///指向音乐内容
                    let contents:[Content]?
                    enum CodingKeys: String, CodingKey {
                        case header = "header"
                        case contents = "contents"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        header = try values.decodeIfPresent(Header.self, forKey: .header)
                        contents = try values.decodeIfPresent([Content].self, forKey: .contents)
                    }
                    ///模块标题
                    struct Header: Codable {
                        let musicCarouselShelfBasicHeaderRenderer:MusicCarouselShelfBasicHeaderRenderer?
                        enum CodingKeys: String, CodingKey {
                            case musicCarouselShelfBasicHeaderRenderer = "musicCarouselShelfBasicHeaderRenderer"
                        }
                        init(from decoder: Decoder) throws {
                            let values = try decoder.container(keyedBy: CodingKeys.self)
                            musicCarouselShelfBasicHeaderRenderer = try values.decodeIfPresent(MusicCarouselShelfBasicHeaderRenderer.self, forKey: .musicCarouselShelfBasicHeaderRenderer)
                        }
                        struct MusicCarouselShelfBasicHeaderRenderer: Codable {
                            let title:Title?
                            enum CodingKeys: String, CodingKey {
                                case title = "title"
                            }
                            init(from decoder: Decoder) throws {
                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                title = try values.decodeIfPresent(Title.self, forKey: .title)
                            }
                            struct Title: Codable {
                                ///一般是第0位
                                let runs:[Run]?
                                enum CodingKeys: String, CodingKey {
                                    case runs = "runs"
                                }
                                init(from decoder: Decoder) throws {
                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                    runs = try values.decodeIfPresent([Run].self, forKey: .runs)
                                }
                                
                                //MARK: - 文本内容，标题/作者/专辑
                                struct Run: Codable {
                                    ///关键文本内容（代表各级标题）
                                    let text:String?
                                    ///指向预览ID
                                    let navigationEndpoint: NavigationEndpoint?
                                    enum CodingKeys: String, CodingKey {
                                        case text = "text"
                                        case navigationEndpoint = "navigationEndpoint"
                                    }
                                    init(from decoder: Decoder) throws {
                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                        text = try values.decodeIfPresent(String.self, forKey: .text)
                                        navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
                                    }
                                    struct NavigationEndpoint: Codable {
                                        let browseEndpoint:BrowseEndpoint?
                                        
                                        enum CodingKeys: String, CodingKey {
                                            case browseEndpoint = "browseEndpoint"
                                        }
                                        init(from decoder: Decoder) throws {
                                            let values = try decoder.container(keyedBy: CodingKeys.self)
                                            browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
                                            
                                        }
                                        //MARK: - 展示内容块的预览内容
                                        struct BrowseEndpoint: Codable {
                                            ///预览ID（作者/歌单/专辑都有，关键内容）
                                            let browseId:String?
                                            ///预览参数（作者/歌单/专辑具备，关键内容）
                                            let params:String?
                                            ///指向预览类型
                                            let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs?
                                            enum CodingKeys: String, CodingKey {
                                                case browseId = "browseId"
                                                case params = "params"
                                                case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs"
                                            }
                                            init(from decoder: Decoder) throws {
                                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                                browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
                                                params = try values.decodeIfPresent(String.self, forKey: .params)
                                                browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs)
                                            }
                                            struct BrowseEndpointContextSupportedConfigs: Codable {
                                                let browseEndpointContextMusicConfig:BrowseEndpointContextMusicConfig?
                                                enum CodingKeys: String, CodingKey {
                                                    case browseEndpointContextMusicConfig = "browseEndpointContextMusicConfig"
                                                }
                                                init(from decoder: Decoder) throws {
                                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                                    browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig)
                                                }
                                                //MARK: - Browse类型 作者/歌单/专辑
                                                struct BrowseEndpointContextMusicConfig: Codable {
                                                    let pageType:String?
                                                    enum CodingKeys: String, CodingKey {
                                                        case pageType = "pageType"
                                                    }
                                                    init(from decoder: Decoder) throws {
                                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                                        pageType = try values.decodeIfPresent(String.self, forKey: .pageType)
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    ///音乐内容
                    struct Content: Codable {
                        ///常规列表(通常是四组件构成，封面，一级标题，二级标题，三级标题，额外包含ID内容，通常是单曲)
                        let musicResponsiveListItemRenderer:RootMusicResponsiveListItemRenderer?
                        ///两行式列表(通常是三组件构成，封面，一级标题，二级标题，额外包含ID内容，通常是歌单)
                        let musicTwoRowItemRenderer:RootMusicTwoRowItemRenderer?
                        enum CodingKeys: String, CodingKey {
                            case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer"
                            case musicTwoRowItemRenderer = "musicTwoRowItemRenderer"
                        }
                        init(from decoder: Decoder) throws {
                            let values = try decoder.container(keyedBy: CodingKeys.self)
                            musicResponsiveListItemRenderer = try values.decodeIfPresent(RootMusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer)
                            musicTwoRowItemRenderer = try values.decodeIfPresent(RootMusicTwoRowItemRenderer.self, forKey: .musicTwoRowItemRenderer)
                        }
                    }
                }
            }
            ///续页编码
            struct Continuation: Codable {
                let nextContinuationData:NextContinuationData?
                enum CodingKeys: String, CodingKey {
                    case nextContinuationData = "nextContinuationData"
                }

                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    nextContinuationData = try values.decodeIfPresent(NextContinuationData.self, forKey: .nextContinuationData)
                }
                //MARK: - 续页编码
                struct NextContinuationData: Codable {
                    let continuation:String?
                    let clickTrackingParams:String?
                    enum CodingKeys: String, CodingKey {
                        case continuation = "continuation"
                        case clickTrackingParams = "clickTrackingParams"
                    }

                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        continuation = try values.decodeIfPresent(String.self, forKey: .continuation)
                        clickTrackingParams = try values.decodeIfPresent(String.self, forKey: .clickTrackingParams)
                    }
                }
            }
        }
    }
}

//MARK: - 图像信息数据结构
///单曲/视频结构(通常是四组件构成，封面，一级标题，二级标题，额外包含ID内容)
struct RootMusicResponsiveListItemRenderer: Codable {
    ///指向封面图像
    let thumbnail:Thumbnail?
    ///指向标题歌手专辑(通常有多位，0位是标题，后续都为副标题)
    let flexColumns:[FlexColumn]?
    ///菜单操作（某些情况下flexColumns无法拿到playListId）
    let menu:Menu?
    ///单曲/视频ID（playlistItemData存在说明这条数据单曲/视频）
    let playlistItemData:PlaylistItemData?
    ///专辑/歌单ID（navigationEndpoint存在说明这条数据是专辑/歌单）
    let navigationEndpoint:NavigationEndpoint?
    enum CodingKeys: String, CodingKey {
        case thumbnail = "thumbnail"
        case flexColumns = "flexColumns"
        case menu = "menu"
        case playlistItemData = "playlistItemData"
        case navigationEndpoint = "navigationEndpoint"
    }
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail)
        flexColumns = try values.decodeIfPresent([FlexColumn].self, forKey: .flexColumns)
        menu = try values.decodeIfPresent(Menu.self, forKey: .menu)
        playlistItemData = try values.decodeIfPresent(PlaylistItemData.self, forKey: .playlistItemData)
        navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
    }
    //含有封面图像
    struct Thumbnail: Codable {
        let musicThumbnailRenderer:MusicThumbnailRenderer?
        enum CodingKeys: String, CodingKey {
            case musicThumbnailRenderer = "musicThumbnailRenderer"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer)
        }
        
        struct MusicThumbnailRenderer: Codable {
            let thumbnail:Thumbnail?
            enum CodingKeys: String, CodingKey {
                case thumbnail = "thumbnail"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                self.thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail)
            }
            struct Thumbnail: Codable {
                ///封面图片组（默认取最后一位，图像内容最大最高清）
                let thumbnails:[Thumbnails]?
                enum CodingKeys: String, CodingKey {
                    case thumbnails = "thumbnails"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    self.thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails)
                }
                //MARK: - 封面图片
                ///封面图片
                struct Thumbnails: Codable {
                    ///封面图片路径
                    let url:String?
                    enum CodingKeys: String, CodingKey {
                        case url = "url"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        url = try values.decodeIfPresent(String.self, forKey: .url)
                    }
                }
            }
        }
    }
    //含有标题作者专辑
    struct FlexColumn: Codable {
        let musicResponsiveListItemFlexColumnRenderer:MusicResponsiveListItemFlexColumnRenderer?
        enum CodingKeys: String, CodingKey {
            case musicResponsiveListItemFlexColumnRenderer = "musicResponsiveListItemFlexColumnRenderer"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            musicResponsiveListItemFlexColumnRenderer = try values.decodeIfPresent(MusicResponsiveListItemFlexColumnRenderer.self, forKey: .musicResponsiveListItemFlexColumnRenderer)
        }
        struct MusicResponsiveListItemFlexColumnRenderer: Codable {
            let text:Text?
            enum CodingKeys: String, CodingKey {
                case text = "text"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                text = try values.decodeIfPresent(Text.self, forKey: .text)
            }
            struct Text: Codable {
                let runs:[Run]?
                enum CodingKeys: String, CodingKey {
                    case runs = "runs"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    runs = try values.decodeIfPresent([Run].self, forKey: .runs)
                }
                struct Run: Codable {
                    ///标题文本
                    let text:String?
                    let navigationEndpoint:NavigationEndpoint?
                    enum CodingKeys: String, CodingKey {
                        case text = "text"
                        case navigationEndpoint = "navigationEndpoint"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        text = try values.decodeIfPresent(String.self, forKey: .text)
                        navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
                    }
                    struct NavigationEndpoint: Codable {
                        let watchEndpoint:WatchEndpoint?
                        enum CodingKeys: String, CodingKey {
                            case watchEndpoint = "watchEndpoint"
                        }
                        init(from decoder: Decoder) throws {
                            let values = try decoder.container(keyedBy: CodingKeys.self)
                            watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint)
                        }
                        struct WatchEndpoint: Codable {
                            let playlistId:String?
                            enum CodingKeys: String, CodingKey {
                                case playlistId = "playlistId"
                            }
                            init(from decoder: Decoder) throws {
                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId)
                            }
                        }
                    }
                }
            }
        }
    }
    //菜单操作
    struct Menu: Codable {
        let menuRenderer:MenuRenderer?
        enum CodingKeys: String, CodingKey {
            case menuRenderer = "menuRenderer"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            menuRenderer = try values.decodeIfPresent(MenuRenderer.self, forKey: .menuRenderer)
        }
        struct MenuRenderer: Codable {
            let items:[Item]?
            enum CodingKeys: String, CodingKey {
                case items = "items"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                items = try values.decodeIfPresent([Item].self, forKey: .items)
            }
            struct Item: Codable {
                let menuNavigationItemRenderer:MenuNavigationItemRenderer?
                enum CodingKeys: String, CodingKey {
                    case menuNavigationItemRenderer = "menuNavigationItemRenderer"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    menuNavigationItemRenderer = try values.decodeIfPresent(MenuNavigationItemRenderer.self, forKey: .menuNavigationItemRenderer)
                }
                struct MenuNavigationItemRenderer: Codable {
                    let navigationEndpoint:NavigationEndpoint?
                    enum CodingKeys: String, CodingKey {
                        case navigationEndpoint = "navigationEndpoint"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
                    }
                    
                    struct NavigationEndpoint: Codable {
                        let watchEndpoint:WatchEndpoint?
                        enum CodingKeys: String, CodingKey {
                            case watchEndpoint = "watchEndpoint"
                        }
                        init(from decoder: Decoder) throws {
                            let values = try decoder.container(keyedBy: CodingKeys.self)
                            watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint)
                        }
                        struct WatchEndpoint: Codable {
                            let playlistId:String?
                            enum CodingKeys: String, CodingKey {
                                case playlistId = "playlistId"
                            }
                            init(from decoder: Decoder) throws {
                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId)
                            }
                        }
                    }
                }
            }
        }
    }
    struct PlaylistItemData: Codable {
        let videoId:String?
        enum CodingKeys: String, CodingKey {
            case videoId = "videoId"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            videoId = try values.decodeIfPresent(String.self, forKey: .videoId)
        }
    }
    struct NavigationEndpoint: Codable {
        let browseEndpoint:BrowseEndpoint?
        enum CodingKeys: String, CodingKey {
            case browseEndpoint = "browseEndpoint"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
        }
        struct BrowseEndpoint: Codable {
            let browseId:String?
            let params:String?
            let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs?
            enum CodingKeys: String, CodingKey {
                case browseId = "browseId"
                case params = "params"
                case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
                params = try values.decodeIfPresent(String.self, forKey: .params)
                browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs)
            }
            struct BrowseEndpointContextSupportedConfigs: Codable {
                let browseEndpointContextMusicConfig:BrowseEndpointContextMusicConfig?
                enum CodingKeys: String, CodingKey {
                    case browseEndpointContextMusicConfig = "browseEndpointContextMusicConfig"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig)
                }
                struct BrowseEndpointContextMusicConfig: Codable {
                    let pageType:String?
                    enum CodingKeys: String, CodingKey {
                        case pageType = "pageType"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        pageType = try values.decodeIfPresent(String.self, forKey: .pageType)
                    }
                }
            }
        }
    }
    
}
///列表/专辑结构(通常是三组件构成，封面，一级标题，二级标题，额外包含ID内容)
struct RootMusicTwoRowItemRenderer: Codable {
    ///内容预览图片
    let thumbnailRenderer:ThumbnailRenderer?
    ///内容标题
    let title:Title?
    ///内容副标题
    let subtitle:Subtitle?
    ///内容iD和编码
    let navigationEndpoint:NavigationEndpoint?
    enum CodingKeys: String, CodingKey {
        case thumbnailRenderer = "thumbnailRenderer"
        case title = "title"
        case subtitle = "subtitle"
        case navigationEndpoint = "navigationEndpoint"
    }
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        thumbnailRenderer = try values.decodeIfPresent(ThumbnailRenderer.self, forKey: .thumbnailRenderer)
        title = try values.decodeIfPresent(Title.self, forKey: .title)
        subtitle = try values.decodeIfPresent(Subtitle.self, forKey: .subtitle)
        navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
    }
    struct ThumbnailRenderer: Codable {
        let musicThumbnailRenderer:MusicThumbnailRenderer?
        enum CodingKeys: String, CodingKey {
            case musicThumbnailRenderer = "musicThumbnailRenderer"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer)
        }
        struct MusicThumbnailRenderer: Codable {
            let thumbnail:Thumbnail?
            enum CodingKeys: String, CodingKey {
                case thumbnail = "thumbnail"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail)
            }
            struct Thumbnail: Codable {
                let thumbnails:[Thumbnails]?
                enum CodingKeys: String, CodingKey {
                    case thumbnails = "thumbnails"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails)
                }
                struct Thumbnails: Codable {
                    let url:String?
                    enum CodingKeys: String, CodingKey {
                        case url = "url"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        url = try values.decodeIfPresent(String.self, forKey: .url)
                    }
                }
            }
        }
    }
    struct Title: Codable {
        let runs:[Run]?
        enum CodingKeys: String, CodingKey {
            case runs = "runs"

        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            runs = try values.decodeIfPresent([Run].self, forKey: .runs)
        }
        struct Run: Codable {
            let text:String?
            enum CodingKeys: String, CodingKey {
                case text = "text"

            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                text = try values.decodeIfPresent(String.self, forKey: .text)
            }
        }
    }
    struct Subtitle: Codable {
        let runs:[Run]?
        enum CodingKeys: String, CodingKey {
            case runs = "runs"

        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            runs = try values.decodeIfPresent([Run].self, forKey: .runs)
        }
        struct Run: Codable {
            let text:String?
            enum CodingKeys: String, CodingKey {
                case text = "text"

            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                text = try values.decodeIfPresent(String.self, forKey: .text)
            }
        }
    }
    struct NavigationEndpoint: Codable {
        ///列表/专辑类型
        let browseEndpoint:BrowseEndpoint?
        ///音视频类型
        let watchEndpoint:WatchEndpoint?
        enum CodingKeys: String, CodingKey {
            case browseEndpoint = "browseEndpoint"
            case watchEndpoint = "watchEndpoint"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
            watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint)
        }
        struct BrowseEndpoint: Codable {
            let browseId:String?
            let params:String?
            let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs?
            enum CodingKeys: String, CodingKey {
                case browseId = "browseId"
                case params = "params"
                case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
                params = try values.decodeIfPresent(String.self, forKey: .params)
                browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs)
            }
            struct BrowseEndpointContextSupportedConfigs: Codable {
                let browseEndpointContextMusicConfig:BrowseEndpointContextMusicConfig?
                enum CodingKeys: String, CodingKey {
                    case browseEndpointContextMusicConfig = "browseEndpointContextMusicConfig"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig)
                }
                struct BrowseEndpointContextMusicConfig: Codable {
                    let pageType:String?
                    enum CodingKeys: String, CodingKey {
                        case pageType = "pageType"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        pageType = try values.decodeIfPresent(String.self, forKey: .pageType)
                    }
                }
            }
        }
        struct WatchEndpoint: Codable {
            ///音视频ID
            let videoId:String?
            ///音视频所在列表ID
            let playlistId:String?
            ///音视频类型
            let watchEndpointMusicSupportedConfigs:WatchEndpointMusicSupportedConfigs?
            enum CodingKeys: String, CodingKey {
                case videoId = "videoId"
                case playlistId = "playlistId"
                case watchEndpointMusicSupportedConfigs = "watchEndpointMusicSupportedConfigs"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                videoId = try values.decodeIfPresent(String.self, forKey: .videoId)
                playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId)
                watchEndpointMusicSupportedConfigs = try values.decodeIfPresent(WatchEndpointMusicSupportedConfigs.self, forKey: .watchEndpointMusicSupportedConfigs)
            }
            struct WatchEndpointMusicSupportedConfigs: Codable {
                let watchEndpointMusicConfig:WatchEndpointMusicConfig?
                enum CodingKeys: String, CodingKey {
                    case watchEndpointMusicConfig = "watchEndpointMusicConfig"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    watchEndpointMusicConfig = try values.decodeIfPresent(WatchEndpointMusicConfig.self, forKey: .watchEndpointMusicConfig)
                }
                struct WatchEndpointMusicConfig: Codable {
                    let musicVideoType:String?
                    enum CodingKeys: String, CodingKey {
                        case musicVideoType = "musicVideoType"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        musicVideoType = try values.decodeIfPresent(String.self, forKey: .musicVideoType)
                    }
                }
            }
        }
    }
}
