1/** 2 * Instagram in-app browser: App Store links are blocked on iOS. 3 * Show a tap-to-copy modal when IG users tap iOS store CTAs only. 4 */ 5(function () { 6 var GET_URL = "https://traderzen.app/get"; 7 8 var IG_ICON = 9 '<svg class="tz-ig-icon" viewBox="0 0 24 24" width="44" height="44" aria-hidden="true">' + 10 '<defs><linearGradient id="tz-ig-grad" x1="0%" y1="100%" x2="100%" y2="0%">' + 11 '<stop offset="0%" stop-color="#feda75"/><stop offset="25%" stop-color="#fa7e1e"/>' + 12 '<stop offset="50%" stop-color="#d62976"/><stop offset="75%" stop-color="#962fbf"/>' + 13 '<stop offset="100%" stop-color="#4f5bd5"/></linearGradient></defs>' + 14 '<rect x="2" y="2" width="20" height="20" rx="6" fill="url(#tz-ig-grad)"/>' + 15 '<rect x="5.5" y="5.5" width="13" height="13" rx="3.5" fill="none" stroke="#fff" stroke-width="1.6"/>' + 16 '<circle cx="12" cy="12" r="3.2" fill="none" stroke="#fff" stroke-width="1.6"/>' + 17 '<circle cx="17.2" cy="6.8" r="1.1" fill="#fff"/></svg>'; 18 19 function ua() { 20 return navigator.userAgent || ""; 21 } 22 23 function isInstagram() { 24 return /Instagram/i.test(ua()); 25 } 26 27 function isInAppBrowser() { 28 var u = ua(); 29 return /Instagram|FBAN|FBAV|FB_IAB|FBIOS|TikTok|BytedanceWebview|musical_ly/i.test(u); 30 } 31 32 function copyText(text) { 33 if (navigator.clipboard && navigator.clipboard.writeText) { 34 return navigator.clipboard.writeText(text).catch(function () { 35 return Promise.resolve(fallbackCopy(text)); 36 }); 37 } 38 return Promise.resolve(fallbackCopy(text)); 39 } 40 41 function fallbackCopy(text) { 42 try { 43 var ta = document.createElement("textarea"); 44 ta.value = text; 45 ta.setAttribute("readonly", ""); 46 ta.style.cssText = "position:fixed;left:-9999px;top:0"; 47 document.body.appendChild(ta); 48 ta.select(); 49 document.execCommand("copy"); 50 document.body.removeChild(ta); 51 return true; 52 } catch (e) { 53 return false; 54 } 55 } 56 57 function ensureStyles() { 58 if (document.getElementById("tz-ig-css")) return; 59 var s = document.createElement("style"); 60 s.id = "tz-ig-css"; 61 s.textContent = [ 62 "#tz-ig-modal{position:fixed;inset:0;z-index:2147483000;background:rgba(2,4,8,.88);", 63 "display:flex;align-items:center;justify-content:center;padding:20px;", 64 "font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}", 65 "#tz-ig-modal *{box-sizing:border-box}", 66 "#tz-ig-modal .card{width:100%;max-width:380px;background:#0a101f;border:1px solid rgba(0,242,255,.25);", 67 "padding:24px 20px 20px;text-align:center;color:#e0fbfc;position:relative;", 68 "box-shadow:0 24px 60px rgba(0,0,0,.55)}", 69 "#tz-ig-modal .tz-ig-icon{display:block;margin:0 auto 14px}", 70 "#tz-ig-modal h2{margin:0 0 8px;font-size:1.25rem;line-height:1.25;font-weight:800}", 71 "#tz-ig-modal .sub{margin:0 0 16px;color:#8a9bb0;font-size:15px;line-height:1.45}", 72 "#tz-ig-modal .url-tap{width:100%;margin:0 0 10px;padding:14px 12px;", 73 "border:1px dashed rgba(0,242,255,.5);background:#05070c;color:#00f2ff;", 74 "font-size:14px;font-weight:700;line-height:1.35;word-break:break-all;", 75 "cursor:pointer;text-align:left;border-radius:0}", 76 "#tz-ig-modal .url-tap:active{background:#0d1525}", 77 "#tz-ig-modal .hint{font-size:12px;color:#6b7c8f;margin:0 0 14px}", 78 "#tz-ig-modal .ok{min-height:20px;font-size:14px;font-weight:700;color:#28c840;margin:0 0 12px}", 79 "#tz-ig-modal .btn{width:100%;appearance:none;border:0;padding:14px;font-size:15px;", 80 "font-weight:800;cursor:pointer;margin-bottom:8px}", 81 "#tz-ig-modal .btn-copy{background:#00f2ff;color:#020408}", 82 "#tz-ig-modal .btn-close{background:transparent;color:#8a9bb0;border:1px solid rgba(255,255,255,.12)}", 83 "#tz-ig-modal .close-x{position:absolute;top:8px;right:10px;width:36px;height:36px;", 84 "border:0;background:transparent;color:#8a9bb0;font-size:22px;line-height:1;cursor:pointer}", 85 ].join(""); 86 document.head.appendChild(s); 87 } 88 89 function showInstructions(opts) { 90 opts = opts || {}; 91 ensureStyles(); 92 93 var existing = document.getElementById("tz-ig-modal"); 94 if (existing) existing.remove(); 95
96 var link = opts.copyUrl || GET_URL; 97 var fromIg = isInstagram(); 98 99 var modal = document.createElement("div"); 100 modal.id = "tz-ig-modal"; 101 modal.setAttribute("role", "dialog"); 102 modal.setAttribute("aria-modal", "true"); 103 modal.setAttribute("aria-labelledby", "tz-ig-title"); 104 modal.innerHTML = 105 '<div class="card">' + 106 '<button type="button" class="close-x" aria-label="Close">×</button>' + 107 (fromIg ? IG_ICON : "") + 108 '<h2 id="tz-ig-title">' + 109 (fromIg ? "Instagram blocks App Store links" : "Open in your mobile browser") + 110 "</h2>" + 111 '<p class="sub">' + 112 (fromIg 113 ? "Links from Instagram canât open the App Store. Copy this URL, paste it in <strong>Safari</strong>, then tap download." 114 : "This in-app browser blocks App Store links. Copy the URL below and paste it in Safari.") + 115 "</p>" + 116 '<button type="button" class="url-tap" id="tz-ig-url">' + link + "</button>" + 117 '<p class="hint">Tap the link above to copy</p>' + 118 '<div class="ok" id="tz-ig-ok"></div>' + 119 '<button type="button" class="btn btn-copy" data-act="copy">Tap to copy URL</button>' + 120 '<button type="button" class="btn btn-close" data-act="close">Close</button>' + 121 "</div>"; 122 123 document.body.appendChild(modal); 124 document.documentElement.style.overflow = "hidden"; 125 126 function closeModal() { 127 modal.remove(); 128 document.documentElement.style.overflow = ""; 129 } 130 131 function doCopy() { 132 copyText(link).then(function () { 133 var el = modal.querySelector("#tz-ig-ok"); 134 if (el) { 135 el.textContent = "Now open Safari and paste the URL."; 136 } 137 }); 138 } 139 140 modal.querySelector(".close-x").onclick = closeModal; 141 modal.querySelector('[data-act="close"]').onclick = closeModal; 142 modal.querySelector('[data-act="copy"]').onclick = doCopy; 143 modal.querySelector("#tz-ig-url").onclick = doCopy; 144 modal.addEventListener("click", function (e) { 145 if (e.target === modal) closeModal(); 146 }); 147 } 148 149 function isIosStoreCta(el) { 150 if (!el || el.tagName !== "A") return false; 151 var href = el.getAttribute("href") || ""; 152 var text = (el.textContent || "").toLowerCase(); 153 if (/play\.google|platform=android|platform=play|platform=google/i.test(href)) return false; 154 if (/google play|\bandroid\b/i.test(text)) return false; 155 if (/apps\.apple|itunes\.apple/i.test(href)) return true; 156 if (/platform=ios|platform=iphone|platform=apple/i.test(href)) return true; 157 if (/app store|\bios\b/i.test(text)) return true; 158 return false; 159 } 160 161 function bindStoreClicks() { 162 document.querySelectorAll("a").forEach(function (a) { 163 if (a.dataset.tzIgBound || !isIosStoreCta(a)) return; 164 a.dataset.tzIgBound = "1"; 165 a.addEventListener("click", function (e) { 166 if (!isInAppBrowser()) return; 167 e.preventDefault(); 168 showInstructions({ copyUrl: GET_URL }); 169 }); 170 }); 171 } 172 173 function init() { 174 if (!isInAppBrowser()) return; 175 bindStoreClicks(); 176 setTimeout(bindStoreClicks, 600); 177 } 178 179 window.TZStoreBreakout = { 180 isInstagram: isInstagram, 181 isInAppBrowser: isInAppBrowser, 182 isIosStoreCta: isIosStoreCta, 183 showInstructions: showInstructions, 184 GET_URL: GET_URL, 185 }; 186 187 if (document.readyState === "loading") { 188 document.addEventListener("DOMContentLoaded", init); 189 } else { 190 init(); 191 } 192})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.