PageSourceSearch

https://manico.im/purchase/

html manico.im collected 2026-10-02 05:34:38 UTC 11,642 bytes, 351 lines download raw bytes

1
2<!DOCTYPE HTML>
3<html>
4  <head>
5    <title>Manico - Fast App Switcher for macOS</title>
6    <link rel="stylesheet" type="text/css" href="/static/css/manico-style.4367173d6540.css">
7    <meta charset="utf-8">
8    <link rel="icon" href="/static/img/favicon_32.19963e235090.png" sizes="32x32">
9    <meta name="google-site-verification" content="dWbu-QUEbOvZOqNzeqC5RHaJMa9yuNIOJwMjSPJXizw" />
10  </head>
11    <body data-spy="scroll" data-target=".navbar">
12      <div class="back">
13        <div class="wrapper">
14          <div class="header">
15            <img src="/static/img/manico-icon-64.57c44ac69cd4.png" srcset="/static/img/[email protected] 2x" width="64" height="64" alt="Manico">
16            <h1>Manico</h1>
17            <nav class="navbar">
18              <ul class="nav">
19                <li><a href="/#home">Home</a></li>
20                <li><a href="/#why">What is Manico</a></li>
21                <li><a href="/purchase/">Purchase</a></li>
22                <li><a href="/#faq">FAQ</a></li>
23                <li><a href="/cdn-cgi/l/email-protection#8dfef8fdfde2fff9cde0ece3e4eee2a3e4e0">Contact us</a></li>
24              </ul>
25            </nav>
26          </div>
27        </div>
28      </div>
29      <div id="home" style="height: 80px"></div>
30      
31<style>
32.purchase-card {
33    max-width: 420px;
34    margin: 0 auto;
35    padding: 35px 0 45px;
36}
37
38.purchase-card .offer-price {
39    padding-top: 20px;
40    text-align: center;
41    font-size: 28px;
42    font-weight: bold;
43    color: #333333;
44}
45
46.purchase-card form {
47    padding-top: 25px;
48}
49
50.purchase-card label {
51    display: block;
52    padding-top: 14px;
53    color: #333333;
54}
55
56.purchase-card input[type="email"] {
57    box-sizing: border-box;
58    width: 100%;
59    margin: 8px 0 0;
60    padding: 10px;
61    border: 1px solid #d8d8d8;
62    border-radius: 4px;
63    font-size: 16px;
64}
65
66.purchase-card button {
67    width: 100%;
68    margin-top: 22px;
69    padding: 12px;
70    border: 0;
71    border-radius: 4px;
72    background: #4CAF50;
73    color: #ffffff;
74    font-size: 16px;
75    font-weight: bold;
76    cursor: pointer;
77}
78
79.purchase-card button:disabled {
80    background: #b8b8b8;
81    cursor: not-allowed;
82}
83
84.purchase-card .checkout-status {
85    min-height: 24px;
86    padding-top: 14px;
87    text-align: center;
88}
89
90.purchase-card .checkout-status.error {
91    color: #cc3333;
92}
93</style>
94
95<div class="wrapper">
96  <div class="purchase">
97    <div class="purchase-card">
98      <h2>Purchase</h2>
99      <p>You can enjoy the free trial for up to 14 days. After the trial period, please purchase a license to use it without limitation.</p>
100      <p>License supports activation of up to three devices for a single user.</p>
101
102      <div class="offer-price">
103        <span id="offer-price">--</span>
104        <span id="offer-currency">USD</span>
105      </div>
106
107      <form id="checkout-form">
108        <label for="id_email">Email:</label>
109        <input type="email" name="email" maxlength="100" required id="id_email" autocomplete="email">
110
111        <label for="id_confirm_email">Email Confirmation:</label>
112        <input type="email" name="confirm_email" maxlength="100" required id="id_confirm_email" autocomplete="email">
113
114        <input id="id_currency" name="currency" type="hidden">
115        <input id="id_payment_method" name="payment_method" type="hidden">
116
117        <button type="submit" id="submit" disabled>Continue</button>
118        <p class="checkout-status" id="checkout-status" role="status"></p>
119      </form>
120    </div>
121  </div>
122</div>
vendor: 110 bytes, lines 122-124
122
123
124<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
124<script>
125(function () {
126    var config = {
127        offerSlug: "manico",
128        offerUrl: "https://api.tutu\u002Dstudio.com/v4/checkout/offers/manico/",
129        sessionUrl: "https://api.tutu\u002Dstudio.com/v4/checkout/sessions/",
130        successPath: "/purchase/success/",
131        cancelPath: "/purchase/canceled/"
132    };
133
134    var offer = null;
135    var activeIdempotencyKey = null;
136    var form = document.getElementById("checkout-form");
137    var emailInput = document.getElementById("id_email");
138    var confirmEmailInput = document.getElementById("id_confirm_email");
139    var currencyInput = document.getElementById("id_currency");
140    var paymentInput = document.getElementById("id_payment_method");
141    var submitButton = document.getElementById("submit");
142    var statusMessage = document.getElementById("checkout-status");
143    var priceElement = document.getElementById("offer-price");
144    var currencyElement = document.getElementById("offer-currency");
145
146    function setStatus(message, isError) {
147        statusMessage.textContent = message || "";
148        statusMessage.classList.toggle("error", Boolean(isError));
149    }
150
151    function idempotencyKey() {
152        if (window.crypto && window.crypto.randomUUID) {
153            return window.crypto.randomUUID();
154        }
155        return "manico-" + Date.now() + "-" + Math.random().toString(16).slice(2);
156    }
157
158    function resetCheckoutAttempt() {
159        activeIdempotencyKey = null;
160    }
161
162    function firstValue(values) {
163        return values && values.length ? values[0] : "";
164    }
165
166    function amountFor(offerData, currency) {
167        var value = ((offerData || {}).prices || {})[currency];
168        if (value && typeof value === "object") {
169            value = value.amount;
170        }
171        return value;
172    }
173
174    function hasAmount(offerData, currency) {
175        var value = amountFor(offerData, currency);
176        return value !== undefined && value !== null && value !== "";
177    }
178
179    function availableCurrencies(offerData) {
180        return Object.keys(((offerData || {}).prices) || {});
181    }
182
183    function normalizeLanguage(language) {
184        return (language || "").toLowerCase().replace(/_/g, "-");
185    }
186
187    function isSimplifiedChinese(language) {
188        var normalized = normalizeLanguage(language);
189        return normalized === "zh-hans" ||
190            normalized.indexOf("zh-hans-") === 0 ||
191            normalized === "zh-cn" ||
192            normalized.indexOf("zh-cn-") === 0 ||
193            normalized === "zh-sg" ||
194            normalized.indexOf("zh-sg-") === 0 ||
195            normalized === "zh-my" ||
196            normalized.indexOf("zh-my-") === 0;
197    }
198
199    function languageCandidates() {
200        var values = [];
201        if (navigator.languages && Array.isArray(navigator.languages)) {
202            values = values.concat(navigator.languages);
203        }
204        if (navigator.language) {
205            values.push(navigator.language);
206        }
207        if (document.documentElement.lang) {
208            values.push(document.documentElement.lang);
209        }
210        return values;
211    }
212
213    function preferredLocale() {
214        return firstValue(languageCandidates()) || "en";
215    }
216
217    function preferredCurrency() {
218        var currencies = availableCurrencies(offer);
219        var preferred = isSimplifiedChinese(preferredLocale()) ? "CNY" : "USD";
220        if (hasAmount(offer, preferred)) {
221            return preferred;
222        }
223        if (preferred !== "USD" && hasAmount(offer, "USD")) {
224            return "USD";
225        }
226        if (offer.default_currency && hasAmount(offer, offer.default_currency)) {
227            return offer.default_currency;
228        }
229        return firstValue(currencies);
230    }
231
232    function preferredPaymentMethod(currency, methods) {
233        var preferredByCurrency = {
234            "CNY": "alipay",
235            "USD": "stripe"
236        };
237        var preferred = preferredByCurrency[currency];
238        if (preferred && methods.indexOf(preferred) !== -1) {
239            return preferred;
240        }
241        if (methods.indexOf("stripe") !== -1) {
242            return "stripe";
243        }
244        return firstValue(methods);
245    }
246
247    function updatePrice() {
248        var currency = currencyInput.value;
249        priceElement.textContent = amountFor(offer, currency) || "--";
250        currencyElement.textContent = currency;
251    }
252
253    function validateEmailConfirmation() {
254        var email = emailInput.value.trim().toLowerCase();
255        var confirmedEmail = confirmEmailInput.value.trim().toLowerCase();
256        if (confirmedEmail && confirmedEmail !== email) {
257            confirmEmailInput.setCustomValidity('Email addresses must match.');
258        } else {
259            confirmEmailInput.setCustomValidity("");
260        }
261    }
262
263    fetch(config.offerUrl, { headers: { "Accept": "application/json" } })
264        .then(function (response) {
265            if (!response.ok) {
266                throw new Error("Offer unavailable");
267            }
268            return response.json();
269        })
270        .then(function (data) {
271            offer = data;
272            currencyInput.value = preferredCurrency();
273            paymentInput.value = preferredPaymentMethod(
274                currencyInput.value,
275                offer.enabled_payment_methods || []
276            );
277            if (!currencyInput.value || !paymentInput.value) {
278                throw new Error("Offer unavailable");
279            }
280            updatePrice();
281            submitButton.disabled = false;
282            setStatus("");
283        })
284        .catch(function () {
285            setStatus('Purchase options are temporarily unavailable.', true);
286            submitButton.disabled = true;
287        });
288
289    emailInput.addEventListener("input", function () {
290        validateEmailConfirmation();
291        resetCheckoutAttempt();
292    });
293    confirmEmailInput.addEventListener("input", function () {
294        validateEmailConfirmation();
295        resetCheckoutAttempt();
296    });
297
298    form.addEventListener("submit", function (event) {
299        event.preventDefault();
300        validateEmailConfirmation();
301        if (!form.reportValidity() || !offer) {
302            return;
303        }
304
305        submitButton.disabled = true;
306        setStatus('Creating secure checkout...');
307        if (!activeIdempotencyKey) {
308            activeIdempotencyKey = idempotencyKey();
309        }
310
311        fetch(config.sessionUrl, {
312            method: "POST",
313            headers: {
314                "Accept": "application/json",
315                "Content-Type": "application/json"
316            },
317            body: JSON.stringify({
318                offer_slug: config.offerSlug,
319                email: emailInput.value.trim(),
320                currency: currencyInput.value,
321                payment_method: paymentInput.value,
322                quantity: 1,
323                locale: preferredLocale(),
324                success_url: window.location.origin + config.successPath,
325                cancel_url: window.location.origin + config.cancelPath,
326                idempotency_key: activeIdempotencyKey
327            })
328        })
329            .then(function (response) {
330                if (!response.ok) {
331                    throw new Error("Checkout unavailable");
332                }
333                return response.json();
334            })
335            .then(function (data) {
336                activeIdempotencyKey = null;
337                window.location.href = data.checkout_url;
338            })
339            .catch(function () {
340                setStatus('Checkout could not be created. Please try again.', true);
341                submitButton.disabled = false;
342            });
343    });
344})();
345</script>
345
346
347    
348    
349  
349<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"d5ebc7df50314f8ca81cc480e339f38f","r":1,"spa":2}' crossorigin="anonymous"></script>
349
350</body>
351</html>

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.