melonsoda 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/js/official.js ADDED
@@ -0,0 +1,119 @@
1
+ (function() {
2
+
3
+ window.officialUrls = [
4
+ { url: "https://durokotte.foo.ng/melonsoda/", comment: "ts is the main page" },
5
+ { url: "https://meronsooda.netlify.app/", comment: "netlify mirror" },
6
+ { url: "https://raw.githack.com/linuxfandudeguy/melonsoda/main/", comment: "not hosted by me but i personally use it so is passes" },
7
+ { url: "https://learn-french-easy.wasmer.app/", comment: "you can learn some very nice french words like le cul" },
8
+ { url: "https://k12-algebra-tutoring-edu-us-resources.pages.dev/", comment: "omg algebra tutoring!1!1!11" },
9
+ { url: "https://educational-algebra-study-tutor.edgeone.app/", comment: "had to use the sketchy tencent edge service as that wasn't blocked " },
10
+ { url: "https://free-french-resources.web.app/", comment: "firebase deploy" },
11
+ { url: "https://free-french-resources.firebaseapp.com/", comment: "alternate firebase deploy " },
12
+ { url: "https://k12-resources-for-french.koshlandjg105.workers.dev/", comment: "french resources 100% real" }
13
+
14
+
15
+ ];
16
+
17
+ window.expandedUrls = window.officialUrls.flatMap(obj => [
18
+ { url: obj.url, comment: obj.comment },
19
+ { url: obj.url + "index.html", comment: obj.comment }
20
+ ]);
21
+
22
+ // === NORMALIZE FUNCTION ===
23
+ function normalize(url) {
24
+ try {
25
+ const u = new URL(url);
26
+ return u.origin + u.pathname.replace(/\/$/, "");
27
+ } catch {
28
+ return url;
29
+ }
30
+ }
31
+
32
+ // Normalized list globally accessible
33
+ window.normalizedList = window.expandedUrls.map(obj => ({
34
+ url: normalize(obj.url),
35
+ comment: obj.comment
36
+ }));
37
+
38
+ // === GLOBAL FUNCTION ===
39
+ window.checkOfficialURL = function(url) {
40
+ const normalized = normalize(url);
41
+ const match = window.normalizedList.find(obj => obj.url === normalized);
42
+ return match
43
+ ? { official: true, comment: match.comment, url: match.url }
44
+ : { official: false, comment: null, url: normalized };
45
+ };
46
+
47
+ // === POPUP FUNCTION ===
48
+ const current = window.location.href;
49
+ const result = window.checkOfficialURL(current);
50
+
51
+ // === CREATE STYLE ===
52
+ const style = document.createElement("style");
53
+ style.textContent = `
54
+ #url-popup {
55
+ position: fixed;
56
+ top: 20px;
57
+ right: -320px;
58
+ width: 300px;
59
+ padding: 15px;
60
+ color: white;
61
+ box-shadow: 0 5px 15px rgba(0,0,0,0.3);
62
+ transition: right 0.4s ease, opacity 0.3s ease;
63
+ opacity: 0;
64
+ z-index: 9999;
65
+ font-family: initial;
66
+ }
67
+ #url-popup.show { right: 20px; opacity: 1; }
68
+ #url-popup.hide { right: -320px; opacity: 0; }
69
+ #url-popup.official { background: #2ecc71; }
70
+ #url-popup.unofficial { background: #e74c3c; }
71
+ #url-popup button {
72
+ border: none;
73
+ background: rgba(255,255,255,0.2);
74
+ color: white;
75
+ padding: 5px 10px;
76
+ cursor: pointer;
77
+ font-family: initial;
78
+ }
79
+ `;
80
+ document.head.appendChild(style);
81
+
82
+ // === CREATE POPUP ===
83
+ const popup = document.createElement("div");
84
+ popup.id = "url-popup";
85
+
86
+ const text = document.createElement("div");
87
+ const button = document.createElement("button");
88
+ button.textContent = "Close";
89
+
90
+ popup.appendChild(text);
91
+ popup.appendChild(button);
92
+ document.body.appendChild(popup);
93
+
94
+ // === SET MESSAGE ===
95
+ if (result.official) {
96
+ popup.className = "official";
97
+ text.textContent = "✅ this is an official melonsoda URL";
98
+ } else {
99
+ popup.className = "unofficial";
100
+ text.textContent = "⚠️ this is either NOT an official melonsoda URL or one of the singlefiles";
101
+ }
102
+
103
+ // === SHOW POPUP ===
104
+ setTimeout(() => popup.classList.add("show"), 10);
105
+
106
+ // === CLOSE FUNCTION ===
107
+ function closePopup() {
108
+ popup.classList.remove("show");
109
+ popup.classList.add("hide");
110
+ setTimeout(() => {
111
+ popup.remove();
112
+ style.remove();
113
+ }, 400);
114
+ }
115
+
116
+ button.onclick = closePopup;
117
+ setTimeout(closePopup, 5000);
118
+
119
+ })();
@@ -0,0 +1,151 @@
1
+
2
+ const unblockersPage = {
3
+ id: "unblock",
4
+ title: "unblockers",
5
+ html: `
6
+ <h1>unblockers</h1>
7
+
8
+ <div id="viewer-cli-container">
9
+ <div class="terminal"></div>
10
+ <div class="input-line">
11
+ <div class="prompt">></div>
12
+ <input class="cmd" autocomplete="off">
13
+ </div>
14
+ <div class="videos"></div>
15
+ </div>
16
+
17
+ <style>
18
+ #viewer-cli-container {
19
+ background: #000;
20
+ color: #00ff88;
21
+ font-family: monospace;
22
+ display: flex;
23
+ flex-direction: column;
24
+ height: 100%;
25
+ }
26
+ #viewer-cli-container .terminal {
27
+ padding: 15px;
28
+ flex: 1;
29
+ overflow-y: auto;
30
+ white-space: pre-wrap;
31
+ }
32
+ #viewer-cli-container .input-line {
33
+ display: flex;
34
+ padding: 10px;
35
+ border-top: 1px solid #003322;
36
+ }
37
+ #viewer-cli-container .prompt {
38
+ margin-right: 8px;
39
+ }
40
+ #viewer-cli-container .cmd {
41
+ flex: 1;
42
+ background: black;
43
+ border: none;
44
+ color: #00ff88;
45
+ outline: none;
46
+ font-family: monospace;
47
+ }
48
+ #viewer-cli-container .videos {
49
+ padding: 10px;
50
+ }
51
+ #viewer-cli-container iframe {
52
+ width: 100%;
53
+ height: 300px;
54
+ border: none;
55
+ margin-top: 10px;
56
+ }
57
+ </style>
58
+
59
+ <script>
60
+ (function () {
61
+ const root = document.getElementById("viewer-cli-container");
62
+ const term = root.querySelector(".terminal");
63
+ const input = root.querySelector(".cmd");
64
+ const videos = root.querySelector(".videos");
65
+
66
+ const base = "https://www.youtube-nocookie.com/embed/";
67
+ const end = "?autoplay=1&rel=0&modestbranding=1";
68
+
69
+ function log(text, type) {
70
+ type = type || "INFO";
71
+ const line = document.createElement("div");
72
+ line.textContent = "[ " + type + " ] " + text;
73
+ term.appendChild(line);
74
+ term.scrollTop = term.scrollHeight;
75
+ }
76
+
77
+ function getYouTubeID(url) {
78
+ const regExp = /(?:youtube\\.com\\/(?:watch\\?v=|embed\\/|shorts\\/)|youtu\\.be\\/)([a-zA-Z0-9_-]{11})/;
79
+ const match = url.match(regExp);
80
+ return match ? match[1] : null;
81
+ }
82
+
83
+ function loadVideo(url) {
84
+ log("Parsing URL...");
85
+
86
+ const id = getYouTubeID(url);
87
+ if (!id) {
88
+ log("Invalid URL", "ERROR");
89
+ return;
90
+ }
91
+
92
+ log("Connecting...", "CONNECT");
93
+
94
+ const iframe = document.createElement("iframe");
95
+ iframe.src = base + id + end;
96
+ iframe.allow = "fullscreen; autoplay; encrypted-media; picture-in-picture";
97
+ iframe.allowFullscreen = true;
98
+
99
+ videos.prepend(iframe);
100
+ log("Playback started", "SUCCESS");
101
+
102
+ try {
103
+ if (iframe.requestFullscreen) {
104
+ iframe.requestFullscreen();
105
+ log("Fullscreen activated!", "FULLSCREEN");
106
+ }
107
+ } catch (err) {
108
+ log("Fullscreen denied: " + err.message, "ERROR");
109
+ }
110
+ }
111
+
112
+ function runCommand(cmd) {
113
+ log("> " + cmd, "CMD");
114
+
115
+ const parts = cmd.split(" ");
116
+ const command = parts[0];
117
+ const arg = parts[1];
118
+
119
+ if (command === "help") {
120
+ log("Commands:");
121
+ log("load <url>");
122
+ log("clear");
123
+ } else if (command === "load") {
124
+ if (!arg) {
125
+ log("Missing URL", "ERROR");
126
+ return;
127
+ }
128
+ loadVideo(arg);
129
+ } else if (command === "clear") {
130
+ term.innerHTML = "";
131
+ } else {
132
+ log("Unknown command", "ERROR");
133
+ }
134
+ }
135
+
136
+ input.addEventListener("keydown", function(e) {
137
+ if (e.key === "Enter") {
138
+ const val = input.value.trim();
139
+ if (val) runCommand(val);
140
+ input.value = "";
141
+ }
142
+ });
143
+
144
+ log("viewer-cli initialized", "BOOT");
145
+ })();
146
+ </scr` + `ipt>
147
+ `
148
+
149
+ };
150
+ window.Pages = window.Pages || [];
151
+ window.Pages.push(unblockersPage);
package/links.py ADDED
@@ -0,0 +1,138 @@
1
+ import yaml
2
+ import os
3
+ import re
4
+
5
+ # Paths
6
+ yaml_file = "urls.yaml"
7
+ output_dir = "js"
8
+ links_file = os.path.join(output_dir, "links.js")
9
+ official_file = os.path.join(output_dir, "official.js")
10
+ readme_file = "README.md"
11
+
12
+ # Ensure output directory exists
13
+ os.makedirs(output_dir, exist_ok=True)
14
+
15
+ # === LOAD YAML ===
16
+ with open(yaml_file, "r", encoding="utf-8") as f:
17
+ data = yaml.safe_load(f)
18
+
19
+ # === BUILD HTML LINKS ===
20
+ links_html = ""
21
+ for entry in data:
22
+ name = entry.get("name", "link")
23
+ url = entry.get("url", "#")
24
+ comment = entry.get("comment", "")
25
+ links_html += f'<a href="{url}" target="_blank">{name}</a> {comment}<br>\n'
26
+
27
+ # === links.js ===
28
+ links_js = f"""const linksPage = {{
29
+ id: "link",
30
+ title: "links",
31
+ html: `
32
+ <h1>links</h1>
33
+ {links_html}``
34
+ }};
35
+ window.Pages = window.Pages || [];
36
+ window.Pages.push(linksPage);
37
+ """
38
+
39
+ with open(links_file, "w", encoding="utf-8") as f:
40
+ f.write(links_js)
41
+ print(f"links.js generated at {links_file}")
42
+
43
+ # === Update README.md safely ===
44
+ readme_section = f"\n\n## links\n\n{links_html}"
45
+
46
+ if os.path.exists(readme_file):
47
+ with open(readme_file, "r", encoding="utf-8") as f:
48
+ readme_content = f.read()
49
+
50
+ # Replace old Links section if exists
51
+ if "## Links" in readme_content:
52
+ readme_content = re.sub(r"\n## Links\n.*", readme_section, readme_content, flags=re.DOTALL)
53
+ else:
54
+ readme_content += readme_section
55
+ else:
56
+ readme_content = readme_section
57
+
58
+ with open(readme_file, "w", encoding="utf-8") as f:
59
+ f.write(readme_content)
60
+ print(f"README.md updated at {readme_file}")
61
+
62
+ # === official.js ===
63
+ official_js = """(function() {
64
+
65
+ window.officialUrls = [
66
+ { urls }
67
+ ];
68
+
69
+ window.expandedUrls = window.officialUrls.flatMap(obj => [
70
+ { url: obj.url, comment: obj.comment },
71
+ { url: obj.url + "index.html", comment: obj.comment }
72
+ ]);
73
+
74
+ function normalize(url) {
75
+ try { const u = new URL(url); return u.origin + u.pathname.replace(/\\/$/, ""); }
76
+ catch { return url; }
77
+ }
78
+
79
+ window.normalizedList = window.expandedUrls.map(obj => ({
80
+ url: normalize(obj.url),
81
+ comment: obj.comment
82
+ }));
83
+
84
+ window.checkOfficialURL = function(url) {
85
+ const normalized = normalize(url);
86
+ const match = window.normalizedList.find(obj => obj.url === normalized);
87
+ return match
88
+ ? { official: true, comment: match.comment, url: match.url }
89
+ : { official: false, comment: null, url: normalized };
90
+ };
91
+
92
+ const current = window.location.href;
93
+ const result = window.checkOfficialURL(current);
94
+
95
+ const style = document.createElement("style");
96
+ style.textContent = `
97
+ #url-popup {position: fixed; top: 20px; right: -320px; width: 300px; padding: 15px; color: white; box-shadow: 0 5px 15px rgba(0,0,0,0.3); transition: right 0.4s ease, opacity 0.3s ease; opacity: 0; z-index: 9999; font-family: initial;}
98
+ #url-popup.show { right: 20px; opacity: 1; }
99
+ #url-popup.hide { right: -320px; opacity: 0; }
100
+ #url-popup.official { background: #2ecc71; }
101
+ #url-popup.unofficial { background: #e74c3c; }
102
+ #url-popup button { border: none; background: rgba(255,255,255,0.2); color: white; padding: 5px 10px; cursor: pointer; font-family: initial; }
103
+ `;
104
+ document.head.appendChild(style);
105
+
106
+ const popup = document.createElement("div");
107
+ popup.id = "url-popup";
108
+ const text = document.createElement("div");
109
+ const button = document.createElement("button");
110
+ button.textContent = "Close";
111
+ popup.appendChild(text);
112
+ popup.appendChild(button);
113
+ document.body.appendChild(popup);
114
+
115
+ if (result.official) { popup.className = "official"; text.textContent = "✅ this is an official melonsoda URL"; }
116
+ else { popup.className = "unofficial"; text.textContent = "⚠️ this is either NOT an official melonsoda URL or one of the singlefiles"; }
117
+
118
+ setTimeout(() => popup.classList.add("show"), 10);
119
+
120
+ function closePopup() {
121
+ popup.classList.remove("show");
122
+ popup.classList.add("hide");
123
+ setTimeout(() => { popup.remove(); style.remove(); }, 400);
124
+ }
125
+
126
+ button.onclick = closePopup;
127
+ setTimeout(closePopup, 5000);
128
+
129
+ })();
130
+ """
131
+
132
+ urls_js_list = [f' {{ url: "{entry.get("url","")}", comment: "{entry.get("comment","")}" }}' for entry in data]
133
+ urls_js_str = ",\n".join(urls_js_list)
134
+ official_js = official_js.replace("{ urls }", urls_js_str)
135
+
136
+ with open(official_file, "w", encoding="utf-8") as f:
137
+ f.write(official_js)
138
+ print(f"official.js generated at {official_file}")
package/melon.png ADDED
Binary file
@@ -0,0 +1,33 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Page Not Found</title>
7
+
8
+ <style media="screen">
9
+ body { background: #ECEFF1; color: rgba(0,0,0,0.87); font-family: Roboto, Helvetica, Arial, sans-serif; margin: 0; padding: 0; }
10
+ #message { background: white; max-width: 360px; margin: 100px auto 16px; padding: 32px 24px 16px; border-radius: 3px; }
11
+ #message h3 { color: #888; font-weight: normal; font-size: 16px; margin: 16px 0 12px; }
12
+ #message h2 { color: #ffa100; font-weight: bold; font-size: 16px; margin: 0 0 8px; }
13
+ #message h1 { font-size: 22px; font-weight: 300; color: rgba(0,0,0,0.6); margin: 0 0 16px;}
14
+ #message p { line-height: 140%; margin: 16px 0 24px; font-size: 14px; }
15
+ #message a { display: block; text-align: center; background: #039be5; text-transform: uppercase; text-decoration: none; color: white; padding: 16px; border-radius: 4px; }
16
+ #message, #message a { box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); }
17
+ #load { color: rgba(0,0,0,0.4); text-align: center; font-size: 13px; }
18
+ @media (max-width: 600px) {
19
+ body, #message { margin-top: 0; background: white; box-shadow: none; }
20
+ body { border-top: 16px solid #ffa100; }
21
+ }
22
+ </style>
23
+ </head>
24
+ <body>
25
+ <div id="message">
26
+ <h2>404</h2>
27
+ <h1>Page Not Found</h1>
28
+ <p>The specified file was not found on this website. Please check the URL for mistakes and try again.</p>
29
+ <h3>Why am I seeing this?</h3>
30
+ <p>This page was generated by the Firebase Command-Line Interface. To modify it, edit the <code>404.html</code> file in your project's configured <code>public</code> directory.</p>
31
+ </div>
32
+ </body>
33
+ </html>