PageSourceSearch

https://hmongdailynews.com/NewMember

html hmongdailynews.com collected 2026-09-28 11:13:27 UTC 76,469 bytes, 1,502 lines download raw bytes

1<!doctype html>
2<html lang="en">
3
4<head>
5    <!-- Performance Optimizations -->
6    <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
7    <link rel="preconnect" href="https://code.jquery.com" crossorigin>
8    <link rel="dns-prefetch" href="https://cdn.jsdelivr.net">
9    <link rel="dns-prefetch" href="https://code.jquery.com">
10    <link rel="dns-prefetch" href="https://maxcdn.bootstrapcdn.com">
11    <link rel="preload" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" as="style">
12
13    <!-- meta tags -->
14    <meta charset="UTF-8">
15    <title>Welcome to Hmong Daily News!</title>
16     
17    <meta name="keywords" content="Hmong, Hmong American, AAPI, Hmong News"> 
18    <meta name="description" content="Hmong Daily News"> 
19    
20        <link rel="shortcut icon" href="/favicon.png?v=1788930124">
21    
21<script type="text/javascript" language="javascript" src="/lib/bl2.js"></script>
21
22
23    <!-- bootstrap -->
24    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="" crossorigin="anonymous">
25    
25<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="" crossorigin="anonymous"></script>
25
26    <link type="text/css" rel="stylesheet" href="https://bulletlink.com/bootstrap.css">
27    <!-- /bootstrap -->
28
29    <!-- jQuery -->
30    
30<script src="https://code.jquery.com/jquery-1.7.min.js" integrity="" crossorigin="anonymous"></script>
30
31    <!-- /jQuery -->
32
33    <!-- system -->
34    
34<script type="text/javascript" language="javascript" src="/settings.js?v=1788930124"></script>
34
35    
35<script type="text/javascript" language="javascript" src="/ads.js?v=1788930124"></script>
35
36    
36<script type="text/javascript" language="javascript" src="/menu_horizontal.js?v=1788930124"></script>
36
37    
37<script type="text/javascript" language="javascript" src="/sections.js?v=1788930124"></script>
37
38    
38<script type="text/javascript" language="javascript" src="/polls.js?v=1788930124"></script>
38
39    
39<script type="text/javascript" language="javascript" src="/articles.js?v=1788930124"></script>
39
40    
40<script type="text/javascript" language="javascript" src="/lib/iframeResizer.min.js"></script>
40
41    <!-- /system -->
42
43    <!-- fontAwesome-->
44    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
45    <!-- /fontAwesome-->
46
47    <!-- general -->
48    
48<script type="text/javascript" language="javascript" src="/jscript30.js?v=1788930124"></script>
48
49    <link type="text/css" rel="stylesheet" href="/custom.css?v=1788930124">
50    
50<script type="text/javascript" language="javascript" src="/custom.js?v=1788930124"></script>
50
51    <!-- /general -->
52
53    <!--StartMH-->
54    <!--MetaSharing-->
55    <!--EndMH-->
56
57    <!-- live-Builder --> 
58    <link type="text/css" rel="stylesheet" href="/ufields.css?v=1788930124"/>
59    
59<script type="text/javascript" src="/ufields.js?v=1788930124"></script>
59
60    <!-- /live-Builder --> 
61    <!-- Google tag (gtag.js) -->
62
63
64<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
65 <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
66<meta http-equiv="Pragma" content="no-cache" />
67<meta http-equiv="Expires" content="0" />
68<style>:root{--cms-theme-color: #555;}</style><link rel="stylesheet" href="/sys-popup.css?v=1788930124"><style id="universal-submit-spinner">
69.form-submit-spinner{display:inline-block;width:16px;height:16px;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:frmSpin .7s linear infinite;vertical-align:middle;margin-right:6px}
70@keyframes frmSpin{to{transform:rotate(360deg)}}
71</style></head>
72
73<body id="blbodymain" class="blbody cus-select-red"><a href="https://hmongdailynews.com/cdn-cgi/content?id=BV62ZFItdt32o3pwRKFQ45YuDNo7stzDvxE_7EDpMXg-1790594004.503381-1.2.1.1-hZ9SHf5J7wq.88zjAKMpv52xq.._Ce0UG_GYTcxvVY5mqA4F0vXWIbI4W2Y9pxkM" aria-hidden="true" rel="nofollow noopener" style="display: none !important; visibility: hidden !important"></a>
74 
75    <div class="mainbody">
76        <!-- sticky ads-->
77        <span class="cus-sticky-ads">
78</span>
79        <!-- /sticky ads-->
80        <div class="container-bl mt-2">
81            <!-- top-links -->
82<div class="row mb-3">
83   <div class="cus-column-133-2 col-lg-12 mb-lg-2">
84                   
85
86                 
87                </div>
88                <div class="cus-top-links col-sm-8 float-start mb-sm-0 ps-lg-0">
89                    <div class="float-start">
90                        <!-- search-->
91                        
91<script type="text/javascript" language="JavaScript">GetGoogleCustomSearch();</script>
91
92                        <a class="search-link text-decoration-none text-black fs-6 fw-bold me-3 border rounded p-1 px-2 bl-toplink-1-133-searchlink" href="javascript:void(0)" data-bs-toggle="tooltip" data-bs-placement="right" title="Click to Search Articles..."><i class="fa fa-search" aria-hidden="true"></i> SEARCH</a>
93                        <div class="search_content">
94                            <div class="search_box"><gcse:searchbox></gcse:searchbox></div>
95                            <div class="search_results"><gcse:searchresults></gcse:searchresults></div>
96                            <div class="search_remove">
97                                <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-x-lg" viewBox="0 0 16 16">
98                                    <path fill-rule="evenodd" d="M13.854 2.146a.5.5 0 0 1 0 .708l-11 11a.5.5 0 0 1-.708-.708l11-11a.5.5 0 0 1 .708 0Z"/>
99                                    <path fill-rule="evenodd" d="M2.146 2.146a.5.5 0 0 0 0 .708l11 11a.5.5 0 0 0 .708-.708l-11-11a.5.5 0 0 0-.708 0Z"/>
100                              </svg>
101                            </div>
102                        </div>
103                        
103<script>
104                            document.getElementsByClassName('search-link')[0].addEventListener("click", function() {
105                                document.getElementById("gsc-i-id1").setAttribute("placeholder", "Search for...");
106                                document.getElementsByClassName('search_content')[0].classList.add("search-flex");
107                                document.getElementsByClassName('search_remove')[0].style.display = "block";
108                                document.getElementsByClassName('gsc-results-close-btn')[0].addEventListener("click", function() {
109                                    document.getElementsByClassName('search_content')[0].classList.remove("search-flex");
110                                });
111                            });
112                            document.getElementsByClassName('search_remove')[0].addEventListener("click", function() {
113                                document.getElementsByClassName('search_content')[0].classList.remove("search-flex");
114                                document.getElementsByClassName('search_remove')[0].style.display = "none";                            });
115                        </script>
115
116                        <style>
117                            .gsc-adBlock {display: none !important;}
118                            #gsc-i-id1{color:#000!important}
119                            #gsc-i-id1::placeholder{color:#555!important;opacity:1;font-size:inherit!important}
120                            .search_content{display:flex;display:-webkit-flex;-ms-display:flex;align-items:center;-webkit-align-items:center;-ms-align-items:center;justify-content:center;-webkit-justify-content:center;-ms-justify-content:center;background-color:rgba(255,255,255,.98);height:100%;position:fixed;top:100%;opacity:0;left:0;width:100%;z-index:2147483647;transition: 400ms linear;}
121                            .search-flex{top: 0;opacity: 1;display:flex;display:-webkit-flex;-ms-display:flex;align-items:center;-webkit-align-items:center;-ms-align-items:center;justify-content:center;-webkit-justify-content:center;-ms-justify-content:center;transition: 300ms linear;}
122                            .search_remove{cursor:pointer;user-select:none;position:absolute;top:10px;left:3%;}
123                            .search_remove:hover{color:gray}
124                            .gsc-control-cse.gsc-control-cse-en{background-color:transparent;border-width:0;position:absolute}.search_box{border-bottom:2px solid #000;width:70%;padding-bottom:6px}
125                            .gsib_b,.gsst_a{display:none!important}
126                            .gscb_a{display:none!important}
127                            .gsc-input{background-image:none!important}
128                            .gsc-input{background-color:transparent!important}
129                            .gsc-input-box{background-color:transparent!important;border-bottom:0 solid #ff4500!important;border-width:0!important}
130                            .gsc-input{border-width:0!important;color:#fff!important;font-size:20px!important}
131                            .gsc-adBlock{display:none!important}
132                            .search-icon-desk{cursor:pointer}
133                            .search-icon-desk{float:right;height:54px;margin-right:10px}
134                            .search-icon-desk i{border:1px solid #ddd;border-radius:4px;color:#000;display:block;line-height:35px;margin-top:9px;padding:0 12px}
135                            .search-icon-desk i:hover{color:#79655d}
136                            .gsc-results-wrapper-overlay.gsc-results-wrapper-visible {width: 100%;left: 0;top: 0;height: 100%;}
137                            .gcsc-branding {display: none;}
138                            .gsc-search-button.gsc-search-button-v2{padding:0 18px;line-height:35px;display:inline-block!important;background:#ddd;border-radius:5px;border-color:#555}
139                            .gsc-search-button{width:auto!important;float:right!important}.gsc-search-button.gsc-search-button-v2:hover{background:#ddd!important}
140                            .gsc-search-button-v2 svg{fill:#000!important}
141                            .gsc-search-button.gsc-search-button-v2:hover{background:#05a2d3!important;border-color:#006899!important}
142                            .gsc-search-button.gsc-search-button-v2:hover svg{fill:#fff!important}
143                        </style>
144                        <!-- /search-->
145                        <a class="text-decoration-none text-black fs-6 me-3 cus-toplink-1-133-link text-red-hover" href="https://hmongdailynews.com/about-us-p665-147.htm">ABOUT</a>
146                        <a class="text-decoration-none text-black fs-6 me-3 cus-toplink-1-133-link text-red-hover" href="ContactUs">CONTACT</a>
147                        <a class="text-decoration-none text-black fs-6 me-3 cus-toplink-1-133-link text-red-hover" href="NewMember">SUBSCRIBE</a>
148                    </div>
149                </div>
150                <div class="cus-social-links col-sm-4 float-lg-end d-flex justify-content-center d-sm-inline-block pe-lg-0">
151                    <div class="float-lg-end">
152                        <a class="text-decoration-none text-dark rounded ms-3 fs-4 d-inline-block lh-1 cus-social-1-133-icon" href="https://www.facebook.com/hmongdailynews/?ref=pages_you_manage" target="_blank"><i class="fa fa-facebook-square text-red-hover" aria-hidden="true"></i></a>
153                        <a class="text-decoration-none text-dark rounded ms-3 fs-4 d-inline-block lh-1 cus-social-1-133-icon" href="https://www.youtube.com/@hmongdailynews1547" target="_blank"><i class="fa fa-brands fa-youtube text-red-hover" aria-hidden="true"></i></a>
154                        <a class="text-decoration-none text-dark rounded ms-3 fs-4 d-inline-block lh-1 cus-social-1-133-icon" href="https://www.linkedin.com/" target="_blank"><i class="fa fa-linkedin-square text-red-hover" aria-hidden="true"></i></a>
155                    </div>
156                </div>
157            </div>
158            <!-- /top-links -->
159            <!-- logo-->
160            <div class="row mb-3">
161                <div class="hpe-logo col-12 mb-3 d-flex justify-content-center px-lg-0">
161<script type="text/javascript" language="JavaScript">GetLogo();</script>
161</div>
162
163            </div>
164            <!-- /logo -->
165            <!-- menu -->
166            <div class="row mb-3">
167                <div class="col-12 px-0 bg-black">
168                     <div class="row mx-0">
169                    
169<script type="text/javascript" language="JavaScript">
170                        GetMenuH();
171                    </script>
171
172                        
173               </div>
174                </div>
175            </div>
176            <!-- /menu -->
177            
178
179<div class="row mb-3">
180                <div class=" col-lg-12 adgroup-14 d-flex justify-content-center mb-3 my-lg-0 px-0 pt-1">
180<script type="text/javascript" language="JavaScript">AdGroup14();</script>
180</div>
181
182
183</div>
184
185            <!-- 3-columns -->
186            <div class="cus-column-133-row row mb-3 border-bottom">
187                <div class="cus-column-133-1 col-lg-9 pe-lg-3 ps-lg-0 mb-5 mb-lg-0">
188                    <div class="w-100 cus-position-sticky" data-sticky="85">
189                      <div data-cms-popup-root="1"><style>
190#CustomForm {background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='32' viewBox='0 0 16 32'%3E%3Cg fill='%23c9d1cb' fill-opacity='0.16'%3E%3Cpath fill-rule='evenodd' d='M0 24h4v2H0v-2zm0 4h6v2H0v-2zm0-8h2v2H0v-2zM0 0h4v2H0V0zm0 4h2v2H0V4zm16 20h-6v2h6v-2zm0 4H8v2h8v-2zm0-8h-4v2h4v-2zm0-20h-6v2h6V0zm0 4h-4v2h4V4zm-2 12h2v2h-2v-2zm0-8h2v2h-2V8zM2 8h10v2H2V8zm0 8h10v2H2v-2zm-2-4h14v2H0v-2zm4-8h6v2H4V4zm0 16h6v2H4v-2zM6 0h2v2H6V0zm0 24h2v2H6v-2z'/%3E%3C/g%3E%3C/svg%3E");background-attachment: fixed;}
191.form-check-label:hover {color: #0d6efd;cursor: pointer;}
192.cus-form-loader .cus-form-loading {display: block !important;}
193.cus-form-loader .formbody fieldset, .cus-form-loader .system_text.footer_text {opacity: 0.5;pointer-events: none;}
194#cus-form-button-loader {display:none;}
195.cus-form-loader footer, .cus-form-loader button {cursor: no-drop;}
196.fast-spin {-webkit-animation: fa-spin 1s infinite linear;animation: fa-spin 1s infinite linear;}
197.cus-form-loader #SUBMIT1 {display:none;}
198.cus-form-loader #cus-form-button-loader {display:inline-block;}
199.form-floating > .form-control:focus ~ label {color: #0d6efd !important;}
200.form-control:not(:disabled):not([readonly])::file-selector-button {position: absolute;right: 0;border-radius: 5px !important;}
201.input-file-preview {display: none;}
202.input-file-preview img {max-width: 30%;max-height: 200px;border: 1px solid #ced4da;border-radius: 5px;padding: 5px;box-sizing: border-box;cursor: zoom-in;}
203.w-96 {width: 96% !important;}
204.p-valid {color: green;}
205.p-valid:before {position: relative;left: -10px;content: "✔";}
206.p-invalid {color: red;}
207.p-invalid:before {position: relative;left: -10px;content: "✖";font-size: 0.875rem !important;}
208.open-eye, .close-eye {position: absolute;right: 2%;top: 50%;transform: translate(0,-50%);cursor: pointer;}
209.open-eye i:hover, .close-eye i:hover {color: gray !important;}
210.cus-form-help:before {content: "\f05a";font-family: FontAwesome;padding-left: 0.5rem;padding-right: 0.5rem;}
211.cus-form-help {display: none;}
212.cus-form-help:empty {display: none !important;}
213.form-control:focus ~ .cus-form-help {display: block;}
214.formdivider.formdivider_custom {border-left: 5px solid #ffc107;}
215.form-floating > .form-control {caret-color: #0d6efd;}
216</style>
217<style id="force-form-styles" data-version="2026-01-26-v2">
218      textarea, textarea.form-control, textarea.formfieldinput { min-height: 120px !important; height: 120px !important; }
219
220      /* Enhanced Spinner Styles - More visible and animated */
221      .form-spinner-ring { 
222        display: inline-block; 
223        width: 18px; 
224        height: 18px; 
225        border: 3px solid rgba(255,255,255,0.4); 
226        border-top-color: #fff; 
227        border-radius: 50%; 
228        animation: formSpin 0.7s linear infinite; 
229        margin-right: 8px; 
230        vertical-align: middle; 
231      }
232      @keyframes formSpin { 
233        0% { transform: rotate(0deg); }
234        100% { transform: rotate(360deg); } 
235      }
236      
237      /* Submit Button Loading State */
238      button.btn-loading, input.btn-loading {
239        position: relative;
240        pointer-events: none;
241        opacity: 0.85;
242      }
243      button.btn-loading::after {
244        content: '';
245        position: absolute;
246        width: 18px;
247        height: 18px;
248        top: 50%;
249        left: 12px;
250        margin-top: -9px;
251        border: 3px solid rgba(255,255,255,0.4);
252        border-top-color: #fff;
253        border-radius: 50%;
254        animation: formSpin 0.7s linear infinite;
255      }
256      
257      /* Form Overlay during submission */
258      .form-loading-overlay {
259        position: absolute;
260        top: 0;
261        left: 0;
262        right: 0;
263        bottom: 0;
264        background: rgba(255,255,255,0.7);
265        display: flex;
266        align-items: center;
267        justify-content: center;
268        z-index: 9999;
269        border-radius: inherit;
270      }
271      .form-loading-overlay .spinner-container {
272        display: flex;
273        flex-direction: column;
274        align-items: center;
275        gap: 12px;
276        padding: 30px;
277        background: white;
278        border-radius: 12px;
279        box-shadow: 0 4px 20px rgba(0,0,0,0.15);
280      }
281      .form-loading-overlay .spinner-large {
282        width: 40px;
283        height: 40px;
284        border: 4px solid #e0e0e0;
285        border-top-color: #007bff;
286        border-radius: 50%;
287        animation: formSpin 0.8s linear infinite;
288      }
289      .form-loading-overlay .loading-text {
290        color: #333;
291        font-size: 14px;
292        font-weight: 500;
293      }
294      
295      /* Bootstrap 5 Floating Label Fix - Force proper behavior */
296      .form-floating > .form-control:focus ~ label,
297      .form-floating > .form-control:not(:placeholder-shown) ~ label,
298      .form-floating > .form-select ~ label {
299        opacity: 0.65 !important;
300        transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem) !important;
301      }
302      .form-floating > .form-control::placeholder {
303        color: transparent !important;
304      }
305      .form-floating > label {
306        position: absolute !important;
307        top: 0 !important;
308        left: 0 !important;
309        height: 100% !important;
310        padding: 1rem 0.75rem !important;
311        pointer-events: none !important;
312        border: 1px solid transparent !important;
313        transform-origin: 0 0 !important;
314        transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out !important;
315      }
316    </style>
317<style>.grecaptcha-badge{visibility:hidden!important;position:fixed!important;bottom:14px!important;right:14px!important;}</style>
318<script src="/iframe-resizer-master/js/iframeResizer.contentWindow.js"></script>
vendor: 1 bytes, line 318
318
319<script type="text/javascript" language="javascript" src="https://hmongdailynews.com/lib/bl.js"></script>
vendor: 1 bytes, line 319
319
320<script>
321function ChangeInputFocus(obj, evt, cname) {
322/*if (evt.type == "focus")
323obj.className = cname;
324else if (evt.type == "blur")
325/*obj.className = cname;*/
326}
327</script>
vendor: 1 bytes, line 327
327
328<script src="https://recaptcha.net/recaptcha/api.js?render=6LdXmfgUAAAAAJNuEHBxVCY0w9eA73hvaWsdgPlM"></script>
vendor: 1 bytes, line 328
328
329<script>
330(function(){
331  function setToken(t){
332    var els = document.querySelectorAll('.g-recaptcha-token');
333    for (var i = 0; i < els.length; i++) els[i].value = t;
334  }
335  function refresh(){
336    if (typeof grecaptcha === 'undefined') return;
337    grecaptcha.ready(function(){
338      grecaptcha.execute('6LdXmfgUAAAAAJNuEHBxVCY0w9eA73hvaWsdgPlM', {action: 'submit'}).then(setToken);
339    });
340  }
341  // Submit-time minter. Login pages call this in their submit handler and await it,
342  // so the request always carries a freshly-minted token instead of reading the
343  // pre-filled hidden field — which may still be empty when a user with saved
344  // credentials presses Enter before the page-load mint resolves (-> recaptcha_missing,
345  // a hard block). Resolves to a fresh token, or falls back to whatever's already in
346  // the field (and never hangs the form: 3s timeout, and resolves if grecaptcha is
347  // unavailable). Also updates the hidden field so FormData-based submits pick it up.
348  window.cmsMintCaptchaToken = function(){
349    return new Promise(function(resolve){
350      var els = document.querySelectorAll('.g-recaptcha-token');
351      var fallback = (els[0] && els[0].value) || '';
352      var done = false;
353      var to = setTimeout(function(){ if(!done){ done = true; resolve(fallback); } }, 3000);
354      function fin(v){ if(done) return; done = true; clearTimeout(to); setToken(v); resolve(v); }
355      function attempt(){
356        if (typeof grecaptcha === 'undefined' || !grecaptcha.execute) return false;
357        try {
358          grecaptcha.ready(function(){
359            grecaptcha.execute('6LdXmfgUAAAAAJNuEHBxVCY0w9eA73hvaWsdgPlM', {action: 'submit'})
360              .then(function(t){ fin(t || fallback); })
361              .catch(function(){ fin(fallback); });
362          });
363          return true;
364        } catch(_) { return false; }
365      }
366      // grecaptcha may still be loading -- common when the form is rendered
367      // inside a popup, where api.js was injected only moments ago. Poll until
368      // it's ready (or the 3s timeout fires) instead of bailing immediately.
369      if (!attempt()) {
370        var iv = setInterval(function(){
371          if (done) { clearInterval(iv); return; }
372          if (attempt()) clearInterval(iv);
373        }, 150);
374      }
375    });
376  };
377  refresh();
378  setTimeout(refresh, 5000);
379  setInterval(refresh, 120000);
380})();
381</script>
381
382<div class="formbody">
383<div class="body p-2">
384<!--FormError-->
385<!--FormMessage-->
386<form class="custom-form p-3 mx-0 border rounded" enctype="multipart/form-data" autocomplete="off" id="CustomForm" method="post" name="CustomForm" onsubmit="return unifiedSubmitForm(event)">
387<div aria-hidden="true" style="position:absolute;left:-9999px;top:-9999px;height:0;width:0;overflow:hidden;">
388  <label for="website_url_hp">Website (leave blank)</label>
389  <input type="text" name="website_url" id="website_url_hp" tabindex="-1" autocomplete="off" value="">
390</div>
391<input type="hidden" name="token" class="g-recaptcha-token" value="">
392<!--FKeys-->
393<input type="hidden" name="SystemEmailSubject" value="hmongdailynews.com:  Subscriber"> 
394<input type="hidden" name="SystemEmailConfirmMessage" value="Your message has been forwarded to appropriate personnel. Thank you."> 
395<input type="hidden" name="SystemEmailFormat" value="HTML"> 
396<input type="hidden" name="SystemEmailTo" value="[email protected]"> 
397<input type="hidden" name="SystemEmailCC" value="">
398<center class="fw-bold mb-3 fs-3 text-secondary">Welcome to Hmong Daily News!</center>
399<fieldset>
400<div class="system_text Header_text mb-5 text-center"><html>
401<head>
402 
403 <link href="http://fonts.googleapis.com/css?family=" rel="StyleSheet" />
404 <link href="http://fonts.googleapis.com/css?family=" rel="StyleSheet" />
405 <link href="http://fonts.googleapis.com/css?family=" rel="StyleSheet" />
406 <link href="http://fonts.googleapis.com/css?family=" rel="StyleSheet" />
407 <link href="http://fonts.googleapis.com/css?family=" rel="StyleSheet" />
408 <link href="http://fonts.googleapis.com/css?family=" rel="StyleSheet" />
409</head>
410<body>
411 <p style="text-align: left;"><span style="color: rgb(33, 37, 41); font-family: " times="" new="" roman",="" times,="" serif;="" font-size:="" 16px;="" text-align:="" center;="" background-color:="" rgb(255,="" 255,="" 255);"="">We are committed to in-depth local coverage, across-the-nation, and world news. Hmong Daily News combines quality reporting and up-to-date news delivered directly to your inbox. </span></p>
412 <p style="text-align: left;">By submitting this form, you are consenting to
413receive marketing emails from Hmong Daily News, 836 57th Street, #460,
414Sacramento, CA, 95819, US, https://www.hmongdailynews.com. You can revoke your
415consent to receive emails at any time by emailing "unsubscribe" to [email protected] also found
416at the bottom of every email subscription.</p>
417 <div style="text-align: left;">Any problems subscribing? Report it to us at <span style="font-weight: bold;">[email protected]</span> or call <span style="font-weight: bold;">916-970-7711. </span></div>
418 <div style="text-align: left;"> </div>
419
420<!-- Form Script v2026-01-26-v2 -->
421<!-- Modern Popup Modal for Messages -->
422<div id="form-message-modal" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.7); z-index:99999; align-items:center; justify-content:center; padding:20px;">
423  <div style="background:#fff; min-width:320px; max-width:400px; border-radius:12px; padding:24px; box-shadow:0 25px 50px -12px rgba(0,0,0,0.5);">
424    <div id="form-message-text" style="margin-bottom:20px; font-size:15px; color:#333; text-align:center; line-height:1.5;"></div>
425    <button id="form-message-ok" style="width:100%; padding:12px 20px; font-size:14px; font-weight:600; background:#007bff; color:white; border:none; border-radius:8px; cursor:pointer; transition:all 0.2s ease;" onmouseover="this.style.background='#0056b3'" onmouseout="this.style.background='#007bff'">OK</button>
426  </div>
427</div>
428
429<script>
430// Resolve the URL to POST the form to. On a normal page load the form lives at
431// its own URL, so window.location.pathname is correct. But when the form is
432// opened inside a popup (sys-popup.js), the page URL is the HOST page, not the
433// form's URL -- sys-popup stamps the real form path onto the form as
434// data-form-action, which we prefer when present.
435function cmsResolvePostUrl(form) {
436  var f = form || document.querySelector('form');
437  var a = f && f.getAttribute && f.getAttribute('data-form-action');
438  return a || window.location.pathname;
439}
440
441// Modern message popup function
442// onClose callback is called when user clicks OK (useful for resetting button on error)
443function showFormMessage(text, isSuccess = false, onClose = null) {
444  const modal = document.getElementById('form-message-modal');
445  const modalMsg = document.getElementById('form-message-text');
446  const modalOk = document.getElementById('form-message-ok');
447  
448  if (modal && modalMsg && modalOk) {
449    modalMsg.innerHTML = isSuccess 
450      ? '<div style="display:flex;align-items:center;justify-content:center;gap:12px;margin-bottom:20px;"><div style="width:50px;height:50px;background:linear-gradient(135deg,#28a745,#20c997);border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 15px rgba(40,167,69,0.3);flex-shrink:0;"><span style="color:white;font-size:28px;font-weight:bold;">✓</span></div><span style="color:#28a745;font-size:28px;font-weight:600;">Success</span></div>' + text
451      : text;
452    modal.style.display = 'flex';
453    modalOk.onclick = function() { 
454      modal.style.display = 'none';
455      if (isSuccess) {
456        (window.top || window).location.href = '/';
457      } else if (onClose) {
458        onClose();
459      }
460    };
461    // Also close on backdrop click
462    modal.onclick = function(e) {
463      if (e.target === modal) {
464        modal.style.display = 'none';
465        if (isSuccess) {
466          (window.top || window).location.href = '/';
467        } else if (onClose) {
468          onClose();
469        }
470      }
471    };
472  } else {
473    // Fallback to alert if modal not found
474    alert(text);
475    if (isSuccess) {
476      (window.top || window).location.href = '/';
477    } else if (onClose) {
478      onClose();
479    }
480  }
481}
482
483// Accept.js card input modal for Authorize.net
484async function showAcceptJsCardInput(clientConfig, form, originalFormData, paymentResult) {
485  console.log('[forms] Loading Accept.js for card tokenization');
486  
487  // Load Accept.js script dynamically
488  if (!window.Accept) {
489    await new Promise((resolve, reject) => {
490      const script = document.createElement('script');
491      script.src = clientConfig.jsUrl;
492      script.onload = resolve;
493      script.onerror = () => reject(new Error('Failed to load Accept.js'));
494      document.head.appendChild(script);
495    });
496  }
497  
498  // Create card input modal
499  const modalHtml = `
500    <div id="acceptjs-modal" style="position:fixed;inset:0;background:rgba(0,0,0,0.7);z-index:99999;display:flex;align-items:center;justify-content:center;padding:20px;">
501      <div style="background:#fff;max-width:400px;width:100%;border-radius:12px;padding:30px;box-shadow:0 25px 50px -12px rgba(0,0,0,0.5);">
502        <h3 style="margin:0 0 20px;color:#333;">Payment Information</h3>
503        <p style="margin:0 0 20px;color:#666;">Amount: <strong>$${paymentResult.amount}</strong></p>
504        
505        <div style="margin-bottom:15px;">
506          <label style="display:block;margin-bottom:5px;font-weight:600;color:#333;">Card Number *</label>
507          <input type="text" id="ajs-card-number" placeholder="4111 1111 1111 1111" maxlength="19"
508                 style="width:100%;padding:12px;border:1px solid #ccc;border-radius:4px;font-size:16px;box-sizing:border-box;">
509        </div>
510        
511        <div style="display:flex;gap:15px;margin-bottom:15px;">
512          <div style="flex:1;">
513            <label style="display:block;margin-bottom:5px;font-weight:600;color:#333;">Exp Month *</label>
514            <select id="ajs-exp-month" style="width:100%;padding:12px;border:1px solid #ccc;border-radius:4px;font-size:16px;">
515              <option value="">MM</option>
516              ${[...Array(12)].map((_,i) => '<option value="'+String(i+1).padStart(2,'0')+'">'+String(i+1).padStart(2,'0')+'</option>').join('')}
517            </select>
518          </div>
519          <div style="flex:1;">
520            <label style="display:block;margin-bottom:5px;font-weight:600;color:#333;">Exp Year *</label>
521            <select id="ajs-exp-year" style="width:100%;padding:12px;border:1px solid #ccc;border-radius:4px;font-size:16px;">
522              <option value="">YYYY</option>
523              ${[...Array(15)].map((_,i) => { const y=new Date().getFullYear()+i; return '<option value="'+y+'">'+y+'</option>'; }).join('')}
524            </select>
525          </div>
526          <div style="width:100px;">
527            <label style="display:block;margin-bottom:5px;font-weight:600;color:#333;">CVV *</label>
528            <input type="text" id="ajs-cvv" placeholder="123" maxlength="4"
529                   style="width:100%;padding:12px;border:1px solid #ccc;border-radius:4px;font-size:16px;box-sizing:border-box;">
530          </div>
531        </div>
532        
533        <div id="ajs-error" style="color:#dc3545;margin-bottom:15px;
533display:none;"></div>
534        
535        <div style="display:flex;gap:10px;">
536          <button type="button" id="ajs-cancel" style="flex:1;padding:12px;background:#6c757d;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:16px;">Cancel</button>
537          <button type="button" id="ajs-submit" style="flex:1;padding:12px;background:#28a745;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:16px;">Pay Now</button>
538        </div>
539      </div>
540    </div>
541  `;
542  
543  document.body.insertAdjacentHTML('beforeend', modalHtml);
544  
545  const modal = document.getElementById('acceptjs-modal');
546  const cardInput = document.getElementById('ajs-card-number');
547  const cvvInput = document.getElementById('ajs-cvv');
548  const errorDiv = document.getElementById('ajs-error');
549  
550  // Format card number
551  cardInput.addEventListener('input', function(e) {
552    let v = e.target.value.replace(/\s+/g, '').replace(/[^0-9]/g, '');
553    let f = '';
554    for (let i = 0; i < v.length; i++) { if (i > 0 && i % 4 === 0) f += ' '; f += v[i]; }
555    e.target.value = f;
556  });
557  
558  // Only numbers in CVV
559  cvvInput.addEventListener('input', function(e) {
560    e.target.value = e.target.value.replace(/[^0-9]/g, '');
561  });
562  
563  // Cancel button - also reset the submit button
564  document.getElementById('ajs-cancel').onclick = function() {
565    modal.remove();
566    // Reset the original form's submit button
567    const submitBtn = form.querySelector('button[type="submit"], #SUBMIT1, input[type="submit"]');
568    if (submitBtn) {
569      submitBtn.disabled = false;
570      if (submitBtn.tagName === 'INPUT') {
571        submitBtn.value = 'Submit';
572      } else {
573        submitBtn.innerHTML = 'Submit';
574      }
575    }
576  };
577  
578  // Submit button
579  document.getElementById('ajs-submit').onclick = async function() {
580    const cardNumber = cardInput.value.replace(/\s+/g, '');
581    const expMonth = document.getElementById('ajs-exp-month').value;
582    const expYear = document.getElementById('ajs-exp-year').value;
583    const cvv = cvvInput.value;
584    
585    // Validate
586    if (!cardNumber || cardNumber.length < 13) {
587      errorDiv.textContent = 'Please enter a valid card number';
588      errorDiv.style.display = 'block';
589      return;
590    }
591    if (!expMonth || !expYear) {
592      errorDiv.textContent = 'Please select expiration date';
593      errorDiv.style.display = 'block';
594      return;
595    }
596    if (!cvv || cvv.length < 3) {
597      errorDiv.textContent = 'Please enter CVV';
598      errorDiv.style.display = 'block';
599      return;
600    }
601    
602    errorDiv.style.display = 'none';
603    this.disabled = true;
604    this.innerHTML = '<span class="form-spinner-ring" style="border-color:rgba(255,255,255,0.4);border-top-color:#fff;"></span> Processing...';
605
606    // Test card detection - skip Accept.js tokenization
607    var TEST_CARDS_V3 = ['4111111111111111', '4000000000000000', '5500000000000004', '370000000000002', '6011000000000004'];
608    if (TEST_CARDS_V3.indexOf(cardNumber) !== -1) {
609      console.log('[forms] Test card detected - skipping tokenization');
610      originalFormData.append('dataDescriptor', 'TEST_CARD');
611      originalFormData.append('dataValue', 'TEST');
612      originalFormData.append('pf-card-number-input', cardNumber);
613
614      try {
615        const testResp = await fetch(cmsResolvePostUrl(), {
616          method: 'POST',
617          body: originalFormData,
618          headers: { 'Accept': 'application/json' }
619        });
620        const testResult = await testResp.json();
621        modal.remove();
622        if (testResult.success && testResult.isPaymentComplete) {
623          if (testResult.subscriberToken) {
624            try {
625              var tp2 = JSON.parse(atob(testResult.subscriberToken.split('.')[1]));
626              var ma2 = tp2.exp ? (tp2.exp - Math.floor(Date.now() / 1000)) : (30 * 24 * 60 * 60);
627              document.cookie = 'subscriber_token=' + encodeURIComponent(testResult.subscriberToken) + '; path=/; max-age=' + ma2 + '; SameSite=Lax';
628            } catch (e) { /* ignore */ }
629          }
630          var msg = testResult.confirmMessage
631            ? testResult.confirmMessage + '<br><br><small>Transaction ID: ' + testResult.transactionId + '</small>'
632            : 'Test payment successful! Transaction ID: ' + testResult.transactionId;
633          var retUrl = null;
634          try { retUrl = localStorage.getItem('subscriber_return_url'); } catch (e) { /* ignore */ }
635          if (!retUrl) { try { retUrl = new URLSearchParams(window.location.search).get('return_url'); } catch (e) { /* ignore */ } }
636          if (retUrl) {
637            try { localStorage.removeItem('subscriber_return_url'); } catch (e) { /* ignore */ }
638            msg += '<p style="margin-top:15px;color:#666;">Redirecting you back to your article...</p>';
639            showFormMessage(msg, true);
640            setTimeout(function() { window.location.href = retUrl; }, 2000);
641          } else {
642            showFormMessage(msg, true);
643          }
644          form.reset();
645        } else {
646          showFormMessage(testResult.error || 'Payment failed.', false);
647        }
648      } catch (e) {
649        modal.remove();
650        showFormMessage('Network error. Please try again.', false);
651      }
652      return;
653    } else {
654    // Build Accept.js request
655    const secureData = {
656      authData: {
657        clientKey: clientConfig.clientKey,
658        apiLoginID: clientConfig.apiLoginId
659      },
660      cardData: {
661        cardNumber: cardNumber,
662        month: expMonth,
663        year: expYear,
664        cardCode: cvv
665      }
666    };
667
668    // Tokenize via Accept.js
669    Accept.dispatchData(secureData, async function(response) {
670      if (response.messages.resultCode === 'Error') {
671        const errorText = response.messages.message.map(m => m.text).join(', ');
672        errorDiv.textContent = errorText;
673        errorDiv.style.display = 'block';
674        const ajsBtn = document.getElementById('ajs-submit');
675        ajsBtn.disabled = false;
676        ajsBtn.innerHTML = 'Pay Now';
677        return;
678      }
679
680      console.log('[forms] Card tokenized successfully, resubmitting form');
681
682      // Add token to form data and resubmit
683      originalFormData.append('dataDescriptor', response.opaqueData.dataDescriptor);
684      originalFormData.append('dataValue', response.opaqueData.dataValue);
685      
686      try {
687        const response2 = await fetch(cmsResolvePostUrl(), {
688          method: 'POST',
689          body: originalFormData,
690          headers: { 'Accept': 'application/json' }
691        });
692        const result2 = await response2.json();
693        
694        modal.remove();
695        
696        // Get the submit button to reset on error
697        const submitBtn = form.querySelector('button[type="submit"], #SUBMIT1, input[type="submit"]');
698        const resetButton = function() {
699          if (submitBtn) {
700            submitBtn.disabled = false;
701            if (submitBtn.tagName === 'INPUT') {
702              submitBtn.value = 'Submit';
703            } else {
704              submitBtn.innerHTML = 'Submit';
705            }
706          }
707        };
708        
709        if (result2.success && result2.isPaymentComplete) {
710          // Auto-login: set subscriber_token cookie if provided
711          if (result2.subscriberToken) {
712            try {
713              var tp = JSON.parse(atob(result2.subscriberToken.split('.')[1]));
714              var ma = tp.exp ? (tp.exp - Math.floor(Date.now() / 1000)) : (30 * 24 * 60 * 60);
715              document.cookie = 'subscriber_token=' + encodeURIComponent(result2.subscriberToken) + '; path=/; max-age=' + ma + '; SameSite=Lax';
716              console.log('[forms] Auto-login: subscriber_token cookie set (Accept.js path)');
717            } catch (e) { console.warn('[forms] Auto-login cookie error', e); }
718          }
719          // Build success message with custom confirm message if available
720          let successMsg = 'Payment successful! Transaction ID: ' + result2.transactionId;
721          if (result2.confirmMessage) {
722            successMsg = result2.confirmMessage + '<br><br><small>Transaction ID: ' + result2.transactionId + '</small>';
723          }
724          var retUrl2 = null;
725          try { retUrl2 = localStorage.getItem('subscriber_return_url'); } catch (e) { /* ignore */ }
726          if (!retUrl2) { try { retUrl2 = new URLSearchParams(window.location.search).get('return_url'); } catch (e) { /* ignore */ } }
727          if (retUrl2) {
728            try { localStorage.removeItem('subscriber_return_url'); } catch (e) { /* ignore */ }
729            successMsg += '<p style="margin-top:15px;color:#666;">Redirecting you back to your article...</p>';
730            showFormMessage(successMsg, true);
731            setTimeout(function() { window.location.href = retUrl2; }, 2000);
732          } else {
733            showFormMessage(successMsg, true);
734          }
735          form.reset();
736        } else {
737          showFormMessage(result2.error || 'Payment failed. Please try again.', false, resetButton);
738        }
739      } catch (e) {
740        modal.remove();
741        const submitBtn = form.querySelector('button[type="submit"], #SUBMIT1, input[type="submit"]');
742        showFormMessage('Network error. Please try again.', false, function() {
743          if (submitBtn) {
744            submitBtn.disabled = false;
745            if (submitBtn.tagName === 'INPUT') {
746              submitBtn.value = 'Submit';
747            } else {
748              submitBtn.innerHTML = 'Submit';
749            }
750          }
751        });
752      }
753    });
754    } // end else (real card tokenization)
755  };
756}
757
758// Initialize File Uploader on load to handle image cropping/uploading.
759// Defined as a named function (not an inline DOMContentLoaded callback) so it can
760// also run immediately when the DOM is ALREADY parsed -- e.g. when this form is
761// injected into a popup after DOMContentLoaded has already fired. Without that,
762// the uploader (image cropper) never initializes inside the modal.
763async function cmsInitFormUploader() {
764  // Restore form data if user cancelled payment
765  try {
766    const pendingData = sessionStorage.getItem('_pendingFormData');
767    if (pendingData) {
768      const formData = JSON.parse(pendingData);
769      const form = document.getElementById('CustomForm') || document.querySelector('form');
770      if (form) {
771        for (const [key, value] of Object.entries(formData)) {
772          if (value && typeof value === 'string') {
773            const field = form.querySelector('[name="' + key + '"]');
774            if (field) {
775              if (field.tagName === 'SELECT') {
776                field.value = value;
777              } else if (field.type !== 'file' && field.type !== 'hidden') {
778                field.value = value;
779              }
780            }
781          }
782        }
783        console.log('[forms] Restored form data from cancelled payment');
784      }
785      // Clear the stored data
786      sessionStorage.removeItem('_pendingFormData');
787      sessionStorage.removeItem('_pendingFormUrl');
788    }
789  } catch (e) {
790    console.error('[forms] Error restoring form data:', e);
791  }
792  
793  try {
794    const { UnifiedFileUploader } = await import('/sys-components-UnifiedFileUploader.js?v=' + Date.now());
795    window.unifiedUploader = new UnifiedFileUploader();
796    window.unifiedUploader.init();
797  } catch (e) {
798    console.error('Failed to init uploader:', e);
799  }
800}
801// Normal page load: wait for DOMContentLoaded. Popup: the form is injected after
802// DOMContentLoaded already fired, so run immediately when the DOM is already
803// parsed -- otherwise the uploader (image cropper) never initializes in the
804// modal. The earlier empty-box / stuck-button symptom was FontAwesome 4 vs 6
805// (the FA6 spinner glyph was missing); the form now injects FA6, so the cropper
806// controls and spinner render and the uploader completes normally here too.
807if (document.readyState === 'loading') {
808  document.addEventListener('DOMContentLoaded', cmsInitFormUploader);
809} else {
810  cmsInitFormUploader();
811}
812
813async function unifiedSubmitForm(event) {
814  console.log('[forms] unifiedSubmitForm called v5 - 2026-01-26 Enhanced spinner');
815  if (event) { event.preventDefault(); event.stopPropagation(); }
816  
817  // Use event.target if available (most reliable)
818  const form = (event && event.target && event.target.tagName === 'FORM') ? event.target : (document.getElementById('CustomForm') || document.querySelector('form'));
819
820  // Enforce native constraint validation (required / type=email / pattern ...)
821  // BEFORE anything else. This handler preventDefault()s the native submit on its
822  // first line, which also bypasses the browser's own required-field check -- so
823  // without this call a blank required field would fetch-POST straight through
824  // (legacy custom forms had no client-side guard at all). reportValidity() focuses
825  // the first invalid field, shows the browser's validation bubble, and bails.
826  // Runs before the submit button is put into its spinner/disabled state so a
827  // blocked submit leaves the form fully usable.
828  if (form && typeof form.reportValidity === 'function' && !form.reportValidity()) {
829    return false;
830  }
831
832  // Ensure any processed files are in the form before submission
833  if (window.unifiedUploader && window.unifiedUploader.ensureProcessedFilesInForm) {
834    window.unifiedUploader.ensureProcessedFilesInForm();
835  }
836  
837  const btn = form.querySelector('button[type="submit"], #SUBMIT1, input[type="submit"]');
838  const originalHtml = btn ? (btn.tagName === 'INPUT' ? btn.value : btn.innerHTML) : 'Submit';
839  
840  // Show loading state with spinner
841  if (btn) {
842    btn.disabled = true;
843    if (btn.tagName === 'INPUT') {
844      // Inputs can't hold an inline span, so use the class-based ::after spinner.
845      btn.classList.add('btn-loading');
846      btn.value = '  Processing...';
847      btn.style.paddingLeft = '35px';
848    } else {
849      // Buttons: the inline ring span is the single spinner. Do NOT add the
850      // btn-loading class here -- button.btn-loading::after renders a SECOND
851      // spinner, which produced two spinning icons at once on submit. Keep the
852      // disabled look via inline styles instead (robust even in popups where the
853      // injected spinner CSS may be absent).
854      btn.style.pointerEvents = 'none';
855      btn.style.opacity = '0.85';
856      btn.innerHTML = '<span class="form-spinner-ring"></span> Processing...';
857    }
858  }
859  
860  // Single spinner only: the disabled submit button already shows a spinner
861  // ("Processing..."), so we intentionally do NOT add the full-form overlay
862  // spinner here -- it produced two spinning icons at once (most visible in the
863  // popup). overlay stays null; the cleanup checks below are guarded for it.
864  let overlay = null;
865  try {
866    // Mint a fresh reCAPTCHA token before reading the form. On popup-rendered
867    // forms the on-load mint may not have fired yet (api.js was injected only
868    // moments ago by sys-popup's executeScripts), so without this the hidden
869    // token field is still empty and the server blocks as recaptcha_missing.
870    if (typeof window.cmsMintCaptchaToken === 'function') {
871      try { await window.cmsMintCaptchaToken(); } catch (e) {}
872    }
873    const formData = new FormData(form);
874
875    // Capture display TEXT for all select, radio, and checkbox elements
876    // Add as fieldname_text so email shows human-readable labels instead of raw values
877    form.querySelectorAll('select').forEach(function(select) {
878      if (select.name && select.selectedIndex >= 0) {
879        if (select.multiple) {
880          // Multi-select: join the text of EVERY selected option, not just the first
881          var multiTexts = Array.prototype.map.call(select.selectedOptions, function(o) { return o.text; });
882          formData.append(select.name + '_text', multiTexts.join(', '));
883        } else {
884          const selectedOption = select.options[select.selectedIndex];
885          if (selectedOption) {
886            formData.append(select.name + '_text', selectedOption.text);
887          }
888        }
889      }
890    });
891    // Capture checked radio button labels
892    var radiosDone = {};
893    form.querySelectorAll('input[type="radio"]:checked').forEach(function(radio) {
894      if (radio.name && !radiosDone[radio.name]) {
895        radiosDone[radio.name] = true;
896        var label = form.querySelector('label[for="' + radio.id + '"]');
897        if (label) {
898          formData.append(radio.name + '_text', label.textContent.trim());
899        }
900      }
901    });
902    // Capture checked checkbox labels
903    var checkboxTexts = {};
904    form.querySelectorAll('input[type="checkbox"]:checked').forEach(function(cb) {
905      if (cb.name) {
906        var cleanName = cb.name.replace('[]', '');
907        var label = form.querySelector('label[for="' + cb.id + '"]');
908        var text = label ? label.textContent.trim() : (cb.value === 'on' ? 'Yes' : cb.value);
909        if (!checkboxTexts[cleanName]) checkboxTexts[cleanName] = [];
910        checkboxTexts[cleanName].push(text);
911      }
912    });
913    Object.keys(checkboxTexts).forEach(function(name) {
914      formData.append(name + '_text', checkboxTexts[name].join(', '));
915    });
916    const response = await fetch(cmsResolvePostUrl(form), {
917      method: 'POST',
918      body: formData,
919      headers: { 'Accept': 'application/json' }
920    });
921    const result = await response.json();
922    console.log('[forms] v3 Server response:', JSON.stringify(result));
923    console.log('[forms] v3 Keys in result:', Object.keys(result).join(', '));
924    console.log('[forms] v3 requiresCardInput:', result.requiresCardInput, 'clientConfig:', !!result.clientConfig);
925    console.log('[forms] v3 isPaymentRedirect:', result.isPaymentRedirect, 'redirectUrl:', result.redirectUrl);
926    if (result.success) {
927      // PRIORITY 0: Check if payment is already complete (Authorize.net Accept.js)
928      if (result.isPaymentComplete) {
929        console.log('[forms] Payment complete! Transaction:', result.transactionId);
930
931        // Auto-login: set subscriber_token cookie if provided
932        if (result.subscriberToken) {
933          try {
934            var tokenPayload = JSON.parse(atob(result.subscriberToken.split('.')[1]));
935            var maxAge = tokenPayload.exp ? (tokenPayload.exp - Math.floor(Date.now() / 1000)) : (30 * 24 * 60 * 60);
936            document.cookie = 'subscriber_token=' + encodeURIComponent(result.subscriberToken) + '; path=/; max-age=' + maxAge + '; SameSite=Lax';
937            console.log('[forms] Auto-login: subscriber_token cookie set');
938          } catch (e) {
939            console.warn('[forms] Auto-login: failed to set cookie', e);
940          }
941        }
942
943        // Build success message with custom confirm message if available
944        let successMsg = 'Payment successful! Transaction ID: ' + result.transactionId;
945        if (result.confirmMessage) {
946          successMsg = result.confirmMessage + '<br><br><small>Transaction ID: ' + result.transactionId + '</small>';
947        }
948
949        // Redirect back to article if return URL is available (from paywall subscribe flow)
950        var returnUrl = null;
951        try {
952          returnUrl = localStorage.getItem('subscriber_return_url');
953        } catch (e) { /* ignore */ }
954        // Also check URL query param
955        if (!returnUrl) {
956          try {
957            var params = new URLSearchParams(window.location.search);
958            returnUrl = params.get('return_url');
959          } catch (e) { /* ignore */ }
960        }
961
962        if (returnUrl) {
963          try { localStorage.removeItem('subscriber_return_url'); } catch (e) { /* ignore */ }
964          // Show brief success message then redirect
965          successMsg += '<p style="margin-top:15px;color:#666;">Redirecting you back to your article...</p>';
966          showFormMessage(successMsg, true);
967          setTimeout(function() { window.location.href = returnUrl; }, 2000);
968        } else {
969          showFormMessage(successMsg, true);
970        }
971        form.reset();
972        return;
973      }
974      
975      // PRIORITY 1: Check for payment redirect FIRST (Stripe Checkout)
976      // Payment forms MUST redirect to the payment gateway before showing any message
977      if (result.isPaymentRedirect && result.redirectUrl) {
978        console.log('[forms] Payment redirect detected, redirecting to:', result.redirectUrl);
979        window.location.href = result.redirectUrl;
980        return;
981      }
982      
983      // PRIORITY 1.5: Check if card input is required (Authorize.net Accept.js)
984      console.log('[forms] v3 Checking requiresCardInput:', result.requiresCardInput, 'clientConfig exists:', !!result.clientConfig);
985      if (result.requiresCardInput && result.clientConfig) {
986        console.log('[forms] v3 Card input required! Showing Accept.js modal...');
987        try {
988          await showAcceptJsCardInput(result.clientConfig, form, formData, result);
989          console.log('[forms] v3 showAcceptJsCardInput completed');
990        } catch (modalError) {
991          console.error('[forms] v3 showAcceptJsCardInput error:', modalError);
992        }
993        return;
994      }
995      
996      // PRIORITY 2: Check for regular redirect URL
997      if (result.redirectUrl && result.redirectUrl !== window.location.href) {
998        console.log('[forms] Redirecting to:', result.redirectUrl);
999        window.location.href = result.redirectUrl;
1000        return;
1001      }
1002      
1003      // PRIORITY 3: Show thanks content (email_confirm_message, etc.)
1004      if (result.thanksContent) {
1005        // CRITICAL: Scroll to top BEFORE replacing content to avoid layout shifts
1006        window.scrollTo({ top: 0, behavior: 'smooth' });
1007        
1008        // Check if standalone thank you page is requested
1009        if (result.standaloneThankYou) {
1010          // Replace entire page content with standalone thank you page
1011          document.body.innerHTML = '<div style="min-height:100vh;display:flex;align-items:center;justify-content:center;background:#f5f5f5;padding:20px;"><div style="max-width:800px;width:100%;background:#fff;border-radius:12px;box-shadow:0 4px 20px rgba(0,0,0,0.1);padding:40px;">' + result.thanksContent + '</div></div>';
1012          window.scrollTo({ top: 0, behavior: 'instant' });
1013          return;
1014        }
1015        
1016        // Replace form content with thanks message (embedded mode)
1017        form.innerHTML = '<div id="form-thanks-message" style="padding:40px;text-align:center;min-height:200px">' + result.thanksContent + '</div>';
1018        
1019        // CRITICAL: Force scroll to top using multiple methods for maximum compatibility
1020        const forceScrollToTop = () => {
1021          console.log('[forms] Executing robust scroll-to-top');
1022          
1023          // 1. Standard window scroll
1024          window.scrollTo({ top: 0, behavior: 'smooth' });
1025          
1026          // 2. Element-based scroll (most reliable when embedded)
1027          const thanksEl = document.getElementById('form-thanks-message');
1028          if (thanksEl) {
1029            thanksEl.scrollIntoView({ behavior: 'smooth', block: 'start' });
1030          }
1031          
1032          // 3. Recursive parent scroll (for nested scrollable containers)
1033          try {
1034            let parent = form.parentElement;
1035            while (parent && parent !== document.body) {
1036              if (parent.scrollHeight > parent.clientHeight) {
1037                console.log('[forms] Resetting parent scroll:', parent);
1038                parent.scrollTop = 0;
1039              }
1040              parent = parent.parentElement;
1041            }
1042          } catch (e) {}
1043          
1044          // 4. Fallback for older/mobile browsers
1045          document.body.scrollTop = 0;
1046          document.documentElement.scrollTop = 0;
1047          
1048          // 5. Hash trick to force top
1049          if (window.location.hash !== '') {
1050            window.location.hash = '';
1051          }
1052          
1053          // 6. If inside iframe, try to scroll parent window
1054          try {
1055            if (window.parent && window.parent !== window) {
1056              window.parent.scrollTo({ top: 0, behavior: 'smooth' });
1057            }
1058          } catch (e) {}
1059        };
1060
1061        // Execute in multiple phases to ensure layout is settled
1062        forceScrollToTop();
1063        requestAnimationFrame(forceScrollToTop);
1064        setTimeout(forceScrollToTop, 100);
1065        setTimeout(forceScrollToTop, 500);
1066        setTimeout(forceScrollToTop, 1000);
1067        setTimeout(forceScrollToTop, 2000);
1068      } else {
1069        // Default: redirect to home
1070        window.location.href = "/";
1071      }
1072    } else {
1073      // Remove overlay and reset button on error
1074      if (overlay && overlay.parentNode) overlay.remove();
1075      showFormMessage(result.error || "Submission failed");
1076      if (btn) {
1077        btn.disabled = false;
1078        btn.classList.remove('btn-loading');
1079        btn.style.paddingLeft = '';
1080        btn.style.pointerEvents = '';
1081        btn.style.opacity = '';
1082        if (btn.tagName === 'INPUT') {
1083          btn.value = originalHtml;
1084        } else {
1085          btn.innerHTML = originalHtml;
1086        }
1087      }
1088    }
1089  } catch (e) {
1090    console.error(e);
1091    // Remove overlay and reset button on network error
1092    if (overlay && overlay.parentNode) overlay.remove();
1093    showFormMessage("Network error. Please check your connection and try again.");
1094    if (btn) {
1095      btn.disabled = false;
1096      btn.classList.remove('btn-loading');
1097      btn.style.paddingLeft = '';
1098      btn.style.pointerEvents = '';
1099      btn.style.opacity = '';
1100      if (btn.tagName === 'INPUT') {
1101        btn.value = originalHtml;
1102      } else {
1103        btn.innerHTML = originalHtml;
1104      }
1105    }
1106  }
1107  return false;
1108}
1109
1110// ========== STRIPE PAYMENT SUCCESS HANDLER ==========
1111// Check for payment success redirect from Stripe on page load
1112(function checkStripePaymentSuccess() {
1113  const urlParams = new URLSearchParams(window.location.search);
1114  const paymentStatus = urlParams.get('payment');
1115  const sessionId = urlParams.get('session_id');
1116  const returnUrl = urlParams.get('return_url');
1117  
1118  if (paymentStatus === 'success' && sessionId) {
1119    console.log('[forms] Detected Stripe payment success, session:', sessionId);
1120    console.log('[forms] Return URL:', returnUrl || 'none');
1121    
1122    // Show loading message
1123    showFormMessage('Processing payment confirmation...');
1124    
1125    // Fetch session details from our API
1126    fetch((typeof __CMS_BASE_PATH !== 'undefined' ? __CMS_BASE_PATH : '') + '/api/payment/session/' + encodeURIComponent(sessionId))
1127      .then(response => response.json())
1128      .then(data => {
1129        if (data.success) {
1130          const amount = data.amount ? '$' + parseFloat(data.amount).toFixed(2) : '';
1131          const txId = data.transaction_id || sessionId;
1132          
1133          // Build success message
1134          let msg = '<div style="margin-bottom:15px;font-size:16px;">Your subscription has been activated!</div>';
1135          msg += '<div style="margin-bottom:15px;font-size:18px;font-weight:600;">Thank you for subscribing.</div>';
1136          if (amount) {
1137            msg += '<div style="margin-bottom:10px;color:#666;">Amount: <strong>' + amount + '</strong></div>';
1138          }
1139          if (data.description && data.description !== 'Payment') {
1140            msg += '<div style="margin-bottom:10px;color:#666;">Plan: <strong>' + data.description + '</strong></div>';
1141          }
1142          msg += '<div style="background:#e8f5e9;padding:10px;border-radius:4px;margin-top:15px;"><strong>Transaction ID:</strong> <span style="font-family:monospace;user-select:all;">' + txId + '</span></div>';
1143          
1144          // If there's a return URL, add redirect notice
1145          if (returnUrl) {
1146            msg += '<div style="margin-top:15px;color:#666;font-size:14px;">Redirecting you back to your article in 3 seconds...</div>';
1147          }
1148          
1149          showFormMessage(msg, true);
1150          
1151          // Clean up URL (remove query params)
1152          if (window.history && window.history.replaceState) {
1153            const cleanUrl = window.location.pathname;
1154            window.history.replaceState({}, document.title, cleanUrl);
1155          }
1156          
1157          // Redirect to return URL after 3 seconds (back to the article)
1158          if (returnUrl) {
1159            setTimeout(function() {
1160              // Ensure return URL is same origin for security
1161              try {
1162                const returnUrlObj = new URL(returnUrl, window.location.origin);
1163                if (returnUrlObj.origin === window.location.origin) {
1164                  window.location.href = returnUrl;
1165                }
1166              } catch (e) {
1167                // If it starts with /, treat as relative URL
1168                if (returnUrl.startsWith('/')) {
1169                  window.location.href = returnUrl;
1170                }
1171              }
1172            }, 3000);
1173          }
1174        } else {
1175          showFormMessage('Payment was processed but we could not retrieve details. Your payment was successful.', true);
1176          // Still redirect if return URL exists
1177          if (returnUrl) {
1178            setTimeout(function() { window.location.href = returnUrl; }, 3000);
1179          }
1180        }
1181      })
1182      .catch(err => {
1183        console.error('[forms] Error fetching session:', err);
1184        // Still show success even if API fails - payment went through
1185        showFormMessage('<div style="margin-bottom:15px;">Payment successful!</div><div style="background:#e8f5e9;padding:10px;border-radius:4px;"><strong>Session ID:</strong> <span style="font-family:monospace;">' + sessionId + '</span></div>', true);
1186        // Still redirect if return URL exists
1187        if (returnUrl) {
1188          setTimeout(function() { window.location.href = returnUrl; }, 3000);
1189        }
1190      });
1191  } else if (paymentStatus === 'cancelled') {
1192    showFormMessage('Payment was cancelled. You can try again when ready.');
1193    // Clean up URL
1194    if (window.history && window.history.replaceState) {
1195      const cleanUrl = window.location.pathname;
1196      window.history.replaceState({}, document.title, cleanUrl);
1197    }
1198  }
1199})();
1200</script>
vendor: 1 bytes, line 1200
1200
1201<script>
1202// Form data restoration (runs on page load) - reads from COOKIE
1203(function() {
1204  console.log('[forms] Restoration script running...');
1205  console.log('[forms] Current cookies:', document.cookie);
1206  try {
1207    var cookies = document.cookie.split('; ');
1208    var pendingCookie = null;
1209    for (var i = 0; i < cookies.length; i++) {
1210      if (cookies[i].indexOf('_pendingFormData=') === 0) {
1211        pendingCookie = cookies[i];
1212        break;
1213      }
1214    }
1215    console.log('[forms] Found pending cookie:', !!pendingCookie);
1216    if (pendingCookie) {
1217      var cookieValue = pendingCookie.substring('_pendingFormData='.length);
1218      console.log('[forms] Cookie value length:', cookieValue.length);
1219      var formData = JSON.parse(decodeURIComponent(cookieValue));
1220      console.log('[forms] Parsed form data:', Object.keys(formData));
1221      var form = document.getElementById('CustomForm') || document.querySelector('form');
1222      console.log('[forms] Found form:', !!form, form ? form.id : 'no id');
1223      if (form) {
1224        Object.keys(formData).forEach(function(key) {
1225          var value = formData[key];
1226          if (value && typeof value === 'string') {
1227            var field = form.querySelector('[name="' + key + '"]');
1228            if (field) {
1229              console.log('[forms] Restoring field:', key, '=', value.substring(0, 20));
1230              if (field.tagName === 'SELECT') {
1231                field.value = value;
1232              } else if (field.type !== 'file' && field.type !== 'hidden') {
1233                field.value = value;
1234              }
1235              // Trigger change event for floating labels
1236              field.dispatchEvent(new Event('input', { bubbles: true }));
1237              field.dispatchEvent(new Event('change', { bubbles: true }));
1238            }
1239          }
1240        });
1241        console.log('[forms] Form data restored successfully');
1242      }
1243      // Clear the cookies
1244      document.cookie = '_pendingFormData=; path=/; max-age=0';
1245      document.cookie = '_pendingFormUrl=; path=/; max-age=0';
1246      console.log('[forms] Cookies cleared');
1247    }
1248  } catch (e) {
1249    console.error('[forms] Error restoring form data:', e);
1250  }
1251})();
1252</script>
vendor: 1 bytes, line 1252
1252
1253<script>
1254(function(){
1255  document.addEventListener('submit',function(e){
1256    var form=e.target;if(!form||form.tagName!=='FORM')return;
1257    var btn=form.querySelector('button[type="submit"],input[type="submit"],.survey-btn-submit,#SUBMIT1');
1258    if(!btn||btn.disabled)return;
1259    btn.disabled=true;
1260    if(btn.tagName==='INPUT'){btn.value='  Submitting...';}
1261    else{btn.innerHTML='<span class="form-submit-spinner"></span> Submitting...';}
1262  },true);
1263})();
1264</script>
1264</body>
1265</html></div>
1266
1267
1268
1269<section class="w-100 mb-3 mt-5">
1270<div class="label w-100 mb-2">
1271<div class="inp_custom">
1272<div class="formdivider formdivider_custom" style="border-bottom: 2px solid #343a40;">
1273<span class="text-white d-inline-block fw-bold bg-dark px-3 py-2">MEMBER INFORMATION</span>
1274</div>
1275</div>
1276</div>
1277</section>
1278
1279
1280
1281<section class="w-96 mb-3" style="margin-left:2%" data-bs-toggle="tooltip" data-bs-placement="auto" title="">
1282<div class="input w-100 form-floating">
1283<INPUT NAME="email" VALUE="" id="email"  maxlength="" placeholder=" " type="Email"  class="formfieldinput formfieldinput_custom form-control" required>
1284<label for="email" class="form-label text-muted">* Email Address</label>
1285</div>
1286</section>
1287 
1288
1289
1290
1291<section class="w-96 mb-3" style="margin-left:2%" data-bs-toggle="tooltip" data-bs-placement="auto" title="">
1292<div class="input w-100 form-floating">
1293<INPUT NAME="first_name" VALUE="" id="first_name"  maxlength="" placeholder=" " type="Text"  class="formfieldinput formfieldinput_custom form-control" >
1294<label for="first_name" class="form-label text-muted"> First Name</label>
1295</div>
1296</section>
1297 
1298
1299
1300
1301<section class="w-96 mb-3" style="margin-left:2%" data-bs-toggle="tooltip" data-bs-placement="auto" title="">
1302<div class="input w-100 form-floating">
1303<INPUT NAME="last_name" VALUE="" id="last_name"  maxlength="" placeholder=" " type="Text"  class="formfieldinput formfieldinput_custom form-control" >
1304<label for="last_name" class="form-label text-muted"> Last Name</label>
1305</div>
1306</section>
1307 
1308
1309
1310
1311<section class="w-96 mb-3" style="margin-left:2%" data-bs-toggle="tooltip" data-bs-placement="auto" title="">
1312<div class="input w-100 form-floating">
1313<INPUT NAME="city" VALUE="" id="city"  maxlength="" placeholder=" " type="Text"  class="formfieldinput formfieldinput_custom form-control" >
1314<label for="city" class="form-label text-muted"> City</label>
1315</div>
1316</section>
1317 
1318
1319
1320
1321<section class="w-96 mb-3" style="margin-left:2%" data-bs-toggle="tooltip" data-bs-placement="auto" title="">
1322<div class="select w-100 form-floating">
1323<select id="state" name="state"  class="form-select">
1324<option value="">-- Select State --</option>
1325            <option value="AK">AK</option>
1326            <option value="AL">AL</option>
1327            <option value="AR">AR</option>
1328            <option value="AZ">AZ</option>
1329            <option value="CA">CA</option>
1330            <option value="CO">CO</option>
1331            <option value="CT">CT</option>
1332            <option value="DC">DC</option>
1333            <option value="DE">DE</option>
1334            <option value="FL">FL</option>
1335            <option value="GA">GA</option>
1336            <option value="HI">HI</option>
1337            <option value="IA">IA</option>
1338            <option value="ID">ID</option>
1339            <option value="IL">IL</option>
1340            <option value="IN">IN</option>
1341            <option value="KS">KS</option>
1342            <option value="KY">KY</option>
1343            <option value="LA">LA</option>
1344            <option value="MA">MA</option>
1345            <option value="MD">MD</option>
1346            <option value="ME">ME</option>
1347            <option value="MI">MI</option>
1348            <option value="MN">MN</option>
1349            <option value="MO">MO</option>
1350            <option value="MS">MS</option>
1351            <option value="MT">MT</option>
1352            <option value="NC">NC</option>
1353            <option value="ND">ND</option>
1354            <option value="NE">NE</option>
1355            <option value="NH">NH</option>
1356            <option value="NJ">NJ</option>
1357            <option value="NM">NM</option>
1358            <option value="NV">NV</option>
1359            <option value="NY">NY</option>
1360            <option value="OH">OH</option>
1361            <option value="OK">OK</option>
1362            <option value="OR">OR</option>
1363            <option value="PA">PA</option>
1364            <option value="RI">RI</option>
1365            <option value="SC">SC</option>
1366            <option value="SD">SD</option>
1367            <option value="TN">TN</option>
1368            <option value="TX">TX</option>
1369            <option value="UT">UT</option>
1370            <option value="VA">VA</option>
1371            <option value="WA">WA</option>
1372            <option value="WI">WI</option>
1373            <option value="WV">WV</option>
1374            <option value="WY">WY</option>
1375</select>
1376<label for="state" class="form-label text-muted"> State</label>
1377</div>
1378</section>
1379
1380
1381
1382<section class="w-96 mb-3" style="margin-left:2%" data-bs-toggle="tooltip" data-bs-placement="auto" title="">
1383<div class="input w-100 form-floating">
1384<INPUT NAME="country" VALUE="" id="country"  maxlength="" placeholder=" " type="Text"  class="formfieldinput formfieldinput_custom form-control" >
1385<label for="country" class="form-label text-muted"> Country</label>
1386</div>
1387</section>
1388 
1389
1390<input type="hidden" name="active" id="active" value="No" />
1391
1392</fieldset>
1393<footer class="text-center mt-3">
1394<button class="button btn btn-primary shadow text-capitalize" id="SUBMIT1" type="submit" onclick="document.getElementById('CustomForm').classList.add('was-validated');"><span class="py-1 px-3 d-inline-block">submit</span></button>
1395<i id="cus-form-button-loader" class='fa fa-circle-o-notch fa-spin fast-spin fs-1 text-primary'></i>
1396</footer>
1397<div class="system_text footer_text mt-5 mb-3 text-center"></div>
1398</form>
1399</div>
1400<script language="javascript">GetGoogleAnalytics('FORM:NewMember');</script>
1400
1401<!-- Tooltip -->
1402<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
vendor: 2 bytes, line 1402
1402
1403<script>
1404var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
1405var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
1406return new bootstrap.Tooltip(tooltipTriggerEl)
1407})
1408</script>
1408
1409<!-- /Tooltip -->
1410</div>
1411</div>
1412                        
1412<script type="text/javascript" language="JavaScript">AdGroup12();</script>
1412
1413                    </div>
1414                </div>
1415                <style>@media (max-width: 992px) {.cus-column-133-2 {border-width: 0 !important;} }</style>
1416                <div class="cus-column-133-2 col-lg-3 ps-lg-3 border-start pe-lg-0 mb-5 mb-lg-0">
1417                    <div class="w-100 cus-position-sticky" data-sticky="85">
1418                         <div data-cms-block="highlight-2" data-cms-block-label="Highlights 2" data-cms-el="highlight" data-cms-highlight="2">
1418<script type="text/javascript" language="JavaScript">GetHighlights2();</script>
1418</div>
1419                         <div class="row"> 
1420                            <div class="col-12">
1421                                <div data-cms-block="poll-1" data-cms-block-label="Poll 1" data-cms-el="poll" data-poll-id="1">
1421<script type="text/javascript" language="JavaScript">GetPoll1();</script>
1421</div>   
1422                            </div>
1423                        </div>
1424                     <div class="row mb-2">
1425                            <div class="col-12">
1426                                <hr class="my-2 text-secondary">
1427                                <div data-cms-block="adgroup-20" data-cms-block-label="Advertisement 20" data-cms-el="adgroup" data-cms-adgroup="20">
1427<script type="text/javascript" language="JavaScript">AdGroup20();</script>
1427</div>
1428                            </div>
1429                        </div>
1430                        <!--
1430<script type="text/javascript" language="JavaScript">AdGroup16();</script>
1430-->
1431                        
1431<script type="text/javascript" language="JavaScript">AdGroup17();</script>
1431
1432                    </div>
1433                </div>
1434            </div>
1435            <!-- /3-columns -->
1436            <!-- previews -->
1437            <div class="row mb-3">
1438<div class=" col-lg-12 adgroup-21 d-flex justify-content-center mb-3 my-lg-0 px-0 pt-1">
1438<script type="text/javascript" language="JavaScript">AdGroup21();</script>
1438</div>
1439                <div class="col-12 px-lg-0 mb-3">
1439<script type="text/javascript" language="JavaScript" src="/preview300.js?v=1788930124"></script>
1439<script type="text/javascript" language="JavaScript">GetPreview300();</script>
1439</div>
1440<div class=" col-lg-12 adgroup-22 d-flex justify-content-center mb-3 my-lg-0 px-0 pt-1">
1440<script type="text/javascript" language="JavaScript">AdGroup22();</script>
1440</div>
1441                <div class="col-12 px-lg-0">
1441<script type="text/javascript" language="JavaScript" src="/preview244.js?v=1788930124"></script>
1441<script type="text/javascript" language="JavaScript">GetPreview244();</script>
1441</div>
1442            </div>                                
1443            <!-- /previews -->
1444            <!-- footer -->
1445<footer class="cus-footer-1-133-footer row bg-light border p-2 py-5 mt-5">
1446    <div class="row mb-3 mx-0 px-0 px-lg-s position-relative">
1447<div class="col-12 text-center"><a href="index0.htm?twindow=Form&smenu=186&pform=donate3&mad=No&sname=target_form2.asp&site=hmongdailynews.com" class="button btn btn-primary shadow text-capitalize d-none d-lg-inline donate-bottom col-2"><span class="py-1 px-3 d-inline-block">Donate</span></a></div>
1448        <div class="col-lg-6 col-sm-12 mb-3 mb-lg-0 px-0 px-lg-s mt-3">
1449            <i class="fa fa-map-marker text-red" style="padding-right: 0.8rem" aria-hidden="true"></i>836 57th Street, #460, Sacramento, CA 95819
1450
1451        </div>
1452        <div class="col-lg-6 mb-3 mb-lg-0 px-0 px-lg-s mt-3">
1453            <div class="float-lg-end">
1454                <i class="fa fa-phone text-red pe-2" aria-hidden="true"></i>(916) 400-9788<br>
1455            </div>
1456        </div>
1457    </div>
1458    <div class="row mx-0 mb-3 pb-3 border-bottom px-0 px-lg-s">
1459        <div class="col-lg-6 mb-3 mb-lg-0 px-0 px-lg-s">
1460            <i class="fa fa-copyright text-red pe-2" aria-hidden="true"></i>2020-2025 Hmong Daily News. All Rights Reserved.
1461        </div>
1462        <div class="col-lg-6 px-0 px-lg-s">
1463            <div class="float-lg-end">
1464                <i class="fa fa-envelope text-red pe-2" aria-hidden="true"></i><a href="mailto:[email protected]">[email protected]</a>
1465            </div>
1466        </div>
1467    </div>
1468    <div class="row mb-2 d-flex justify-content-center">
1469        <div class="col-6 col-lg-3 d-flex justify-content-center px-0">
1470           
1471        </div>
1472    </div>
1473    <div class="row mb-2 d-flex justify-content-center">
1474        <div class="col-6 col-lg-3 d-flex justify-content-center px-0">
1475            <div data-cms-el="logo">
1475<script type="text/javascript" language="JavaScript">GetLogo();</script>
1475</div>
1476        </div>
1477    </div>
1478    <div class="row mx-0">
1479        <div class="col-12 d-flex justify-content-center px-0">
1480            <a class="text-decoration-none text-dark rounded ms-3 fs-4 d-inline-block lh-1 cus-social-1-133-icon" href="https://www.facebook.com/hmongdailynews/?ref=pages_you_manage" target="_blank"><i class="fa fa-facebook-square text-red-hover" aria-hidden="true"></i></a>
1481            <a class="text-decoration-none text-dark rounded ms-3 fs-4 d-inline-block lh-1 cus-social-1-133-icon" href="https://www.youtube.com/@hmongdailynews1547" target="_blank"><i class="fa fa-brands fa-youtube text-red-hover" aria-hidden="true"></i></a>
1482            <a class="text-decoration-none text-dark rounded ms-3 fs-4 d-inline-block lh-1 cus-social-1-133-icon" href="https://www.linkedin.com/" target="_blank"><i class="fa fa-linkedin-square text-red-hover" aria-hidden="true"></i></a>
1483        </div>
1484    </div>
1485</footer>
1486<!-- /footer -->
1487        </div>
1488    </div>
1489    <!-- go to top --><div class="cus-scroll-top position-fixed bg-dark text-white fs-4 px-2 rounded-circle d-flex align-items-center justify-content-center"><i class="fa fa-angle-up lh-base text-shadow-3"></i></div>
1489<script>    if (document.getElementsByClassName("cus-scroll-top")) {        window.addEventListener("scroll", function() {            if (document.body.scrollTop > 600 || document.documentElement.scrollTop > 600) {                document.getElementsByClassName('cus-scroll-top')[0].style.bottom = '20px';            } else {                document.getElementsByClassName('cus-scroll-top')[0].style.bottom = "-100px";            }        });        document.getElementsByClassName('cus-scroll-top')[0].addEventListener('click', function() {            window.scrollTo(0, 0);        });    }</script>
1489<style>    .cus-scroll-top {cursor: pointer; right:20px; bottom: auto;transition: 400ms linear;opacity: 0.8; width:40px;height: 40px;}    .cus-scroll-top:hover {transition: 300ms linear;box-shadow: 0 0 0 15px rgba(0,0,0,0.3) !important;opacity: 1;}</style><!-- /go to top -->
1490    <div class="cus-g-analytics-133">
1490<script language="javascript">GetGoogleAnalytics('MENU:HOME-FRONT PAGE');</script>
1490</div>
1491    <!-- tooltip -->
1492    
1492<script>
1493        var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
1494        var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
1495            return new bootstrap.Tooltip(tooltipTriggerEl)
1496        });
1497    </script>
1497
1498    <!-- /tooltip -->
1499
1500<script defer src="/sys-popup.js?v=1788930124"></script>
1500</body>
1501<!--Template-133-->
1502</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.