├── images ├── test.txt └── lnbits-api-key-screenshot.png ├── README.md ├── LICENSE └── btcpaywall ├── qr.js ├── btcPaywall.php └── jquery-3.5.1.min.js /images/test.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/lnbits-api-key-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lnbits/btcpaywall/HEAD/images/lnbits-api-key-screenshot.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BTC Paywall 2 | A wordpress plugin that creates a paywall for almost any wordpress content, payable in bitcoin over the lightning network 3 | 4 | The files in the btcpaywall subdirectory of this git repository are the source code of the plugin. You can download the btcpaywall subdirectory, zip it, and upload it to your wordpress directory, or -- if you don't want to do the zipping -- you can download a prezipped version here: 5 | 6 | https://highlevelbitcoin.com/wp-content/uploads/2020/11/btcpaywall-0.1.0.zip 7 | 8 | # Installation 9 | 10 | Install and activate the plugin through the plugins page in the backend of your wordpress installation. Just select Add new and upload the zip file. 11 | 12 | # Lnbits 13 | 14 | After you install and activate BTC Paywall, but before you can use it, you'll have to connect it to an lnbits wallet. Lnbits is, among other things, an abstraction layer that allows programs built for bitcoin's lightning network to communicate in a standardized way with most popular lightning network implementations, such as clightning and lnd, as well as custodial lightning wallets like opennode, lnpay, and lntxbot. You can either self-host lnbits in order to do everything with minimized trust (see github.com/lnbits/lnbits for more details) or get a custodial lnbits wallet at lnbits.com. 15 | 16 | To connect BTC Paywall to lnbits, use the BTCPaywall Settings menu. It is located in the backend of your wordpress website > Settings > BTC Paywall. Visit the Settings menu and take the url of your lnbits host as well as your wallet api key and add them to the settings menu of BTC Paywall. The hostname will be https://lnbits.com if that is the site you are using or, if you are self-hosting lnbits on the same server that hosts your wordpress site, it may be something like http://localhost:5000. As for your api key, obtain that by creating an lnbits wallet and looking at the righthand sidebar. "Invoice/read key" is the one you want. 17 | 18 | ![Screenshot showcasing api key](https://github.com/supertestnet/btcpaywall/raw/main/images/lnbits-api-key-screenshot.png) 19 | 20 | # Syntax 21 | 22 | Once the plugin is installed and your lnbits url and api key are saved in Settings, create a paywall on any wordpress page or post using this syntax: [paywall price="1"]any wordpress content[/paywall] 23 | 24 | The price, by default, is denominated in sats. In the above example, you will sell access to the content "any wordpress content" for 1 sat, or 0.00000001 bitcoins. In settings, you can change the denomination to US dollars if you want, which will cause the plugin to pull a price feed from coinbase. If you do that, [paywall price="1"]any wordpress content[/paywall] will cost the equivalent of 1 US dollar in bitcoin. You can also use decimalization if you select USD as your currency -- price="0.01" is a valid way to charge someone a penny or whatever content you are charging money for. 25 | 26 | # Details 27 | 28 | BTC Paywall uses server-side software to conceal the content of your paywall. That means the user does not have the content in their browser if they just de-obfuscate it. Instead, the server simply doesn't serve the content until the paywall is paid. 29 | 30 | You are not limited to paywalling your written content. You can paywall your videos, your podcasts, your pictures, your livestreams -- almost anything you want to charge money for. If you can embed it on a wordpress page, you can paywall it. 31 | 32 | When a user pays for a piece of content, their browser will store some data about their payment in a cookie. (Actually it's in the browser's local storage, but meh.) If they visit the page containing that content in the future, their browser will share that payment data with the server which will then use it to look up their old invoice. Since it is paid, the server will then show them the content they paid for. 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /btcpaywall/qr.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * modified qr.js -- QR code generator in Javascript (revision 2011-01-19) 3 | * Written by Kang Seonghoon . 4 | * v0.0.20110119 5 | * This source code is in the public domain; if your jurisdiction does not 6 | * recognize the public domain the terms of Creative Commons CC0 license 7 | * apply. In the other words, you can always do what you want. 8 | * added options properties: fillcolor and textcolor 9 | * svg now works in Edge 13 and IE 11 10 | * gist.github.com/englishextra/b46969e3382ef737c611bb59d837220b 11 | * source: github.com/lifthrasiir/qr.js/blob/v0.0.20110119/qr.js 12 | * passes jshint with suppressing comments 13 | */ 14 | /* jslint bitwise: true */ 15 | /* jshint shadow: true */ 16 | /* jshint sub:true */ 17 | /* jshint -W041 */ 18 | (function (root, name, definition) { 19 | root[name] = definition(); 20 | })("undefined" !== typeof window ? window : this, 'QRCode', function () { 21 | var VERSIONS = [null, [[10, 7, 17, 13], [1, 1, 1, 1], []], [[16, 10, 28, 22], [1, 1, 1, 1], [4, 16]], [[26, 15, 22, 18], [1, 1, 2, 2], [4, 20]], [[18, 20, 16, 26], [2, 1, 4, 2], [4, 24]], [[24, 26, 22, 18], [2, 1, 4, 4], [4, 28]], [[16, 18, 28, 24], [4, 2, 4, 4], [4, 32]], [[18, 20, 26, 18], [4, 2, 5, 6], [4, 20, 36]], [[22, 24, 26, 22], [4, 2, 6, 6], [4, 22, 40]], [[22, 30, 24, 20], [5, 2, 8, 8], [4, 24, 44]], [[26, 18, 28, 24], [5, 4, 8, 8], [4, 26, 48]], [[30, 20, 24, 28], [5, 4, 11, 8], [4, 28, 52]], [[22, 24, 28, 26], [8, 4, 11, 10], [4, 30, 56]], [[22, 26, 22, 24], [9, 4, 16, 12], [4, 32, 60]], [[24, 30, 24, 20], [9, 4, 16, 16], [4, 24, 44, 64]], [[24, 22, 24, 30], [10, 6, 18, 12], [4, 24, 46, 68]], [[28, 24, 30, 24], [10, 6, 16, 17], [4, 24, 48, 72]], [[28, 28, 28, 28], [11, 6, 19, 16], [4, 28, 52, 76]], [[26, 30, 28, 28], [13, 6, 21, 18], [4, 28, 54, 80]], [[26, 28, 26, 26], [14, 7, 25, 21], [4, 28, 56, 84]], [[26, 28, 28, 30], [16, 8, 25, 20], [4, 32, 60, 88]], [[26, 28, 30, 28], [17, 8, 25, 23], [4, 26, 48, 70, 92]], [[28, 28, 24, 30], [17, 9, 34, 23], [4, 24, 48, 72, 96]], [[28, 30, 30, 30], [18, 9, 30, 25], [4, 28, 52, 76, 100]], [[28, 30, 30, 30], [20, 10, 32, 27], [4, 26, 52, 78, 104]], [[28, 26, 30, 30], [21, 12, 35, 29], [4, 30, 56, 82, 108]], [[28, 28, 30, 28], [23, 12, 37, 34], [4, 28, 56, 84, 112]], [[28, 30, 30, 30], [25, 12, 40, 34], [4, 32, 60, 88, 116]], [[28, 30, 30, 30], [26, 13, 42, 35], [4, 24, 48, 72, 96, 120]], [[28, 30, 30, 30], [28, 14, 45, 38], [4, 28, 52, 76, 100, 124]], [[28, 30, 30, 30], [29, 15, 48, 40], [4, 24, 50, 76, 102, 128]], [[28, 30, 30, 30], [31, 16, 51, 43], [4, 28, 54, 80, 106, 132]], [[28, 30, 30, 30], [33, 17, 54, 45], [4, 32, 58, 84, 110, 136]], [[28, 30, 30, 30], [35, 18, 57, 48], [4, 28, 56, 84, 112, 140]], [[28, 30, 30, 30], [37, 19, 60, 51], [4, 32, 60, 88, 116, 144]], [[28, 30, 30, 30], [38, 19, 63, 53], [4, 28, 52, 76, 100, 124, 148]], [[28, 30, 30, 30], [40, 20, 66, 56], [4, 22, 48, 74, 100, 126, 152]], [[28, 30, 30, 30], [43, 21, 70, 59], [4, 26, 52, 78, 104, 130, 156]], [[28, 30, 30, 30], [45, 22, 74, 62], [4, 30, 56, 82, 108, 134, 160]], [[28, 30, 30, 30], [47, 24, 77, 65], [4, 24, 52, 80, 108, 136, 164]], [[28, 30, 30, 30], [49, 25, 81, 68], [4, 28, 56, 84, 112, 140, 168]]]; 22 | var MODE_TERMINATOR = 0; 23 | var MODE_NUMERIC = 1, 24 | MODE_ALPHANUMERIC = 2, 25 | MODE_OCTET = 4, 26 | MODE_KANJI = 8; 27 | var NUMERIC_REGEXP = /^\d*$/; 28 | var ALPHANUMERIC_REGEXP = /^[A-Za-z0-9 $%*+\-./:] * $ / ; 29 | var ALPHANUMERIC_OUT_REGEXP = /^[A-Z0-9 $%*+\-./:] * $ / ; 30 | var ECCLEVEL_L = 1, 31 | ECCLEVEL_M = 0, 32 | ECCLEVEL_Q = 3, 33 | ECCLEVEL_H = 2; 34 | var GF256_MAP = [], 35 | GF256_INVMAP = [-1]; 36 | for (var i = 0, v = 1; i < 255; ++i) { 37 | GF256_MAP.push(v); 38 | GF256_INVMAP[v] = i; 39 | v = (v * 2) ^ (v >= 128 ? 0x11d : 0); 40 | } 41 | var GF256_GENPOLY = [[]]; 42 | for (var i = 0; i < 30; ++i) { 43 | var prevpoly = GF256_GENPOLY[i], 44 | poly = []; 45 | for (var j = 0; j <= i; ++j) { 46 | var a = (j < i ? GF256_MAP[prevpoly[j]] : 0); 47 | var b = GF256_MAP[(i + (prevpoly[j - 1] || 0)) % 255]; 48 | poly.push(GF256_INVMAP[a ^ b]); 49 | } 50 | GF256_GENPOLY.push(poly); 51 | } 52 | var ALPHANUMERIC_MAP = {}; 53 | for (var i = 0; i < 45; ++i) { 54 | ALPHANUMERIC_MAP['0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:'.charAt(i)] = i; 55 | } 56 | var MASKFUNCS = [function (i, j) { 57 | return (i + j) % 2 == 0; 58 | }, function (i, j) { 59 | return i % 2 == 0; 60 | }, function (i, j) { 61 | return j % 3 == 0; 62 | }, function (i, j) { 63 | return (i + j) % 3 == 0; 64 | }, function (i, j) { 65 | return (((i / 2) | 0) + ((j / 3) | 0)) % 2 == 0; 66 | }, function (i, j) { 67 | return (i * j) % 2 + (i * j) % 3 == 0; 68 | }, function (i, j) { 69 | return ((i * j) % 2 + (i * j) % 3) % 2 == 0; 70 | }, function (i, j) { 71 | return ((i + j) % 2 + (i * j) % 3) % 2 == 0; 72 | } 73 | ]; 74 | var needsverinfo = function (ver) { 75 | return ver > 6; 76 | }; 77 | var getsizebyver = function (ver) { 78 | return 4 * ver + 17; 79 | }; 80 | var nfullbits = function (ver) { 81 | var v = VERSIONS[ver]; 82 | var nbits = 16 * ver * ver + 128 * ver + 64; 83 | if (needsverinfo(ver)) 84 | nbits -= 36; 85 | if (v[2].length) { 86 | nbits -= 25 * v[2].length * v[2].length - 10 * v[2].length - 55; 87 | } 88 | return nbits; 89 | }; 90 | var ndatabits = function (ver, ecclevel) { 91 | var nbits = nfullbits(ver) & ~7; 92 | var v = VERSIONS[ver]; 93 | nbits -= 8 * v[0][ecclevel] * v[1][ecclevel]; 94 | return nbits; 95 | }; 96 | var ndatalenbits = function (ver, mode) { 97 | switch (mode) { 98 | case MODE_NUMERIC: 99 | return (ver < 10 ? 10 : ver < 27 ? 12 : 14); 100 | case MODE_ALPHANUMERIC: 101 | return (ver < 10 ? 9 : ver < 27 ? 11 : 13); 102 | case MODE_OCTET: 103 | return (ver < 10 ? 8 : 16); 104 | case MODE_KANJI: 105 | return (ver < 10 ? 8 : ver < 27 ? 10 : 12); 106 | } 107 | }; 108 | var getmaxdatalen = function (ver, mode, ecclevel) { 109 | var nbits = ndatabits(ver, ecclevel) - 4 - ndatalenbits(ver, mode); 110 | switch (mode) { 111 | case MODE_NUMERIC: 112 | return ((nbits / 10) | 0) * 3 + (nbits % 10 < 4 ? 0 : nbits % 10 < 7 ? 1 : 2); 113 | case MODE_ALPHANUMERIC: 114 | return ((nbits / 11) | 0) * 2 + (nbits % 11 < 6 ? 0 : 1); 115 | case MODE_OCTET: 116 | return (nbits / 8) | 0; 117 | case MODE_KANJI: 118 | return (nbits / 13) | 0; 119 | } 120 | }; 121 | var validatedata = function (mode, data) { 122 | switch (mode) { 123 | case MODE_NUMERIC: 124 | if (!data.match(NUMERIC_REGEXP)) 125 | return null; 126 | return data; 127 | case MODE_ALPHANUMERIC: 128 | if (!data.match(ALPHANUMERIC_REGEXP)) 129 | return null; 130 | return data.toUpperCase(); 131 | case MODE_OCTET: 132 | if (typeof data === 'string') { 133 | var newdata = []; 134 | for (var i = 0; i < data.length; ++i) { 135 | var ch = data.charCodeAt(i); 136 | if (ch < 0x80) { 137 | newdata.push(ch); 138 | } else if (ch < 0x800) { 139 | newdata.push(0xc0 | (ch >> 6), 0x80 | (ch & 0x3f)); 140 | } else if (ch < 0x10000) { 141 | newdata.push(0xe0 | (ch >> 12), 0x80 | ((ch >> 6) & 0x3f), 0x80 | (ch & 0x3f)); 142 | } else { 143 | newdata.push(0xf0 | (ch >> 18), 0x80 | ((ch >> 12) & 0x3f), 0x80 | ((ch >> 6) & 0x3f), 0x80 | (ch & 0x3f)); 144 | } 145 | } 146 | return newdata; 147 | } else { 148 | return data; 149 | } 150 | } 151 | }; 152 | var encode = function (ver, mode, data, maxbuflen) { 153 | var buf = []; 154 | var bits = 0, 155 | remaining = 8; 156 | var datalen = data.length; 157 | var pack = function (x, n) { 158 | if (n >= remaining) { 159 | buf.push(bits | (x >> (n -= remaining))); 160 | while (n >= 8) 161 | buf.push((x >> (n -= 8)) & 255); 162 | bits = 0; 163 | remaining = 8; 164 | } 165 | if (n > 0) 166 | bits |= (x & ((1 << n) - 1)) << (remaining -= n); 167 | }; 168 | var nlenbits = ndatalenbits(ver, mode); 169 | pack(mode, 4); 170 | pack(datalen, nlenbits); 171 | switch (mode) { 172 | case MODE_NUMERIC: 173 | for (var i = 2; i < datalen; i += 3) { 174 | pack(parseInt(data.substring(i - 2, i + 1), 10), 10); 175 | } 176 | pack(parseInt(data.substring(i - 2), 10), [0, 4, 7][datalen % 3]); 177 | break; 178 | case MODE_ALPHANUMERIC: 179 | for (var i = 1; i < datalen; i += 2) { 180 | pack(ALPHANUMERIC_MAP[data.charAt(i - 1)] * 45 + 181 | ALPHANUMERIC_MAP[data.charAt(i)], 11); 182 | } 183 | if (datalen % 2 == 1) { 184 | pack(ALPHANUMERIC_MAP[data.charAt(i - 1)], 6); 185 | } 186 | break; 187 | case MODE_OCTET: 188 | for (var i = 0; i < datalen; ++i) { 189 | pack(data[i], 8); 190 | } 191 | break; 192 | } 193 | pack(MODE_TERMINATOR, 4); 194 | if (remaining < 8) 195 | buf.push(bits); 196 | while (buf.length + 1 < maxbuflen) 197 | buf.push(0xec, 0x11); 198 | if (buf.length < maxbuflen) 199 | buf.push(0xec); 200 | return buf; 201 | }; 202 | var calculateecc = function (poly, genpoly) { 203 | var modulus = poly.slice(0); 204 | var polylen = poly.length, 205 | genpolylen = genpoly.length; 206 | for (var i = 0; i < genpolylen; ++i) 207 | modulus.push(0); 208 | for (var i = 0; i < polylen; ) { 209 | var quotient = GF256_INVMAP[modulus[i++]]; 210 | if (quotient >= 0) { 211 | for (var j = 0; j < genpolylen; ++j) { 212 | modulus[i + j] ^= GF256_MAP[(quotient + genpoly[j]) % 255]; 213 | } 214 | } 215 | } 216 | return modulus.slice(polylen); 217 | }; 218 | var augumenteccs = function (poly, nblocks, genpoly) { 219 | var subsizes = []; 220 | var subsize = (poly.length / nblocks) | 0, 221 | subsize0 = 0; 222 | var pivot = nblocks - poly.length % nblocks; 223 | for (var i = 0; i < pivot; ++i) { 224 | subsizes.push(subsize0); 225 | subsize0 += subsize; 226 | } 227 | for (var i = pivot; i < nblocks; ++i) { 228 | subsizes.push(subsize0); 229 | subsize0 += subsize + 1; 230 | } 231 | subsizes.push(subsize0); 232 | var eccs = []; 233 | for (var i = 0; i < nblocks; ++i) { 234 | eccs.push(calculateecc(poly.slice(subsizes[i], subsizes[i + 1]), genpoly)); 235 | } 236 | var result = []; 237 | var nitemsperblock = (poly.length / nblocks) | 0; 238 | for (var i = 0; i < nitemsperblock; ++i) { 239 | for (var j = 0; j < nblocks; ++j) { 240 | result.push(poly[subsizes[j] + i]); 241 | } 242 | } 243 | for (var j = pivot; j < nblocks; ++j) { 244 | result.push(poly[subsizes[j + 1] - 1]); 245 | } 246 | for (var i = 0; i < genpoly.length; ++i) { 247 | for (var j = 0; j < nblocks; ++j) { 248 | result.push(eccs[j][i]); 249 | } 250 | } 251 | return result; 252 | }; 253 | var augumentbch = function (poly, p, genpoly, q) { 254 | var modulus = poly << q; 255 | for (var i = p - 1; i >= 0; --i) { 256 | if ((modulus >> (q + i)) & 1) 257 | modulus ^= genpoly << i; 258 | } 259 | return (poly << q) | modulus; 260 | }; 261 | var makebasematrix = function (ver) { 262 | var v = VERSIONS[ver], 263 | n = getsizebyver(ver); 264 | var matrix = [], 265 | reserved = []; 266 | for (var i = 0; i < n; ++i) { 267 | matrix.push([]); 268 | reserved.push([]); 269 | } 270 | var blit = function (y, x, h, w, bits) { 271 | for (var i = 0; i < h; ++i) { 272 | for (var j = 0; j < w; ++j) { 273 | matrix[y + i][x + j] = (bits[i] >> j) & 1; 274 | reserved[y + i][x + j] = 1; 275 | } 276 | } 277 | }; 278 | blit(0, 0, 9, 9, [0x7f, 0x41, 0x5d, 0x5d, 0x5d, 0x41, 0x17f, 0x00, 0x40]); 279 | blit(n - 8, 0, 8, 9, [0x100, 0x7f, 0x41, 0x5d, 0x5d, 0x5d, 0x41, 0x7f]); 280 | blit(0, n - 8, 9, 8, [0xfe, 0x82, 0xba, 0xba, 0xba, 0x82, 0xfe, 0x00, 0x00]); 281 | for (var i = 9; i < n - 8; ++i) { 282 | matrix[6][i] = matrix[i][6] = ~i & 1; 283 | reserved[6][i] = reserved[i][6] = 1; 284 | } 285 | var aligns = v[2], 286 | m = aligns.length; 287 | for (var i = 0; i < m; ++i) { 288 | var minj = (i == 0 || i == m - 1 ? 1 : 0), 289 | maxj = (i == 0 ? m - 1 : m); 290 | for (var j = minj; j < maxj; ++j) { 291 | blit(aligns[i], aligns[j], 5, 5, [0x1f, 0x11, 0x15, 0x11, 0x1f]); 292 | } 293 | } 294 | if (needsverinfo(ver)) { 295 | var code = augumentbch(ver, 6, 0x1f25, 12); 296 | var k = 0; 297 | for (var i = 0; i < 6; ++i) { 298 | for (var j = 0; j < 3; ++j) { 299 | matrix[i][(n - 11) + j] = matrix[(n - 11) + j][i] = (code >> k++) & 1; 300 | reserved[i][(n - 11) + j] = reserved[(n - 11) + j][i] = 1; 301 | } 302 | } 303 | } 304 | return { 305 | matrix: matrix, 306 | reserved: reserved 307 | }; 308 | }; 309 | var putdata = function (matrix, reserved, buf) { 310 | var n = matrix.length; 311 | var k = 0, 312 | dir = -1; 313 | for (var i = n - 1; i >= 0; i -= 2) { 314 | if (i == 6) 315 | --i; 316 | var jj = (dir < 0 ? n - 1 : 0); 317 | for (var j = 0; j < n; ++j) { 318 | for (var ii = i; ii > i - 2; --ii) { 319 | if (!reserved[jj][ii]) { 320 | matrix[jj][ii] = (buf[k >> 3] >> (~k & 7)) & 1; 321 | ++k; 322 | } 323 | } 324 | jj += dir; 325 | } 326 | dir = -dir; 327 | } 328 | return matrix; 329 | }; 330 | var maskdata = function (matrix, reserved, mask) { 331 | var maskf = MASKFUNCS[mask]; 332 | var n = matrix.length; 333 | for (var i = 0; i < n; ++i) { 334 | for (var j = 0; j < n; ++j) { 335 | if (!reserved[i][j]) 336 | matrix[i][j] ^= maskf(i, j); 337 | } 338 | } 339 | return matrix; 340 | }; 341 | var putformatinfo = function (matrix, reserved, ecclevel, mask) { 342 | var n = matrix.length; 343 | var code = augumentbch((ecclevel << 3) | mask, 5, 0x537, 10) ^ 0x5412; 344 | for (var i = 0; i < 15; ++i) { 345 | var r = [0, 1, 2, 3, 4, 5, 7, 8, n - 7, n - 6, n - 5, n - 4, n - 3, n - 2, n - 1][i]; 346 | var c = [n - 1, n - 2, n - 3, n - 4, n - 5, n - 6, n - 7, n - 8, 7, 5, 4, 3, 2, 1, 0][i]; 347 | matrix[r][8] = matrix[8][c] = (code >> i) & 1; 348 | } 349 | return matrix; 350 | }; 351 | var evaluatematrix = function (matrix) { 352 | var PENALTY_CONSECUTIVE = 3; 353 | var PENALTY_TWOBYTWO = 3; 354 | var PENALTY_FINDERLIKE = 40; 355 | var PENALTY_DENSITY = 10; 356 | var evaluategroup = function (groups) { 357 | var score = 0; 358 | for (var i = 0; i < groups.length; ++i) { 359 | if (groups[i] >= 5) 360 | score += PENALTY_CONSECUTIVE + (groups[i] - 5); 361 | } 362 | for (var i = 5; i < groups.length; i += 2) { 363 | var p = groups[i]; 364 | if (groups[i - 1] == p && groups[i - 2] == 3 * p && groups[i - 3] == p && groups[i - 4] == p && (groups[i - 5] >= 4 * p || groups[i + 1] >= 4 * p)) { 365 | score += PENALTY_FINDERLIKE; 366 | } 367 | } 368 | return score; 369 | }; 370 | var n = matrix.length; 371 | var score = 0, 372 | nblacks = 0; 373 | for (var i = 0; i < n; ++i) { 374 | var row = matrix[i]; 375 | var groups; 376 | groups = [0]; 377 | for (var j = 0; j < n; ) { 378 | var k; 379 | for (k = 0; j < n && row[j]; ++k) 380 | ++j; 381 | groups.push(k); 382 | for (k = 0; j < n && !row[j]; ++k) 383 | ++j; 384 | groups.push(k); 385 | } 386 | score += evaluategroup(groups); 387 | groups = [0]; 388 | for (var j = 0; j < n; ) { 389 | var k; 390 | for (k = 0; j < n && matrix[j][i]; ++k) 391 | ++j; 392 | groups.push(k); 393 | for (k = 0; j < n && !matrix[j][i]; ++k) 394 | ++j; 395 | groups.push(k); 396 | } 397 | score += evaluategroup(groups); 398 | var nextrow = matrix[i + 1] || []; 399 | nblacks += row[0]; 400 | for (var j = 1; j < n; ++j) { 401 | var p = row[j]; 402 | nblacks += p; 403 | if (row[j - 1] == p && nextrow[j] === p && nextrow[j - 1] === p) { 404 | score += PENALTY_TWOBYTWO; 405 | } 406 | } 407 | } 408 | score += PENALTY_DENSITY * ((Math.abs(nblacks / n / n - 0.5) / 0.05) | 0); 409 | return score; 410 | }; 411 | var generate = function (data, ver, mode, ecclevel, mask) { 412 | var v = VERSIONS[ver]; 413 | var buf = encode(ver, mode, data, ndatabits(ver, ecclevel) >> 3); 414 | buf = augumenteccs(buf, v[1][ecclevel], GF256_GENPOLY[v[0][ecclevel]]); 415 | var result = makebasematrix(ver); 416 | var matrix = result.matrix, 417 | reserved = result.reserved; 418 | putdata(matrix, reserved, buf); 419 | if (mask < 0) { 420 | maskdata(matrix, reserved, 0); 421 | putformatinfo(matrix, reserved, ecclevel, 0); 422 | var bestmask = 0, 423 | bestscore = evaluatematrix(matrix); 424 | maskdata(matrix, reserved, 0); 425 | for (mask = 1; mask < 8; ++mask) { 426 | maskdata(matrix, reserved, mask); 427 | putformatinfo(matrix, reserved, ecclevel, mask); 428 | var score = evaluatematrix(matrix); 429 | if (bestscore > score) { 430 | bestscore = score; 431 | bestmask = mask; 432 | } 433 | maskdata(matrix, reserved, mask); 434 | } 435 | mask = bestmask; 436 | } 437 | maskdata(matrix, reserved, mask); 438 | putformatinfo(matrix, reserved, ecclevel, mask); 439 | return matrix; 440 | }; 441 | var QRCode = { 442 | 'generate': function (data, options) { 443 | var MODES = { 444 | 'numeric': MODE_NUMERIC, 445 | 'alphanumeric': MODE_ALPHANUMERIC, 446 | 'octet': MODE_OCTET 447 | }; 448 | var ECCLEVELS = { 449 | 'L': ECCLEVEL_L, 450 | 'M': ECCLEVEL_M, 451 | 'Q': ECCLEVEL_Q, 452 | 'H': ECCLEVEL_H 453 | }; 454 | options = options || {}; 455 | var ver = options.version || -1; 456 | var ecclevel = ECCLEVELS[(options.ecclevel || 'L').toUpperCase()]; 457 | var mode = options.mode ? MODES[options.mode.toLowerCase()] : -1; 458 | var mask = 'mask' in options ? options.mask : -1; 459 | if (mode < 0) { 460 | if (typeof data === 'string') { 461 | if (data.match(NUMERIC_REGEXP)) { 462 | mode = MODE_NUMERIC; 463 | } else if (data.match(ALPHANUMERIC_OUT_REGEXP)) { 464 | mode = MODE_ALPHANUMERIC; 465 | } else { 466 | mode = MODE_OCTET; 467 | } 468 | } else { 469 | mode = MODE_OCTET; 470 | } 471 | } else if (!(mode == MODE_NUMERIC || mode == MODE_ALPHANUMERIC || mode == MODE_OCTET)) { 472 | throw 'invalid or unsupported mode'; 473 | } 474 | data = validatedata(mode, data); 475 | if (data === null) 476 | throw 'invalid data format'; 477 | if (ecclevel < 0 || ecclevel > 3) 478 | throw 'invalid ECC level'; 479 | if (ver < 0) { 480 | for (ver = 1; ver <= 40; ++ver) { 481 | if (data.length <= getmaxdatalen(ver, mode, ecclevel)) 482 | break; 483 | } 484 | if (ver > 40) 485 | throw 'too large data'; 486 | } else if (ver < 1 || ver > 40) { 487 | throw 'invalid version'; 488 | } 489 | if (mask != -1 && (mask < 0 || mask > 8)) 490 | throw 'invalid mask'; 491 | return generate(data, ver, mode, ecclevel, mask); 492 | }, 493 | 'generateHTML': function (data, options) { 494 | options = options || {}; 495 | 496 | var fillcolor = options.fillcolor ? options.fillcolor : "#FFFFFF"; 497 | var textcolor = options.textcolor ? options.textcolor : "#000000"; 498 | 499 | var matrix = QRCode['generate'](data, options); 500 | var modsize = Math.max(options.modulesize || 5, 0.5); 501 | var margin = Math.max(options.margin !== null ? options.margin : 4, 0.0); 502 | var e = document.createElement('div'); 503 | var n = matrix.length; 504 | var html = ['']; 506 | for (var i = 0; i < n; ++i) { 507 | html.push(''); 508 | for (var j = 0; j < n; ++j) { 509 | html.push(''); 511 | } 512 | html.push(''); 513 | } 514 | e.className = 'qrcode'; 515 | /* e.innerHTML = html.join('') + '
'; */ 516 | 517 | var range = document.createRange(); 518 | range.selectNodeContents(e); 519 | var frag = range.createContextualFragment(html.join('') + ''); 520 | e.appendChild(frag); 521 | 522 | return e; 523 | }, 524 | 'generateSVG': function (data, options) { 525 | options = options || {}; 526 | 527 | var fillcolor = options.fillcolor ? options.fillcolor : "#FFFFFF"; 528 | var textcolor = options.textcolor ? options.textcolor : "#000000"; 529 | 530 | var matrix = QRCode['generate'](data, options); 531 | var n = matrix.length; 532 | var modsize = Math.max(options.modulesize || 5, 0.5); 533 | var margin = Math.max(options.margin ? options.margin : 4, 0.0); 534 | var size = modsize * (n + 2 * margin); 535 | /* var common = ' class= "fg"' + ' width="' + modsize + '" height="' + modsize + '"/>'; */ 536 | var e = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); 537 | e.setAttribute('viewBox', '0 0 ' + size + ' ' + size); 538 | e.setAttribute('style', 'shape-rendering:crispEdges'); 539 | 540 | var frag = document.createDocumentFragment(); 541 | 542 | /* var svg = ['', '', ]; */ 543 | var style = document.createElementNS('http://www.w3.org/2000/svg', 'style'); 544 | style.appendChild(document.createTextNode('.bg{fill:' + fillcolor + '}.fg{fill:' + textcolor + '}')); 545 | style.setAttribute("scoped", "scoped"); 546 | 547 | frag.appendChild(style); 548 | 549 | var createRect = function (c, f, x, y, s) { 550 | var fg = document.createElementNS('http://www.w3.org/2000/svg', 'rect') || ""; 551 | fg.setAttributeNS(null, "class", c); 552 | fg.setAttributeNS(null, "fill", f); 553 | fg.setAttributeNS(null, "x", x); 554 | fg.setAttributeNS(null, "y", y); 555 | fg.setAttributeNS(null, "width", s); 556 | fg.setAttributeNS(null, "height", s); 557 | return fg; 558 | }; 559 | 560 | frag.appendChild(createRect("bg", "none", 0, 0, size)); 561 | 562 | var yo = margin * modsize; 563 | 564 | for (var y = 0; y < n; ++y) { 565 | var xo = margin * modsize; 566 | for (var x = 0; x < n; ++x) { 567 | if (matrix[y][x]) { 568 | /* svg.push('data->amount; 38 | $amt_in_btc = $atts["price"]/$price_of_btc; 39 | $amt_in_btc = $amt_in_btc * 100000000; 40 | $amt_in_btc = round( $amt_in_btc ); 41 | } 42 | 43 | //Connect to lnbits and get an invoice for that amount 44 | 45 | ob_start(); 46 | $payload = '{"out": false, "amount": ' . $amt_in_btc . ', "memo": "Paywall"}'; 47 | $url = get_option( 'lnbits_url ') . '/api/v1/payments'; 48 | $ch = curl_init(); 49 | curl_setopt( $ch, CURLOPT_URL, $url ); 50 | curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 51 | 'X-Api-Key: ' . get_option( 'lnbits_api_key' ), 52 | 'Content-Type: application/json' 53 | )); 54 | curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload ); 55 | $head = curl_exec( $ch ); 56 | $httpCode = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); 57 | curl_close( $ch ); 58 | $data = ob_get_clean(); 59 | $data = json_decode( $data, true ); 60 | $payment_hash = $data["payment_hash"]; 61 | $invoice = $data["payment_request"]; 62 | 63 | //The function called createQR2 uses a javascript qr library to turn a lightning invoice into a qr code 64 | 65 | return ' 66 | 67 | 88 | 89 | 142 | 163 | 203 | '; 204 | } 205 | } 206 | 207 | add_shortcode("paywall", "paywall"); 208 | 209 | //Connect to lnbits and find out if payment hash is paid 210 | 211 | function checkInvoice( $pmthash ) { 212 | 213 | //invoice is paid = 1 214 | ob_start(); 215 | $url = get_option( 'lnbits_url' ) . '/api/v1/payments/' . $pmthash; 216 | $ch = curl_init(); 217 | curl_setopt( $ch, CURLOPT_URL, $url ); 218 | curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 219 | 'X-Api-Key: ' . get_option( 'lnbits_api_key' ), 220 | 'Content-Type: application/json' 221 | )); 222 | $head = curl_exec( $ch ); 223 | $httpCode = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); 224 | curl_close( $ch ); 225 | $paychecker = ob_get_clean(); 226 | if ( strpos( $paychecker, "true" ) !== false ) { 227 | $paychecker = 1; 228 | } else { 229 | $paychecker = 0; 230 | } 231 | return $paychecker; 232 | } 233 | 234 | //This script checks invoices. 235 | 236 | function invoiceChecker() { 237 | 238 | //Filter get requests so hackers can't abuse the system 239 | 240 | filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING); 241 | 242 | //If there is a post request with a payment hash, check if the invoice associated with that payment hash is paid. If it is, display the content concealed by the shortcode. 243 | 244 | if ( isset( $_POST["pmthash"] ) ) { 245 | $status = checkInvoice( $_POST["pmthash"] ); 246 | if ( $status ) { 247 | echo 1; 248 | die(); 249 | } 250 | } 251 | echo 0; 252 | die(); 253 | } 254 | 255 | add_action( 'wp_ajax_invoicechecker', 'invoiceChecker' ); 256 | add_action( 'wp_ajax_nopriv_invoicechecker', 'invoiceChecker' ); 257 | 258 | //This function creates a pretty lightbox to display invoices in 259 | 260 | function lightbox2() { 261 | 262 | //This part customizes the lightbox using options in a settings page 263 | 264 | if ( !empty( get_option( 'lightbox_blackbgroundcss2' ) ) ) { 265 | $blackbgroundcss = 'style="' . get_option( 'lightbox_blackbgroundcss2' ) . '"'; 266 | } else { 267 | $blackbgroundcss = ''; 268 | } 269 | if ( !empty( get_option( 'lightbox_boxcss2' ) ) ) { 270 | $boxcss = 'style="' . get_option( 'lightbox_boxcss2' ) . '"'; 271 | } else { 272 | $boxcss = ''; 273 | } 274 | 275 | //This part echoes a black backround and the lightbox itself onto the page. They start out invisible and become visible when certain events are triggered. 276 | 277 | echo ' 278 |
279 | 280 | 281 | 282 | 304 | '; 305 | } 306 | add_action( 'wp_footer', 'lightbox2' ); 307 | 308 | function btcPaywall_register_settings() { 309 | add_option( 'lnbits_url', '' ); 310 | add_option( 'lnbits_api_key', '' ); 311 | add_option( 'currency', 'sats' ); 312 | add_option( 'lightbox_showpaywalltext', 'Read more' ); 313 | add_option( 'lightbox_showpaywallcss', 'max-width: 200px;' ); 314 | add_option( 'lightbox_boxcss2', 'background-color: white; color: black; position: fixed; padding: 20px; width: 80%; max-width: 400px; height: 100%; max-height: 590px; overflow-y: auto; border-radius: 20px; z-index: 2; display: none; z-index: 1;' ); 315 | add_option( 'lightbox_blackbgroundcss2', 'width: 100%; position: fixed; top: 0px; left: 0px; background-color: black; z-index: 1; opacity: 0.7; display: none;' ); 316 | add_option( 'lightbox_closecss2', 'float: right; font-size: 25px; line-height: 22px; cursor: pointer;' ); 317 | add_option( 'lightbox_toptext2', 'Pay this invoice' ); 318 | add_option( 'lightbox_invoicedescriptor', 'Invoice' ); 319 | add_option( 'lightbox_descriptorcss', '' ); 320 | add_option( 'lightbox_invoicebox2', 'height: 30px; overflow: hidden; text-overflow: ellipsis; width: 80%; max-width: 300px; white-space: nowrap; border: 1px solid black; padding: 5px; vertical-align: middle; font-size: 18px;' ); 321 | add_option( 'lightbox_copycss2', 'display: inline-block; width: 10%; font-size: 25px; cursor: pointer; vertical-align: middle;' ); 322 | add_option( 'lightbox_btntext2', 'Open Wallet' ); 323 | add_option( 'lightbox_bottomtext2', '' ); 324 | register_setting( 'btcPaywall_options_group', 'currency', 'btcPaywall_callback' ); 325 | register_setting( 'btcPaywall_options_group', 'lnbits_url', 'btcPaywall_callback' ); 326 | register_setting( 'btcPaywall_options_group', 'lnbits_api_key', 'btcPaywall_callback' ); 327 | register_setting( 'btcPaywall_options_group', 'lightbox_showpaywalltext', 'btcPaywall_callback' ); 328 | register_setting( 'btcPaywall_options_group', 'lightbox_showpaywallcss', 'btcPaywall_callback' ); 329 | register_setting( 'btcPaywall_options_group', 'lightbox_boxcss2', 'btcPaywall_callback' ); 330 | register_setting( 'btcPaywall_options_group', 'lightbox_blackbgroundcss2', 'btcPaywall_callback' ); 331 | register_setting( 'btcPaywall_options_group', 'lightbox_closecss2', 'btcPaywall_callback' ); 332 | register_setting( 'btcPaywall_options_group', 'lightbox_toptext2', 'btcPaywall_callback' ); 333 | register_setting( 'btcPaywall_options_group', 'lightbox_invoicedescriptor', 'btcPaywall_callback' ); 334 | register_setting( 'btcPaywall_options_group', 'lightbox_descriptorcss', 'btcPaywall_callback' ); 335 | register_setting( 'btcPaywall_options_group', 'lightbox_invoicebox2', 'btcPaywall_callback' ); 336 | register_setting( 'btcPaywall_options_group', 'lightbox_copycss2', 'btcPaywall_callback' ); 337 | register_setting( 'btcPaywall_options_group', 'lightbox_btntext2', 'btcPaywall_callback' ); 338 | register_setting( 'btcPaywall_options_group', 'lightbox_bottomtext2', 'btcPaywall_callback' ); 339 | } 340 | add_action( 'admin_init', 'btcPaywall_register_settings' ); 341 | 342 | function btcPaywall_register_options_page() { 343 | add_options_page('BTC Paywall', 'BTC Paywall', 'manage_options', 'btcPaywall', 'btcPaywall_options_page'); 344 | } 345 | add_action('admin_menu', 'btcPaywall_register_options_page'); 346 | 347 | function btcPaywall_options_page() 348 | { 349 | ?> 350 |

BTC Paywall

351 |
352 | 353 |

354 | LNBits Settings 355 |

356 | 357 | 358 | 363 | 366 | 367 |
359 | 362 | 364 | 365 |
368 | 369 | 370 | 375 | 378 | 379 |
371 | 374 | 376 | 377 |
380 |

381 | Customization 382 |

383 | 384 | Currency 385 | 386 |

387 | 388 |
389 | 390 | 391 | 396 |

397 | You can use the above option to set whether your want to use sats or USD as the currency for your paywalls. If you use sats, your paywall should look like [paywall price="1500"]any wordpress content[/paywall] if you want to charge 0.00001500 btc for your content. If you use USD, your paywall shortcodes should look like [paywall price="0.01"]any wordpress content[/paywall] if you want to charge one penny for your content. 398 |

399 | 400 | 401 | 406 | 409 | 410 |
402 | 405 | 407 | 408 |
411 |

412 | The text in the Read More button can be customized to say something other than Read More. Whatever you type here will show up instead of Read More. 413 |

414 | 415 | 416 | 421 | 424 | 425 |
417 | 420 | 422 | 423 |
426 |

427 | The css here controls the style of the Read More button. If you wish to control the css of the button using a regular css document rather than this field, remove all text from this field and set the css for #showpaywall in a regular css document. 428 |

429 | 430 | 431 | 436 | 439 | 440 |
432 | 435 | 437 | 438 |
441 |

442 | The css in Lightbox CSS will modify the appearance of the lightbox that appears when you click the "Read more" button. You can set its background color, width, and other parameters using standard css. If you wish to control the css of the lightbox using a regular css document rather than this field, remove all text from this field and set the css for #lightbox in a regular css document. 443 |

444 | 445 | 446 | 451 | 454 | 455 |
447 | 450 | 452 | 453 |
456 |

457 | The css in Black Background CSS will modify the appearance of the black background that appears behind the lightbox. You can set its color, width, and other parameters using standard css. If you wish to control the css of the black background using a regular css document rather than this field, remove all text from this field and set the css for #blackBackground in a regular css document. 458 |

459 | 460 | 461 | 466 | 469 | 470 |
462 | 465 | 467 | 468 |
471 |

472 | The css in X Button CSS will modify the x button which, by default, appears at the top right of the lightbox. 473 |

474 | 475 | 476 | 481 | 484 | 485 |
477 | 480 | 482 | 483 |
486 |

487 | The text in "Top text" will appear at the top of the lightbox. 488 |

489 | 490 | 491 | 496 | 499 | 500 |
492 | 495 | 497 | 498 |
501 |

502 | The text in "Invoice descriptor" appears below the qr code. 503 |

504 | 505 | 506 | 511 | 514 | 515 |
507 | 510 | 512 | 513 |
516 |

517 | The css in "Descriptor css" controls the style of the invoice descriptor. If you wish to control the css using a regular css document rather than this field, remove all text from this field and set the css for #invoiceDescriptor in a regular css document. 518 |

519 | 520 | 521 | 526 | 529 | 530 |
522 | 525 | 527 | 528 |
531 |

532 | The css in "Invoice box" controls the style of the box that the invoice's text appears in. If you wish to control the css using a regular css document rather than this field, remove all text from this field and set the css for #invoiceBox2 in a regular css document. 533 |

534 | 535 | 536 | 541 | 544 | 545 |
537 | 540 | 542 | 543 |
546 |

547 | The css in "Copy button css" controls the style of the copy button next to the lightbox. If you wish to control the css using a regular css document rather than this field, remove all text from this field and set the css for #copyButton2 in a regular css document. 548 |

549 | 550 | 551 | 556 | 559 | 560 |
552 | 555 | 557 | 558 |
561 |

562 | The text in "Button text" will appear in the button in the lightbox. 563 |

564 | 565 | 566 | 571 | 574 | 575 |
567 | 570 | 572 | ' /> 573 |
576 |

577 | The text in "Bottom text" will appear at the bottom of the lightbox after the button. 578 |

579 | 580 |
581 | 583 | -------------------------------------------------------------------------------- /btcpaywall/jquery-3.5.1.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */ 2 | !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0