├── .gitignore ├── .travis.yml ├── AUDIENCE.md ├── README.md ├── assets ├── Web_Assembly_Logo.svg ├── favicon.ico ├── icon-apple.png ├── icon.png └── readmeBanner.png ├── build-system ├── build.js └── homepage.js ├── demo-util ├── domConsole.js └── instantiateWasm.js ├── devops └── build.sh ├── examples ├── classes │ ├── classes.assemblyscript.en-us.md │ └── demo │ │ └── assemblyscript │ │ ├── ASBindTest.ts │ │ ├── ASBindTest.wasm │ │ ├── index.js │ │ ├── package-lock.json │ │ └── package.json ├── exports │ ├── demo │ │ ├── assemblyscript │ │ │ ├── README.md │ │ │ ├── exports.js │ │ │ ├── exports.ts │ │ │ ├── exports.wasm │ │ │ ├── exports.wat │ │ │ └── index.html │ │ ├── go │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── main.go │ │ │ ├── main.wasm │ │ │ └── wasm_exec.js │ │ └── rust │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── pkg │ │ │ ├── README.md │ │ │ ├── exports.d.ts │ │ │ ├── exports.js │ │ │ ├── exports_bg.d.ts │ │ │ ├── exports_bg.wasm │ │ │ └── package.json │ │ │ └── src │ │ │ └── lib.rs │ ├── exports.assemblyscript.en-us.md │ ├── exports.go.en-us.md │ ├── exports.rust.en-us.md │ └── exports.rust.pt-br.md ├── hello-world │ ├── demo │ │ ├── assemblyscript │ │ │ ├── README.md │ │ │ ├── hello-world.js │ │ │ ├── hello-world.ts │ │ │ ├── hello-world.wasm │ │ │ ├── hello-world.wat │ │ │ └── index.html │ │ ├── go │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── main.go │ │ │ ├── main.wasm │ │ │ └── wasm_exec.js │ │ └── rust │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── pkg │ │ │ ├── README.md │ │ │ ├── hello_world.d.ts │ │ │ ├── hello_world.js │ │ │ ├── hello_world_bg.d.ts │ │ │ ├── hello_world_bg.wasm │ │ │ └── package.json │ │ │ └── src │ │ │ └── lib.rs │ ├── hello-world.assemblyscript.en-us.md │ ├── hello-world.c.en-us.md │ ├── hello-world.go.en-us.md │ ├── hello-world.rust.en-us.md │ └── hello-world.rust.pt-br.md ├── importing-javascript-functions-into-webassembly │ ├── demo │ │ ├── assemblyscript │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── index.ts │ │ │ ├── index.wasm │ │ │ └── index.wat │ │ ├── go │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── main.go │ │ │ ├── main.wasm │ │ │ └── wasm_exec.js │ │ └── rust │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── pkg │ │ │ ├── README.md │ │ │ ├── importing_javascript_functions_into_webassembly.d.ts │ │ │ ├── importing_javascript_functions_into_webassembly.js │ │ │ ├── importing_javascript_functions_into_webassembly_bg.d.ts │ │ │ ├── importing_javascript_functions_into_webassembly_bg.wasm │ │ │ └── package.json │ │ │ └── src │ │ │ └── lib.rs │ ├── importing-javascript-functions-into-webassembly.assemblyscript.en-us.md │ ├── importing-javascript-functions-into-webassembly.go.en-us.md │ ├── importing-javascript-functions-into-webassembly.rust.en-us.md │ └── importing-javascript-functions-into-webassembly.rust.pt-br.md ├── introduction │ ├── introduction.all.en-us.md │ └── introduction.all.pt-br.md ├── passing-high-level-data-types-with-as-bind │ ├── demo │ │ └── assemblyscript │ │ │ ├── addWasmByExample.wasm │ │ │ ├── assembly │ │ │ ├── index.ts │ │ │ └── tsconfig.json │ │ │ ├── build │ │ │ └── .gitignore │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── package-lock.json │ │ │ ├── package.json │ │ │ └── tests │ │ │ └── index.js │ └── passing-high-level-data-types-with-as-bind.assemblyscript.en-us.md ├── passing-high-level-data-types-with-wasm-bindgen │ ├── demo │ │ └── rust │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── pkg │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── strings.d.ts │ │ │ ├── strings.js │ │ │ ├── strings_bg.d.ts │ │ │ └── strings_bg.wasm │ │ │ └── src │ │ │ └── lib.rs │ ├── passing-high-level-data-types-with-wasm-bindgen.rust.en-us.md │ └── passing-high-level-data-types-with-wasm-bindgen.rust.pt-br.md ├── reading-and-writing-audio │ ├── demo │ │ ├── assemblyscript │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── index.ts │ │ │ ├── index.wasm │ │ │ └── index.wat │ │ ├── go │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── main.go │ │ │ ├── main.wasm │ │ │ └── wasm_exec.js │ │ └── rust │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── pkg │ │ │ ├── README.md │ │ │ ├── audio.d.ts │ │ │ ├── audio.js │ │ │ ├── audio_bg.d.ts │ │ │ ├── audio_bg.wasm │ │ │ ├── graphics.d.ts │ │ │ ├── graphics.js │ │ │ ├── graphics_bg.d.ts │ │ │ ├── graphics_bg.wasm │ │ │ └── package.json │ │ │ └── src │ │ │ └── lib.rs │ ├── reading-and-writing-audio.assemblyscript.en-us.md │ ├── reading-and-writing-audio.go.en-us.md │ ├── reading-and-writing-audio.rust.en-us.md │ └── reading-and-writing-audio.rust.pt-br.md ├── reading-and-writing-graphics │ ├── demo │ │ ├── assemblyscript │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── index.ts │ │ │ ├── index.wasm │ │ │ └── index.wat │ │ ├── go │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── main.go │ │ │ ├── main.wasm │ │ │ └── wasm_exec.js │ │ └── rust │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── pkg │ │ │ ├── README.md │ │ │ ├── graphics.d.ts │ │ │ ├── graphics.js │ │ │ ├── graphics_bg.d.ts │ │ │ ├── graphics_bg.wasm │ │ │ └── package.json │ │ │ └── src │ │ │ └── lib.rs │ ├── reading-and-writing-graphics.assemblyscript.en-us.md │ ├── reading-and-writing-graphics.go.en-us.md │ ├── reading-and-writing-graphics.rust.en-us.md │ └── reading-and-writing-graphics.rust.pt-br.md ├── strings │ ├── demo │ │ └── c │ │ │ ├── caesar.cpp │ │ │ ├── caesar.wasm │ │ │ └── index.html │ └── strings.c.en-us.md ├── wasi-hello-world │ ├── demo │ │ ├── assemblyscript │ │ │ ├── assembly │ │ │ │ └── index.ts │ │ │ ├── build │ │ │ │ ├── index.wasm │ │ │ │ └── index.wat │ │ │ ├── helloworld.txt │ │ │ ├── package-lock.json │ │ │ └── package.json │ │ ├── go │ │ │ ├── helloworld.txt │ │ │ ├── main.go │ │ │ ├── main.wasm │ │ │ └── run.sh │ │ └── rust │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ ├── helloworld.txt │ │ │ └── src │ │ │ └── main.rs │ ├── wasi-hello-world.assemblyscript.en-us.md │ ├── wasi-hello-world.go.en-us.md │ ├── wasi-hello-world.rust.en-us.md │ └── wasi-hello-world.rust.pt-br.md ├── wasi-introduction │ ├── wasi-introduction.all.en-us.md │ └── wasi-introduction.all.pt-br.md └── webassembly-linear-memory │ ├── demo │ ├── assemblyscript │ │ ├── README.md │ │ ├── index.html │ │ ├── index.js │ │ ├── index.ts │ │ ├── index.wasm │ │ └── index.wat │ ├── go │ │ ├── README.md │ │ ├── index.html │ │ ├── index.js │ │ ├── main.go │ │ ├── main.wasm │ │ └── wasm_exec.js │ └── rust │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── index.html │ │ ├── index.js │ │ ├── pkg │ │ ├── README.md │ │ ├── package.json │ │ ├── webassembly_linear_memory.d.ts │ │ ├── webassembly_linear_memory.js │ │ ├── webassembly_linear_memory_bg.d.ts │ │ └── webassembly_linear_memory_bg.wasm │ │ └── src │ │ └── lib.rs │ ├── webassembly-linear-memory.assemblyscript.en-us.md │ ├── webassembly-linear-memory.go.en-us.md │ ├── webassembly-linear-memory.rust.en-us.md │ └── webassembly-linear-memory.rust.pt-br.md ├── package-lock.json ├── package.json └── shell ├── about.html ├── additional-resources.html ├── all-examples-list.html ├── demo-redirect.html ├── example-redirect.html ├── example.html ├── home.html ├── index.html ├── js ├── demoRedirect.js ├── examplesList.js ├── examplesRedirect.js ├── index.js ├── indexRedirect.js └── sourceRedirect.js ├── manifest.json ├── partials ├── announcements.html ├── footer.html ├── head.html └── header.html ├── source-redirect.html └── styles ├── examples-list.css └── index.css /.gitignore: -------------------------------------------------------------------------------- 1 | # Build output 2 | dist/ 3 | 4 | # Rust 5 | **/rust/target/**/* 6 | **/rust/pkg/.gitignore 7 | 8 | # Logs 9 | logs 10 | *.log 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # Runtime data 16 | pids 17 | *.pid 18 | *.seed 19 | *.pid.lock 20 | 21 | # Directory for instrumented libs generated by jscoverage/JSCover 22 | lib-cov 23 | 24 | # Coverage directory used by tools like istanbul 25 | coverage 26 | 27 | # nyc test coverage 28 | .nyc_output 29 | 30 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 31 | .grunt 32 | 33 | # Bower dependency directory (https://bower.io/) 34 | bower_components 35 | 36 | # node-waf configuration 37 | .lock-wscript 38 | 39 | # Compiled binary addons (https://nodejs.org/api/addons.html) 40 | build/Release 41 | 42 | # Dependency directories 43 | node_modules/ 44 | jspm_packages/ 45 | 46 | # TypeScript v1 declaration files 47 | typings/ 48 | 49 | # Optional npm cache directory 50 | .npm 51 | 52 | # Optional eslint cache 53 | .eslintcache 54 | 55 | # Optional REPL history 56 | .node_repl_history 57 | 58 | # Output of 'npm pack' 59 | *.tgz 60 | 61 | # Yarn Integrity file 62 | .yarn-integrity 63 | 64 | # dotenv environment variables file 65 | .env 66 | 67 | # next.js build output 68 | .next 69 | 70 | # macOS cruft 71 | .DS_Store 72 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | notifications: 2 | email: false 3 | language: node_js 4 | sudo: false 5 | node_js: 6 | - "node" 7 | install: 8 | - npm install 9 | script: 10 | - npm run lint:ci 11 | - npm run build 12 | -------------------------------------------------------------------------------- /assets/Web_Assembly_Logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/torch2424/wasm-by-example/fce82ed5c4a30c4fe39317e59e354eb60552234c/assets/favicon.ico -------------------------------------------------------------------------------- /assets/icon-apple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/torch2424/wasm-by-example/fce82ed5c4a30c4fe39317e59e354eb60552234c/assets/icon-apple.png -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/torch2424/wasm-by-example/fce82ed5c4a30c4fe39317e59e354eb60552234c/assets/icon.png -------------------------------------------------------------------------------- /assets/readmeBanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/torch2424/wasm-by-example/fce82ed5c4a30c4fe39317e59e354eb60552234c/assets/readmeBanner.png -------------------------------------------------------------------------------- /build-system/homepage.js: -------------------------------------------------------------------------------- 1 | // Supported homepage reading languages 2 | const readingLanguages = ["en-us", "pt-br"]; 3 | 4 | // Our introduction text 5 | const introductionHtml = { 6 | "en-us": ` 7 |
8 | WebAssembly (Wasm) is an universal low level bytecode that runs on the 9 | web. It is a compilation target for languages like 10 | Rust, AssemblyScript (Typescript-like), Emscripten (C/C++), and much 12 | more! 14 | Wasm offer a compact binary format with predictable performance, and 15 | portability to run alongside Javascript and other host languages. Wasm is 16 | currently shipped in all major browsers, and has runtimes meant for 17 | running on servers or interfacing with systems using WASI. 18 |
19 | 20 |21 |34 | ` 35 | }; 36 | 37 | const examplesTitle = { 38 | "en-us": "Examples" 39 | }; 40 | 41 | // Our overall example order 42 | const exampleOrder = [ 43 | "introduction", 44 | "hello-world", 45 | "exports", 46 | "webassembly-linear-memory", 47 | "importing-javascript-functions-into-webassembly", 48 | "reading-and-writing-graphics", 49 | "reading-and-writing-audio", 50 | "passing-high-level-data-types-with-wasm-bindgen", 51 | "passing-high-level-data-types-with-as-bind", 52 | "strings", 53 | "classes", 54 | "wasi-introduction", 55 | "wasi-hello-world" 56 | ]; 57 | 58 | // Catgeories 59 | const concepts = { 60 | title: { 61 | "en-us": "Concepts" 62 | }, 63 | description: { 64 | "en-us": 65 | "Examples that express some of the major underlying concepts in WebAssembly. Some of these examples are not the most convenient or productive way for building projects with WebAssembly. However, these minimal examples are great for learning, or developing straightforward / lower-level parts of an application." 66 | }, 67 | examples: [ 68 | "introduction", 69 | "hello-world", 70 | "exports", 71 | "webassembly-linear-memory", 72 | "importing-javascript-functions-into-webassembly" 73 | ] 74 | }; 75 | 76 | const applyingTheConcepts = { 77 | title: { 78 | "en-us": "Applying the Concepts" 79 | }, 80 | description: { 81 | "en-us": 82 | "Examples that expand on the conceptual examples to show how these minimal examples could be used to build common features in larger applications." 83 | }, 84 | examples: ["reading-and-writing-graphics", "reading-and-writing-audio"] 85 | }; 86 | 87 | const ecosystemAndLanguage = { 88 | title: { 89 | "en-us": "Ecosystem tools and Language features" 90 | }, 91 | description: { 92 | "en-us": 93 | "Examples that highlight tools, libraries, and features of your selected programming language. These ecosystem components can drastically help in building powerful applications. For example, tools can be used to help pass data between your host runtime and WebAssembly module, and/or languages features can abstract away some of the lower-level parts of WebAssembly such as memory management." 94 | }, 95 | examples: [ 96 | "passing-high-level-data-types-with-wasm-bindgen", 97 | "passing-high-level-data-types-with-as-bind", 98 | "strings", 99 | "classes" 100 | ] 101 | }; 102 | 103 | const webassemblyOutsideTheBrowser = { 104 | title: { 105 | "en-us": "WebAssembly Outside of the Browser" 106 | }, 107 | description: { 108 | "en-us": 109 | "Examples that highlight the WebAssembly System Interface (WASI), standalone WebAssembly runtimes, tools for applications that use WASI, and use cases for tasks like cloud computing and internet-of-things devices. WebAssembly has a lot of key features that make it great for the browser web, and these same features make it a popular choice for uses outside of the browser as well." 110 | }, 111 | examples: ["wasi-introduction", "wasi-hello-world"] 112 | }; 113 | 114 | module.exports = { 115 | readingLanguages, 116 | introductionHtml, 117 | examplesTitle, 118 | exampleOrder, 119 | categories: [ 120 | concepts, 121 | applyingTheConcepts, 122 | ecosystemAndLanguage, 123 | webassemblyOutsideTheBrowser 124 | ] 125 | }; 126 | -------------------------------------------------------------------------------- /demo-util/domConsole.js: -------------------------------------------------------------------------------- 1 | // Set up a console element in the dom 2 | const consoleElement = document.createElement("pre"); 3 | consoleElement.style = `border: 1px solid black`; 4 | consoleElement.textContent = ` 5 | DOM Console: 6 | `; 7 | document.body.appendChild(consoleElement); 8 | 9 | export function domConsoleLog(string) { 10 | console.log(string); 11 | 12 | if (string === undefined) { 13 | string = "undefined"; 14 | } 15 | 16 | consoleElement.textContent = `${consoleElement.textContent} 17 | ${string} 18 | `; 19 | } 20 | -------------------------------------------------------------------------------- /demo-util/instantiateWasm.js: -------------------------------------------------------------------------------- 1 | export const wasmBrowserInstantiate = async (wasmModuleUrl, importObject) => { 2 | let response = undefined; 3 | 4 | if (!importObject) { 5 | importObject = { 6 | env: { 7 | abort: () => console.log("Abort!") 8 | } 9 | }; 10 | } 11 | 12 | if (WebAssembly.instantiateStreaming) { 13 | response = await WebAssembly.instantiateStreaming( 14 | fetch(wasmModuleUrl), 15 | importObject 16 | ); 17 | } else { 18 | const fetchAndInstantiateTask = async () => { 19 | const wasmArrayBuffer = await fetch(wasmModuleUrl).then(response => 20 | response.arrayBuffer() 21 | ); 22 | return WebAssembly.instantiate(wasmArrayBuffer, importObject); 23 | }; 24 | response = await fetchAndInstantiateTask(); 25 | } 26 | 27 | return response; 28 | }; 29 | -------------------------------------------------------------------------------- /devops/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Script to do frontend staging deployments 4 | 5 | # redirect stdout/stderr to a file 6 | exec &> wasm-by-example-build.log 7 | 8 | cd ../ 9 | 10 | git stash 11 | 12 | git checkout master 13 | 14 | git pull origin master 15 | 16 | rm package-lock.json 17 | 18 | npm install 19 | 20 | npm run build 21 | 22 | # Copy the build output to public/ if successful build 23 | if [ $? -eq 0 ]; then 24 | rm -rf public 25 | mkdir -p public 26 | cp -r dist/* public/ 27 | else 28 | echo "Failed Building wasm-by-example" 29 | fi 30 | 31 | echo "Done!" 32 | -------------------------------------------------------------------------------- /examples/classes/demo/assemblyscript/ASBindTest.ts: -------------------------------------------------------------------------------- 1 | // Vector2D is a mathematical vector in 2D space. 2 | // It has an x and y directional component and a magnitude 3 | export class Vector2D { 4 | // x and y directional component of the vector 5 | x: i32; 6 | y: i32; 7 | // constructor for initializing the x and y components 8 | constructor(x: i32, y: i32) { 9 | this.x = x; 10 | this.y = y; 11 | } 12 | 13 | // the squared magnitude of the vector 14 | MagSQ(): i32 { 15 | return this.x * this.x + this.y * this.y; 16 | } 17 | 18 | // getting the magnitude of the vector 19 | Magnitude(): f32 { 20 | return f32.sqrt(What is Wasm By Example?
22 |23 | Wasm By Example is a concise, hands-on introduction to WebAssembly using 24 | code snippets and annotated WebAssembly example programs. Learn more 25 | about Wasm at the 26 | WebAssembly Introduction 30 | 31 | or browse the list of examples below. 32 |
33 |
Please check your JavaScript console for the results.
11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/importing-javascript-functions-into-webassembly/demo/rust/index.js: -------------------------------------------------------------------------------- 1 | import wasmInit from "./pkg/importing_javascript_functions_into_webassembly.js"; 2 | 3 | const runWasm = async () => { 4 | // Instantiate our wasm module 5 | const rustWasm = await wasmInit( 6 | "./pkg/importing_javascript_functions_into_webassembly_bg.wasm" 7 | ); 8 | 9 | // Run the exported function 10 | rustWasm.console_log_from_wasm(); // Should log "This console.log is from wasm!" 11 | }; 12 | runWasm(); 13 | -------------------------------------------------------------------------------- /examples/importing-javascript-functions-into-webassembly/demo/rust/pkg/README.md: -------------------------------------------------------------------------------- 1 | # Hello World (Assemblyscript) 2 | 3 | Compile with `asc hello-world.ts -b hello-world.wasm -t hello-world.wat` 4 | -------------------------------------------------------------------------------- /examples/importing-javascript-functions-into-webassembly/demo/rust/pkg/importing_javascript_functions_into_webassembly.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /** 3 | * @returns {void} 4 | */ 5 | export function console_log_from_wasm(): void; 6 | 7 | /** 8 | * If `module_or_path` is {RequestInfo}, makes a request and 9 | * for everything else, calls `WebAssembly.instantiate` directly. 10 | * 11 | * @param {RequestInfo | BufferSource | WebAssembly.Module} module_or_path 12 | * 13 | * @returns {Promise20 | Wasm By Example is a concise, hands-on introduction to WebAssembly using 21 | code snippets and annotated WebAssembly example programs. If you "learn 22 | best by doing", or just need a good starting point for a concept, this 23 | is the place for you. Wasm By Example offers wasm examples in multiple 24 | programming / written languages, where the languages are available for 25 | the example. Browse the list of wasm examples below. 26 |
27 | 28 |29 | Google Analytics is used on Wasm By Example, and is only used to record 30 | Basic visit data, as the script is only loaded. 35 |
36 | 37 |38 | Just a quick shoutout to 39 | Carlos Baraza. Who created the 42 | WebAssembly Logo 48 | under a Creative Commons Universal license. The logo is used in the site 49 | favicon and title header. 50 |
51 | 52 |53 |64 | 65 | {{{partials.footer}}} 66 |Got stuck? Found a bug?
54 |55 | If you can't find what you are looking for, feel free to 56 | open a request, or contribute back! 61 | 62 |
63 |
23 | Below is a list of all available WebAssembly examples on Wasm by 24 | Example. Organized by their respective language. Currently, this 25 | will not switch your language preferences. But will allow you 26 | to see another WebAssembly example without having to set the default 27 | language. 28 |
29 |3 | The maintainer of this website has a 4 | Spotify Coding Playlist of their Lo-fi Hip Hop beats! 9 |
10 |