rener97 / domestika-downloader Goto Github PK
View Code? Open in Web Editor NEWDownload full domestika courses
Home Page: https://www.buymeacoffee.com/ReneR97
Download full domestika courses
Home Page: https://www.buymeacoffee.com/ReneR97
Hi, thanks for this tool!
I cannot find the "credentials" cookie...
But there is a "remember_user_token" is this the same?
Thank you.
I'm on an M2 Mac mini. Tried to run it, installed Node, ffmpeg (using homebrew), downloaded the arm64 binary of N_m3u8DL-RE and put it in the directory. But I get this error:
node:internal/errors:865
const err = new Error(message);
^
Error: Command failed: N_m3u8DL-RE -sv res="1080*":codec=hvc1:for=best "https://cdn-videos.domestika.org/videos/000/059/250/1d55d7f46ef294fd10ba89f877fbd66d/master.m3u8?1676409564" --save-dir "domestika_courses/Course/U1- Introduction" --save-name "0_About Me"
/bin/sh: N_m3u8DL-RE: command not found
at ChildProcess.exithandler (node:child_process:421:12)
at ChildProcess.emit (node:events:514:28)
at maybeClose (node:internal/child_process:1105:16)
at Socket.<anonymous> (node:internal/child_process:457:11)
at Socket.emit (node:events:514:28)
at Pipe.<anonymous> (node:net:337:12) {
code: 127,
killed: false,
signal: null,
cmd: 'N_m3u8DL-RE -sv res="1080*":codec=hvc1:for=best "https://cdn-videos.domestika.org/videos/000/059/250/1d55d7f46ef294fd10ba89f877fbd66d/master.m3u8?1676409564" --save-dir "domestika_courses/Leather Crafting 101/U1- Introduction" --save-name "0_About Me"',
stdout: '',
stderr: '/bin/sh: N_m3u8DL-RE: command not found\n'
}
I've tried adding the .exe (windows app) extension, and removing the .exe in the index.js:
//Check if the N_m3u8DL-RE.exe exists, throw error if not
if (fs.existsSync('N_m3u8DL-RE.exe')) {
scrapeSite();
} else {
throw Error('N_m3u8DL-RE.exe not found! Download the Binary here: https://github.com/nilaoda/N_m3u8DL-RE/releases');
}
But both ways failed. Is it possible to make it work on macOS?
Hi and thanks for create/support this script, it's a lifesaver! I've encountered a couple of issues that I was able to troubleshoot, but I'm unable to fix this one. I get the error message below, and then, an empty folder is created on domestika_courses
, but at the same time, a folder for each unit is created within the main folder, that has videos that last 2 to 5 seconds.
Do you have any idea what it could possibly be?
TIA!!!
const err = new Error(message);
^
Error: Command failed: N_m3u8DL-RE -sv res="1080*":codec=hvc1:for=best "https://cdn-videos.domestika.org/videos/000/002/827/6bc2b9ea801300f3b9717c41ff3528b5/master.m3u8?1676414175" --save-dir "domestika_courses/Design and Illustration of a Fanzine//U4- Illustration and Methodology" --save-name "6_Vector drawing 3"
at genericNodeError (node:internal/errors:984:15)
at wrappedFn (node:internal/errors:538:14)
at ChildProcess.exithandler (node:child_process:422:12)
at ChildProcess.emit (node:events:518:28)
at maybeClose (node:internal/child_process:1105:16)
at ChildProcess._handle.onexit (node:internal/child_process:305:5) {
code: 1,
killed: false,
signal: null,
cmd: 'N_m3u8DL-RE -sv res="1080*":codec=hvc1:for=best "https://cdn-videos.domestika.org/videos/000/002/827/6bc2b9ea801300f3b9717c41ff3528b5/master.m3u8?1676414175" --save-dir "domestika_courses/Design and Illustration of a Fanzine//U4- Illustration and Methodology" --save-name "6_Vector drawing 3"',
stdout: '17:50:54.895 INFO : N_m3u8DL-RE (Beta version) 20230628\r\n' +
'17:50:54.912 INFO : Loading URL: https://cdn-videos.domestika.org/videos/000/002/827/6bc2b9ea801300f3b9717c41ff3528b5/master.m3u8?1676414175\r\n' +
'17:50:55.909 INFO : Content Matched: HTTP Live Streaming\r\n' +
'17:50:55.909 INFO : Parsing streams...\r\n' +
'17:50:55.909 WARN : Master List detected, try parse all streams\r\n' +
'17:50:55.923 WARN : Writing meta json\r\n' +
'17:50:55.924 INFO : Extracted, there are 9 streams, with 5 basic streams, 1 audio streams, 3 subtitle streams\r\n' +
'17:50:55.924 INFO : Vid 1920x1080 | 4269 Kbps | 25 | mp4a.40.2\r\n' +
'17:50:55.924 INFO : Vid 1280x720 | 2384 Kbps | 25 | mp4a.40.2\r\n' +
'17:50:55.925 INFO : Vid 960x540 | 1625 Kbps | 25 | mp4a.40.2\r\n' +
'17:50:55.925 INFO : Vid 640x360 | 1291 Kbps | 25 | mp4a.40.2\r\n' +
'17:50:55.925 INFO : Vid 400x224 | 431 Kbps | 25 | mp4a.40.2\r\n' +
'17:50:55.926 INFO : Aud audio-medium | Original | es | 2CH\r\n' +
'17:50:55.926 INFO : Sub sub1 | es | Espa�ol\r\n' +
'17:50:55.926 INFO : Sub sub1 | en | English\r\n' +
'17:50:55.927 INFO : Sub sub1 | pt | Portugu�s\r\n' +
'17:50:55.927 INFO : Parsing streams...\r\n' +
'17:50:55.985 INFO : Selected streams:\r\n' +
'17:50:55.985 INFO : Vid 1920x1080 | 4269 Kbps | 25 | mp4a.40.2 | 99 Segments | \r\n' +
'~15m12s\r\n' +
'17:50:55.985 WARN : Writing meta json\r\n' +
'17:50:55.986 INFO : Save Name: 6_Vector drawing 3\r\n' +
'17:50:55.987 INFO : Start downloading...Vid 1920x1080 | 4269 Kbps | 25 | \r\n' +
'mp4a.40.2\r\n' +
'17:50:56.153 WARN : Reading media info...\r\n' +
'17:50:56.541 INFO : [0x100]: Video, h264 (High) ([27][0][0][0]), 1920x1080, 25 \r\n' +
'fps\r\n' +
'17:50:56.541 INFO : [0x101]: Audio, aac (LC) ([15][0][0][0]), 130 kb/s\r\n' +
'17:50:56.542 INFO : [0x102]: Data, timed_id3 (ID3 )\r\n' +
'Vid 1920x1080 | 4269 Kbps | 25: 4%\r\n' +
'17:51:00.128 WARN : The SSL connection could not be established, see inner \r\n' +
'exception.\r\n' +
'17:51:00.146 WARN : The SSL connection could not be established, see inner \r\n' +
'exception.\r\n' +
'Vid 1920x1080 | 4269 Kbps | 25: 26%\r\n' +
'Vid 1920x1080 | 4269 Kbps | 25: 43%\r\n' +
'Vid 1920x1080 | 4269 Kbps | 25: 49%\r\n' +
'Vid 1920x1080 | 4269 Kbps | 25: 50%\r\n' +
'Vid 1920x1080 | 4269 Kbps | 25: 72%\r\n' +
'Vid 1920x1080 | 4269 Kbps | 25: 75%\r\n' +
'Vid 1920x1080 | 4269 Kbps | 25: 94%\r\n' +
'Vid 1920x1080 | 4269 Kbps | 25: 95%\r\n' +
'Vid 1920x1080 | 4269 Kbps | 25: 96%\r\n' +
'Vid 1920x1080 | 4269 Kbps | 25: 97%\r\n' +
'Vid 1920x1080 | 4269 Kbps | 25: 98%\r\n' +
'17:53:51.134 ERROR: Segment count check not pass, total: 99, downloaded: 97.\r\n' +
'17:53:51.134 ERROR: Failed\r\n',
stderr: ''
}
Node.js v20.12.2
Close #24
Hello, my language is Portuguese, but I am not able to download subtitles in Portuguese. I've already tested in English and Italian and they worked (en, it)
For my language I already tried:
pt, por, po and pt-br and subtitle files are not downloaded in the folder.
Do you know what this code would be to download in Portuguese? Can you test?
De ante mano pido disculpas no se nada de código, pero encontré la solución para que funcionara en mac, me apoye en GPT4PLus para solucionar y les comparto entonces como yo lo hice, quizás para algunos sea tonto pero yo tarde horas debido a mi inexperiencia.
Yo lo hice usando una nueva terminal llamada warp que tiene IA incluida:
https://www.warp.dev/ te la descargas e instalas.
Hello,
I noticed that the "credentials" cookie isn't available. Is this a known issue? Are there plans to update the script to address this? Additionally, is there an alternative to the .exe file for running the script on Linux or macOS?
Thank you in advance
access_token = regex_token.exec(access_token)[1];
^
TypeError: Cannot read properties of null (reading '1')
at scrapeSite (/home/hyk-zorin/Videos/Domestika/domestika-downloader-main/index.js:71:50)
now there is no credentials cookie.. The name of the cookie is "remember_user_token"
[email protected] start
node index.js
Only these two lines are displayed after that the cursor blinks it doesn't download anything
Now I get this error after changing few things
node:internal/deps/undici/undici:12345
Error.captureStackTrace(err, this);
^
TypeError: fetch failed
at node:internal/deps/undici/undici:12345:11
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async fetchFromApi (C:\Users\domestika-downloader-main\domestika-downloader-main\index.js:151:22)
at async scrapeSite (C:\Users\domestika-downloader-main\domestika-downloader-main\index.js:73:22) {
cause: Error: read ECONNRESET
at TLSWrap.onStreamRead (node:internal/stream_base_commons:217:20) {
errno: -4077,
code: 'ECONNRESET',
syscall: 'read'
}
}
Node.js v20.11.1
I found a weird problem, dd skips an entire chapter! Pls check your discord!
I have Domestika PLUS and would like to download some of the free courses but when I try one of the courses I get with PLUS I just get a Error message for all the video files.
How can I download by choosing the audio from another specific language or download it in several audio languages?
Thanks for sharing it! Is there a way to download courses that are not actually added to my library (not bought for cash or credits) but I can access them with my Domestika Plus subscription? It looks like there is no videos array available in the data object (retrieved with getInitialProps) for such courses even though I can watch them online.
Error
/Users/xxx/Repositories/domestika-downloader/index.js:136
for (let i = 0; i < data.videos.length; i++) {
^
TypeError: Cannot read properties of undefined (reading 'length')
at getInitialProps (/Users/xxx/Repositories/domestika-downloader/index.js:136:41)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async scrapeSite (/Users/xxx/Repositories/domestika-downloader/index.js:56:25)
Data object
{
user: {
settings: { audioLanguage: 'es', subtitleLanguage: 'en', isEmpty: false }
},
course: {
id: 3043,
cover: 'https://cdn.domestika.org/c_fill,dpr_auto,f_auto,pg_1,t_base_params/v1652427744/course-covers/000/003/043/3043-original.jpg?1652427744',
totalNumUnits: 4,
totalNumLessons: 15
},
video: {
id: 54601,
cover: 'https://i.vimeocdn.com/video/1431079023-c47906653e8c57038a3792f8da1a1567c5eb2a4c9730f1925d50527990858106-d_1280x720',
duration: 145,
playbackURL: 'https://lambda-videos.domestika.org/master.m3u8?fallback_url=https%253A%252F%252Fwww.domestika.org%252Fapi%252Fv2%252Fvideo_item_m3u8%252F54601.m3u8&provider_playlist_url=https%253A%252F%252Fplayer.vimeo.com%252Fexternal%252F695778529.m3u8%253Fs%253D19a5a25cac043182642929093c47d6facc98ff49%2526oauth2_token_id%xxx&static_playlist_url=https%253A%252F%252Fcdn-videos.domestika.org%252Fvideos%252F000%252F054%252F601%252Fa09c543c608c1eee725d2f6fd99d1f51%252Fmaster.m3u8%253F1676406911',
isTrailer: true,
allowPlay: true,
thumbnailsURL: 'https://cdn-videos.domestika.org/videos/000/054/601/a09c543c608c1eee725d2f6fd99d1f51/thumbnails/thumbnails.vtt?1676406912'
}
}
Getting a lot of errors:
`Video Found: Introduction and materials
Video Found: Ink 1
Video Found: Ink 2
Video Found: Watercolor 1
Video Found: Watercolor 2
Video Found: Ink and watercolor
Video Found: Hundertwasser
Video Found: The five skins
Video Found: Theme and documentation
Video Found: Character 1
Video Found: Character 2
Video Found: Home
Video Found: Community
Video Found: World
Video Found: Sketch and pose illustration
Video Found: Apply the color with watercolor
Video Found: Inking and final details
All Videos Found
Fetching Final Project
Download 1/20 Started
Download 2/20 Started
Download 3/20 Started
Download 4/20 Started
Download 5/20 Started
Download 6/20 Started
Download 7/20 Started
Download 8/20 Started
Download 9/20 Started
Download 10/20 Started
Download 11/20 Started
Download 12/20 Started
Download 13/20 Started
Download 14/20 Started
Download 15/20 Started
Download 16/20 Started
Download 17/20 Started
Download 18/20 Started
Download 19/20 Started
Download 20/20 Started
node:internal/errors:932
const err = new Error(message);
^
Error: Command failed: N_m3u8DL-RE -sv res="1080*":codec=hvc1:for=best "https://cdn-videos.domestika.org/videos/000/042/099/e5fe1b566fe895531f3dadca95af8293/master.m3u8?1676400687" --save-dir "domestika_courses/Imaginary Worlds Illustrated with Ink and Watercolor//U5- Illustrated scene step by step" --save-name "2_Inking and final details"
Die Version von J:@domestika-downloader\N_m3u8DL-RE.exe ist mit der ausgef�hrten Windows-Version nicht kompatibel. �berpr�fen Sie die Systeminformationen des Computers, und wenden Sie sich anschlie�end an den Herausgeber der Software.
at ChildProcess.exithandler (node:child_process:422:12)
at ChildProcess.emit (node:events:514:28)
at maybeClose (node:internal/child_process:1105:16)
at Socket.<anonymous> (node:internal/child_process:457:11)
at Socket.emit (node:events:514:28)
at Pipe.<anonymous> (node:net:337:12) {
code: 1,
killed: false,
signal: null,
cmd: 'N_m3u8DL-RE -sv res="1080*":codec=hvc1:for=best "https://cdn-videos.domestika.org/videos/000/042/099/e5fe1b566fe895531f3dadca95af8293/master.m3u8?1676400687" --save-dir "domestika_courses/Imaginary Worlds Illustrated with Ink and Watercolor//U5- Illustrated scene step by step" --save-name "2_Inking and final details"',
stdout: '',
stderr: 'Die Version von J:\@domestika-downloader\N_m3u8DL-RE.exe ist mit der ausgef�hrten Windows-Version nicht kompatibel. �berpr�fen Sie die Systeminformationen des Computers, und wenden Sie sich anschlie�end an den Herausgeber der Software.\r\n'
}
Node.js v20.10.0
PS J:@domestika-downloader>`
Close #19
This is not an issue or a big deal at all as much as a curious question.
Some courses are available in dual audio, and English is one of them. Is there a line I code to add to pick this audio instead of the original?
Example: https://www.domestika.org/en/courses/3019-creativity-for-beginners-level-1
Thanks
after download finished all folders in empty only create folder with course and units names but not downloading any thing
Hi, first of all, thank you for maintaining this tool. It is a god sent! :)
I have a difficult downloading one of the course. This one:
https://www.domestika.org/en/courses/83-2d-animation-with-toon-boom-harmony/course
It seems all downloaded fine, but half of the folders are empty. But the other half did downloaded successfully.
Just to be sure, I have my ffmpeg.exe place at the same folder as the index.js. Is it correct?
Thank you.
This is the log.json file:
Managed to solve the problem! The program was running great! It is my computer problem. Thank you So much ReneR97!
When running the script I have this error. Please, help.
TypeError: Cannot read properties of undefined (reading 'relationships')
at scrapeSite ([REDACTED]\index.js:76:40)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Close #30
Result:
C:\Users\Prohi\Downloads\domestika-downloader-main>npm run start
[email protected] start
node index.js
C:\Users\Prohi\Downloads\domestika-downloader-main\index.js:135
for (let i = 0; i < data.videos.length; i++) {
^
TypeError: Cannot read properties of undefined (reading 'length')
at getInitialProps (C:\Users\Prohi\Downloads\domestika-downloader-main\index.js:135:41)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async scrapeSite (C:\Users\Prohi\Downloads\domestika-downloader-main\index.js:54:25)
Node.js v20.11.1
The provided JavaScript file seems to be a web scraping script designed to download videos from a website. Here are a few potential errors and improvements:
Empty course_url: The course_url variable is empty, which means the script won't know which course to scrape. You need to provide a valid URL for a course.
Empty credentials: The credentials variable is empty, and the script tries to extract an access token from it using a regular expression. You need to provide valid credentials or remove the access token logic if it's not necessary.
Missing fetch: The fetch function is used in the fetchFromApi function, but it hasn't been imported or defined. You should import it at the beginning of the script (const fetch = require('node-fetch');) or use a different HTTP client.
fetchFromApi doesn't handle non-OK responses: If the API request fails (e.g., due to invalid credentials), the function returns false without providing much information. It might be helpful to log the actual error or response status code.
Potential concurrency issue in logging: In the downloadVideo function, multiple asynchronous exec calls are made to download videos. The debug_data array is shared among these calls, which could lead to concurrency issues if multiple calls modify it simultaneously. Consider using a lock mechanism or logging separately for each video download.
Potential filename issues: The filenames generated for saving videos might contain characters that are not allowed in filenames on some filesystems (/\?%*:|"<>). You should handle or replace these characters appropriately.
Error handling in downloadVideo: The exec calls in the downloadVideo function are awaited, but there's no error handling for potential failures in the video download process. You should handle errors or at least log them to understand what went wrong.
Potential unhandled promise rejections: There are several asynchronous operations in the script, but not all promise rejections are handled. Make sure to add appropriate error handling (e.g., .catch) for all asynchronous operations.
By addressing these potential issues, you can improve the robustness and reliability of the web scraping script.
The first two are obvious, but I hope the rest are of some value.
Download 1/19 Downloaded
Download 2/19 Downloaded
Download 3/19 Downloaded
Download 4/19 Downloaded
Download 5/19 Downloaded
Download 6/19 Downloaded
Download 7/19 Downloaded
Download 8/19 Downloaded
Download 9/19 Downloaded
Download 10/19 Downloaded
Download 11/19 Downloaded
Download 12/19 Downloaded
Download 13/19 Downloaded
Download 14/19 Downloaded
Download 15/19 Downloaded
Download 16/19 Downloaded
Download 17/19 Downloaded
Download 18/19 Downloaded
Download 19/19 Downloaded
All Videos Downloaded
but the folder have no video
Hello Rene,
Getting SyntaxError: Unexpected token '%' after executing npm start
Thanks for the plugin. It has been a little bit of a challenge getting it to work.
I have installed cookie-editor for chrome extension for brave and it only gives me 2 items, _domestika_session and remember user token. Credentials does not come.
I opened the extension in Chrome, and get the same 2 options.
I opened the extension in Firefox and got the whole list of options.
I pasted the credentials value and got the above error message. Here is the full error message, you may be able to decode it
SyntaxError: Unexpected token '%'
at internalCompileFunction (node:internal/vm:77:18)
at wrapSafe (node:internal/modules/cjs/loader:1288:20)
at Module._compile (node:internal/modules/cjs/loader:1340:27)
at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
at Module.load (node:internal/modules/cjs/loader:1207:32)
at Module._load (node:internal/modules/cjs/loader:1023:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:135:12)
at node:internal/main/run_main_module:28:49
Thanks
Downloading works but sometimes there are videos within a Unit not being downloaded. I found the problem. If you go in the course page on Domestika and pick a unit, you will see 1 or more videos for that unit. For some reason, some video title have a blank space at the end of the name (use inspect to see the code).
To fix the download problem related to the trailing blank space, I modified the index.js code to remove the trailing blank:
vData.title becomes vData.title.trimEnd() for both the video and subtitle:
let log = await exec(N_m3u8DL-RE -sv res="1080*":codec=hvc1:for=best "${vData.playbackURL}" --save-dir "domestika_courses/${title}/${unit.title}" --save-name "${a}_${vData.title.trimEnd()}"
);
let log2 = await exec(N_m3u8DL-RE --auto-subtitle-fix --sub-format SRT --select-subtitle lang="${subtitle_lang}":for=all "${vData.playbackURL}" --save-dir "domestika_courses/${title}/${unit.title}" --save-name "${a}_${vData.title.trimEnd()}"
);
Works like a charm now.
Cheers
Hello,
My link:
const course_url = 'https://www.domestika.org/en/courses/4911-sculpture-and-color-polychrome-techniques/course';
const subtitle_lang = 'en';
while performing npm run start
getting the below error:
Any suggestions. Thanks in advance for your efforts.
Hi,
At the Terminal stepn when I enter "npm i", it says "zsh: command not found: npm"
Same thing when entering "npm run start."
I think I did everything right, I'm on a mac M1
Good night !
E:\N_m3u8DL-RE_Beta_win-x64\index.js:37
const access_token = regex_token.exec(decodeURI(credentials))[1];
^
TypeError: Cannot read properties of null (reading '1')
at Object. (E:\N_m3u8DL-RE_Beta_win-x64\index.js:37:64)
at Module._compile (node:internal/modules/cjs/loader:1368:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1426:10)
at Module.load (node:internal/modules/cjs/loader:1205:32)
at Module._load (node:internal/modules/cjs/loader:1021:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:142:12)
at node:internal/main/run_main_module:28:49
Node.js v21.7.1
error: new Errors_js_1.ProtocolError(),
^
ProtocolError: Protocol error (Page.navigate): Cannot navigate to invalid URL
I get this error after npm run start.
Any ideas?
not sure how to "open a terminal and type npm i"..
i've followed the instructions, pasted from Cookie-editor, downloaded and installed ffmpeg, N_m3u8DL-RE, but i don't know how to move forward from here. ^^; tried to use the command prompt but i'm stuck. help please? thanks!
Hey! I don't seem to make this work, Maybe I am missing a step?
const access_token = regex_token.exec(decodeURI(credentials))[1];
^
TypeError: Cannot read properties of null (reading '1')
at Object. (C:\Users....\Desktop\domestika-downloader-main\index.js:36:64)
at Module._compile (node:internal/modules/cjs/loader:1256:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
at Module.load (node:internal/modules/cjs/loader:1119:32)
at Module._load (node:internal/modules/cjs/loader:960:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:23:47
Domestika.org just show this two cookies:
_domestika_session
remember_user_token
Using "remember_user_token" on credentials report this error:
access_token = regex_token.exec(access_token)[1];
TypeError: Cannot read properties of null (reading '1')
at scrapeSite (C:\Users\Openbravo\Downloads\Crochet\domestika-downloader-main\index.js:71:50)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.