bitcoin-serverless-donations 1.0.13

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Tom Bennet
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,187 @@
1
+ # Bitcoin Serverless Donations
2
+
3
+ A simple, self-custodial solution for accepting private, on-chain Bitcoin payments with minimal overhead and a good level of privacy.
4
+
5
+ This repository contains both the serverless backend and an npm package which serves as the frontend. You can see a [live demo on my blog](https://bennet.org/blog/private-serverless-bitcoin-payments-for-indie-devs/).
6
+
7
+ ![Bitcoin Serverless Donations widget](/src/img/preview.png)
8
+
9
+ ## ✨ Features
10
+
11
+ - **Serverless**: No database required, and zero server maintenance.
12
+ - **Sovereign**: Receive payments directly to your own wallet - just grab your account XPUB and you're good to go.
13
+ - **Private**: No third-party payment processors, middlemen, or KYC requirements. Automatically rotate addresses for privacy.
14
+ - **Free**: Backend can be hosted for free on Netlify, and the convenient `BitcoinPay()` browser function is easy to integrate into any website.
15
+
16
+ ## 🚀 Quick Start
17
+
18
+ ### Backend
19
+
20
+ One click deployment to Netlify - just set your environment variables and you're ready to go.
21
+
22
+ [![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/tombennet/bitcoin-serverless-donations#BITCOIN_XPUB=your_extended_public_key&BITCOIN_DERIVATION_PATH=your_account_path)
23
+
24
+ ### Frontend
25
+
26
+ The simplest approach is to add the CDN versions of the script and stylesheet, and then call `BitcoinPay.render()`.
27
+
28
+ ```html
29
+ <link
30
+ rel="stylesheet"
31
+ href="https://cdn.jsdelivr.net/npm/bitcoin-serverless-donations@latest/dist/bitcoin-pay.min.css"
32
+ />
33
+ <script src="https://cdn.jsdelivr.net/npm/bitcoin-serverless-donations@latest/dist/bitcoin-pay.min.js"></script>
34
+
35
+ <div id="bitcoin-donate"></div>
36
+
37
+ <script>
38
+ BitcoinPay.render({
39
+ endpoint: "https://your-site.netlify.app/.netlify/functions/get-address",
40
+ selector: "#bitcoin-donate",
41
+ bitcoinFallbackAddress: "bc1q...",
42
+ }).catch((error) => {
43
+ console.error("Failed to render Bitcoin widget:", error);
44
+ });
45
+ </script>
46
+ ```
47
+
48
+ **For a complete step-by-step tutorial, visit: [https://bennet.org/blog/private-serverless-bitcoin-payments-for-indie-devs/](https://bennet.org/blog/private-serverless-bitcoin-payments-for-indie-devs/)**
49
+
50
+ ## 📦 Backend Setup
51
+
52
+ 1. **Clone repository**
53
+ ```bash
54
+ git clone https://github.com/tombennet/bitcoin-serverless-donations.git
55
+ cd bitcoin-serverless-donations
56
+ npm install
57
+ ```
58
+ 2. **Set your environment variables in `.env`**:
59
+
60
+ ```bash
61
+ BITCOIN_XPUB="xpub6..."
62
+ BITCOIN_DERIVATION_PATH="m/84'/0'/0'"
63
+ ```
64
+
65
+ 3. **Test locally**, making sure that the derived addresses match those you see in your wallet software
66
+ ```bash
67
+ netlify dev
68
+ ```
69
+ 4. **Deploy to Netlify**, and set both environment variables in your deployment settings. Your function's endpoint will be available at this path:
70
+
71
+ ```bash
72
+ /.netlify/functions/get-address
73
+ ```
74
+
75
+ **Common Derivation Paths:**
76
+
77
+ - **BIP86 (P2TR)**: `m/86'/0'/0'` - Taproot (bech32m addresses starting with `bc1p`). Extended public keys begin with `xpub`.
78
+ - **BIP84 (P2WPKH)**: `m/84'/0'/0'` - Native SegWit, most common for modern wallets (bech32 addresses starting with `bc1q`). Extended public keys begin with `zpub`.
79
+ - **BIP49 (P2WPKH-in-P2SH)**: `m/49'/0'/0'` - Nested SegWit (P2SH addresses starting with `3`). Extended public keys begin with `ypub`.
80
+ - **BIP44 (P2PKH)**: `m/44'/0'/0'` - Legacy addresses (base58 format). Extended public keys begin with `xpub`.
81
+
82
+ **Important Notes:**
83
+
84
+ - Your XPUB should be from the **account level** (e.g., `m/84'/0'/0'`). The system automatically derives receiving addresses (`/0/index`) from your account-level XPUB.
85
+ - Ensure values are enclosed in quotes, e.g. `BITCOIN_DERIVATION_PATH="m/84'/0'/0'"`
86
+ - **Always verify that your config is producing expected addresses** by comparing the first few generated addresses with your wallet software. This is critical to ensure you can receive funds.
87
+
88
+ **Advanced users**: See [TECHNICAL.md](TECHNICAL.md) for implementation details, cache management, and troubleshooting.
89
+
90
+ ## 🎨 Frontend Setup
91
+
92
+ ### Add the library
93
+
94
+ The fastest way to get started is to load the script via CDN using a basic `<script>` tag (shown above in Quick Start). Alternatively, if you're using a bundler like Vite, you can install this library as an ES module using npm:
95
+
96
+ ```bash
97
+ npm install bitcoin-serverless-donations
98
+ ```
99
+
100
+ Then import the script and styles into your project:
101
+
102
+ ```javascript
103
+ import { BitcoinPay } from "bitcoin-serverless-donations";
104
+ import "bitcoin-serverless-donations/css";
105
+ ```
106
+
107
+ Loading it this way comes with several advantages, including a smaller bundle size and better caching. The library also comes with full TypeScript support.
108
+
109
+ Once you've loaded the script, you can use the `BitcoinPay()` function.
110
+
111
+ ### Render the widget
112
+
113
+ The `BitcoinPay()` function accepts multiple parameters:
114
+
115
+ - `selector`: A CSS selector for the element(s) into which it will render the payment widget (e.g., `#bitcoin-donate` or `.donation-widget`).
116
+ - `endpoint`: The full URL of your backend function - by default it will live at `/.netlify/functions/get-address` on whichever domain you deployed to.
117
+ - `bitcoinFallbackAddress`: The Bitcoin address to use if your backend function is ever unavailable. I'd suggest picking the first unused address from the account associated with your XPUB.
118
+ - `bitcoinDonateText`: Optional custom text to display above the Bitcoin address field.
119
+ - `lightningAddress`: Optional [Lightning address](https://lightningaddress.com/) (e.g., `yourname@provider.com`) for dual Bitcoin/Lightning mode.
120
+ - `lightningDonateText`: Optional custom text to display above the Lightning address field.
121
+
122
+ For example:
123
+
124
+ ```html
125
+ <script>
126
+ BitcoinPay.render({
127
+ selector: "#bitcoin-donate",
128
+ endpoint: "https://your-site.netlify.app/.netlify/functions/get-address",
129
+ bitcoinFallbackAddress: "bc1q...",
130
+ lightningAddress: "yourname@provider.com",
131
+ }).catch((error) => {
132
+ console.error("Failed to render Bitcoin widget:", error);
133
+ });
134
+ </script>
135
+ ```
136
+
137
+ You can have multiple Bitcoin payment widgets on the same page by passing in a class selector (e.g., `.donation-widget`). Alternatively you can call `BitcoinPay.render()` multiple times with a different element each time.
138
+
139
+ Refer to [bitcoin-pay.js](/src/bitcoin-pay.js) to see all available API options.
140
+
141
+ ### Styling
142
+
143
+ The widget can be fully customized using CSS custom properties (variables). You can change colors, spacing, typography, and more to match your site's design. **Dark mode is supported automatically** based on the user's system preferences.
144
+
145
+ ```css
146
+ .bitcoin-pay-widget {
147
+ --btc-pay-primary: #2563eb;
148
+ --btc-pay-primary-hover: #1d4ed8;
149
+ --btc-pay-border-radius: 4px;
150
+ }
151
+ ```
152
+
153
+ Refer to [bitcoin-pay.css](/src/bitcoin-pay.css) to see the full list of variables.
154
+
155
+ ## 🏗️ How It Works
156
+
157
+ ### Backend (Serverless function)
158
+
159
+ Your extended public key (or 'XPUB', exported from your Bitcoin wallet) is stored as an environment variable, along with its derivation path. The serverless function derives addresses using [Swan's XPUB tool](https://github.com/swan-bitcoin/xpub-tool), stores them, rotates them, checks for transactions, and removes used addresses from circulation.
160
+
161
+ - Address pool rotates every 10 minutes automatically
162
+ - The mempool.space API is used to check for used addresses, which are replaced with fresh ones from your XPUB
163
+ - Pool size stays constant at 5 addresses to prevent index bloat
164
+ - Supports BIP44 (P2PKH), BIP49 (P2WPKH-in-P2SH), BIP84 (P2WPKH), and BIP86 (P2TR) address types
165
+
166
+ ### Frontend (`BitcoinPay` function)
167
+
168
+ The frontend script:
169
+
170
+ - Fetches a Bitcoin address from your serverless function
171
+ - Displays a QR code for easy scanning
172
+ - Provides a copy button for the address
173
+ - Caches addresses for 10 minutes to reduce API calls
174
+ - Falls back to your specified address if the API is unavailable
175
+ - Supports both Bitcoin-only and Bitcoin + Lightning layouts
176
+
177
+ ## 🤝 Contributing
178
+
179
+ Contributions are welcome! Please feel free to submit a Pull Request. Before submitting, please ensure all tests pass.
180
+
181
+ ## 📄 License
182
+
183
+ MIT License - see the [LICENSE](LICENSE) file for details.
184
+
185
+ ---
186
+
187
+ **Built with ❤️ for the Bitcoin community**
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Bitcoin Serverless Payments - TypeScript Definitions
3
+ */
4
+
5
+ /**
6
+ * Configuration options for customizing the widget appearance and behavior
7
+ */
8
+ export interface BitcoinPayOptions {
9
+ /** Width of the QR code in pixels */
10
+ width?: number;
11
+ /** Height of the QR code in pixels */
12
+ height?: number;
13
+ /** Whether to show the copy button */
14
+ showCopyButton?: boolean;
15
+ /** Text displayed on the copy button */
16
+ copyButtonText?: string;
17
+ /** Text displayed when address is copied */
18
+ copiedText?: string;
19
+ /** Cache duration in milliseconds (0 to 1 week) */
20
+ cacheDuration?: number;
21
+ /** QR code configuration options */
22
+ qrCodeOptions?: {
23
+ /** Error correction level: 'L' | 'M' | 'Q' | 'H' */
24
+ ecc?: "L" | "M" | "Q" | "H";
25
+ /** Logo to display in QR code center */
26
+ logo?: "btc" | "lightning" | undefined;
27
+ /** Bitcoin logo image data URL */
28
+ bitcoinImage?: string;
29
+ /** Lightning logo image data URL */
30
+ lightningImage?: string;
31
+ };
32
+ }
33
+
34
+ /**
35
+ * Configuration for rendering the Bitcoin payment widget
36
+ */
37
+ export interface BitcoinPayConfig {
38
+ /** CSS selector for the target element(s) (e.g., "#bitcoin-donate" or ".donation-widget") */
39
+ selector: string;
40
+ /** The serverless function endpoint URL */
41
+ endpoint: string;
42
+ /** Fallback Bitcoin address to use if the serverless function fails */
43
+ bitcoinFallbackAddress: string;
44
+ /** Optional custom text to display above the Bitcoin address field */
45
+ bitcoinDonateText?: string;
46
+ /** Optional Lightning address (e.g., "name@provider.com") */
47
+ lightningAddress?: string;
48
+ /** Optional custom text to display above the Lightning address field */
49
+ lightningDonateText?: string;
50
+ /** Optional configuration overrides */
51
+ options?: BitcoinPayOptions;
52
+ }
53
+
54
+ /**
55
+ * Result of a successful widget render
56
+ */
57
+ export interface RenderSuccess {
58
+ success: true;
59
+ element: Element;
60
+ }
61
+
62
+ /**
63
+ * Result types from Promise.allSettled
64
+ */
65
+ export type RenderResult =
66
+ | { status: "fulfilled"; value: RenderSuccess }
67
+ | { status: "rejected"; reason: Error };
68
+
69
+ /**
70
+ * Bitcoin Serverless Payments Widget
71
+ */
72
+ export class BitcoinPay {
73
+ /** Library version */
74
+ readonly version: string;
75
+
76
+ /**
77
+ * Render the Bitcoin donation widget
78
+ * @param config - Configuration object
79
+ * @returns Promise that resolves to an array of results for each matched element
80
+ * @throws Error if required parameters are missing or no elements match the selector
81
+ */
82
+ static render(config: BitcoinPayConfig): Promise<RenderResult[]>;
83
+
84
+ constructor();
85
+ }
86
+
87
+ /**
88
+ * Default export
89
+ */
90
+ export default BitcoinPay;
91
+
92
+ /**
93
+ * Global declaration for script tag usage
94
+ */
95
+ declare global {
96
+ interface Window {
97
+ BitcoinPay: typeof BitcoinPay;
98
+ }
99
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Bitcoin Serverless Payments - TypeScript Definitions
3
+ */
4
+
5
+ /**
6
+ * Configuration options for customizing the widget appearance and behavior
7
+ */
8
+ export interface BitcoinPayOptions {
9
+ /** Width of the QR code in pixels */
10
+ width?: number;
11
+ /** Height of the QR code in pixels */
12
+ height?: number;
13
+ /** Whether to show the copy button */
14
+ showCopyButton?: boolean;
15
+ /** Text displayed on the copy button */
16
+ copyButtonText?: string;
17
+ /** Text displayed when address is copied */
18
+ copiedText?: string;
19
+ /** Cache duration in milliseconds (0 to 1 week) */
20
+ cacheDuration?: number;
21
+ /** QR code configuration options */
22
+ qrCodeOptions?: {
23
+ /** Error correction level: 'L' | 'M' | 'Q' | 'H' */
24
+ ecc?: "L" | "M" | "Q" | "H";
25
+ /** Logo to display in QR code center */
26
+ logo?: "btc" | "lightning" | undefined;
27
+ /** Bitcoin logo image data URL */
28
+ bitcoinImage?: string;
29
+ /** Lightning logo image data URL */
30
+ lightningImage?: string;
31
+ };
32
+ }
33
+
34
+ /**
35
+ * Configuration for rendering the Bitcoin payment widget
36
+ */
37
+ export interface BitcoinPayConfig {
38
+ /** CSS selector for the target element(s) (e.g., "#bitcoin-donate" or ".donation-widget") */
39
+ selector: string;
40
+ /** The serverless function endpoint URL */
41
+ endpoint: string;
42
+ /** Fallback Bitcoin address to use if the serverless function fails */
43
+ bitcoinFallbackAddress: string;
44
+ /** Optional custom text to display above the Bitcoin address field */
45
+ bitcoinDonateText?: string;
46
+ /** Optional Lightning address (e.g., "name@provider.com") */
47
+ lightningAddress?: string;
48
+ /** Optional custom text to display above the Lightning address field */
49
+ lightningDonateText?: string;
50
+ /** Optional configuration overrides */
51
+ options?: BitcoinPayOptions;
52
+ }
53
+
54
+ /**
55
+ * Result of a successful widget render
56
+ */
57
+ export interface RenderSuccess {
58
+ success: true;
59
+ element: Element;
60
+ }
61
+
62
+ /**
63
+ * Result types from Promise.allSettled
64
+ */
65
+ export type RenderResult =
66
+ | { status: "fulfilled"; value: RenderSuccess }
67
+ | { status: "rejected"; reason: Error };
68
+
69
+ /**
70
+ * Bitcoin Serverless Payments Widget
71
+ */
72
+ export class BitcoinPay {
73
+ /** Library version */
74
+ readonly version: string;
75
+
76
+ /**
77
+ * Render the Bitcoin donation widget
78
+ * @param config - Configuration object
79
+ * @returns Promise that resolves to an array of results for each matched element
80
+ * @throws Error if required parameters are missing or no elements match the selector
81
+ */
82
+ static render(config: BitcoinPayConfig): Promise<RenderResult[]>;
83
+
84
+ constructor();
85
+ }
86
+
87
+ /**
88
+ * Default export
89
+ */
90
+ export default BitcoinPay;
91
+
92
+ /**
93
+ * Global declaration for script tag usage
94
+ */
95
+ declare global {
96
+ interface Window {
97
+ BitcoinPay: typeof BitcoinPay;
98
+ }
99
+ }
@@ -0,0 +1 @@
1
+ var qrcode=function(){var t=function(t,e){var n=t,r=l[e],i=null,o=0,a=null,c=[],s={},u=function(t,e){i=function(t){for(var e=new Array(t),n=0;n<t;n+=1){e[n]=new Array(t);for(var r=0;r<t;r+=1)e[n][r]=null}return e}(o=4*n+17),d(0,0),d(o-7,0),d(0,o-7),f(),g(),M(t,e),n>=7&&h(t),null==a&&(a=y(n,r,c)),w(a,e)},d=function(t,e){for(var n=-1;n<=7;n+=1)if(!(t+n<=-1||o<=t+n))for(var r=-1;r<=7;r+=1)e+r<=-1||o<=e+r||(i[t+n][e+r]=0<=n&&n<=6&&(0==r||6==r)||0<=r&&r<=6&&(0==n||6==n)||2<=n&&n<=4&&2<=r&&r<=4)},g=function(){for(var t=8;t<o-8;t+=1)null==i[t][6]&&(i[t][6]=t%2==0);for(var e=8;e<o-8;e+=1)null==i[6][e]&&(i[6][e]=e%2==0)},f=function(){for(var t=p.getPatternPosition(n),e=0;e<t.length;e+=1)for(var r=0;r<t.length;r+=1){var o=t[e],a=t[r];if(null==i[o][a])for(var c=-2;c<=2;c+=1)for(var s=-2;s<=2;s+=1)i[o+c][a+s]=-2==c||2==c||-2==s||2==s||0==c&&0==s}},h=function(t){for(var e=p.getBCHTypeNumber(n),r=0;r<18;r+=1){var a=!t&&1==(e>>r&1);i[Math.floor(r/3)][r%3+o-8-3]=a}for(r=0;r<18;r+=1){a=!t&&1==(e>>r&1);i[r%3+o-8-3][Math.floor(r/3)]=a}},M=function(t,e){for(var n=r<<3|e,a=p.getBCHTypeInfo(n),c=0;c<15;c+=1){var s=!t&&1==(a>>c&1);c<6?i[c][8]=s:c<8?i[c+1][8]=s:i[o-15+c][8]=s}for(c=0;c<15;c+=1){s=!t&&1==(a>>c&1);c<8?i[8][o-c-1]=s:c<9?i[8][15-c-1+1]=s:i[8][15-c-1]=s}i[o-8][8]=!t},w=function(t,e){for(var n=-1,r=o-1,a=7,c=0,s=p.getMaskFunction(e),u=o-1;u>0;u-=2)for(6==u&&(u-=1);;){for(var l=0;l<2;l+=1)if(null==i[r][u-l]){var d=!1;c<t.length&&(d=1==(t[c]>>>a&1)),s(r,u-l)&&(d=!d),i[r][u-l]=d,-1==(a-=1)&&(c+=1,a=7)}if((r+=n)<0||o<=r){r-=n,n=-n;break}}},y=function(t,e,n){for(var r=x.getRSBlocks(t,e),i=C(),o=0;o<n.length;o+=1){var a=n[o];i.put(a.getMode(),4),i.put(a.getLength(),p.getLengthInBits(a.getMode(),t)),a.write(i)}var c=0;for(o=0;o<r.length;o+=1)c+=r[o].dataCount;if(i.getLengthInBits()>8*c)throw"code length overflow. ("+i.getLengthInBits()+">"+8*c+")";for(i.getLengthInBits()+4<=8*c&&i.put(0,4);i.getLengthInBits()%8!=0;)i.putBit(!1);for(;!(i.getLengthInBits()>=8*c||(i.put(236,8),i.getLengthInBits()>=8*c));)i.put(17,8);return function(t,e){for(var n=0,r=0,i=0,o=new Array(e.length),a=new Array(e.length),c=0;c<e.length;c+=1){var s=e[c].dataCount,u=e[c].totalCount-s;r=Math.max(r,s),i=Math.max(i,u),o[c]=new Array(s);for(var l=0;l<o[c].length;l+=1)o[c][l]=255&t.getBuffer()[l+n];n+=s;var d=p.getErrorCorrectPolynomial(u),g=b(o[c],d.getLength()-1).mod(d);for(a[c]=new Array(d.getLength()-1),l=0;l<a[c].length;l+=1){var f=l+g.getLength()-a[c].length;a[c][l]=f>=0?g.getAt(f):0}}var h=0;for(l=0;l<e.length;l+=1)h+=e[l].totalCount;var M=new Array(h),w=0;for(l=0;l<r;l+=1)for(c=0;c<e.length;c+=1)l<o[c].length&&(M[w]=o[c][l],w+=1);for(l=0;l<i;l+=1)for(c=0;c<e.length;c+=1)l<a[c].length&&(M[w]=a[c][l],w+=1);return M}(i,r)};s.addData=function(t,e){var n=null;switch(e=e||"Byte"){case"Numeric":n=D(t);break;case"Alphanumeric":n=m(t);break;case"Byte":n=j(t);break;case"Kanji":n=N(t);break;default:throw"mode:"+e}c.push(n),a=null},s.isDark=function(t,e){if(t<0||o<=t||e<0||o<=e)throw t+","+e;return i[t][e]},s.getModuleCount=function(){return o},s.make=function(){if(n<1){for(var t=1;t<40;t++){for(var e=x.getRSBlocks(t,r),i=C(),o=0;o<c.length;o++){var a=c[o];i.put(a.getMode(),4),i.put(a.getLength(),p.getLengthInBits(a.getMode(),t)),a.write(i)}var l=0;for(o=0;o<e.length;o++)l+=e[o].dataCount;if(i.getLengthInBits()<=8*l)break}n=t}u(!1,function(){for(var t=0,e=0,n=0;n<8;n+=1){u(!0,n);var r=p.getLostPoint(s);(0==n||t>r)&&(t=r,e=n)}return e}())},s.createTableTag=function(t,e){t=t||2;var n="";n+='<table style="',n+=" border-width: 0px; border-style: none;",n+=" border-collapse: collapse;",n+=" padding: 0px; margin: "+(e=void 0===e?4*t:e)+"px;",n+='">',n+="<tbody>";for(var r=0;r<s.getModuleCount();r+=1){n+="<tr>";for(var i=0;i<s.getModuleCount();i+=1)n+='<td style="',n+=" border-width: 0px; border-style: none;",n+=" border-collapse: collapse;",n+=" padding: 0px; margin: 0px;",n+=" width: "+t+"px;",n+=" height: "+t+"px;",n+=" background-color: ",n+=s.isDark(r,i)?"#000000":"#ffffff",n+=";",n+='"/>';n+="</tr>"}return n+="</tbody>",n+="</table>"},s.createSvgTag=function(t,e,n,r){var i={};"object"==typeof arguments[0]&&(t=(i=arguments[0]).cellSize,e=i.margin,n=i.alt,r=i.title),t=t||2,e=void 0===e?4*t:e,(n="string"==typeof n?{text:n}:n||{}).text=n.text||null,n.id=n.text?n.id||"qrcode-description":null,(r="string"==typeof r?{text:r}:r||{}).text=r.text||null,r.id=r.text?r.id||"qrcode-title":null;var o,a,c,u,l=s.getModuleCount()*t+2*e,d="";for(u="l"+t+",0 0,"+t+" -"+t+",0 0,-"+t+"z ",d+='<svg version="1.1" xmlns="http://www.w3.org/2000/svg"',d+=i.scalable?"":' width="'+l+'px" height="'+l+'px"',d+=' viewBox="0 0 '+l+" "+l+'" ',d+=' preserveAspectRatio="xMinYMin meet"',d+=r.text||n.text?' role="img" aria-labelledby="'+v([r.id,n.id].join(" ").trim())+'"':"",d+=">",d+=r.text?'<title id="'+v(r.id)+'">'+v(r.text)+"</title>":"",d+=n.text?'<description id="'+v(n.id)+'">'+v(n.text)+"</description>":"",d+='<rect width="100%" height="100%" fill="white" cx="0" cy="0"/>',d+='<path d="',a=0;a<s.getModuleCount();a+=1)for(c=a*t+e,o=0;o<s.getModuleCount();o+=1)s.isDark(a,o)&&(d+="M"+(o*t+e)+","+c+u);return d+='" stroke="transparent" fill="black"/>',d+="</svg>"},s.createDataURL=function(t,e){t=t||2,e=void 0===e?4*t:e;var n=s.getModuleCount()*t+2*e,r=e,i=n-e;return S(n,n,function(e,n){if(r<=e&&e<i&&r<=n&&n<i){var o=Math.floor((e-r)/t),a=Math.floor((n-r)/t);return s.isDark(a,o)?0:1}return 1})},s.createImgTag=function(t,e,n){t=t||2,e=void 0===e?4*t:e;var r=s.getModuleCount()*t+2*e,i="";return i+="<img",i+=' src="',i+=s.createDataURL(t,e),i+='"',i+=' width="',i+=r,i+='"',i+=' height="',i+=r,i+='"',n&&(i+=' alt="',i+=v(n),i+='"'),i+="/>"};var v=function(t){for(var e="",n=0;n<t.length;n+=1){var r=t.charAt(n);switch(r){case"<":e+="&lt;";break;case">":e+="&gt;";break;case"&":e+="&amp;";break;case'"':e+="&quot;";break;default:e+=r}}return e};return s.createASCII=function(t,e){if((t=t||1)<2)return function(t){t=void 0===t?2:t;var e,n,r,i,o,a=1*s.getModuleCount()+2*t,c=t,u=a-t,l={"██":"█","█ ":"▀"," █":"▄"," ":" "},d={"██":"▀","█ ":"▀"," █":" "," ":" "},g="";for(e=0;e<a;e+=2){for(r=Math.floor((e-c)/1),i=Math.floor((e+1-c)/1),n=0;n<a;n+=1)o="█",c<=n&&n<u&&c<=e&&e<u&&s.isDark(r,Math.floor((n-c)/1))&&(o=" "),c<=n&&n<u&&c<=e+1&&e+1<u&&s.isDark(i,Math.floor((n-c)/1))?o+=" ":o+="█",g+=t<1&&e+1>=u?d[o]:l[o];g+="\n"}return a%2&&t>0?g.substring(0,g.length-a-1)+Array(a+1).join("▀"):g.substring(0,g.length-1)}(e);t-=1,e=void 0===e?2*t:e;var n,r,i,o,a=s.getModuleCount()*t+2*e,c=e,u=a-e,l=Array(t+1).join("██"),d=Array(t+1).join(" "),g="",f="";for(n=0;n<a;n+=1){for(i=Math.floor((n-c)/t),f="",r=0;r<a;r+=1)o=1,c<=r&&r<u&&c<=n&&n<u&&s.isDark(i,Math.floor((r-c)/t))&&(o=0),f+=o?l:d;for(i=0;i<t;i+=1)g+=f+"\n"}return g.substring(0,g.length-1)},s.renderTo2dContext=function(t,e){e=e||2;for(var n=s.getModuleCount(),r=0;r<n;r++)for(var i=0;i<n;i++)t.fillStyle=s.isDark(r,i)?"black":"white",t.fillRect(i*e,r*e,e,e)},s};t.stringToBytes=(t.stringToBytesFuncs={default:function(t){for(var e=[],n=0;n<t.length;n+=1){var r=t.charCodeAt(n);e.push(255&r)}return e}}).default,t.createStringToBytes=function(t,e){var n=function(){for(var n=T(t),r=function(){var t=n.read();if(-1==t)throw"eof";return t},i=0,o={};;){var a=n.read();if(-1==a)break;var c=r(),s=r()<<8|r();o[String.fromCharCode(a<<8|c)]=s,i+=1}if(i!=e)throw i+" != "+e;return o}(),r="?".charCodeAt(0);return function(t){for(var e=[],i=0;i<t.length;i+=1){var o=t.charCodeAt(i);if(o<128)e.push(o);else{var a=n[t.charAt(i)];"number"==typeof a?(255&a)==a?e.push(a):(e.push(a>>>8),e.push(255&a)):e.push(r)}}return e}};var e,n,r,i,o,a=1,c=2,s=4,u=8,l={L:1,M:0,Q:3,H:2},d=0,g=1,f=2,h=3,M=4,w=5,y=6,v=7,p=(e=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],n=1335,r=7973,o=function(t){for(var e=0;0!=t;)e+=1,t>>>=1;return e},(i={}).getBCHTypeInfo=function(t){for(var e=t<<10;o(e)-o(n)>=0;)e^=n<<o(e)-o(n);return 21522^(t<<10|e)},i.getBCHTypeNumber=function(t){for(var e=t<<12;o(e)-o(r)>=0;)e^=r<<o(e)-o(r);return t<<12|e},i.getPatternPosition=function(t){return e[t-1]},i.getMaskFunction=function(t){switch(t){case d:return function(t,e){return(t+e)%2==0};case g:return function(t,e){return t%2==0};case f:return function(t,e){return e%3==0};case h:return function(t,e){return(t+e)%3==0};case M:return function(t,e){return(Math.floor(t/2)+Math.floor(e/3))%2==0};case w:return function(t,e){return t*e%2+t*e%3==0};case y:return function(t,e){return(t*e%2+t*e%3)%2==0};case v:return function(t,e){return(t*e%3+(t+e)%2)%2==0};default:throw"bad maskPattern:"+t}},i.getErrorCorrectPolynomial=function(t){for(var e=b([1],0),n=0;n<t;n+=1)e=e.multiply(b([1,L.gexp(n)],0));return e},i.getLengthInBits=function(t,e){if(1<=e&&e<10)switch(t){case a:return 10;case c:return 9;case s:case u:return 8;default:throw"mode:"+t}else if(e<27)switch(t){case a:return 12;case c:return 11;case s:return 16;case u:return 10;default:throw"mode:"+t}else{if(!(e<41))throw"type:"+e;switch(t){case a:return 14;case c:return 13;case s:return 16;case u:return 12;default:throw"mode:"+t}}},i.getLostPoint=function(t){for(var e=t.getModuleCount(),n=0,r=0;r<e;r+=1)for(var i=0;i<e;i+=1){for(var o=0,a=t.isDark(r,i),c=-1;c<=1;c+=1)if(!(r+c<0||e<=r+c))for(var s=-1;s<=1;s+=1)i+s<0||e<=i+s||0==c&&0==s||a==t.isDark(r+c,i+s)&&(o+=1);o>5&&(n+=3+o-5)}for(r=0;r<e-1;r+=1)for(i=0;i<e-1;i+=1){var u=0;t.isDark(r,i)&&(u+=1),t.isDark(r+1,i)&&(u+=1),t.isDark(r,i+1)&&(u+=1),t.isDark(r+1,i+1)&&(u+=1),0!=u&&4!=u||(n+=3)}for(r=0;r<e;r+=1)for(i=0;i<e-6;i+=1)t.isDark(r,i)&&!t.isDark(r,i+1)&&t.isDark(r,i+2)&&t.isDark(r,i+3)&&t.isDark(r,i+4)&&!t.isDark(r,i+5)&&t.isDark(r,i+6)&&(n+=40);for(i=0;i<e;i+=1)for(r=0;r<e-6;r+=1)t.isDark(r,i)&&!t.isDark(r+1,i)&&t.isDark(r+2,i)&&t.isDark(r+3,i)&&t.isDark(r+4,i)&&!t.isDark(r+5,i)&&t.isDark(r+6,i)&&(n+=40);var l=0;for(i=0;i<e;i+=1)for(r=0;r<e;r+=1)t.isDark(r,i)&&(l+=1);return n+=Math.abs(100*l/e/e-50)/5*10},i),L=function(){for(var t=new Array(256),e=new Array(256),n=0;n<8;n+=1)t[n]=1<<n;for(n=8;n<256;n+=1)t[n]=t[n-4]^t[n-5]^t[n-6]^t[n-8];for(n=0;n<255;n+=1)e[t[n]]=n;var r={glog:function(t){if(t<1)throw"glog("+t+")";return e[t]},gexp:function(e){for(;e<0;)e+=255;for(;e>=256;)e-=255;return t[e]}};return r}();function b(t,e){if(void 0===t.length)throw t.length+"/"+e;var n=function(){for(var n=0;n<t.length&&0==t[n];)n+=1;for(var r=new Array(t.length-n+e),i=0;i<t.length-n;i+=1)r[i]=t[i+n];return r}(),r={getAt:function(t){return n[t]},getLength:function(){return n.length},multiply:function(t){for(var e=new Array(r.getLength()+t.getLength()-1),n=0;n<r.getLength();n+=1)for(var i=0;i<t.getLength();i+=1)e[n+i]^=L.gexp(L.glog(r.getAt(n))+L.glog(t.getAt(i)));return b(e,0)},mod:function(t){if(r.getLength()-t.getLength()<0)return r;for(var e=L.glog(r.getAt(0))-L.glog(t.getAt(0)),n=new Array(r.getLength()),i=0;i<r.getLength();i+=1)n[i]=r.getAt(i);for(i=0;i<t.getLength();i+=1)n[i]^=L.gexp(L.glog(t.getAt(i))+e);return b(n,0).mod(t)}};return r}var x=function(){var t=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12,7,37,13],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],e=function(t,e){var n={};return n.totalCount=t,n.dataCount=e,n},n={};return n.getRSBlocks=function(n,r){var i=function(e,n){switch(n){case l.L:return t[4*(e-1)+0];case l.M:return t[4*(e-1)+1];case l.Q:return t[4*(e-1)+2];case l.H:return t[4*(e-1)+3];default:return}}(n,r);if(void 0===i)throw"bad rs block @ typeNumber:"+n+"/errorCorrectionLevel:"+r;for(var o=i.length/3,a=[],c=0;c<o;c+=1)for(var s=i[3*c+0],u=i[3*c+1],d=i[3*c+2],g=0;g<s;g+=1)a.push(e(u,d));return a},n}(),C=function(){var t=[],e=0,n={getBuffer:function(){return t},getAt:function(e){var n=Math.floor(e/8);return 1==(t[n]>>>7-e%8&1)},put:function(t,e){for(var r=0;r<e;r+=1)n.putBit(1==(t>>>e-r-1&1))},getLengthInBits:function(){return e},putBit:function(n){var r=Math.floor(e/8);t.length<=r&&t.push(0),n&&(t[r]|=128>>>e%8),e+=1}};return n},D=function(t){var e=a,n=t,r={getMode:function(){return e},getLength:function(t){return n.length},write:function(t){for(var e=n,r=0;r+2<e.length;)t.put(i(e.substring(r,r+3)),10),r+=3;r<e.length&&(e.length-r==1?t.put(i(e.substring(r,r+1)),4):e.length-r==2&&t.put(i(e.substring(r,r+2)),7))}},i=function(t){for(var e=0,n=0;n<t.length;n+=1)e=10*e+o(t.charAt(n));return e},o=function(t){if("0"<=t&&t<="9")return t.charCodeAt(0)-"0".charCodeAt(0);throw"illegal char :"+t};return r},m=function(t){var e=c,n=t,r={getMode:function(){return e},getLength:function(t){return n.length},write:function(t){for(var e=n,r=0;r+1<e.length;)t.put(45*i(e.charAt(r))+i(e.charAt(r+1)),11),r+=2;r<e.length&&t.put(i(e.charAt(r)),6)}},i=function(t){if("0"<=t&&t<="9")return t.charCodeAt(0)-"0".charCodeAt(0);if("A"<=t&&t<="Z")return t.charCodeAt(0)-"A".charCodeAt(0)+10;switch(t){case" ":return 36;case"$":return 37;case"%":return 38;case"*":return 39;case"+":return 40;case"-":return 41;case".":return 42;case"/":return 43;case":":return 44;default:throw"illegal char :"+t}};return r},j=function(e){var n=s,r=t.stringToBytes(e),i={getMode:function(){return n},getLength:function(t){return r.length},write:function(t){for(var e=0;e<r.length;e+=1)t.put(r[e],8)}};return i},N=function(e){var n=u,r=t.stringToBytesFuncs.SJIS;if(!r)throw"sjis not supported.";!function(){var t=r("友");if(2!=t.length||38726!=(t[0]<<8|t[1]))throw"sjis not supported."}();var i=r(e),o={getMode:function(){return n},getLength:function(t){return~~(i.length/2)},write:function(t){for(var e=i,n=0;n+1<e.length;){var r=(255&e[n])<<8|255&e[n+1];if(33088<=r&&r<=40956)r-=33088;else{if(!(57408<=r&&r<=60351))throw"illegal char at "+(n+1)+"/"+r;r-=49472}r=192*(r>>>8&255)+(255&r),t.put(r,13),n+=2}if(n<e.length)throw"illegal char at "+(n+1)}};return o},I=function(){var t=[],e={writeByte:function(e){t.push(255&e)},writeShort:function(t){e.writeByte(t),e.writeByte(t>>>8)},writeBytes:function(t,n,r){n=n||0,r=r||t.length;for(var i=0;i<r;i+=1)e.writeByte(t[i+n])},writeString:function(t){for(var n=0;n<t.length;n+=1)e.writeByte(t.charCodeAt(n))},toByteArray:function(){return t},toString:function(){var e="";e+="[";for(var n=0;n<t.length;n+=1)n>0&&(e+=","),e+=t[n];return e+="]"}};return e},T=function(t){var e=t,n=0,r=0,i=0,o={read:function(){for(;i<8;){if(n>=e.length){if(0==i)return-1;throw"unexpected end of file./"+i}var t=e.charAt(n);if(n+=1,"="==t)return i=0,-1;t.match(/^\s$/)||(r=r<<6|a(t.charCodeAt(0)),i+=6)}var o=r>>>i-8&255;return i-=8,o}},a=function(t){if(65<=t&&t<=90)return t-65;if(97<=t&&t<=122)return t-97+26;if(48<=t&&t<=57)return t-48+52;if(43==t)return 62;if(47==t)return 63;throw"c:"+t};return o},S=function(t,e,n){for(var r=function(t,e){var n=t,r=e,i=new Array(t*e),o={setPixel:function(t,e,r){i[e*n+t]=r},write:function(t){t.writeString("GIF87a"),t.writeShort(n),t.writeShort(r),t.writeByte(128),t.writeByte(0),t.writeByte(0),t.writeByte(0),t.writeByte(0),t.writeByte(0),t.writeByte(255),t.writeByte(255),t.writeByte(255),t.writeString(","),t.writeShort(0),t.writeShort(0),t.writeShort(n),t.writeShort(r),t.writeByte(0);var e=a(2);t.writeByte(2);for(var i=0;e.length-i>255;)t.writeByte(255),t.writeBytes(e,i,255),i+=255;t.writeByte(e.length-i),t.writeBytes(e,i,e.length-i),t.writeByte(0),t.writeString(";")}},a=function(t){for(var e=1<<t,n=1+(1<<t),r=t+1,o=c(),a=0;a<e;a+=1)o.add(String.fromCharCode(a));o.add(String.fromCharCode(e)),o.add(String.fromCharCode(n));var s,u,l,d=I(),g=(s=d,u=0,l=0,{write:function(t,e){if(t>>>e!=0)throw"length over";for(;u+e>=8;)s.writeByte(255&(t<<u|l)),e-=8-u,t>>>=8-u,l=0,u=0;l|=t<<u,u+=e},flush:function(){u>0&&s.writeByte(l)}});g.write(e,r);var f=0,h=String.fromCharCode(i[f]);for(f+=1;f<i.length;){var M=String.fromCharCode(i[f]);f+=1,o.contains(h+M)?h+=M:(g.write(o.indexOf(h),r),o.size()<4095&&(o.size()==1<<r&&(r+=1),o.add(h+M)),h=M)}return g.write(o.indexOf(h),r),g.write(n,r),g.flush(),d.toByteArray()},c=function(){var t={},e=0,n={add:function(r){if(n.contains(r))throw"dup key:"+r;t[r]=e,e+=1},size:function(){return e},indexOf:function(e){return t[e]},contains:function(e){return void 0!==t[e]}};return n};return o}(t,e),i=0;i<e;i+=1)for(var o=0;o<t;o+=1)r.setPixel(o,i,n(o,i));var a=I();r.write(a);for(var c=function(){var t=0,e=0,n=0,r="",i={},o=function(t){r+=String.fromCharCode(a(63&t))},a=function(t){if(t<0);else{if(t<26)return 65+t;if(t<52)return t-26+97;if(t<62)return t-52+48;if(62==t)return 43;if(63==t)return 47}throw"n:"+t};return i.writeByte=function(r){for(t=t<<8|255&r,e+=8,n+=1;e>=6;)o(t>>>e-6),e-=6},i.flush=function(){if(e>0&&(o(t<<6-e),t=0,e=0),n%3!=0)for(var i=3-n%3,a=0;a<i;a+=1)r+="="},i.toString=function(){return r},i}(),s=a.toByteArray(),u=0;u<s.length;u+=1)c.writeByte(s[u]);return c.flush(),"data:image/gif;base64,"+c};return t}();function clamp(t,e,n){return Math.max(e,Math.min(n,t))}function generateQrSvg(t){const{text:e,size:n=200,ecc:r="H",marginModules:i=3,dark:o="#000000",light:a="#ffffff",logoHref:c,logoSizeRatio:s=.2,logoBgPaddingRatio:u=.01,title:l,alt:d}=t||{};if(!e||"string"!=typeof e)throw new Error("generateQrSvg: 'text' is required");const g=qrcode(0,r);g.addData(e,"Byte"),g.make();const f=g.getModuleCount(),h=Math.max(0,Math.floor(i)),M=n/(f+2*h),w=n,y=`l${M},0 0,${M} -${M},0 0,-${M}z`;let v="";for(let t=0;t<f;t++){const e=t*M+h*M;for(let n=0;n<f;n++)if(g.isDark(t,n)){v+=`M${n*M+h*M},${e}${y}`}}const p={titleId:l?"qrcode-title":null,descId:d?"qrcode-description":null};let L="";if(L+=`<svg xmlns="http://www.w3.org/2000/svg" width="${w}px" height="${w}px" viewBox="0 0 ${w} ${w}" preserveAspectRatio="none"`,l||d){L+=` role="img" aria-labelledby="${[p.titleId,p.descId].filter(Boolean).join(" ")}"`}if(L+=">",l&&(L+=`<title id="${p.titleId}">${escapeXml(l)}</title>`),d&&(L+=`<description id="${p.descId}">${escapeXml(d)}</description>`),L+=`<rect width="100%" height="100%" fill="${a}"/>`,L+=`<path d="${v}" fill="${o}"/>`,c){const t=w*clamp(s,.08,.25),e=w/2,n=w/2;L+=`<circle cx="${e}" cy="${n}" r="${t/2+w*clamp(u,0,.08)}" fill="#ffffff"/>`,L+=`<image href="${c}" x="${e-t/2}" y="${n-t/2}" width="${t}" height="${t}" preserveAspectRatio="xMidYMid meet"/>`}return L+="</svg>",L}function escapeXml(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\"/g,"&quot;")}qrcode.stringToBytesFuncs["UTF-8"]=function(t){return function(t){for(var e=[],n=0;n<t.length;n++){var r=t.charCodeAt(n);r<128?e.push(r):r<2048?e.push(192|r>>6,128|63&r):r<55296||r>=57344?e.push(224|r>>12,128|r>>6&63,128|63&r):(n++,r=65536+((1023&r)<<10|1023&t.charCodeAt(n)),e.push(240|r>>18,128|r>>12&63,128|r>>6&63,128|63&r))}return e}(t)},function(t){"function"==typeof define&&define.amd?define([],t):"object"==typeof exports&&(module.exports=t())}(function(){return qrcode});class BitcoinPay{constructor(){this.version="1.0.13",this.defaultConfig={width:200,height:200,showCopyButton:!0,copyButtonText:"Copy",copiedText:"Copied!",cacheDuration:6e5,qrCodeOptions:{ecc:"H",logo:"btc",bitcoinImage:"data:image/svg+xml;base64,PHN2ZyB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSI2NCIgd2lkdGg9IjY0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+CjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMDA2MzA4NzYsLTAuMDAzMDE5ODQpIj4KPHBhdGggZmlsbD0iI2Y3OTMxYSIgZD0ibTYzLjAzMywzOS43NDRjLTQuMjc0LDE3LjE0My0yMS42MzcsMjcuNTc2LTM4Ljc4MiwyMy4zMDEtMTcuMTM4LTQuMjc0LTI3LjU3MS0yMS42MzgtMjMuMjk1LTM4Ljc4LDQuMjcyLTE3LjE0NSwyMS42MzUtMjcuNTc5LDM4Ljc3NS0yMy4zMDUsMTcuMTQ0LDQuMjc0LDI3LjU3NiwyMS42NCwyMy4zMDIsMzguNzg0eiIvPgo8cGF0aCBmaWxsPSIjRkZGIiBkPSJtNDYuMTAzLDI3LjQ0NGMwLjYzNy00LjI1OC0yLjYwNS02LjU0Ny03LjAzOC04LjA3NGwxLjQzOC01Ljc2OC0zLjUxMS0wLjg3NS0xLjQsNS42MTZjLTAuOTIzLTAuMjMtMS44NzEtMC40NDctMi44MTMtMC42NjJsMS40MS01LjY1My0zLjUwOS0wLjg3NS0xLjQzOSw1Ljc2NmMtMC43NjQtMC4xNzQtMS41MTQtMC4zNDYtMi4yNDItMC41MjdsMC4wMDQtMC4wMTgtNC44NDItMS4yMDktMC45MzQsMy43NXMyLjYwNSwwLjU5NywyLjU1LDAuNjM0YzEuNDIyLDAuMzU1LDEuNjc5LDEuMjk2LDEuNjM2LDIuMDQybC0xLjYzOCw2LjU3MWMwLjA5OCwwLjAyNSwwLjIyNSwwLjA2MSwwLjM2NSwwLjExNy0wLjExNy0wLjAyOS0wLjI0Mi0wLjA2MS0wLjM3MS0wLjA5MmwtMi4yOTYsOS4yMDVjLTAuMTc0LDAuNDMyLTAuNjE1LDEuMDgtMS42MDksMC44MzQsMC4wMzUsMC4wNTEtMi41NTItMC42MzctMi41NTItMC42MzdsLTEuNzQzLDQuMDE5LDQuNTY5LDEuMTM5YzAuODUsMC4yMTMsMS42ODMsMC40MzYsMi41MDMsMC42NDZsLTEuNDUzLDUuODM0LDMuNTA3LDAuODc1LDEuNDM5LTUuNzcyYzAuOTU4LDAuMjYsMS44ODgsMC41LDIuNzk4LDAuNzI2bC0xLjQzNCw1Ljc0NSwzLjUxMSwwLjg3NSwxLjQ1My01LjgyM2M1Ljk4NywxLjEzMywxMC40ODksMC42NzYsMTIuMzg0LTQuNzM5LDEuNTI3LTQuMzYtMC4wNzYtNi44NzUtMy4yMjYtOC41MTUsMi4yOTQtMC41MjksNC4wMjItMi4wMzgsNC40ODMtNS4xNTV6bS04LjAyMiwxMS4yNDljLTEuMDg1LDQuMzYtOC40MjYsMi4wMDMtMTAuODA2LDEuNDEybDEuOTI4LTcuNzI5YzIuMzgsMC41OTQsMTAuMDEyLDEuNzcsOC44NzgsNi4zMTd6bTEuMDg2LTExLjMxMmMtMC45OSwzLjk2Ni03LjEsMS45NTEtOS4wODIsMS40NTdsMS43NDgtNy4wMWMxLjk4MiwwLjQ5NCw4LjM2NSwxLjQxNiw3LjMzNCw1LjU1M3oiLz4KPC9nPgo8L3N2Zz4K",lightningImage:"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjgyIiBoZWlnaHQ9IjI4MiIgdmlld0JveD0iMCAwIDI4MiAyODIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiPgo8Y2lyY2xlIGN4PSIxNDAuOTgzIiBjeT0iMTQxLjAwMyIgcj0iMTQxIiBmaWxsPSIjN0IxQUY3Ii8+CjxwYXRoIGQ9Ik03OS43NjA5IDE0NC4wNDdMMTczLjc2MSA2My4wNDY2QzE3Ny44NTcgNjAuNDIzNSAxODEuNzYxIDYzLjA0NjYgMTc5LjI2MSA2Ny41NDY2TDE0OS4yNjEgMTI2LjU0N0gyMDIuNzYxQzIwMi43NjEgMTI2LjU0NyAyMTEuMjYxIDEyNi41NDcgMjAyLjc2MSAxMzMuNTQ3TDExMC4yNjEgMjE1LjA0N0MxMDMuNzYxIDIyMC41NDcgOTkuMjYxIDIxNy41NDcgMTAzLjc2MSAyMDkuMDQ3TDEzMi43NjEgMTUxLjU0N0g3OS43NjA5Qzc5Ljc2MDkgMTUxLjU0NyA3MS4yNjA5IDE1MS41NDcgNzkuNzYwOSAxNDQuMDQ3WiIgZmlsbD0id2hpdGUiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMCI+CjxyZWN0IHdpZHRoPSIyODIiIGhlaWdodD0iMjgyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="}}}static async render(t){const{endpoint:e,selector:n,bitcoinFallbackAddress:r,bitcoinDonateText:i,lightningAddress:o,lightningDonateText:a,options:c={}}=t;if(!e)throw new Error("BitcoinPay: endpoint is required");if(!r)throw new Error("BitcoinPay: bitcoinFallbackAddress is required");if(!n)throw new Error("BitcoinPay: selector is required");const s=document.querySelectorAll(n);if(0===s.length)throw new Error(`BitcoinPay: no elements found matching "${n}"`);const u=new BitcoinPay,l={...u.defaultConfig,...c},d=btoa(unescape(encodeURIComponent(e))).replace(/[^a-zA-Z0-9]/g,""),g=`btc-address-${d}`,f=`btc-timestamp-${d}`;let h;try{h=await u.getBitcoinAddress(e,g,f,l,r)}catch(t){const e='<div style="color: red; padding: 10px; border: 1px solid red; border-radius: 4px;">\n Failed to load Bitcoin payment widget. Please check your configuration.\n </div>';throw s.forEach(t=>{t.innerHTML=e}),t}const M=Array.from(s).map(t=>u.renderToElement(t,h,o,i,a,l));return await Promise.allSettled(M)}async renderToElement(t,e,n,r,i,o){const a=this.generateInstanceId();try{const c=n?this.createDualWidgetHTML(e,n,r,i,o,a):this.createSingleWidgetHTML(e,r,o,a);return t.innerHTML=c,n?await this.initializeDualWidget(e,n,o,a):await this.initializeSingleWidget(e,o,a),{success:!0,element:t}}catch(e){throw t.innerHTML='<div style="color: red; padding: 10px; border: 1px solid red; border-radius: 4px;">\n Failed to load Bitcoin payment widget. Please check your configuration.\n </div>',e}}isLocalStorageAvailable(){try{return localStorage.setItem("test","test"),localStorage.removeItem("test"),!0}catch{return!1}}async copyToClipboard(t){if(navigator.clipboard&&navigator.clipboard.writeText)try{return await navigator.clipboard.writeText(t),!0}catch{}const e=document.createElement("textarea");e.value=t,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.select();try{return document.execCommand("copy")}catch{return!1}finally{document.body.removeChild(e)}}async getBitcoinAddress(t,e,n,r,i){const o=Math.max(0,Math.min(r.cacheDuration,6048e5));if(this.isLocalStorageAvailable()){const t=localStorage.getItem(e),r=localStorage.getItem(n);if(t&&r){const e=parseInt(r);if(Date.now()-e<o)return t}}try{const r=await fetch(t);if(!r.ok)throw new Error(`HTTP ${r.status}: ${r.statusText}`);const i=await r.json();if(!i.address)throw new Error("Invalid response: no address field");return this.isLocalStorageAvailable()&&(localStorage.setItem(e,i.address),localStorage.setItem(n,Date.now().toString())),i.address}catch(t){if(i)return i;throw new Error(`Failed to fetch Bitcoin address: ${t.message}`)}}createSingleWidgetHTML(t,e,n,r){const i=`btc-btn-${r}`;return`\n <div class="bitcoin-pay-widget">\n <div class="widget-layout">\n <a href="bitcoin:${t}" class="qr-container" aria-label="Open in Bitcoin wallet">\n <div id="${`btc-qr-${r}`}" class="qr-code"></div>\n </a>\n <div class="content-area">\n <p class="description">\n ${e||'<span class="prefix-desktop">Scan with</span>\n <span class="prefix-touch">Tap to open</span>\n your Bitcoin wallet, or copy the on-chain address below.'}\n </p>\n <div class="address-container">\n <div class="address-text">\n <span>${t}</span>\n </div>\n ${n.showCopyButton?`<button id="${i}" class="copy-btn">${n.copyButtonText}</button>`:""}\n </div>\n </div>\n </div>\n </div>\n `}createDualWidgetHTML(t,e,n,r,i,o){const a=`lightning-qr-${o}`,c=`btc-btn-${o}`,s=`lightning-btn-${o}`,u=r||'<span class="prefix-desktop">Scan with</span>\n <span class="prefix-touch">Tap to open</span>\n your Lightning wallet, or copy my Lightning address below.';return`\n <div class="bitcoin-pay-widget has-tabs">\n <div class="widget-content">\n \x3c!-- Tab Navigation --\x3e\n <div class="tab-navigation">\n <button id="bitcoin-tab-${o}" class="tab-btn active" data-tab="bitcoin">\n <svg width="20" height="20" viewBox="0 0 64 64" fill="currentColor">\n <g transform="translate(0.00630876,-0.00301984)">\n <path d="m63.033,39.744c-4.274,17.143-21.637,27.576-38.782,23.301-17.138-4.274-27.571-21.638-23.295-38.78,4.272-17.145,21.635-27.579,38.775-23.305,17.144,4.274,27.576,21.64,23.302,38.784z"/>\n <path fill="#FFF" d="m46.103,27.444c0.637-4.258-2.605-6.547-7.038-8.074l1.438-5.768-3.511-0.875-1.4,5.616c-0.923-0.23-1.871-0.447-2.813-0.662l1.41-5.653-3.509-0.875-1.439,5.766c-0.764-0.174-1.514-0.346-2.242-0.527l0.004-0.018-4.842-1.209-0.934,3.75s2.605,0.597,2.55,0.634c1.422,0.355,1.679,1.296,1.636,2.042l-1.638,6.571c0.098,0.025,0.225,0.061,0.365,0.117-0.117-0.029-0.242-0.061-0.371-0.092l-2.296,9.205c-0.174,0.432-0.615,1.08-1.609,0.834,0.035,0.051-2.552-0.637-2.552-0.637l-1.743,4.019,4.569,1.139c0.85,0.213,1.683,0.436,2.503,0.646l-1.453,5.834,3.507,0.875,1.439-5.772c0.958,0.26,1.888,0.5,2.798,0.726l-1.434,5.745,3.511,0.875,1.453-5.823c5.987,1.133,10.489,0.676,12.384-4.739,1.527-4.36-0.076-6.875-3.226-8.515,2.294-0.529,4.022-2.038,4.483-5.155zm-8.022,11.249c-1.085,4.36-8.426,2.003-10.806,1.412l1.928-7.729c2.38,0.594,10.012,1.77,8.878,6.317zm1.086-11.312c-0.990,3.966-7.1,1.951-9.082,1.457l1.748-7.01c1.982,0.494,8.365,1.416,7.334,5.553z"/>\n </g>\n </svg>\n Bitcoin\n </button>\n <button id="lightning-tab-${o}" class="tab-btn" data-tab="lightning">\n <svg width="20" height="20" viewBox="0 0 282 282" fill="currentColor">\n <g clip-path="url(#clip0)">\n <circle cx="140.983" cy="141.003" r="141" />\n <path d="M79.7609 144.047L173.761 63.0466C177.857 60.4235 181.761 63.0466 179.261 67.5466L149.261 126.547H202.761C202.761 126.547 211.261 126.547 202.761 133.547L110.261 215.047C103.761 220.547 99.261 217.547 103.761 209.047L132.761 151.547H79.7609C79.7609 151.547 71.2609 151.547 79.7609 144.047Z" fill="white"/>\n </g>\n <defs>\n <clipPath id="clip0">\n <rect width="282" height="282" fill="white"/>\n </clipPath>\n </defs>\n </svg>\n Lightning\n </button>\n </div>\n\n \x3c!-- Bitcoin Tab Content --\x3e\n <div id="bitcoin-content-${o}" class="tab-content active" data-tab="bitcoin">\n <div class="widget-layout">\n <a href="bitcoin:${t}" class="qr-container" aria-label="Open in Bitcoin wallet">\n <div id="${`btc-qr-${o}`}" class="qr-code"></div>\n </a>\n <div class="content-area">\n <p class="description">\n ${n||'<span class="prefix-desktop">Scan with</span>\n <span class="prefix-touch">Tap to open</span>\n your Bitcoin wallet, or copy the on-chain address below.'}\n </p>\n <div class="address-container">\n <div class="address-text">\n <span>${t}</span>\n </div>\n ${i.showCopyButton?`<button id="${c}" class="copy-btn">${i.copyButtonText}</button>`:""}\n </div>\n </div>\n </div>\n </div>\n\n \x3c!-- Lightning Tab Content --\x3e\n <div id="lightning-content-${o}" class="tab-content" data-tab="lightning">\n <div class="widget-layout">\n <a href="lightning:${e}" class="qr-container" aria-label="Open in Lightning wallet">\n <div id="${a}" class="qr-code"></div>\n </a>\n <div class="content-area">\n <p class="description">\n ${u}\n </p>\n <div class="address-container">\n <div class="address-text">\n <span>${e}</span>\n </div>\n ${i.showCopyButton?`<button id="${s}" class="copy-btn">Copy</button>`:""}\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n `}async initializeSingleWidget(t,e,n){const r=`btc-qr-${n}`,i=`btc-btn-${n}`,o=document.getElementById(r);if(o){const n="btc"===e.qrCodeOptions.logo?this.defaultConfig.qrCodeOptions.bitcoinImage:void 0,r=generateQrSvg({text:`bitcoin:${t}`,size:e.width,logoHref:n,alt:"Bitcoin address QR"});o.innerHTML=r}if(e.showCopyButton){const n=document.getElementById(i);n&&n.addEventListener("click",async()=>{const r=await this.copyToClipboard(t),i=n.textContent;n.textContent=r?e.copiedText:"Failed to copy",setTimeout(()=>{n.textContent=i},2e3)})}}async initializeDualWidget(t,e,n,r){const i=`btc-qr-${r}`,o=`lightning-qr-${r}`,a=`btc-btn-${r}`,c=`lightning-btn-${r}`,s=document.getElementById(i);if(s){const e=generateQrSvg({text:`bitcoin:${t}`,size:n.width,logoHref:this.defaultConfig.qrCodeOptions.bitcoinImage,alt:"Bitcoin address QR"});s.innerHTML=e}const u=document.getElementById(o);if(u){const t=generateQrSvg({text:`lightning:${e}`,size:n.width,logoHref:this.defaultConfig.qrCodeOptions.lightningImage,alt:"Lightning address QR"});u.innerHTML=t}if(this.setupTabs(r),n.showCopyButton){const r=document.getElementById(a);r&&r.addEventListener("click",async()=>{const e=await this.copyToClipboard(t),i=r.textContent;r.textContent=e?n.copiedText:"Failed to copy",setTimeout(()=>{r.textContent=i},2e3)});const i=document.getElementById(c);i&&i.addEventListener("click",async()=>{const t=await this.copyToClipboard(e),r=i.textContent;i.textContent=t?n.copiedText:"Failed to copy",setTimeout(()=>{i.textContent=r},2e3)})}}setupTabs(t){const e=document.querySelectorAll(`.tab-btn[id$="-${t}"]`),n=document.querySelectorAll(`.tab-content[id$="-${t}"]`);e.forEach(t=>{t.addEventListener("click",()=>{const r=t.getAttribute("data-tab");e.forEach(t=>{t.classList.remove("active")}),t.classList.add("active"),n.forEach(t=>{t.classList.remove("active"),t.getAttribute("data-tab")===r&&t.classList.add("active")})})})}generateInstanceId(){return Math.random().toString(36).substr(2,9)}}"undefined"!=typeof window&&(window.BitcoinPay=BitcoinPay);export{BitcoinPay};export default BitcoinPay;
@@ -0,0 +1 @@
1
+ :where(.bitcoin-pay-widget){--btc-pay-primary:#f7931a;--btc-pay-primary-hover:#e8830a;--btc-pay-text-primary:#333;--btc-pay-text-secondary:#666;--btc-pay-border:#999;--btc-pay-background:#f5f5f5;--btc-pay-surface:#fff;--btc-pay-spacing-xs:8px;--btc-pay-spacing-sm:12px;--btc-pay-spacing-md:16px;--btc-pay-spacing-lg:20px;--btc-pay-font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;--btc-pay-font-size-base:14px;--btc-pay-font-size-sm:12px;--btc-pay-font-weight-medium:500;--btc-pay-line-height:1.4;--btc-pay-max-width:500px;--btc-pay-border-radius:8px;--btc-pay-border-radius-sm:6px;--btc-pay-border-width:1px;--btc-pay-border-width-accent:2px;--btc-pay-address-max-width:400px;--btc-pay-address-width:170px;--btc-pay-button-width:72px;--btc-pay-content-max-width:300px;--btc-pay-transition-speed:0.2s}.bitcoin-pay-widget{border-bottom:var(--btc-pay-border-width) solid var(--btc-pay-border);font-family:var(--btc-pay-font-family);margin:var(--btc-pay-spacing-md) auto;max-width:var(--btc-pay-max-width)}.bitcoin-pay-widget:not(.has-tabs){border-top:var(--btc-pay-border-width) solid var(--btc-pay-border);padding-top:var(--btc-pay-spacing-md)}.bitcoin-pay-widget .tab-navigation,.bitcoin-pay-widget .widget-content{margin-bottom:var(--btc-pay-spacing-md)}.bitcoin-pay-widget .tab-navigation{border-bottom:var(--btc-pay-border-width) solid var(--btc-pay-border);display:flex}.bitcoin-pay-widget .tab-btn{align-items:center;background:none;border:none;border-bottom:var(--btc-pay-border-width-accent) solid transparent;color:var(--btc-pay-text-secondary);cursor:pointer;display:flex;flex:1;font-size:var(--btc-pay-font-size-base);font-weight:var(--btc-pay-font-weight-medium);gap:var(--btc-pay-spacing-xs);justify-content:center;padding:var(--btc-pay-spacing-xs) var(--btc-pay-spacing-md);transition:all var(--btc-pay-transition-speed)}.bitcoin-pay-widget .tab-btn svg{display:inline-block;fill:var(--btc-pay-text-secondary);flex-shrink:0;height:20px;width:20px}.bitcoin-pay-widget .tab-btn.active{border-bottom:var(--btc-pay-border-width-accent) solid var(--btc-pay-primary);color:var(--btc-pay-primary)}.bitcoin-pay-widget .tab-btn.active svg{fill:var(--btc-pay-primary);transition:fill var(--btc-pay-transition-speed)}.bitcoin-pay-widget .tab-btn:hover{color:var(--btc-pay-primary)}.bitcoin-pay-widget .tab-btn:hover svg{fill:var(--btc-pay-primary);transition:fill var(--btc-pay-transition-speed)}.bitcoin-pay-widget .tab-content{display:none}.bitcoin-pay-widget .tab-content.active{display:block}.bitcoin-pay-widget .widget-layout{align-items:center;display:flex;flex-direction:column;gap:0;justify-content:center;margin-bottom:var(--btc-pay-spacing-md)}.bitcoin-pay-widget .qr-container{cursor:pointer;display:block;margin-bottom:var(--btc-pay-spacing-md);position:relative;text-decoration:none}.bitcoin-pay-widget .qr-code svg{display:block;height:200px;height:auto;max-width:100%;width:200px}.bitcoin-pay-widget .content-area{display:flex;flex-direction:column;width:100%}.bitcoin-pay-widget .description{color:var(--btc-pay-text-primary);font-size:var(--btc-pay-font-size-base);margin:0 0 10px;text-align:center;width:100%}.bitcoin-pay-widget .description .prefix-touch{display:none}@media (hover:none) and (pointer:coarse){.bitcoin-pay-widget .description .prefix-desktop{display:none}.bitcoin-pay-widget .description .prefix-touch{display:inline}}.bitcoin-pay-widget .address-container{align-items:center;background:var(--btc-pay-background);border:var(--btc-pay-border-width) solid var(--btc-pay-border);border-radius:var(--btc-pay-border-radius);display:flex;justify-content:space-between;margin:0 auto;max-width:var(--btc-pay-address-max-width);padding:var(--btc-pay-spacing-sm) var(--btc-pay-spacing-md)}.bitcoin-pay-widget .address-text{flex:1;max-width:var(--btc-pay-address-width);min-width:var(--btc-pay-address-width)}.bitcoin-pay-widget .address-text span{color:var(--btc-pay-text-secondary);display:block;font-size:var(--btc-pay-font-size-base);line-height:var(--btc-pay-line-height);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-break:break-all}.bitcoin-pay-widget .copy-btn{background:var(--btc-pay-primary);border:none;border-radius:var(--btc-pay-border-radius-sm);color:var(--btc-pay-surface);cursor:pointer;flex-shrink:0;font-size:var(--btc-pay-font-size-sm);font-weight:var(--btc-pay-font-weight-medium);margin-left:var(--btc-pay-spacing-sm);padding:6px var(--btc-pay-spacing-sm);transition:background-color var(--btc-pay-transition-speed);white-space:nowrap;width:var(--btc-pay-button-width)}.bitcoin-pay-widget .copy-btn:hover{background:var(--btc-pay-primary-hover)}.bitcoin-pay-widget .copy-btn:disabled{cursor:not-allowed;opacity:.5}@media (min-width:640px){.bitcoin-pay-widget .widget-layout{align-items:center;flex-direction:row;gap:var(--btc-pay-spacing-lg)}.bitcoin-pay-widget .qr-container{flex-shrink:0;margin-bottom:0}.bitcoin-pay-widget .content-area{flex:1;max-width:var(--btc-pay-content-max-width)}.bitcoin-pay-widget .description{text-align:left}.bitcoin-pay-widget .address-container{margin:0;max-width:fit-content}}@media (prefers-color-scheme:dark){:where(.bitcoin-pay-widget){--btc-pay-primary:#f7931a;--btc-pay-primary-hover:#ffad33;--btc-pay-text-primary:#e0e0e0;--btc-pay-text-secondary:#a0a0a0;--btc-pay-border:#444;--btc-pay-background:#2a2a2a;--btc-pay-surface:#fff}}html[data-theme=dark] :where(.bitcoin-pay-widget){--btc-pay-primary:#f7931a;--btc-pay-primary-hover:#ffad33;--btc-pay-text-primary:#e0e0e0;--btc-pay-text-secondary:#a0a0a0;--btc-pay-border:#444;--btc-pay-background:#2a2a2a;--btc-pay-surface:#fff}html.dark :where(.bitcoin-pay-widget){--btc-pay-primary:#f7931a;--btc-pay-primary-hover:#ffad33;--btc-pay-text-primary:#e0e0e0;--btc-pay-text-secondary:#a0a0a0;--btc-pay-border:#444;--btc-pay-background:#2a2a2a;--btc-pay-surface:#fff}
@@ -0,0 +1 @@
1
+ var qrcode=function(){var t=function(t,e){var n=t,r=l[e],i=null,o=0,a=null,c=[],s={},u=function(t,e){i=function(t){for(var e=new Array(t),n=0;n<t;n+=1){e[n]=new Array(t);for(var r=0;r<t;r+=1)e[n][r]=null}return e}(o=4*n+17),d(0,0),d(o-7,0),d(0,o-7),f(),g(),M(t,e),n>=7&&h(t),null==a&&(a=y(n,r,c)),w(a,e)},d=function(t,e){for(var n=-1;n<=7;n+=1)if(!(t+n<=-1||o<=t+n))for(var r=-1;r<=7;r+=1)e+r<=-1||o<=e+r||(i[t+n][e+r]=0<=n&&n<=6&&(0==r||6==r)||0<=r&&r<=6&&(0==n||6==n)||2<=n&&n<=4&&2<=r&&r<=4)},g=function(){for(var t=8;t<o-8;t+=1)null==i[t][6]&&(i[t][6]=t%2==0);for(var e=8;e<o-8;e+=1)null==i[6][e]&&(i[6][e]=e%2==0)},f=function(){for(var t=p.getPatternPosition(n),e=0;e<t.length;e+=1)for(var r=0;r<t.length;r+=1){var o=t[e],a=t[r];if(null==i[o][a])for(var c=-2;c<=2;c+=1)for(var s=-2;s<=2;s+=1)i[o+c][a+s]=-2==c||2==c||-2==s||2==s||0==c&&0==s}},h=function(t){for(var e=p.getBCHTypeNumber(n),r=0;r<18;r+=1){var a=!t&&1==(e>>r&1);i[Math.floor(r/3)][r%3+o-8-3]=a}for(r=0;r<18;r+=1){a=!t&&1==(e>>r&1);i[r%3+o-8-3][Math.floor(r/3)]=a}},M=function(t,e){for(var n=r<<3|e,a=p.getBCHTypeInfo(n),c=0;c<15;c+=1){var s=!t&&1==(a>>c&1);c<6?i[c][8]=s:c<8?i[c+1][8]=s:i[o-15+c][8]=s}for(c=0;c<15;c+=1){s=!t&&1==(a>>c&1);c<8?i[8][o-c-1]=s:c<9?i[8][15-c-1+1]=s:i[8][15-c-1]=s}i[o-8][8]=!t},w=function(t,e){for(var n=-1,r=o-1,a=7,c=0,s=p.getMaskFunction(e),u=o-1;u>0;u-=2)for(6==u&&(u-=1);;){for(var l=0;l<2;l+=1)if(null==i[r][u-l]){var d=!1;c<t.length&&(d=1==(t[c]>>>a&1)),s(r,u-l)&&(d=!d),i[r][u-l]=d,-1==(a-=1)&&(c+=1,a=7)}if((r+=n)<0||o<=r){r-=n,n=-n;break}}},y=function(t,e,n){for(var r=C.getRSBlocks(t,e),i=x(),o=0;o<n.length;o+=1){var a=n[o];i.put(a.getMode(),4),i.put(a.getLength(),p.getLengthInBits(a.getMode(),t)),a.write(i)}var c=0;for(o=0;o<r.length;o+=1)c+=r[o].dataCount;if(i.getLengthInBits()>8*c)throw"code length overflow. ("+i.getLengthInBits()+">"+8*c+")";for(i.getLengthInBits()+4<=8*c&&i.put(0,4);i.getLengthInBits()%8!=0;)i.putBit(!1);for(;!(i.getLengthInBits()>=8*c||(i.put(236,8),i.getLengthInBits()>=8*c));)i.put(17,8);return function(t,e){for(var n=0,r=0,i=0,o=new Array(e.length),a=new Array(e.length),c=0;c<e.length;c+=1){var s=e[c].dataCount,u=e[c].totalCount-s;r=Math.max(r,s),i=Math.max(i,u),o[c]=new Array(s);for(var l=0;l<o[c].length;l+=1)o[c][l]=255&t.getBuffer()[l+n];n+=s;var d=p.getErrorCorrectPolynomial(u),g=b(o[c],d.getLength()-1).mod(d);for(a[c]=new Array(d.getLength()-1),l=0;l<a[c].length;l+=1){var f=l+g.getLength()-a[c].length;a[c][l]=f>=0?g.getAt(f):0}}var h=0;for(l=0;l<e.length;l+=1)h+=e[l].totalCount;var M=new Array(h),w=0;for(l=0;l<r;l+=1)for(c=0;c<e.length;c+=1)l<o[c].length&&(M[w]=o[c][l],w+=1);for(l=0;l<i;l+=1)for(c=0;c<e.length;c+=1)l<a[c].length&&(M[w]=a[c][l],w+=1);return M}(i,r)};s.addData=function(t,e){var n=null;switch(e=e||"Byte"){case"Numeric":n=D(t);break;case"Alphanumeric":n=m(t);break;case"Byte":n=j(t);break;case"Kanji":n=N(t);break;default:throw"mode:"+e}c.push(n),a=null},s.isDark=function(t,e){if(t<0||o<=t||e<0||o<=e)throw t+","+e;return i[t][e]},s.getModuleCount=function(){return o},s.make=function(){if(n<1){for(var t=1;t<40;t++){for(var e=C.getRSBlocks(t,r),i=x(),o=0;o<c.length;o++){var a=c[o];i.put(a.getMode(),4),i.put(a.getLength(),p.getLengthInBits(a.getMode(),t)),a.write(i)}var l=0;for(o=0;o<e.length;o++)l+=e[o].dataCount;if(i.getLengthInBits()<=8*l)break}n=t}u(!1,function(){for(var t=0,e=0,n=0;n<8;n+=1){u(!0,n);var r=p.getLostPoint(s);(0==n||t>r)&&(t=r,e=n)}return e}())},s.createTableTag=function(t,e){t=t||2;var n="";n+='<table style="',n+=" border-width: 0px; border-style: none;",n+=" border-collapse: collapse;",n+=" padding: 0px; margin: "+(e=void 0===e?4*t:e)+"px;",n+='">',n+="<tbody>";for(var r=0;r<s.getModuleCount();r+=1){n+="<tr>";for(var i=0;i<s.getModuleCount();i+=1)n+='<td style="',n+=" border-width: 0px; border-style: none;",n+=" border-collapse: collapse;",n+=" padding: 0px; margin: 0px;",n+=" width: "+t+"px;",n+=" height: "+t+"px;",n+=" background-color: ",n+=s.isDark(r,i)?"#000000":"#ffffff",n+=";",n+='"/>';n+="</tr>"}return n+="</tbody>",n+="</table>"},s.createSvgTag=function(t,e,n,r){var i={};"object"==typeof arguments[0]&&(t=(i=arguments[0]).cellSize,e=i.margin,n=i.alt,r=i.title),t=t||2,e=void 0===e?4*t:e,(n="string"==typeof n?{text:n}:n||{}).text=n.text||null,n.id=n.text?n.id||"qrcode-description":null,(r="string"==typeof r?{text:r}:r||{}).text=r.text||null,r.id=r.text?r.id||"qrcode-title":null;var o,a,c,u,l=s.getModuleCount()*t+2*e,d="";for(u="l"+t+",0 0,"+t+" -"+t+",0 0,-"+t+"z ",d+='<svg version="1.1" xmlns="http://www.w3.org/2000/svg"',d+=i.scalable?"":' width="'+l+'px" height="'+l+'px"',d+=' viewBox="0 0 '+l+" "+l+'" ',d+=' preserveAspectRatio="xMinYMin meet"',d+=r.text||n.text?' role="img" aria-labelledby="'+v([r.id,n.id].join(" ").trim())+'"':"",d+=">",d+=r.text?'<title id="'+v(r.id)+'">'+v(r.text)+"</title>":"",d+=n.text?'<description id="'+v(n.id)+'">'+v(n.text)+"</description>":"",d+='<rect width="100%" height="100%" fill="white" cx="0" cy="0"/>',d+='<path d="',a=0;a<s.getModuleCount();a+=1)for(c=a*t+e,o=0;o<s.getModuleCount();o+=1)s.isDark(a,o)&&(d+="M"+(o*t+e)+","+c+u);return d+='" stroke="transparent" fill="black"/>',d+="</svg>"},s.createDataURL=function(t,e){t=t||2,e=void 0===e?4*t:e;var n=s.getModuleCount()*t+2*e,r=e,i=n-e;return S(n,n,function(e,n){if(r<=e&&e<i&&r<=n&&n<i){var o=Math.floor((e-r)/t),a=Math.floor((n-r)/t);return s.isDark(a,o)?0:1}return 1})},s.createImgTag=function(t,e,n){t=t||2,e=void 0===e?4*t:e;var r=s.getModuleCount()*t+2*e,i="";return i+="<img",i+=' src="',i+=s.createDataURL(t,e),i+='"',i+=' width="',i+=r,i+='"',i+=' height="',i+=r,i+='"',n&&(i+=' alt="',i+=v(n),i+='"'),i+="/>"};var v=function(t){for(var e="",n=0;n<t.length;n+=1){var r=t.charAt(n);switch(r){case"<":e+="&lt;";break;case">":e+="&gt;";break;case"&":e+="&amp;";break;case'"':e+="&quot;";break;default:e+=r}}return e};return s.createASCII=function(t,e){if((t=t||1)<2)return function(t){t=void 0===t?2:t;var e,n,r,i,o,a=1*s.getModuleCount()+2*t,c=t,u=a-t,l={"██":"█","█ ":"▀"," █":"▄"," ":" "},d={"██":"▀","█ ":"▀"," █":" "," ":" "},g="";for(e=0;e<a;e+=2){for(r=Math.floor((e-c)/1),i=Math.floor((e+1-c)/1),n=0;n<a;n+=1)o="█",c<=n&&n<u&&c<=e&&e<u&&s.isDark(r,Math.floor((n-c)/1))&&(o=" "),c<=n&&n<u&&c<=e+1&&e+1<u&&s.isDark(i,Math.floor((n-c)/1))?o+=" ":o+="█",g+=t<1&&e+1>=u?d[o]:l[o];g+="\n"}return a%2&&t>0?g.substring(0,g.length-a-1)+Array(a+1).join("▀"):g.substring(0,g.length-1)}(e);t-=1,e=void 0===e?2*t:e;var n,r,i,o,a=s.getModuleCount()*t+2*e,c=e,u=a-e,l=Array(t+1).join("██"),d=Array(t+1).join(" "),g="",f="";for(n=0;n<a;n+=1){for(i=Math.floor((n-c)/t),f="",r=0;r<a;r+=1)o=1,c<=r&&r<u&&c<=n&&n<u&&s.isDark(i,Math.floor((r-c)/t))&&(o=0),f+=o?l:d;for(i=0;i<t;i+=1)g+=f+"\n"}return g.substring(0,g.length-1)},s.renderTo2dContext=function(t,e){e=e||2;for(var n=s.getModuleCount(),r=0;r<n;r++)for(var i=0;i<n;i++)t.fillStyle=s.isDark(r,i)?"black":"white",t.fillRect(i*e,r*e,e,e)},s};t.stringToBytes=(t.stringToBytesFuncs={default:function(t){for(var e=[],n=0;n<t.length;n+=1){var r=t.charCodeAt(n);e.push(255&r)}return e}}).default,t.createStringToBytes=function(t,e){var n=function(){for(var n=T(t),r=function(){var t=n.read();if(-1==t)throw"eof";return t},i=0,o={};;){var a=n.read();if(-1==a)break;var c=r(),s=r()<<8|r();o[String.fromCharCode(a<<8|c)]=s,i+=1}if(i!=e)throw i+" != "+e;return o}(),r="?".charCodeAt(0);return function(t){for(var e=[],i=0;i<t.length;i+=1){var o=t.charCodeAt(i);if(o<128)e.push(o);else{var a=n[t.charAt(i)];"number"==typeof a?(255&a)==a?e.push(a):(e.push(a>>>8),e.push(255&a)):e.push(r)}}return e}};var e,n,r,i,o,a=1,c=2,s=4,u=8,l={L:1,M:0,Q:3,H:2},d=0,g=1,f=2,h=3,M=4,w=5,y=6,v=7,p=(e=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],n=1335,r=7973,o=function(t){for(var e=0;0!=t;)e+=1,t>>>=1;return e},(i={}).getBCHTypeInfo=function(t){for(var e=t<<10;o(e)-o(n)>=0;)e^=n<<o(e)-o(n);return 21522^(t<<10|e)},i.getBCHTypeNumber=function(t){for(var e=t<<12;o(e)-o(r)>=0;)e^=r<<o(e)-o(r);return t<<12|e},i.getPatternPosition=function(t){return e[t-1]},i.getMaskFunction=function(t){switch(t){case d:return function(t,e){return(t+e)%2==0};case g:return function(t,e){return t%2==0};case f:return function(t,e){return e%3==0};case h:return function(t,e){return(t+e)%3==0};case M:return function(t,e){return(Math.floor(t/2)+Math.floor(e/3))%2==0};case w:return function(t,e){return t*e%2+t*e%3==0};case y:return function(t,e){return(t*e%2+t*e%3)%2==0};case v:return function(t,e){return(t*e%3+(t+e)%2)%2==0};default:throw"bad maskPattern:"+t}},i.getErrorCorrectPolynomial=function(t){for(var e=b([1],0),n=0;n<t;n+=1)e=e.multiply(b([1,L.gexp(n)],0));return e},i.getLengthInBits=function(t,e){if(1<=e&&e<10)switch(t){case a:return 10;case c:return 9;case s:case u:return 8;default:throw"mode:"+t}else if(e<27)switch(t){case a:return 12;case c:return 11;case s:return 16;case u:return 10;default:throw"mode:"+t}else{if(!(e<41))throw"type:"+e;switch(t){case a:return 14;case c:return 13;case s:return 16;case u:return 12;default:throw"mode:"+t}}},i.getLostPoint=function(t){for(var e=t.getModuleCount(),n=0,r=0;r<e;r+=1)for(var i=0;i<e;i+=1){for(var o=0,a=t.isDark(r,i),c=-1;c<=1;c+=1)if(!(r+c<0||e<=r+c))for(var s=-1;s<=1;s+=1)i+s<0||e<=i+s||0==c&&0==s||a==t.isDark(r+c,i+s)&&(o+=1);o>5&&(n+=3+o-5)}for(r=0;r<e-1;r+=1)for(i=0;i<e-1;i+=1){var u=0;t.isDark(r,i)&&(u+=1),t.isDark(r+1,i)&&(u+=1),t.isDark(r,i+1)&&(u+=1),t.isDark(r+1,i+1)&&(u+=1),0!=u&&4!=u||(n+=3)}for(r=0;r<e;r+=1)for(i=0;i<e-6;i+=1)t.isDark(r,i)&&!t.isDark(r,i+1)&&t.isDark(r,i+2)&&t.isDark(r,i+3)&&t.isDark(r,i+4)&&!t.isDark(r,i+5)&&t.isDark(r,i+6)&&(n+=40);for(i=0;i<e;i+=1)for(r=0;r<e-6;r+=1)t.isDark(r,i)&&!t.isDark(r+1,i)&&t.isDark(r+2,i)&&t.isDark(r+3,i)&&t.isDark(r+4,i)&&!t.isDark(r+5,i)&&t.isDark(r+6,i)&&(n+=40);var l=0;for(i=0;i<e;i+=1)for(r=0;r<e;r+=1)t.isDark(r,i)&&(l+=1);return n+=Math.abs(100*l/e/e-50)/5*10},i),L=function(){for(var t=new Array(256),e=new Array(256),n=0;n<8;n+=1)t[n]=1<<n;for(n=8;n<256;n+=1)t[n]=t[n-4]^t[n-5]^t[n-6]^t[n-8];for(n=0;n<255;n+=1)e[t[n]]=n;var r={glog:function(t){if(t<1)throw"glog("+t+")";return e[t]},gexp:function(e){for(;e<0;)e+=255;for(;e>=256;)e-=255;return t[e]}};return r}();function b(t,e){if(void 0===t.length)throw t.length+"/"+e;var n=function(){for(var n=0;n<t.length&&0==t[n];)n+=1;for(var r=new Array(t.length-n+e),i=0;i<t.length-n;i+=1)r[i]=t[i+n];return r}(),r={getAt:function(t){return n[t]},getLength:function(){return n.length},multiply:function(t){for(var e=new Array(r.getLength()+t.getLength()-1),n=0;n<r.getLength();n+=1)for(var i=0;i<t.getLength();i+=1)e[n+i]^=L.gexp(L.glog(r.getAt(n))+L.glog(t.getAt(i)));return b(e,0)},mod:function(t){if(r.getLength()-t.getLength()<0)return r;for(var e=L.glog(r.getAt(0))-L.glog(t.getAt(0)),n=new Array(r.getLength()),i=0;i<r.getLength();i+=1)n[i]=r.getAt(i);for(i=0;i<t.getLength();i+=1)n[i]^=L.gexp(L.glog(t.getAt(i))+e);return b(n,0).mod(t)}};return r}var C=function(){var t=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12,7,37,13],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],e=function(t,e){var n={};return n.totalCount=t,n.dataCount=e,n},n={};return n.getRSBlocks=function(n,r){var i=function(e,n){switch(n){case l.L:return t[4*(e-1)+0];case l.M:return t[4*(e-1)+1];case l.Q:return t[4*(e-1)+2];case l.H:return t[4*(e-1)+3];default:return}}(n,r);if(void 0===i)throw"bad rs block @ typeNumber:"+n+"/errorCorrectionLevel:"+r;for(var o=i.length/3,a=[],c=0;c<o;c+=1)for(var s=i[3*c+0],u=i[3*c+1],d=i[3*c+2],g=0;g<s;g+=1)a.push(e(u,d));return a},n}(),x=function(){var t=[],e=0,n={getBuffer:function(){return t},getAt:function(e){var n=Math.floor(e/8);return 1==(t[n]>>>7-e%8&1)},put:function(t,e){for(var r=0;r<e;r+=1)n.putBit(1==(t>>>e-r-1&1))},getLengthInBits:function(){return e},putBit:function(n){var r=Math.floor(e/8);t.length<=r&&t.push(0),n&&(t[r]|=128>>>e%8),e+=1}};return n},D=function(t){var e=a,n=t,r={getMode:function(){return e},getLength:function(t){return n.length},write:function(t){for(var e=n,r=0;r+2<e.length;)t.put(i(e.substring(r,r+3)),10),r+=3;r<e.length&&(e.length-r==1?t.put(i(e.substring(r,r+1)),4):e.length-r==2&&t.put(i(e.substring(r,r+2)),7))}},i=function(t){for(var e=0,n=0;n<t.length;n+=1)e=10*e+o(t.charAt(n));return e},o=function(t){if("0"<=t&&t<="9")return t.charCodeAt(0)-"0".charCodeAt(0);throw"illegal char :"+t};return r},m=function(t){var e=c,n=t,r={getMode:function(){return e},getLength:function(t){return n.length},write:function(t){for(var e=n,r=0;r+1<e.length;)t.put(45*i(e.charAt(r))+i(e.charAt(r+1)),11),r+=2;r<e.length&&t.put(i(e.charAt(r)),6)}},i=function(t){if("0"<=t&&t<="9")return t.charCodeAt(0)-"0".charCodeAt(0);if("A"<=t&&t<="Z")return t.charCodeAt(0)-"A".charCodeAt(0)+10;switch(t){case" ":return 36;case"$":return 37;case"%":return 38;case"*":return 39;case"+":return 40;case"-":return 41;case".":return 42;case"/":return 43;case":":return 44;default:throw"illegal char :"+t}};return r},j=function(e){var n=s,r=t.stringToBytes(e),i={getMode:function(){return n},getLength:function(t){return r.length},write:function(t){for(var e=0;e<r.length;e+=1)t.put(r[e],8)}};return i},N=function(e){var n=u,r=t.stringToBytesFuncs.SJIS;if(!r)throw"sjis not supported.";!function(){var t=r("友");if(2!=t.length||38726!=(t[0]<<8|t[1]))throw"sjis not supported."}();var i=r(e),o={getMode:function(){return n},getLength:function(t){return~~(i.length/2)},write:function(t){for(var e=i,n=0;n+1<e.length;){var r=(255&e[n])<<8|255&e[n+1];if(33088<=r&&r<=40956)r-=33088;else{if(!(57408<=r&&r<=60351))throw"illegal char at "+(n+1)+"/"+r;r-=49472}r=192*(r>>>8&255)+(255&r),t.put(r,13),n+=2}if(n<e.length)throw"illegal char at "+(n+1)}};return o},I=function(){var t=[],e={writeByte:function(e){t.push(255&e)},writeShort:function(t){e.writeByte(t),e.writeByte(t>>>8)},writeBytes:function(t,n,r){n=n||0,r=r||t.length;for(var i=0;i<r;i+=1)e.writeByte(t[i+n])},writeString:function(t){for(var n=0;n<t.length;n+=1)e.writeByte(t.charCodeAt(n))},toByteArray:function(){return t},toString:function(){var e="";e+="[";for(var n=0;n<t.length;n+=1)n>0&&(e+=","),e+=t[n];return e+="]"}};return e},T=function(t){var e=t,n=0,r=0,i=0,o={read:function(){for(;i<8;){if(n>=e.length){if(0==i)return-1;throw"unexpected end of file./"+i}var t=e.charAt(n);if(n+=1,"="==t)return i=0,-1;t.match(/^\s$/)||(r=r<<6|a(t.charCodeAt(0)),i+=6)}var o=r>>>i-8&255;return i-=8,o}},a=function(t){if(65<=t&&t<=90)return t-65;if(97<=t&&t<=122)return t-97+26;if(48<=t&&t<=57)return t-48+52;if(43==t)return 62;if(47==t)return 63;throw"c:"+t};return o},S=function(t,e,n){for(var r=function(t,e){var n=t,r=e,i=new Array(t*e),o={setPixel:function(t,e,r){i[e*n+t]=r},write:function(t){t.writeString("GIF87a"),t.writeShort(n),t.writeShort(r),t.writeByte(128),t.writeByte(0),t.writeByte(0),t.writeByte(0),t.writeByte(0),t.writeByte(0),t.writeByte(255),t.writeByte(255),t.writeByte(255),t.writeString(","),t.writeShort(0),t.writeShort(0),t.writeShort(n),t.writeShort(r),t.writeByte(0);var e=a(2);t.writeByte(2);for(var i=0;e.length-i>255;)t.writeByte(255),t.writeBytes(e,i,255),i+=255;t.writeByte(e.length-i),t.writeBytes(e,i,e.length-i),t.writeByte(0),t.writeString(";")}},a=function(t){for(var e=1<<t,n=1+(1<<t),r=t+1,o=c(),a=0;a<e;a+=1)o.add(String.fromCharCode(a));o.add(String.fromCharCode(e)),o.add(String.fromCharCode(n));var s,u,l,d=I(),g=(s=d,u=0,l=0,{write:function(t,e){if(t>>>e!=0)throw"length over";for(;u+e>=8;)s.writeByte(255&(t<<u|l)),e-=8-u,t>>>=8-u,l=0,u=0;l|=t<<u,u+=e},flush:function(){u>0&&s.writeByte(l)}});g.write(e,r);var f=0,h=String.fromCharCode(i[f]);for(f+=1;f<i.length;){var M=String.fromCharCode(i[f]);f+=1,o.contains(h+M)?h+=M:(g.write(o.indexOf(h),r),o.size()<4095&&(o.size()==1<<r&&(r+=1),o.add(h+M)),h=M)}return g.write(o.indexOf(h),r),g.write(n,r),g.flush(),d.toByteArray()},c=function(){var t={},e=0,n={add:function(r){if(n.contains(r))throw"dup key:"+r;t[r]=e,e+=1},size:function(){return e},indexOf:function(e){return t[e]},contains:function(e){return void 0!==t[e]}};return n};return o}(t,e),i=0;i<e;i+=1)for(var o=0;o<t;o+=1)r.setPixel(o,i,n(o,i));var a=I();r.write(a);for(var c=function(){var t=0,e=0,n=0,r="",i={},o=function(t){r+=String.fromCharCode(a(63&t))},a=function(t){if(t<0);else{if(t<26)return 65+t;if(t<52)return t-26+97;if(t<62)return t-52+48;if(62==t)return 43;if(63==t)return 47}throw"n:"+t};return i.writeByte=function(r){for(t=t<<8|255&r,e+=8,n+=1;e>=6;)o(t>>>e-6),e-=6},i.flush=function(){if(e>0&&(o(t<<6-e),t=0,e=0),n%3!=0)for(var i=3-n%3,a=0;a<i;a+=1)r+="="},i.toString=function(){return r},i}(),s=a.toByteArray(),u=0;u<s.length;u+=1)c.writeByte(s[u]);return c.flush(),"data:image/gif;base64,"+c};return t}();function clamp(t,e,n){return Math.max(e,Math.min(n,t))}function generateQrSvg(t){const{text:e,size:n=200,ecc:r="H",marginModules:i=3,dark:o="#000000",light:a="#ffffff",logoHref:c,logoSizeRatio:s=.2,logoBgPaddingRatio:u=.01,title:l,alt:d}=t||{};if(!e||"string"!=typeof e)throw new Error("generateQrSvg: 'text' is required");const g=qrcode(0,r);g.addData(e,"Byte"),g.make();const f=g.getModuleCount(),h=Math.max(0,Math.floor(i)),M=n/(f+2*h),w=n,y=`l${M},0 0,${M} -${M},0 0,-${M}z`;let v="";for(let t=0;t<f;t++){const e=t*M+h*M;for(let n=0;n<f;n++)if(g.isDark(t,n)){v+=`M${n*M+h*M},${e}${y}`}}const p={titleId:l?"qrcode-title":null,descId:d?"qrcode-description":null};let L="";if(L+=`<svg xmlns="http://www.w3.org/2000/svg" width="${w}px" height="${w}px" viewBox="0 0 ${w} ${w}" preserveAspectRatio="none"`,l||d){L+=` role="img" aria-labelledby="${[p.titleId,p.descId].filter(Boolean).join(" ")}"`}if(L+=">",l&&(L+=`<title id="${p.titleId}">${escapeXml(l)}</title>`),d&&(L+=`<description id="${p.descId}">${escapeXml(d)}</description>`),L+=`<rect width="100%" height="100%" fill="${a}"/>`,L+=`<path d="${v}" fill="${o}"/>`,c){const t=w*clamp(s,.08,.25),e=w/2,n=w/2;L+=`<circle cx="${e}" cy="${n}" r="${t/2+w*clamp(u,0,.08)}" fill="#ffffff"/>`,L+=`<image href="${c}" x="${e-t/2}" y="${n-t/2}" width="${t}" height="${t}" preserveAspectRatio="xMidYMid meet"/>`}return L+="</svg>",L}function escapeXml(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\"/g,"&quot;")}qrcode.stringToBytesFuncs["UTF-8"]=function(t){return function(t){for(var e=[],n=0;n<t.length;n++){var r=t.charCodeAt(n);r<128?e.push(r):r<2048?e.push(192|r>>6,128|63&r):r<55296||r>=57344?e.push(224|r>>12,128|r>>6&63,128|63&r):(n++,r=65536+((1023&r)<<10|1023&t.charCodeAt(n)),e.push(240|r>>18,128|r>>12&63,128|r>>6&63,128|63&r))}return e}(t)},function(t){"function"==typeof define&&define.amd?define([],t):"object"==typeof exports&&(module.exports=t())}(function(){return qrcode});class BitcoinPay{constructor(){this.version="1.0.13",this.defaultConfig={width:200,height:200,showCopyButton:!0,copyButtonText:"Copy",copiedText:"Copied!",cacheDuration:6e5,qrCodeOptions:{ecc:"H",logo:"btc",bitcoinImage:"data:image/svg+xml;base64,PHN2ZyB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSI2NCIgd2lkdGg9IjY0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+CjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMDA2MzA4NzYsLTAuMDAzMDE5ODQpIj4KPHBhdGggZmlsbD0iI2Y3OTMxYSIgZD0ibTYzLjAzMywzOS43NDRjLTQuMjc0LDE3LjE0My0yMS42MzcsMjcuNTc2LTM4Ljc4MiwyMy4zMDEtMTcuMTM4LTQuMjc0LTI3LjU3MS0yMS42MzgtMjMuMjk1LTM4Ljc4LDQuMjcyLTE3LjE0NSwyMS42MzUtMjcuNTc5LDM4Ljc3NS0yMy4zMDUsMTcuMTQ0LDQuMjc0LDI3LjU3NiwyMS42NCwyMy4zMDIsMzguNzg0eiIvPgo8cGF0aCBmaWxsPSIjRkZGIiBkPSJtNDYuMTAzLDI3LjQ0NGMwLjYzNy00LjI1OC0yLjYwNS02LjU0Ny03LjAzOC04LjA3NGwxLjQzOC01Ljc2OC0zLjUxMS0wLjg3NS0xLjQsNS42MTZjLTAuOTIzLTAuMjMtMS44NzEtMC40NDctMi44MTMtMC42NjJsMS40MS01LjY1My0zLjUwOS0wLjg3NS0xLjQzOSw1Ljc2NmMtMC43NjQtMC4xNzQtMS41MTQtMC4zNDYtMi4yNDItMC41MjdsMC4wMDQtMC4wMTgtNC44NDItMS4yMDktMC45MzQsMy43NXMyLjYwNSwwLjU5NywyLjU1LDAuNjM0YzEuNDIyLDAuMzU1LDEuNjc5LDEuMjk2LDEuNjM2LDIuMDQybC0xLjYzOCw2LjU3MWMwLjA5OCwwLjAyNSwwLjIyNSwwLjA2MSwwLjM2NSwwLjExNy0wLjExNy0wLjAyOS0wLjI0Mi0wLjA2MS0wLjM3MS0wLjA5MmwtMi4yOTYsOS4yMDVjLTAuMTc0LDAuNDMyLTAuNjE1LDEuMDgtMS42MDksMC44MzQsMC4wMzUsMC4wNTEtMi41NTItMC42MzctMi41NTItMC42MzdsLTEuNzQzLDQuMDE5LDQuNTY5LDEuMTM5YzAuODUsMC4yMTMsMS42ODMsMC40MzYsMi41MDMsMC42NDZsLTEuNDUzLDUuODM0LDMuNTA3LDAuODc1LDEuNDM5LTUuNzcyYzAuOTU4LDAuMjYsMS44ODgsMC41LDIuNzk4LDAuNzI2bC0xLjQzNCw1Ljc0NSwzLjUxMSwwLjg3NSwxLjQ1My01LjgyM2M1Ljk4NywxLjEzMywxMC40ODksMC42NzYsMTIuMzg0LTQuNzM5LDEuNTI3LTQuMzYtMC4wNzYtNi44NzUtMy4yMjYtOC41MTUsMi4yOTQtMC41MjksNC4wMjItMi4wMzgsNC40ODMtNS4xNTV6bS04LjAyMiwxMS4yNDljLTEuMDg1LDQuMzYtOC40MjYsMi4wMDMtMTAuODA2LDEuNDEybDEuOTI4LTcuNzI5YzIuMzgsMC41OTQsMTAuMDEyLDEuNzcsOC44NzgsNi4zMTd6bTEuMDg2LTExLjMxMmMtMC45OSwzLjk2Ni03LjEsMS45NTEtOS4wODIsMS40NTdsMS43NDgtNy4wMWMxLjk4MiwwLjQ5NCw4LjM2NSwxLjQxNiw3LjMzNCw1LjU1M3oiLz4KPC9nPgo8L3N2Zz4K",lightningImage:"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjgyIiBoZWlnaHQ9IjI4MiIgdmlld0JveD0iMCAwIDI4MiAyODIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiPgo8Y2lyY2xlIGN4PSIxNDAuOTgzIiBjeT0iMTQxLjAwMyIgcj0iMTQxIiBmaWxsPSIjN0IxQUY3Ii8+CjxwYXRoIGQ9Ik03OS43NjA5IDE0NC4wNDdMMTczLjc2MSA2My4wNDY2QzE3Ny44NTcgNjAuNDIzNSAxODEuNzYxIDYzLjA0NjYgMTc5LjI2MSA2Ny41NDY2TDE0OS4yNjEgMTI2LjU0N0gyMDIuNzYxQzIwMi43NjEgMTI2LjU0NyAyMTEuMjYxIDEyNi41NDcgMjAyLjc2MSAxMzMuNTQ3TDExMC4yNjEgMjE1LjA0N0MxMDMuNzYxIDIyMC41NDcgOTkuMjYxIDIxNy41NDcgMTAzLjc2MSAyMDkuMDQ3TDEzMi43NjEgMTUxLjU0N0g3OS43NjA5Qzc5Ljc2MDkgMTUxLjU0NyA3MS4yNjA5IDE1MS41NDcgNzkuNzYwOSAxNDQuMDQ3WiIgZmlsbD0id2hpdGUiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMCI+CjxyZWN0IHdpZHRoPSIyODIiIGhlaWdodD0iMjgyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="}}}static async render(t){const{endpoint:e,selector:n,bitcoinFallbackAddress:r,bitcoinDonateText:i,lightningAddress:o,lightningDonateText:a,options:c={}}=t;if(!e)throw new Error("BitcoinPay: endpoint is required");if(!r)throw new Error("BitcoinPay: bitcoinFallbackAddress is required");if(!n)throw new Error("BitcoinPay: selector is required");const s=document.querySelectorAll(n);if(0===s.length)throw new Error(`BitcoinPay: no elements found matching "${n}"`);const u=new BitcoinPay,l={...u.defaultConfig,...c},d=btoa(unescape(encodeURIComponent(e))).replace(/[^a-zA-Z0-9]/g,""),g=`btc-address-${d}`,f=`btc-timestamp-${d}`;let h;try{h=await u.getBitcoinAddress(e,g,f,l,r)}catch(t){const e='<div style="color: red; padding: 10px; border: 1px solid red; border-radius: 4px;">\n Failed to load Bitcoin payment widget. Please check your configuration.\n </div>';throw s.forEach(t=>{t.innerHTML=e}),t}const M=Array.from(s).map(t=>u.renderToElement(t,h,o,i,a,l));return await Promise.allSettled(M)}async renderToElement(t,e,n,r,i,o){const a=this.generateInstanceId();try{const c=n?this.createDualWidgetHTML(e,n,r,i,o,a):this.createSingleWidgetHTML(e,r,o,a);return t.innerHTML=c,n?await this.initializeDualWidget(e,n,o,a):await this.initializeSingleWidget(e,o,a),{success:!0,element:t}}catch(e){throw t.innerHTML='<div style="color: red; padding: 10px; border: 1px solid red; border-radius: 4px;">\n Failed to load Bitcoin payment widget. Please check your configuration.\n </div>',e}}isLocalStorageAvailable(){try{return localStorage.setItem("test","test"),localStorage.removeItem("test"),!0}catch{return!1}}async copyToClipboard(t){if(navigator.clipboard&&navigator.clipboard.writeText)try{return await navigator.clipboard.writeText(t),!0}catch{}const e=document.createElement("textarea");e.value=t,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.select();try{return document.execCommand("copy")}catch{return!1}finally{document.body.removeChild(e)}}async getBitcoinAddress(t,e,n,r,i){const o=Math.max(0,Math.min(r.cacheDuration,6048e5));if(this.isLocalStorageAvailable()){const t=localStorage.getItem(e),r=localStorage.getItem(n);if(t&&r){const e=parseInt(r);if(Date.now()-e<o)return t}}try{const r=await fetch(t);if(!r.ok)throw new Error(`HTTP ${r.status}: ${r.statusText}`);const i=await r.json();if(!i.address)throw new Error("Invalid response: no address field");return this.isLocalStorageAvailable()&&(localStorage.setItem(e,i.address),localStorage.setItem(n,Date.now().toString())),i.address}catch(t){if(i)return i;throw new Error(`Failed to fetch Bitcoin address: ${t.message}`)}}createSingleWidgetHTML(t,e,n,r){const i=`btc-btn-${r}`;return`\n <div class="bitcoin-pay-widget">\n <div class="widget-layout">\n <a href="bitcoin:${t}" class="qr-container" aria-label="Open in Bitcoin wallet">\n <div id="${`btc-qr-${r}`}" class="qr-code"></div>\n </a>\n <div class="content-area">\n <p class="description">\n ${e||'<span class="prefix-desktop">Scan with</span>\n <span class="prefix-touch">Tap to open</span>\n your Bitcoin wallet, or copy the on-chain address below.'}\n </p>\n <div class="address-container">\n <div class="address-text">\n <span>${t}</span>\n </div>\n ${n.showCopyButton?`<button id="${i}" class="copy-btn">${n.copyButtonText}</button>`:""}\n </div>\n </div>\n </div>\n </div>\n `}createDualWidgetHTML(t,e,n,r,i,o){const a=`lightning-qr-${o}`,c=`btc-btn-${o}`,s=`lightning-btn-${o}`,u=r||'<span class="prefix-desktop">Scan with</span>\n <span class="prefix-touch">Tap to open</span>\n your Lightning wallet, or copy my Lightning address below.';return`\n <div class="bitcoin-pay-widget has-tabs">\n <div class="widget-content">\n \x3c!-- Tab Navigation --\x3e\n <div class="tab-navigation">\n <button id="bitcoin-tab-${o}" class="tab-btn active" data-tab="bitcoin">\n <svg width="20" height="20" viewBox="0 0 64 64" fill="currentColor">\n <g transform="translate(0.00630876,-0.00301984)">\n <path d="m63.033,39.744c-4.274,17.143-21.637,27.576-38.782,23.301-17.138-4.274-27.571-21.638-23.295-38.78,4.272-17.145,21.635-27.579,38.775-23.305,17.144,4.274,27.576,21.64,23.302,38.784z"/>\n <path fill="#FFF" d="m46.103,27.444c0.637-4.258-2.605-6.547-7.038-8.074l1.438-5.768-3.511-0.875-1.4,5.616c-0.923-0.23-1.871-0.447-2.813-0.662l1.41-5.653-3.509-0.875-1.439,5.766c-0.764-0.174-1.514-0.346-2.242-0.527l0.004-0.018-4.842-1.209-0.934,3.75s2.605,0.597,2.55,0.634c1.422,0.355,1.679,1.296,1.636,2.042l-1.638,6.571c0.098,0.025,0.225,0.061,0.365,0.117-0.117-0.029-0.242-0.061-0.371-0.092l-2.296,9.205c-0.174,0.432-0.615,1.08-1.609,0.834,0.035,0.051-2.552-0.637-2.552-0.637l-1.743,4.019,4.569,1.139c0.85,0.213,1.683,0.436,2.503,0.646l-1.453,5.834,3.507,0.875,1.439-5.772c0.958,0.26,1.888,0.5,2.798,0.726l-1.434,5.745,3.511,0.875,1.453-5.823c5.987,1.133,10.489,0.676,12.384-4.739,1.527-4.36-0.076-6.875-3.226-8.515,2.294-0.529,4.022-2.038,4.483-5.155zm-8.022,11.249c-1.085,4.36-8.426,2.003-10.806,1.412l1.928-7.729c2.38,0.594,10.012,1.77,8.878,6.317zm1.086-11.312c-0.990,3.966-7.1,1.951-9.082,1.457l1.748-7.01c1.982,0.494,8.365,1.416,7.334,5.553z"/>\n </g>\n </svg>\n Bitcoin\n </button>\n <button id="lightning-tab-${o}" class="tab-btn" data-tab="lightning">\n <svg width="20" height="20" viewBox="0 0 282 282" fill="currentColor">\n <g clip-path="url(#clip0)">\n <circle cx="140.983" cy="141.003" r="141" />\n <path d="M79.7609 144.047L173.761 63.0466C177.857 60.4235 181.761 63.0466 179.261 67.5466L149.261 126.547H202.761C202.761 126.547 211.261 126.547 202.761 133.547L110.261 215.047C103.761 220.547 99.261 217.547 103.761 209.047L132.761 151.547H79.7609C79.7609 151.547 71.2609 151.547 79.7609 144.047Z" fill="white"/>\n </g>\n <defs>\n <clipPath id="clip0">\n <rect width="282" height="282" fill="white"/>\n </clipPath>\n </defs>\n </svg>\n Lightning\n </button>\n </div>\n\n \x3c!-- Bitcoin Tab Content --\x3e\n <div id="bitcoin-content-${o}" class="tab-content active" data-tab="bitcoin">\n <div class="widget-layout">\n <a href="bitcoin:${t}" class="qr-container" aria-label="Open in Bitcoin wallet">\n <div id="${`btc-qr-${o}`}" class="qr-code"></div>\n </a>\n <div class="content-area">\n <p class="description">\n ${n||'<span class="prefix-desktop">Scan with</span>\n <span class="prefix-touch">Tap to open</span>\n your Bitcoin wallet, or copy the on-chain address below.'}\n </p>\n <div class="address-container">\n <div class="address-text">\n <span>${t}</span>\n </div>\n ${i.showCopyButton?`<button id="${c}" class="copy-btn">${i.copyButtonText}</button>`:""}\n </div>\n </div>\n </div>\n </div>\n\n \x3c!-- Lightning Tab Content --\x3e\n <div id="lightning-content-${o}" class="tab-content" data-tab="lightning">\n <div class="widget-layout">\n <a href="lightning:${e}" class="qr-container" aria-label="Open in Lightning wallet">\n <div id="${a}" class="qr-code"></div>\n </a>\n <div class="content-area">\n <p class="description">\n ${u}\n </p>\n <div class="address-container">\n <div class="address-text">\n <span>${e}</span>\n </div>\n ${i.showCopyButton?`<button id="${s}" class="copy-btn">Copy</button>`:""}\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n `}async initializeSingleWidget(t,e,n){const r=`btc-qr-${n}`,i=`btc-btn-${n}`,o=document.getElementById(r);if(o){const n="btc"===e.qrCodeOptions.logo?this.defaultConfig.qrCodeOptions.bitcoinImage:void 0,r=generateQrSvg({text:`bitcoin:${t}`,size:e.width,logoHref:n,alt:"Bitcoin address QR"});o.innerHTML=r}if(e.showCopyButton){const n=document.getElementById(i);n&&n.addEventListener("click",async()=>{const r=await this.copyToClipboard(t),i=n.textContent;n.textContent=r?e.copiedText:"Failed to copy",setTimeout(()=>{n.textContent=i},2e3)})}}async initializeDualWidget(t,e,n,r){const i=`btc-qr-${r}`,o=`lightning-qr-${r}`,a=`btc-btn-${r}`,c=`lightning-btn-${r}`,s=document.getElementById(i);if(s){const e=generateQrSvg({text:`bitcoin:${t}`,size:n.width,logoHref:this.defaultConfig.qrCodeOptions.bitcoinImage,alt:"Bitcoin address QR"});s.innerHTML=e}const u=document.getElementById(o);if(u){const t=generateQrSvg({text:`lightning:${e}`,size:n.width,logoHref:this.defaultConfig.qrCodeOptions.lightningImage,alt:"Lightning address QR"});u.innerHTML=t}if(this.setupTabs(r),n.showCopyButton){const r=document.getElementById(a);r&&r.addEventListener("click",async()=>{const e=await this.copyToClipboard(t),i=r.textContent;r.textContent=e?n.copiedText:"Failed to copy",setTimeout(()=>{r.textContent=i},2e3)});const i=document.getElementById(c);i&&i.addEventListener("click",async()=>{const t=await this.copyToClipboard(e),r=i.textContent;i.textContent=t?n.copiedText:"Failed to copy",setTimeout(()=>{i.textContent=r},2e3)})}}setupTabs(t){const e=document.querySelectorAll(`.tab-btn[id$="-${t}"]`),n=document.querySelectorAll(`.tab-content[id$="-${t}"]`);e.forEach(t=>{t.addEventListener("click",()=>{const r=t.getAttribute("data-tab");e.forEach(t=>{t.classList.remove("active")}),t.classList.add("active"),n.forEach(t=>{t.classList.remove("active"),t.getAttribute("data-tab")===r&&t.classList.add("active")})})})}generateInstanceId(){return Math.random().toString(36).substr(2,9)}}"undefined"!=typeof window&&(window.BitcoinPay=BitcoinPay);
@@ -0,0 +1,99 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Bitcoin Serverless Payments</title>
7
+ <link rel="stylesheet" href="./bitcoin-pay.min.css" />
8
+ <style>
9
+ body {
10
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
11
+ sans-serif;
12
+ max-width: 800px;
13
+ margin: 0 auto;
14
+ padding: 20px;
15
+ line-height: 1.6;
16
+ }
17
+ h2 {
18
+ margin-top: 40px;
19
+ }
20
+ code {
21
+ background: #f4f4f4;
22
+ padding: 2px 6px;
23
+ border-radius: 3px;
24
+ font-family: "Monaco", "Menlo", monospace;
25
+ }
26
+
27
+ @media (prefers-color-scheme: dark) {
28
+ body {
29
+ background-color: #1a1a1a;
30
+ color: #e0e0e0;
31
+ }
32
+ code {
33
+ background: #2a2a2a;
34
+ color: #e0e0e0;
35
+ }
36
+ a {
37
+ color: #60a5fa;
38
+ }
39
+ a:hover {
40
+ color: #93c5fd;
41
+ }
42
+ }
43
+ </style>
44
+ </head>
45
+ <body>
46
+ <h1>Bitcoin Serverless Payments</h1>
47
+ <p>
48
+ A simple, self-custodial solution for accepting private, on-chain Bitcoin
49
+ payments using just an XPUB (extended public key) and a serverless
50
+ function.
51
+ </p>
52
+ <p>
53
+ This page demonstrates the <code>BitcoinPay()</code> widget integration.
54
+ The widget will attempt to fetch a Bitcoin address from your serverless
55
+ function endpoint.
56
+ </p>
57
+
58
+ <h2>Basic Usage</h2>
59
+ <div id="bitcoin-donate-basic"></div>
60
+
61
+ <h2>Use with Lightning (optional)</h2>
62
+ <div id="bitcoin-donate-lightning"></div>
63
+
64
+ <p>
65
+ For full instructions, see the
66
+ <a href="https://github.com/tombennet/bitcoin-serverless-donations"
67
+ >GitHub repository</a
68
+ >
69
+ or read
70
+ <a
71
+ href="https://bennet.org/blog/private-serverless-bitcoin-payments-for-indie-devs/"
72
+ >the blog post</a
73
+ >.
74
+ </p>
75
+ <!-- Load the script -->
76
+ <script src="./bitcoin-pay.min.js"></script>
77
+
78
+ <script>
79
+ // Basic usage
80
+ BitcoinPay.render({
81
+ selector: "#bitcoin-donate-basic",
82
+ endpoint: "/.netlify/functions/get-address",
83
+ bitcoinFallbackAddress: "bc1qtcp67ktfdcwfc7t3krwy8ttuqznrjldsuh5gsd",
84
+ }).catch((error) => {
85
+ console.error("Failed to render Bitcoin widget:", error);
86
+ });
87
+
88
+ // Bitcoin + Lightning configuration
89
+ BitcoinPay.render({
90
+ selector: "#bitcoin-donate-lightning",
91
+ endpoint: "/.netlify/functions/get-address",
92
+ lightningAddress: "bennet@walletofsatoshi.com",
93
+ bitcoinFallbackAddress: "bc1qtcp67ktfdcwfc7t3krwy8ttuqznrjldsuh5gsd",
94
+ }).catch((error) => {
95
+ console.error("Failed to render Bitcoin widget:", error);
96
+ });
97
+ </script>
98
+ </body>
99
+ </html>
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "bitcoin-serverless-donations",
3
+ "version": "1.0.13",
4
+ "author": "https://github.com/tombennet/bitcoin-serverless-donations",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/tombennet/bitcoin-serverless-donations.git"
9
+ },
10
+ "type": "module",
11
+ "keywords": [
12
+ "bitcoin",
13
+ "donations",
14
+ "payments",
15
+ "xpub",
16
+ "netlify"
17
+ ],
18
+ "scripts": {
19
+ "dev": "netlify dev",
20
+ "build": "node build.js",
21
+ "test": "vitest run",
22
+ "test:watch": "vitest"
23
+ },
24
+ "devDependencies": {
25
+ "@bitcoinerlab/secp256k1": "1.2.0",
26
+ "@netlify/blobs": "10.3.1",
27
+ "@netlify/functions": "5.0.1",
28
+ "@swan-bitcoin/xpub-lib": "0.3.0",
29
+ "cssnano": "7.1.2",
30
+ "netlify-cli": "23.9.5",
31
+ "postcss": "8.5.6",
32
+ "terser": "5.44.0",
33
+ "typescript": "^5.9.3",
34
+ "vitest": "4.0.6"
35
+ },
36
+ "main": "dist/bitcoin-pay.min.js",
37
+ "module": "dist/bitcoin-pay.esm.js",
38
+ "types": "dist/bitcoin-pay.d.ts",
39
+ "exports": {
40
+ ".": {
41
+ "types": "./dist/bitcoin-pay.d.ts",
42
+ "import": "./dist/bitcoin-pay.esm.js",
43
+ "require": "./dist/bitcoin-pay.min.js",
44
+ "default": "./dist/bitcoin-pay.min.js"
45
+ },
46
+ "./esm": "./dist/bitcoin-pay.esm.js",
47
+ "./cdn": "./dist/bitcoin-pay.min.js",
48
+ "./css": "./dist/bitcoin-pay.min.css"
49
+ },
50
+ "files": [
51
+ "dist/",
52
+ "bitcoin-pay.d.ts",
53
+ "README.md"
54
+ ]
55
+ }