{"id":335,"date":"2026-09-03T01:37:34","date_gmt":"2026-09-03T01:37:34","guid":{"rendered":"https:\/\/goodsamaritangroup.org\/?page_id=335"},"modified":"2026-09-03T01:37:34","modified_gmt":"2026-09-03T01:37:34","slug":"volunteer-sign-up","status":"publish","type":"page","link":"https:\/\/goodsamaritangroup.org\/index.php\/volunteer-sign-up\/","title":{"rendered":"Volunteer Sign-Up"},"content":{"rendered":"<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\"><link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin><link href=\"https:\/\/fonts.googleapis.com\/css2?family=Fraunces:ital,wght@0,400;0,500;0,600;0,700;1,500&family=Inter:wght@400;500;600;700;800&display=swap\" rel=\"stylesheet\"><link rel=\"stylesheet\" href=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/assets\/app.css?ver=1.1.0\"><script src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/config.js?ver=1.1.0\"><\/script><script defer src=\"https:\/\/cdn.jsdelivr.net\/npm\/jspdf@2.5.2\/dist\/jspdf.umd.min.js\"><\/script><script defer src=\"https:\/\/cdn.jsdelivr.net\/npm\/jspdf-autotable@3.8.4\/dist\/jspdf.plugin.autotable.min.js\"><\/script><div class=\"gsg-app-shell\" data-gsg-app=\"1\"><header class=\"header\"><div class=\"wrap headin\"><button class=\"brand\" onclick=\"home()\" aria-label=\"Good Samaritan Group\"><img decoding=\"async\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/logo.png\"><div class=\"brand-name\"><b><span>Good Samaritan<\/span><span>Group<\/span><\/b><\/div><\/button><div class=\"nav-actions\"><div class=\"hamburger\"><button class=\"hamburger-btn\" id=\"hamburgerBtn\" type=\"button\" aria-label=\"Open menu\" aria-expanded=\"false\" aria-controls=\"menuPanel\" >\u2630<\/button><div class=\"menu-backdrop\" id=\"menuBackdrop\" aria-hidden=\"true\"><\/div><div class=\"menu-panel\" id=\"menuPanel\" aria-hidden=\"true\"><button class=\"navlink\" id=\"homeTab\" onclick=\"home();closeMenu()\">Home<\/button><button class=\"navlink\" id=\"calendarTab\" onclick=\"calendarPage(event)\">Calendar<\/button><div class=\"menu-parent\"><button class=\"navlink menu-parent-label\" id=\"prayerMenuLabel\" type=\"button\" onclick=\"toggleMenuGroup('prayerGroup')\">Prayer<\/button><button class=\"navlink menu-arrow\" type=\"button\" aria-label=\"Toggle Prayer menu\" aria-expanded=\"false\" onclick=\"toggleMenuGroup('prayerGroup',event)\">\u25bc<\/button><\/div><div class=\"menu-children\" id=\"prayerGroup\"><button class=\"navlink menu-sub\" id=\"prayerTab\" onclick=\"prayerPage(event)\">Additional<\/button><button class=\"navlink menu-sub\" id=\"bibleTab\" onclick=\"biblePage(event)\">Bible<\/button><\/div><div class=\"menu-parent\"><button class=\"navlink menu-parent-label\" id=\"serveMenuLabel\" type=\"button\" onclick=\"toggleMenuGroup('serveGroup')\">Serve<\/button><button class=\"navlink menu-arrow\" type=\"button\" aria-label=\"Toggle Serve menu\" aria-expanded=\"false\" onclick=\"toggleMenuGroup('serveGroup',event)\">\u25bc<\/button><\/div><div class=\"menu-children\" id=\"serveGroup\"><button class=\"navlink menu-sub\" id=\"servicesTab\" onclick=\"servicesPage();closeMenu()\">Volunteer Sign-Up<\/button><button class=\"navlink menu-sub\" id=\"signupListTab\" onclick=\"signupListPage();closeMenu()\">Sign-Up List<\/button><button class=\"navlink menu-sub\" id=\"donationsTab\" onclick=\"donationsPage();closeMenu()\">Donate<\/button><button class=\"navlink menu-sub\" id=\"donationListTab\" onclick=\"donationListPage();closeMenu()\">Donation List<\/button><\/div><button class=\"adminlink\" id=\"adminTabNav\" onclick=\"admin();closeMenu()\">Admin<\/button><\/div><\/div><button class=\"langbtn\" id=\"langbtn\" onclick=\"toggleLanguage()\">\u0627\u0644\u0639\u0631\u0628\u064a\u0629<\/button><button class=\"darkbtn\" id=\"darkbtn\" onclick=\"toggleDarkMode()\" aria-label=\"Toggle dark mode\">\ud83c\udf19<\/button><\/div><\/div><\/header><div id=\"app\"><\/div><footer class=\"site-footer\"><div class=\"wrap site-footer-inner\"><div class=\"site-footer-brand\"><img decoding=\"async\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/logo.png\" alt=\"\"><span>Good Samaritan Group<\/span><\/div><p class=\"site-footer-verse\">&ldquo;Truly I tell you, whatever you did for one of the least of these brothers and sisters of mine, you did for me.&rdquo; &mdash; Matthew 25:40<\/p><p class=\"site-footer-meta\">&copy; <span id=\"footerYear\"><\/span> Good Samaritan Group &middot; St. Abanoub &amp; St. Antonious Coptic Orthodox Church<\/p><\/div><\/footer><script>document.getElementById(\"footerYear\").textContent=new Date().getFullYear()<\/script><script>\nconst C=window.APP_CONFIG||{SUPABASE_URL:'https:\/\/ipcqnrlfrvjsougqabhr.supabase.co',SUPABASE_ANON_KEY:'sb_publishable_FlfhZ-womd37ATpznw5t2w_ynnwVoSE'};\nconst BIBLE_BOOKS=[{name:'Genesis',chapters:50},{name:'Exodus',chapters:40},{name:'Leviticus',chapters:27},{name:'Numbers',chapters:36},{name:'Deuteronomy',chapters:34},{name:'Joshua',chapters:24},{name:'Judges',chapters:21},{name:'Ruth',chapters:4},{name:'1 Samuel',chapters:31},{name:'2 Samuel',chapters:24},{name:'1 Kings',chapters:22},{name:'2 Kings',chapters:25},{name:'1 Chronicles',chapters:29},{name:'2 Chronicles',chapters:36},{name:'Ezra',chapters:10},{name:'Nehemiah',chapters:13},{name:'Esther',chapters:10},{name:'Job',chapters:42},{name:'Psalm',chapters:150},{name:'Proverbs',chapters:31},{name:'Ecclesiastes',chapters:12},{name:'Song of Solomon',chapters:8},{name:'Isaiah',chapters:66},{name:'Jeremiah',chapters:52},{name:'Lamentations',chapters:5},{name:'Ezekiel',chapters:48},{name:'Daniel',chapters:12},{name:'Hosea',chapters:14},{name:'Joel',chapters:3},{name:'Amos',chapters:9},{name:'Obadiah',chapters:1},{name:'Jonah',chapters:4},{name:'Micah',chapters:7},{name:'Nahum',chapters:3},{name:'Habakkuk',chapters:3},{name:'Zephaniah',chapters:3},{name:'Haggai',chapters:2},{name:'Zechariah',chapters:14},{name:'Malachi',chapters:4},{name:'Matthew',chapters:28},{name:'Mark',chapters:16},{name:'Luke',chapters:24},{name:'John',chapters:21},{name:'Acts',chapters:28},{name:'Romans',chapters:16},{name:'1 Corinthians',chapters:16},{name:'2 Corinthians',chapters:13},{name:'Galatians',chapters:6},{name:'Ephesians',chapters:6},{name:'Philippians',chapters:4},{name:'Colossians',chapters:4},{name:'1 Thessalonians',chapters:5},{name:'2 Thessalonians',chapters:3},{name:'1 Timothy',chapters:6},{name:'2 Timothy',chapters:4},{name:'Titus',chapters:3},{name:'Philemon',chapters:1},{name:'Hebrews',chapters:13},{name:'James',chapters:5},{name:'1 Peter',chapters:5},{name:'2 Peter',chapters:3},{name:'1 John',chapters:5},{name:'2 John',chapters:1},{name:'3 John',chapters:1},{name:'Jude',chapters:1},{name:'Revelation',chapters:22}];\nlet donations=[],donationSignups=[],services=[],notes=[],page='home',currentService='',registrationType='volunteer',staffMode=false,language=localStorage.getItem('gsg_language')||'en',token=localStorage.getItem('gsg_admin_token')||'',refreshToken=localStorage.getItem('gsg_admin_refresh_token')||'',adminTab='events',prayerCategories=[],prayerPages=[],prayerError='',prayerLoading=false,currentPrayerPageId='',currentPrayerCategoryId='',pictures=[],picturesLoading=false,picturesError='',bibleBook='John',bibleChapter='3',bibleLoading=false,bibleError='',bibleVerses=null,bibleBookPickerOpen=false,bibleBookFilter='',darkMode=localStorage.getItem('gsg_dark_mode')==='1';\nconst T={\nen:{verse:'The King will reply, \"Truly I tell you, whatever you did for one of the least of these brothers and sisters of mine, you did for me.\" (Matthew 25:40)',homeTab:'Home',servicesTab:'Volunteer Sign-Up',signupListTab:'Sign-Up List',contactTab:'Contact',staffTitle:'Servant \/ Staff Sign-Up',staffIntro:'This private-access page is for Servants \/ Staff. Use the direct staff link to register.',publicListTitle:'Who Is Signed Up?',publicListIntro:'See who has signed up for each upcoming event. Phone numbers are kept private and are not shown on this public list.',noPublicSignups:'No one has signed up for this event yet.',phone:'Phone Number *',phonePlaceholder:'Phone number',homeTitle:'Serving Our Community with Love',homeIntro:'Good Samaritan Group was established in 2017 under the umbrella of St. Abanoub & St. Antonious Coptic Orthodox Church. At the beginning of the service, we were only serving the members of the church. Eventually, we expanded to serve the whole community around the area',valuesTitle:'Our Values',love:'Love',loveText:'We serve with genuine love and care for every person.',service:'Service',serviceText:'We put our faith into action by serving others.',compassion:'Compassion',compassionText:'We meet people with kindness, dignity, and understanding.',exploreServices:'Explore Volunteer Opportunities',contactTitle:'Contact Us',contactEmail:'Email',contactAddress:'Address',contactFacebook:'Facebook',facebookLabel:'Visit us on Facebook',admin:'Admin',tagline:'Volunteer Sign-Up',choose:'Choose Your Service',thanks:'Thank you for volunteering with Good Samaritan Group. Select a ministry below to see upcoming opportunities and sign up.',questions:'Questions? Contact your ministry leader or church office.',back:'Back to Services',signupVolunteer:'Sign Up as a Volunteer',signupServant:'Sign Up as a Servant \/ Staff',chooseType:'Choose Registration Type',volunteer:'Volunteer',servant:'Servant \/ Staff',signup:'Sign Up',fullName:'Full Name *',selectSession:'Select Event *',confirm:'Confirm Sign-Up',submitting:'Submitting\u2026',noSessions:'No events are currently available.',thankYou:'Thank You!',received:'Your registration has been received. May God bless you as you serve our community!',backServices:'Back to Services',signAgain:'Sign Up Again',access:'Admin Access',signinText:'Sign in with your Supabase admin account.',signin:'Sign In',dashboard:'Admin Dashboard',manage:'Manage categories, events, and registrations.',signout:'Sign Out',tabEvents:'Events & Categories',tabServants:'Servant \/ Staff Sign-Ups',tabVolunteers:'Volunteer Sign-Ups',categories:'Categories',categoryHelp:'Create and manage the categories shown on the public website.',addCategory:'+ Add Category',editCategory:'Edit Category',deleteCategory:'Delete Category',events:'Events',eventHelp:'Changes here update the public website automatically.',addEvent:'+ Add Event',addEventSmall:'+ Add event',signups:'Sign-Ups',total:'total registrations',reset:'Reset All Sign-Ups',exportSignups:'Export Sign-Ups',signedUpAt:'Signed up',noSignups:'No sign-ups yet.',categoryName:'Category name',description:'Description',icon:'Icon (emoji)',color:'Color',eventName:'Event name',date:'Date',time:'Time',location:'Location',need:'Volunteer need \/ notes',capacity:'Maximum people (leave blank for unlimited)',volunteerCapacity:'Maximum volunteers (leave blank for unlimited)',servantCapacity:'Maximum servants \/ staff (leave blank for unlimited)',capacityShort:'Capacity',volunteerCapacityShort:'Volunteers',servantCapacityShort:'Servants \/ Staff',remaining:'spots left',full:'Registration Full',open:'Open',saveCategory:'Save Category',saveEvent:'Save Event',cancel:'Cancel',deleteCategoryConfirm:'Delete this category and all of its events?',deleteEventConfirm:'Delete this event? All volunteer and servant\/staff sign-ups for this event will also be permanently deleted.',editEvent:'Edit Event',duplicateEvent:'Duplicate',resetConfirm:'Delete ALL volunteer sign-ups and servant\/staff registrations?',needCategory:'Create a category first.',upcoming:'upcoming',session:'event',sessions:'events',signUpArrow:'Sign up \u2192',needLabel:'Need',adminEmail:'Admin email',password:'Password',edit:'Edit',delete:'Delete',returnLogin:'Return to login',setupTitle:'One-time setup needed',setupText:'Open config.js and replace the two placeholder values with your Supabase Project URL and Publishable\/anon key, then upload the files again.',categoryColorRose:'Rose',categoryColorAmber:'Amber',categoryColorOrange:'Orange',categoryColorRed:'Red',categoryColorPurple:'Purple',registered:'registered',signedUp:'Signed up',registrationClosed:'This event is full and registration is closed.',alreadyFull:'Registration is full. Please choose another event.',servantPlural:'Servants \/ Staff',volunteerPlural:'Volunteers',type:'Type',alreadySignedUp:'Already signed up',adminNotes:'Admin Notes',adminNotesHelp:'Create notices or urgent announcements for volunteers.',addNote:'+ Add Note',editNote:'Edit Note',deleteNote:'Delete Note',noteTitle:'Note title',noteMessage:'Message',noteTitleArabic:'Arabic note title',noteMessageArabic:'Arabic note message',notePriority:'Priority',normal:'Normal',important:'Important',emergency:'Emergency',active:'Active',inactive:'Inactive',saveNote:'Save Note',deleteNoteConfirm:'Delete this admin note?',categoryArabic:'Arabic category name',descriptionArabic:'Arabic description',eventArabic:'Arabic event name',locationArabic:'Arabic location',needArabic:'Arabic volunteer need \/ notes',categoryLink:'Public Link',carQuestion:'Will you have a car available on the day of the event? *',carYes:'Yes, I will have a car',carNo:'No, I will not have a car',carShort:'Car available',calendarTab:'Calendar',calendarTitle:'Upcoming Events Calendar',calendarIntro:'A visual, month-by-month overview of every upcoming volunteer opportunity.',noUpcomingEvents:'There are no upcoming events right now.',bibleTab:'Bible',bibleTitle:'Holy Bible \u2014 ESV',bibleIntro:'Read Scripture in the English Standard Version.',bibleBookLabel:'Book',bibleChapterLabel:'Chapter',bibleGo:'Read',bibleLoading:'Loading passage\u2026',bibleSetupTitle:'Bible tab setup needed',bibleSetupText:'Open config.js, add a free ESV API key from api.esv.org as ESV_API_KEY, then upload the files again.',bibleError:'Could not load that passage. Please try a different book or chapter.',bibleCopyright:'Scripture quotations are from the ESV\u00ae Bible (The Holy Bible, English Standard Version\u00ae), copyright \u00a9 2001 by Crossway, a publishing ministry of Good News Publishers. Used by permission. All rights reserved.',picturesTab:'Photo Gallery',picturesTitle:'Photo Gallery',picturesIntro:'Photos from Good Samaritan Group.',noPictures:'No pictures yet.',pictureTitle:'Picture title',pictureDescription:'Description',picturePhoto:'Photo',picturePhotoHelp:'Drag the photo inside the 760 \u00d7 500 frame to position it. Use the sliders for precise control.',savePicture:'Save Picture',addPicture:'+ Add Picture',deletePictureConfirm:'Delete this picture?',prayerCatArabic:'Arabic category name (optional)',prayerCatDescArabic:'Arabic description (optional)',prayerTitleArabicField:'Arabic title (optional)',prayerTextArabicField:'Arabic prayer text (optional)',autoTranslated:'An Arabic translation is generated automatically.'},\nar:{verse:'\u0648\u0633\u064a\u0631\u062f \u0627\u0644\u0645\u0644\u0643: \u00ab\u0627\u0644\u062d\u0642 \u0623\u0642\u0648\u0644 \u0644\u0643\u0645: \u0628\u0645\u0627 \u0623\u0646\u0643\u0645 \u0641\u0639\u0644\u062a\u0645\u0648\u0647 \u0628\u0623\u062d\u062f \u0625\u062e\u0648\u062a\u064a \u0647\u0624\u0644\u0627\u0621 \u0627\u0644\u0635\u063a\u0627\u0631\u060c \u0641\u0628\u064a \u0641\u0639\u0644\u062a\u0645.\u00bb (\u0645\u062a\u0649 25:40)',homeTab:'\u0627\u0644\u0631\u0626\u064a\u0633\u064a\u0629',servicesTab:'\u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u0645\u062a\u0637\u0648\u0639\u064a\u0646',signupListTab:'\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062a\u0633\u062c\u064a\u0644\u0627\u062a',contactTab:'\u0627\u062a\u0635\u0644 \u0628\u0646\u0627',staffTitle:'\u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u064f\u062f\u0651\u0627\u0645 \/ \u0627\u0644\u0645\u0648\u0638\u0641\u064a\u0646',staffIntro:'\u0647\u0630\u0647 \u0627\u0644\u0635\u0641\u062d\u0629 \u0645\u062e\u0635\u0635\u0629 \u0644\u0644\u062e\u064f\u062f\u0651\u0627\u0645 \/ \u0627\u0644\u0645\u0648\u0638\u0641\u064a\u0646. \u0627\u0633\u062a\u062e\u062f\u0645 \u0631\u0627\u0628\u0637 \u0627\u0644\u0645\u0648\u0638\u0641\u064a\u0646 \u0627\u0644\u0645\u0628\u0627\u0634\u0631 \u0644\u0644\u062a\u0633\u062c\u064a\u0644.',publicListTitle:'\u0645\u0646 \u0642\u0627\u0645 \u0628\u0627\u0644\u062a\u0633\u062c\u064a\u0644\u061f',publicListIntro:'\u064a\u0645\u0643\u0646\u0643 \u0631\u0624\u064a\u0629 \u0645\u0646 \u0642\u0627\u0645 \u0628\u0627\u0644\u062a\u0633\u062c\u064a\u0644 \u0641\u064a \u0643\u0644 \u0641\u0639\u0627\u0644\u064a\u0629 \u0642\u0627\u062f\u0645\u0629. \u0623\u0631\u0642\u0627\u0645 \u0627\u0644\u0647\u0648\u0627\u062a\u0641 \u062e\u0627\u0635\u0629 \u0648\u0644\u0627 \u062a\u0638\u0647\u0631 \u0641\u064a \u0647\u0630\u0647 \u0627\u0644\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0639\u0627\u0645\u0629.',noPublicSignups:'\u0644\u0645 \u064a\u0633\u062c\u0644 \u0623\u062d\u062f \u0641\u064a \u0647\u0630\u0647 \u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0629 \u0628\u0639\u062f.',phone:'\u0631\u0642\u0645 \u0627\u0644\u0647\u0627\u062a\u0641 *',phonePlaceholder:'\u0631\u0642\u0645 \u0627\u0644\u0647\u0627\u062a\u0641',homeTitle:'\u0646\u062e\u062f\u0645 \u0645\u062c\u062a\u0645\u0639\u0646\u0627 \u0628\u0627\u0644\u0645\u062d\u0628\u0629',homeIntro:'\u062a\u0623\u0633\u0633\u062a \u0645\u062c\u0645\u0648\u0639\u0629 \u0627\u0644\u0633\u0627\u0645\u0631\u064a \u0627\u0644\u0635\u0627\u0644\u062d \u0639\u0627\u0645 2017 \u062a\u062d\u062a \u0645\u0638\u0644\u0629 \u0643\u0646\u064a\u0633\u0629 \u0627\u0644\u0642\u062f\u064a\u0633 \u0623\u0628\u0627\u0646\u0648\u0628\u064a\u0633 \u0648\u0627\u0644\u0642\u062f\u064a\u0633 \u0623\u0646\u0637\u0648\u0646\u064a\u0648\u0633 \u0627\u0644\u0642\u0628\u0637\u064a\u0629 \u0627\u0644\u0623\u0631\u062b\u0648\u0630\u0643\u0633\u064a\u0629. \u0641\u064a \u0628\u062f\u0627\u064a\u0629 \u0627\u0644\u062e\u062f\u0645\u0629\u060c \u0643\u0646\u0627 \u0646\u062e\u062f\u0645 \u0623\u0639\u0636\u0627\u0621 \u0627\u0644\u0643\u0646\u064a\u0633\u0629 \u0641\u0642\u0637. \u0648\u0645\u0639 \u0645\u0631\u0648\u0631 \u0627\u0644\u0648\u0642\u062a\u060c \u062a\u0648\u0633\u0639\u0646\u0627 \u0644\u0646\u062e\u062f\u0645 \u0627\u0644\u0645\u062c\u062a\u0645\u0639 \u0628\u0623\u0643\u0645\u0644\u0647 \u0641\u064a \u0627\u0644\u0645\u0646\u0637\u0642\u0629 \u0627\u0644\u0645\u062d\u064a\u0637\u0629.',valuesTitle:'\u0642\u064a\u0645\u0646\u0627',love:'\u0627\u0644\u0645\u062d\u0628\u0629',loveText:'\u0646\u062e\u062f\u0645 \u0628\u0645\u062d\u0628\u0629 \u0635\u0627\u062f\u0642\u0629 \u0648\u0627\u0647\u062a\u0645\u0627\u0645 \u0628\u0643\u0644 \u0625\u0646\u0633\u0627\u0646.',service:'\u0627\u0644\u062e\u062f\u0645\u0629',serviceText:'\u0646\u062d\u0648\u0651\u0644 \u0625\u064a\u0645\u0627\u0646\u0646\u0627 \u0625\u0644\u0649 \u0639\u0645\u0644 \u0645\u0646 \u062e\u0644\u0627\u0644 \u062e\u062f\u0645\u0629 \u0627\u0644\u0622\u062e\u0631\u064a\u0646.',compassion:'\u0627\u0644\u0631\u062d\u0645\u0629',compassionText:'\u0646\u0644\u062a\u0642\u064a \u0628\u0627\u0644\u0646\u0627\u0633 \u0628\u0644\u0637\u0641 \u0648\u0643\u0631\u0627\u0645\u0629 \u0648\u062a\u0641\u0647\u0645.',exploreServices:'\u0627\u0633\u062a\u0643\u0634\u0641 \u0641\u0631\u0635 \u0627\u0644\u062a\u0637\u0648\u0639',contactTitle:'\u062a\u0648\u0627\u0635\u0644 \u0645\u0639\u0646\u0627',contactEmail:'\u0627\u0644\u0628\u0631\u064a\u062f \u0627\u0644\u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a',contactAddress:'\u0627\u0644\u0639\u0646\u0648\u0627\u0646',contactFacebook:'\u0641\u064a\u0633\u0628\u0648\u0643',facebookLabel:'\u062a\u0641\u0636\u0644 \u0628\u0632\u064a\u0627\u0631\u062a\u0646\u0627 \u0639\u0644\u0649 \u0641\u064a\u0633\u0628\u0648\u0643',admin:'\u0627\u0644\u0625\u062f\u0627\u0631\u0629',tagline:'\u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u0645\u062a\u0637\u0648\u0639\u064a\u0646',choose:'\u0627\u062e\u062a\u0631 \u0627\u0644\u062e\u062f\u0645\u0629',thanks:'\u0634\u0643\u0631\u064b\u0627 \u0644\u062a\u0637\u0648\u0639\u0643 \u0645\u0639 \u0645\u062c\u0645\u0648\u0639\u0629 \u0627\u0644\u0633\u0627\u0645\u0631\u064a \u0627\u0644\u0635\u0627\u0644\u062d. \u0627\u062e\u062a\u0631 \u0625\u062d\u062f\u0649 \u0627\u0644\u062e\u062f\u0645\u0627\u062a \u0623\u062f\u0646\u0627\u0647 \u0644\u0631\u0624\u064a\u0629 \u0627\u0644\u0641\u0631\u0635 \u0627\u0644\u0642\u0627\u062f\u0645\u0629 \u0648\u0627\u0644\u062a\u0633\u062c\u064a\u0644.',questions:'\u0644\u062f\u064a\u0643 \u0623\u0633\u0626\u0644\u0629\u061f \u062a\u0648\u0627\u0635\u0644 \u0645\u0639 \u0645\u0633\u0624\u0648\u0644 \u0627\u0644\u062e\u062f\u0645\u0629 \u0623\u0648 \u0645\u0643\u062a\u0628 \u0627\u0644\u0643\u0646\u064a\u0633\u0629.',back:'\u0627\u0644\u0639\u0648\u062f\u0629 \u0625\u0644\u0649 \u0627\u0644\u062e\u062f\u0645\u0627\u062a',signupVolunteer:'\u0627\u0644\u062a\u0633\u062c\u064a\u0644 \u0643\u0645\u062a\u0637\u0648\u0639',signupServant:'\u0627\u0644\u062a\u0633\u062c\u064a\u0644 \u0643\u062e\u0627\u062f\u0645 \/ \u0645\u0648\u0638\u0641',chooseType:'\u0627\u062e\u062a\u0631 \u0646\u0648\u0639 \u0627\u0644\u062a\u0633\u062c\u064a\u0644',volunteer:'\u0645\u062a\u0637\u0648\u0639',servant:'\u062e\u0627\u062f\u0645 \/ \u0645\u0648\u0638\u0641',signup:'\u0627\u0644\u062a\u0633\u062c\u064a\u0644',fullName:'\u0627\u0644\u0627\u0633\u0645 \u0627\u0644\u0643\u0627\u0645\u0644 *',selectSession:'\u0627\u062e\u062a\u0631 \u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0629 *',confirm:'\u062a\u0623\u0643\u064a\u062f \u0627\u0644\u062a\u0633\u062c\u064a\u0644',submitting:'\u062c\u0627\u0631\u064d \u0627\u0644\u0625\u0631\u0633\u0627\u0644\u2026',noSessions:'\u0644\u0627 \u062a\u0648\u062c\u062f \u0641\u0639\u0627\u0644\u064a\u0627\u062a \u0645\u062a\u0627\u062d\u0629 \u062d\u0627\u0644\u064a\u064b\u0627.',thankYou:'\u0634\u0643\u0631\u064b\u0627 \u0644\u0643!',received:'\u062a\u0645 \u0627\u0633\u062a\u0644\u0627\u0645 \u062a\u0633\u062c\u064a\u0644\u0643. \u0628\u0627\u0631\u0643 \u0627\u0644\u0644\u0647 \u0641\u064a\u0643 \u0648\u0623\u0646\u062a \u062a\u062e\u062f\u0645 \u0645\u062c\u062a\u0645\u0639\u0646\u0627!',backServices:'\u0627\u0644\u0639\u0648\u062f\u0629 \u0625\u0644\u0649 \u0627\u0644\u062e\u062f\u0645\u0627\u062a',signAgain:'\u0627\u0644\u062a\u0633\u062c\u064a\u0644 \u0645\u0631\u0629 \u0623\u062e\u0631\u0649',access:'\u062f\u062e\u0648\u0644 \u0627\u0644\u0625\u062f\u0627\u0631\u0629',signinText:'\u0633\u062c\u0651\u0644 \u0627\u0644\u062f\u062e\u0648\u0644 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u062d\u0633\u0627\u0628 \u0645\u0633\u0624\u0648\u0644 Supabase.',signin:'\u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062f\u062e\u0648\u0644',dashboard:'\u0644\u0648\u062d\u0629 \u0627\u0644\u0625\u062f\u0627\u0631\u0629',manage:'\u0625\u062f\u0627\u0631\u0629 \u0627\u0644\u0641\u0626\u0627\u062a \u0648\u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0627\u062a \u0648\u0627\u0644\u062a\u0633\u062c\u064a\u0644\u0627\u062a.',signout:'\u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c',tabEvents:'\u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0627\u062a \u0648\u0627\u0644\u0641\u0626\u0627\u062a',tabServants:'\u062a\u0633\u062c\u064a\u0644\u0627\u062a \u0627\u0644\u062e\u064f\u062f\u0651\u0627\u0645 \/ \u0627\u0644\u0645\u0648\u0638\u0641\u064a\u0646',tabVolunteers:'\u062a\u0633\u062c\u064a\u0644\u0627\u062a \u0627\u0644\u0645\u062a\u0637\u0648\u0639\u064a\u0646',categories:'\u0627\u0644\u0641\u0626\u0627\u062a',categoryHelp:'\u0623\u0646\u0634\u0626 \u0648\u0623\u062f\u0631 \u0627\u0644\u0641\u0626\u0627\u062a \u0627\u0644\u062a\u064a \u062a\u0638\u0647\u0631 \u0639\u0644\u0649 \u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0639\u0627\u0645.',addCategory:'+ \u0625\u0636\u0627\u0641\u0629 \u0641\u0626\u0629',editCategory:'\u062a\u0639\u062f\u064a\u0644 \u0627\u0644\u0641\u0626\u0629',deleteCategory:'\u062d\u0630\u0641 \u0627\u0644\u0641\u0626\u0629',events:'\u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0627\u062a',eventHelp:'\u0627\u0644\u062a\u063a\u064a\u064a\u0631\u0627\u062a \u0647\u0646\u0627 \u062a\u064f\u062d\u062f\u0651\u062b \u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0639\u0627\u0645 \u062a\u0644\u0642\u0627\u0626\u064a\u064b\u0627.',addEvent:'+ \u0625\u0636\u0627\u0641\u0629 \u0641\u0639\u0627\u0644\u064a\u0629',addEventSmall:'+ \u0625\u0636\u0627\u0641\u0629 \u0641\u0639\u0627\u0644\u064a\u0629',signups:'\u0627\u0644\u062a\u0633\u062c\u064a\u0644\u0627\u062a',total:'\u0625\u062c\u0645\u0627\u0644\u064a \u0627\u0644\u062a\u0633\u062c\u064a\u0644\u0627\u062a',reset:'\u062d\u0630\u0641 \u062c\u0645\u064a\u0639 \u0627\u0644\u062a\u0633\u062c\u064a\u0644\u0627\u062a',noSignups:'\u0644\u0627 \u062a\u0648\u062c\u062f \u062a\u0633\u062c\u064a\u0644\u0627\u062a \u0628\u0639\u062f.',categoryName:'\u0627\u0633\u0645 \u0627\u0644\u0641\u0626\u0629',description:'\u0627\u0644\u0648\u0635\u0641',icon:'\u0627\u0644\u0623\u064a\u0642\u0648\u0646\u0629 (\u0625\u064a\u0645\u0648\u062c\u064a)',color:'\u0627\u0644\u0644\u0648\u0646',eventName:'\u0627\u0633\u0645 \u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0629',date:'\u0627\u0644\u062a\u0627\u0631\u064a\u062e',time:'\u0627\u0644\u0648\u0642\u062a',location:'\u0627\u0644\u0645\u0648\u0642\u0639',need:'\u0627\u062d\u062a\u064a\u0627\u062c \u0627\u0644\u0645\u062a\u0637\u0648\u0639\u064a\u0646 \/ \u0645\u0644\u0627\u062d\u0638\u0627\u062a',capacity:'\u0627\u0644\u062d\u062f \u0627\u0644\u0623\u0642\u0635\u0649 \u0644\u0644\u0623\u0634\u062e\u0627\u0635 (\u0627\u062a\u0631\u0643\u0647 \u0641\u0627\u0631\u063a\u064b\u0627 \u0644\u0639\u062f\u062f \u063a\u064a\u0631 \u0645\u062d\u062f\u0648\u062f)',volunteerCapacity:'\u0627\u0644\u062d\u062f \u0627\u0644\u0623\u0642\u0635\u0649 \u0644\u0644\u0645\u062a\u0637\u0648\u0639\u064a\u0646 (\u0627\u062a\u0631\u0643\u0647 \u0641\u0627\u0631\u063a\u064b\u0627 \u0644\u0639\u062f\u062f \u063a\u064a\u0631 \u0645\u062d\u062f\u0648\u062f)',servantCapacity:'\u0627\u0644\u062d\u062f \u0627\u0644\u0623\u0642\u0635\u0649 \u0644\u0644\u062e\u064f\u062f\u0651\u0627\u0645 \/ \u0627\u0644\u0645\u0648\u0638\u0641\u064a\u0646 (\u0627\u062a\u0631\u0643\u0647 \u0641\u0627\u0631\u063a\u064b\u0627 \u0644\u0639\u062f\u062f \u063a\u064a\u0631 \u0645\u062d\u062f\u0648\u062f)',capacityShort:'\u0627\u0644\u0633\u0639\u0629',volunteerCapacityShort:'\u0627\u0644\u0645\u062a\u0637\u0648\u0639\u0648\u0646',servantCapacityShort:'\u0627\u0644\u062e\u064f\u062f\u0651\u0627\u0645 \/ \u0627\u0644\u0645\u0648\u0638\u0641\u0648\u0646',remaining:'\u0623\u0645\u0627\u0643\u0646 \u0645\u062a\u0628\u0642\u064a\u0629',full:'\u0627\u0643\u062a\u0645\u0644 \u0627\u0644\u062a\u0633\u062c\u064a\u0644',open:'\u0645\u0641\u062a\u0648\u062d',saveCategory:'\u062d\u0641\u0638 \u0627\u0644\u0641\u0626\u0629',saveEvent:'\u062d\u0641\u0638 \u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0629',cancel:'\u0625\u0644\u063a\u0627\u0621',deleteCategoryConfirm:'\u0647\u0644 \u062a\u0631\u064a\u062f \u062d\u0630\u0641 \u0647\u0630\u0647 \u0627\u0644\u0641\u0626\u0629 \u0648\u062c\u0645\u064a\u0639 \u0641\u0639\u0627\u0644\u064a\u0627\u062a\u0647\u0627\u061f',deleteEventConfirm:'\u0647\u0644 \u062a\u0631\u064a\u062f \u062d\u0630\u0641 \u0647\u0630\u0647 \u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0629\u061f \u0633\u064a\u062a\u0645 \u0623\u064a\u0636\u064b\u0627 \u062d\u0630\u0641 \u062c\u0645\u064a\u0639 \u062a\u0633\u062c\u064a\u0644\u0627\u062a \u0627\u0644\u0645\u062a\u0637\u0648\u0639\u064a\u0646 \u0648\u0627\u0644\u062e\u064f\u062f\u0651\u0627\u0645 \/ \u0627\u0644\u0645\u0648\u0638\u0641\u064a\u0646 \u0644\u0647\u0630\u0647 \u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0629 \u0646\u0647\u0627\u0626\u064a\u064b\u0627.',editEvent:'\u062a\u0639\u062f\u064a\u0644 \u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0629',duplicateEvent:'\u062a\u0643\u0631\u0627\u0631',resetConfirm:'\u0647\u0644 \u062a\u0631\u064a\u062f \u062d\u0630\u0641 \u062c\u0645\u064a\u0639 \u062a\u0633\u062c\u064a\u0644\u0627\u062a \u0627\u0644\u0645\u062a\u0637\u0648\u0639\u064a\u0646 \u0648\u062a\u0633\u062c\u064a\u0644\u0627\u062a \u0627\u0644\u062e\u064f\u062f\u0651\u0627\u0645 \/ \u0627\u0644\u0645\u0648\u0638\u0641\u064a\u0646\u061f',needCategory:'\u0623\u0646\u0634\u0626 \u0641\u0626\u0629 \u0623\u0648\u0644\u064b\u0627.',upcoming:'\u0627\u0644\u0642\u0627\u062f\u0645\u0629',session:'\u0641\u0639\u0627\u0644\u064a\u0629',sessions:'\u0641\u0639\u0627\u0644\u064a\u0627\u062a',signUpArrow:'\u0633\u062c\u0651\u0644 \u0627\u0644\u0622\u0646 \u2190',needLabel:'\u0627\u0644\u0627\u062d\u062a\u064a\u0627\u062c',adminEmail:'\u0627\u0644\u0628\u0631\u064a\u062f \u0627\u0644\u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a \u0644\u0644\u0645\u0633\u0624\u0648\u0644',password:'\u0643\u0644\u0645\u0629 \u0627\u0644\u0645\u0631\u0648\u0631',edit:'\u062a\u0639\u062f\u064a\u0644',delete:'\u062d\u0630\u0641',returnLogin:'\u0627\u0644\u0639\u0648\u062f\u0629 \u0625\u0644\u0649 \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062f\u062e\u0648\u0644',setupTitle:'\u064a\u0644\u0632\u0645 \u0625\u062c\u0631\u0627\u0621 \u0625\u0639\u062f\u0627\u062f \u0644\u0645\u0631\u0629 \u0648\u0627\u062d\u062f\u0629',setupText:'\u0627\u0641\u062a\u062d \u0645\u0644\u0641 config.js \u0648\u0627\u0633\u062a\u0628\u062f\u0644 \u0627\u0644\u0642\u064a\u0645\u062a\u064a\u0646 \u0627\u0644\u062a\u062c\u0631\u064a\u0628\u064a\u062a\u064a\u0646 \u0628\u0639\u0646\u0648\u0627\u0646 \u0645\u0634\u0631\u0648\u0639 Supabase \u0648\u0645\u0641\u062a\u0627\u062d Publishable\/anon\u060c \u062b\u0645 \u0627\u0631\u0641\u0639 \u0627\u0644\u0645\u0644\u0641\u0627\u062a \u0645\u0631\u0629 \u0623\u062e\u0631\u0649.',categoryColorRose:'\u0648\u0631\u062f\u064a',categoryColorAmber:'\u0643\u0647\u0631\u0645\u0627\u0646\u064a',categoryColorOrange:'\u0628\u0631\u062a\u0642\u0627\u0644\u064a',categoryColorRed:'\u0623\u062d\u0645\u0631',categoryColorPurple:'\u0628\u0646\u0641\u0633\u062c\u064a',registered:'\u0645\u0633\u062c\u0644',signedUp:'\u0627\u0644\u0645\u0633\u062c\u0644\u0648\u0646',registrationClosed:'\u0647\u0630\u0647 \u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0629 \u0645\u0643\u062a\u0645\u0644\u0629 \u0648\u0627\u0644\u062a\u0633\u062c\u064a\u0644 \u0645\u063a\u0644\u0642.',alreadyFull:'\u0627\u0643\u062a\u0645\u0644 \u0627\u0644\u062a\u0633\u062c\u064a\u0644. \u064a\u0631\u062c\u0649 \u0627\u062e\u062a\u064a\u0627\u0631 \u0641\u0639\u0627\u0644\u064a\u0629 \u0623\u062e\u0631\u0649.',servantPlural:'\u0627\u0644\u062e\u064f\u062f\u0651\u0627\u0645 \/ \u0627\u0644\u0645\u0648\u0638\u0641\u0648\u0646',volunteerPlural:'\u0627\u0644\u0645\u062a\u0637\u0648\u0639\u0648\u0646',type:'\u0627\u0644\u0646\u0648\u0639',alreadySignedUp:'\u0645\u0633\u062c\u064e\u0651\u0644 \u0628\u0627\u0644\u0641\u0639\u0644',adminNotes:'\u0645\u0644\u0627\u062d\u0638\u0627\u062a \u0627\u0644\u0625\u062f\u0627\u0631\u0629',adminNotesHelp:'\u0623\u0646\u0634\u0626 \u062a\u0646\u0628\u064a\u0647\u0627\u062a \u0623\u0648 \u0625\u0639\u0644\u0627\u0646\u0627\u062a \u0639\u0627\u062c\u0644\u0629 \u0644\u0644\u0645\u062a\u0637\u0648\u0639\u064a\u0646.',addNote:'+ \u0625\u0636\u0627\u0641\u0629 \u0645\u0644\u0627\u062d\u0638\u0629',editNote:'\u062a\u0639\u062f\u064a\u0644 \u0627\u0644\u0645\u0644\u0627\u062d\u0638\u0629',deleteNote:'\u062d\u0630\u0641 \u0627\u0644\u0645\u0644\u0627\u062d\u0638\u0629',noteTitle:'\u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u0645\u0644\u0627\u062d\u0638\u0629',noteMessage:'\u0646\u0635 \u0627\u0644\u0645\u0644\u0627\u062d\u0638\u0629',noteTitleArabic:'\u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u0645\u0644\u0627\u062d\u0638\u0629 \u0628\u0627\u0644\u0639\u0631\u0628\u064a\u0629',noteMessageArabic:'\u0646\u0635 \u0627\u0644\u0645\u0644\u0627\u062d\u0638\u0629 \u0628\u0627\u0644\u0639\u0631\u0628\u064a\u0629',notePriority:'\u0627\u0644\u0623\u0648\u0644\u0648\u064a\u0629',normal:'\u0639\u0627\u062f\u064a',important:'\u0645\u0647\u0645',emergency:'\u0637\u0648\u0627\u0631\u0626',active:'\u0646\u0634\u0637\u0629',inactive:'\u063a\u064a\u0631 \u0646\u0634\u0637\u0629',saveNote:'\u062d\u0641\u0638 \u0627\u0644\u0645\u0644\u0627\u062d\u0638\u0629',deleteNoteConfirm:'\u0647\u0644 \u062a\u0631\u064a\u062f \u062d\u0630\u0641 \u0645\u0644\u0627\u062d\u0638\u0629 \u0627\u0644\u0625\u062f\u0627\u0631\u0629 \u0647\u0630\u0647\u061f',categoryArabic:'\u0627\u0633\u0645 \u0627\u0644\u0641\u0626\u0629 \u0628\u0627\u0644\u0639\u0631\u0628\u064a\u0629',descriptionArabic:'\u0627\u0644\u0648\u0635\u0641 \u0628\u0627\u0644\u0639\u0631\u0628\u064a\u0629',eventArabic:'\u0627\u0633\u0645 \u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0629 \u0628\u0627\u0644\u0639\u0631\u0628\u064a\u0629',locationArabic:'\u0627\u0644\u0645\u0648\u0642\u0639 \u0628\u0627\u0644\u0639\u0631\u0628\u064a\u0629',needArabic:'\u0627\u062d\u062a\u064a\u0627\u062c \u0627\u0644\u0645\u062a\u0637\u0648\u0639\u064a\u0646 \/ \u0627\u0644\u0645\u0644\u0627\u062d\u0638\u0627\u062a \u0628\u0627\u0644\u0639\u0631\u0628\u064a\u0629',categoryLink:'\u0627\u0644\u0631\u0627\u0628\u0637 \u0627\u0644\u0639\u0627\u0645 \u0644\u0644\u0641\u0626\u0629',carQuestion:'\u0647\u0644 \u0633\u062a\u062a\u0648\u0641\u0631 \u0644\u062f\u064a\u0643 \u0633\u064a\u0627\u0631\u0629 \u064a\u0648\u0645 \u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0629\u061f *',carYes:'\u0646\u0639\u0645\u060c \u0633\u062a\u062a\u0648\u0641\u0631 \u0644\u062f\u064a \u0633\u064a\u0627\u0631\u0629',carNo:'\u0644\u0627\u060c \u0644\u0646 \u062a\u062a\u0648\u0641\u0631 \u0644\u062f\u064a \u0633\u064a\u0627\u0631\u0629',carShort:'\u062a\u0648\u0641\u0631 \u0633\u064a\u0627\u0631\u0629',calendarTab:'\u0627\u0644\u062a\u0642\u0648\u064a\u0645',calendarTitle:'\u062a\u0642\u0648\u064a\u0645 \u0627\u0644\u0641\u0639\u0627\u0644\u064a\u0627\u062a \u0627\u0644\u0642\u0627\u062f\u0645\u0629',calendarIntro:'\u0646\u0638\u0631\u0629 \u0639\u0627\u0645\u0629 \u0645\u0631\u0626\u064a\u0629\u060c \u0634\u0647\u0631\u064b\u0627 \u0628\u0634\u0647\u0631\u060c \u0639\u0644\u0649 \u062c\u0645\u064a\u0639 \u0641\u0631\u0635 \u0627\u0644\u062a\u0637\u0648\u0639 \u0627\u0644\u0642\u0627\u062f\u0645\u0629.',noUpcomingEvents:'\u0644\u0627 \u062a\u0648\u062c\u062f \u0641\u0639\u0627\u0644\u064a\u0627\u062a \u0642\u0627\u062f\u0645\u0629 \u062d\u0627\u0644\u064a\u064b\u0627.',bibleTab:'\u0627\u0644\u0643\u062a\u0627\u0628 \u0627\u0644\u0645\u0642\u062f\u0633',bibleTitle:'\u0627\u0644\u0643\u062a\u0627\u0628 \u0627\u0644\u0645\u0642\u062f\u0633 \u2014 \u062a\u0631\u062c\u0645\u0629 ESV',bibleIntro:'\u0627\u0642\u0631\u0623 \u0627\u0644\u0643\u062a\u0627\u0628 \u0627\u0644\u0645\u0642\u062f\u0633 \u0628\u0627\u0644\u062a\u0631\u062c\u0645\u0629 \u0627\u0644\u0625\u0646\u062c\u0644\u064a\u0632\u064a\u0629 \u0627\u0644\u0642\u064a\u0627\u0633\u064a\u0629 (ESV).',bibleBookLabel:'\u0627\u0644\u0633\u0641\u0631',bibleChapterLabel:'\u0627\u0644\u0625\u0635\u062d\u0627\u062d',bibleGo:'\u0642\u0631\u0627\u0621\u0629',bibleLoading:'\u062c\u0627\u0631\u064d \u062a\u062d\u0645\u064a\u0644 \u0627\u0644\u0646\u0635\u2026',bibleSetupTitle:'\u064a\u0644\u0632\u0645 \u0625\u0639\u062f\u0627\u062f \u0642\u0633\u0645 \u0627\u0644\u0643\u062a\u0627\u0628 \u0627\u0644\u0645\u0642\u062f\u0633',bibleSetupText:'\u0627\u0641\u062a\u062d \u0645\u0644\u0641 config.js \u0648\u0623\u0636\u0641 \u0645\u0641\u062a\u0627\u062d ESV API \u0645\u062c\u0627\u0646\u064a \u0645\u0646 api.esv.org \u0628\u0627\u0633\u0645 ESV_API_KEY\u060c \u062b\u0645 \u0627\u0631\u0641\u0639 \u0627\u0644\u0645\u0644\u0641\u0627\u062a \u0645\u0631\u0629 \u0623\u062e\u0631\u0649.',bibleError:'\u062a\u0639\u0630\u0631 \u062a\u062d\u0645\u064a\u0644 \u0647\u0630\u0627 \u0627\u0644\u0646\u0635. \u064a\u0631\u062c\u0649 \u062a\u062c\u0631\u0628\u0629 \u0633\u0641\u0631 \u0623\u0648 \u0625\u0635\u062d\u0627\u062d \u0622\u062e\u0631.',bibleCopyright:'\u0627\u0644\u0627\u0642\u062a\u0628\u0627\u0633\u0627\u062a \u0627\u0644\u0643\u062a\u0627\u0628\u064a\u0629 \u0645\u0623\u062e\u0648\u0630\u0629 \u0645\u0646 \u062a\u0631\u062c\u0645\u0629 ESV\u00ae (\u0627\u0644\u0643\u062a\u0627\u0628 \u0627\u0644\u0645\u0642\u062f\u0633\u060c \u0627\u0644\u0646\u0633\u062e\u0629 \u0627\u0644\u0625\u0646\u062c\u0644\u064a\u0632\u064a\u0629 \u0627\u0644\u0642\u064a\u0627\u0633\u064a\u0629\u00ae)\u060c \u062d\u0642\u0648\u0642 \u0627\u0644\u0637\u0628\u0639 \u0648\u0627\u0644\u0646\u0634\u0631 \u00a9 2001 \u0644\u0634\u0631\u0643\u0629 Crossway. \u062a\u064f\u0633\u062a\u062e\u062f\u0645 \u0628\u0625\u0630\u0646. \u062c\u0645\u064a\u0639 \u0627\u0644\u062d\u0642\u0648\u0642 \u0645\u062d\u0641\u0648\u0638\u0629.',picturesTab:'\u0645\u0639\u0631\u0636 \u0627\u0644\u0635\u0648\u0631',picturesTitle:'\u0645\u0639\u0631\u0636 \u0627\u0644\u0635\u0648\u0631',picturesIntro:'\u0635\u0648\u0631 \u0645\u0646 \u0645\u062c\u0645\u0648\u0639\u0629 \u0627\u0644\u0633\u0627\u0645\u0631\u064a \u0627\u0644\u0635\u0627\u0644\u062d.',noPictures:'\u0644\u0627 \u062a\u0648\u062c\u062f \u0635\u0648\u0631 \u0628\u0639\u062f.',pictureTitle:'\u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u0635\u0648\u0631\u0629',pictureDescription:'\u0627\u0644\u0648\u0635\u0641',picturePhoto:'\u0627\u0644\u0635\u0648\u0631\u0629',picturePhotoHelp:'\u0627\u0633\u062d\u0628 \u0627\u0644\u0635\u0648\u0631\u0629 \u062f\u0627\u062e\u0644 \u0625\u0637\u0627\u0631 760 \u00d7 500 \u0644\u0636\u0628\u0637 \u0645\u0648\u0636\u0639\u0647\u0627\u060c \u0623\u0648 \u0627\u0633\u062a\u062e\u062f\u0645 \u0623\u0634\u0631\u0637\u0629 \u0627\u0644\u062a\u0645\u0631\u064a\u0631.',savePicture:'\u062d\u0641\u0638 \u0627\u0644\u0635\u0648\u0631\u0629',addPicture:'+ \u0625\u0636\u0627\u0641\u0629 \u0635\u0648\u0631\u0629',deletePictureConfirm:'\u062d\u0630\u0641 \u0647\u0630\u0647 \u0627\u0644\u0635\u0648\u0631\u0629\u061f',prayerCatArabic:'\u0627\u0633\u0645 \u0627\u0644\u0641\u0626\u0629 \u0628\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u0627\u062e\u062a\u064a\u0627\u0631\u064a)',prayerCatDescArabic:'\u0627\u0644\u0648\u0635\u0641 \u0628\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u0627\u062e\u062a\u064a\u0627\u0631\u064a)',prayerTitleArabicField:'\u0627\u0644\u0639\u0646\u0648\u0627\u0646 \u0628\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u0627\u062e\u062a\u064a\u0627\u0631\u064a)',prayerTextArabicField:'\u0646\u0635 \u0627\u0644\u0635\u0644\u0627\u0629 \u0628\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u0627\u062e\u062a\u064a\u0627\u0631\u064a)',autoTranslated:'\u062a\u062a\u0645 \u0625\u0636\u0627\u0641\u0629 \u0627\u0644\u062a\u0631\u062c\u0645\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u062a\u0644\u0642\u0627\u0626\u064a\u064b\u0627.'}};\nconst t=k=>T[language][k]||T.en[k]||k;\nfunction applyLanguage(){document.documentElement.lang=language;document.body.classList.toggle('rtl',language==='ar');applyDarkMode();const b=document.getElementById('langbtn');if(b)b.textContent=language==='en'?'\u0627\u0644\u0639\u0631\u0628\u064a\u0629':'English';const ab=document.querySelector('.adminlink');if(ab){ab.textContent=t('admin');ab.classList.toggle('active',page==='admin')}const ht=document.getElementById('homeTab');if(ht)ht.textContent=t('homeTab');const pt=document.getElementById('prayerTab');if(pt)pt.textContent=language==='ar'?'\u0635\u0644\u0648\u0627\u062a \u0625\u0636\u0627\u0641\u064a\u0629':'Additional';const pml=document.getElementById('prayerMenuLabel');if(pml)pml.textContent=language==='ar'?'\u0627\u0644\u0635\u0644\u0627\u0629':'Prayer';const sml=document.getElementById('serveMenuLabel');if(sml)sml.textContent=language==='ar'?'\u0627\u0644\u062e\u062f\u0645\u0629':'Serve';const pict=document.getElementById('picturesTab');if(pict)pict.textContent=t('picturesTab');const clt=document.getElementById('calendarTab');if(clt)clt.textContent=t('calendarTab');const blt=document.getElementById('bibleTab');if(blt)blt.textContent=t('bibleTab');const st=document.getElementById('servicesTab');if(st)st.textContent=staffMode?t('signupServant'):t('servicesTab');const lt=document.getElementById('signupListTab');if(lt)lt.textContent=t('signupListTab');const dlt=document.getElementById('donationListTab');if(dlt)dlt.textContent=language==='ar'?'\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062a\u0628\u0631\u0639\u0627\u062a':'Donation List';const ct=document.getElementById('contactTab');if(ct)ct.textContent=t('contactTab');const isHome=staffMode?page==='staffHome':page==='home';const isSignup=staffMode?(page==='staff'||(!['staffHome','staff','publicSignups','contact','admin','success'].includes(page))):(page==='services'||(!['home','services','publicSignups','contact','admin','success','staff','staffHome'].includes(page)));if(ht)ht.classList.toggle('active',isHome);if(st)st.classList.toggle('active',isSignup);if(lt)lt.classList.toggle('active',page==='publicSignups');if(ct)ct.classList.toggle('active',page==='contact')}\nfunction toggleLanguage(){language=language==='en'?'ar':'en';localStorage.setItem('gsg_language',language);render()}\nfunction applyDarkMode(){document.body.classList.toggle('dark',darkMode);const b=document.getElementById('darkbtn');if(b){b.textContent=darkMode?'\u2600\ufe0f':'\ud83c\udf19';b.setAttribute('aria-label',darkMode?(language==='ar'?'\u0625\u064a\u0642\u0627\u0641 \u0627\u0644\u0648\u0636\u0639 \u0627\u0644\u062f\u0627\u0643\u0646':'Turn off dark mode'):(language==='ar'?'\u062a\u0641\u0639\u064a\u0644 \u0627\u0644\u0648\u0636\u0639 \u0627\u0644\u062f\u0627\u0643\u0646':'Turn on dark mode'))}}\nfunction toggleDarkMode(){darkMode=!darkMode;localStorage.setItem('gsg_dark_mode',darkMode?'1':'0');render()}\napplyDarkMode();\nconst configured=()=>{const u=String(C.SUPABASE_URL||'').trim(),k=String(C.SUPABASE_ANON_KEY||'').trim();return \/^https:\\\/\\\/[a-z0-9-]+\\.supabase\\.co$\/i.test(u)&&!!k&&!k.includes('PASTE_')&&!k.includes('YOUR_')};const base=()=>String(C.SUPABASE_URL||'').trim().replace(\/\\\/$\/,'');\nlet refreshPromise=null;\nfunction clearAdminTokens(){token='';refreshToken='';localStorage.removeItem('gsg_admin_token');localStorage.removeItem('gsg_admin_refresh_token')}\nfunction readableNetworkError(e){const m=String(e?.message||e||'');if(\/Failed to fetch|NetworkError|Load failed|fetch\/i.test(m))return language==='ar'?'\u062a\u0639\u0630\u0631 \u0627\u0644\u0627\u062a\u0635\u0627\u0644 \u0628\u0642\u0627\u0639\u062f\u0629 \u0628\u064a\u0627\u0646\u0627\u062a Supabase. \u062a\u062d\u0642\u0642 \u0645\u0646 \u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0648\u0627\u0644\u0645\u0641\u062a\u0627\u062d \u0641\u064a config.js \u062b\u0645 \u0623\u0639\u062f \u0631\u0641\u0639 \u0627\u0644\u0645\u0648\u0642\u0639.':'Could not connect to Supabase. Check the Supabase Project URL and Publishable\/anon key in config.js, then redeploy the site.';return m}\nasync function refreshAuth(){if(!configured()||!refreshToken)return false;if(refreshPromise)return refreshPromise;refreshPromise=(async()=>{try{const r=await fetch(base()+'\/auth\/v1\/token?grant_type=refresh_token',{method:'POST',headers:{apikey:C.SUPABASE_ANON_KEY,'Content-Type':'application\/json'},body:JSON.stringify({refresh_token:refreshToken}),cache:'no-store'});if(!r.ok){clearAdminTokens();return false}const d=await r.json();token=d.access_token||'';refreshToken=d.refresh_token||refreshToken;if(!token){clearAdminTokens();return false}localStorage.setItem('gsg_admin_token',token);localStorage.setItem('gsg_admin_refresh_token',refreshToken);return true}catch(e){return false}finally{refreshPromise=null}})();return refreshPromise}\nasync function request(path,opt={},auth=token,isRpc=false,retried=false){if(!configured())throw Error('SUPABASE_CONFIG_MISSING');const url=base()+(isRpc?'\/rest\/v1\/rpc\/'+path:'\/rest\/v1\/'+path);const headers={apikey:C.SUPABASE_ANON_KEY,'Content-Type':'application\/json',...(opt.headers||{})};if(auth)headers.Authorization='Bearer '+auth;let r;try{r=await fetch(url,{...opt,headers,cache:opt.cache||'no-store'});}catch(e){throw Error(readableNetworkError(e))}if(!r.ok){const text=await r.text();const expired=r.status===401||text.includes('PGRST303')||text.toLowerCase().includes('jwt expired');if(expired&&!retried&&auth&&auth===token&&await refreshAuth())return request(path,opt,token,isRpc,true);throw Error(text||('HTTP '+r.status))}const tx=await r.text();if(!tx)return null;try{return JSON.parse(tx)}catch(e){throw Error('Invalid response from Supabase for '+path)}}\nasync function api(path,opt={},auth=token){return request(path,opt,auth,false)}\nasync function rpc(fn,body={},auth=''){return request(fn,{method:'POST',body:JSON.stringify(body)},auth,true)}\nasync function authLogin(email,password){let r;try{r=await fetch(base()+'\/auth\/v1\/token?grant_type=password',{method:'POST',headers:{apikey:C.SUPABASE_ANON_KEY,'Content-Type':'application\/json'},body:JSON.stringify({email,password}),cache:'no-store'})}catch(e){throw Error(readableNetworkError(e))}if(!r.ok)throw Error(language==='ar'?'\u0627\u0644\u0628\u0631\u064a\u062f \u0627\u0644\u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a \u0623\u0648 \u0643\u0644\u0645\u0629 \u0627\u0644\u0645\u0631\u0648\u0631 \u063a\u064a\u0631 \u0635\u062d\u064a\u062d\u0629.':'Incorrect email or password.');const d=await r.json();token=d.access_token||'';refreshToken=d.refresh_token||'';if(!token||!refreshToken)throw Error('Authentication response was incomplete.');localStorage.setItem('gsg_admin_token',token);localStorage.setItem('gsg_admin_refresh_token',refreshToken)}\nasync function load(){const [a,b,c,d]=await Promise.all([api('services?select=*&order=name.asc',{},''),api('sessions?select=*&order=created_at.asc',{},''),rpc('get_session_counts'),api('admin_notes?select=*&order=created_at.desc',{},token)]);const counts=Object.fromEntries((c||[]).map(x=>[x.session_id,{total:Number(x.signup_count||0),volunteer:Number(x.volunteer_count||0),servant:Number(x.servant_count||0)}]));notes=d||[];if(language==='ar'&&notes.length){notes=await Promise.all(notes.map(async n=>{const copy={...n};if(!copy.title_ar&&copy.title)copy.title_ar=await translateToArabic(copy.title);if(!copy.message_ar&&copy.message)copy.message_ar=await translateToArabic(copy.message);return copy}))}services=(a||[]).map(s=>({...s,sessions:(b||[]).filter(x=>x.service_id===s.id).map(x=>({...x,signup_count:(counts[x.id]||{}).total||0,volunteer_count:(counts[x.id]||{}).volunteer||0,servant_count:(counts[x.id]||{}).servant||0,max_volunteer_capacity:x.max_volunteer_capacity!=null?x.max_volunteer_capacity:x.max_capacity}))}))}\nasync function loadPublicNotes(){try{const d=await api('admin_notes?select=id,title,message,title_ar,message_ar,priority,is_active,created_at&is_active=eq.true&order=created_at.desc',{},'');notes=d||[];if(language==='ar'&&notes.length){notes=await Promise.all(notes.map(async n=>{const copy={...n};if(!copy.title_ar&&copy.title)copy.title_ar=await translateToArabic(copy.title);if(!copy.message_ar&&copy.message)copy.message_ar=await translateToArabic(copy.message);return copy}))}}catch(e){console.warn('Could not load public admin notes:',e)}}\nfunction esc(x){return String(x??'').replace(\/[&<>\"']\/g,m=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#039;'}[m]))}\nfunction color(c){if(darkMode)return {rose:'#2a1f19',amber:'#2a2116',orange:'#2a1f15',red:'#2c1616',purple:'#201a19'}[c]||'#221a12';return {rose:'#f6e9e2',amber:'#faf1de',orange:'#f9ece0',red:'#fff0f0',purple:'#efe9f4'}[c]||'#f7efe0'}\nfunction capacityForType(x,type){const cap=type==='servant'?x.max_servant_capacity:x.max_volunteer_capacity;const count=type==='servant'?x.servant_count:x.volunteer_count;if(cap==null)return {cap:null,left:null,full:false};const left=Math.max(0,Number(cap)-Number(count||0));return {cap:Number(cap),left,full:left===0}}\nfunction capacityText(x,type=registrationType){const z=capacityForType(x,type);if(z.cap==null)return t('open');return z.full?t('full'):`${z.left} ${t('remaining')}`}\nfunction signupNamesText(){return ''}\nfunction updateNavForMode(){const brand=document.querySelector('.brand');const ids=['homeTab','prayerTab','picturesTab','calendarTab','bibleTab','servicesTab','signupListTab','donationsTab','donationListTab','contactTab','adminTabNav'];const get=id=>document.getElementById(id);if(brand)brand.setAttribute('onclick',staffMode?'staffHomePage()':'home()');ids.forEach(id=>get(id)?.classList.remove('active'));const homeTab=get('homeTab'),calendarTab=get('calendarTab'),bibleTab=get('bibleTab'),prayerTab=get('prayerTab'),picturesTab=get('picturesTab'),servicesTab=get('servicesTab'),signupListTab=get('signupListTab'),donationsTab=get('donationsTab'),donationListTab=get('donationListTab'),contactTab=get('contactTab'),adminTabEl=get('adminTabNav');if(homeTab){homeTab.setAttribute('onclick',staffMode?'staffHomePage();closeMenu()':'home();closeMenu()');homeTab.textContent=t('homeTab');homeTab.classList.toggle('active',staffMode?page==='staffHome':page==='home')}if(calendarTab){calendarTab.setAttribute('onclick','calendarPage(event)');calendarTab.textContent=t('calendarTab');calendarTab.classList.toggle('active',page==='calendar')}if(bibleTab){bibleTab.setAttribute('onclick','biblePage(event)');bibleTab.textContent=t('bibleTab');bibleTab.classList.toggle('active',page==='bible')}if(prayerTab){prayerTab.setAttribute('onclick','prayerPage(event)');prayerTab.textContent=language==='ar'?'\u0635\u0644\u0648\u0627\u062a \u0625\u0636\u0627\u0641\u064a\u0629':'Additional';prayerTab.classList.toggle('active',page==='prayer')}if(picturesTab){picturesTab.setAttribute('onclick','picturesPage(event)');picturesTab.textContent=t('picturesTab');picturesTab.classList.toggle('active',page==='pictures')}if(servicesTab){servicesTab.setAttribute('onclick',staffMode?'staffPage();closeMenu()':'servicesPage();closeMenu()');servicesTab.textContent=staffMode?t('signupServant'):t('servicesTab');servicesTab.classList.toggle('active',!staffMode&&page==='services'||staffMode&&page==='staff')}if(signupListTab){signupListTab.setAttribute('onclick',staffMode?'staffSignupListPage();closeMenu()':'signupListPage();closeMenu()');signupListTab.textContent=t('signupListTab');signupListTab.classList.toggle('active',page==='publicSignups')}if(donationsTab){donationsTab.setAttribute('onclick','donationsPage();closeMenu()');donationsTab.textContent=language==='ar'?'\u062a\u0628\u0631\u0639':'Donate';donationsTab.classList.toggle('active',page==='donations'||page==='donationSignup'||page==='donationSuccess')}if(donationListTab){donationListTab.setAttribute('onclick','donationListPage();closeMenu()');donationListTab.textContent=language==='ar'?'\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062a\u0628\u0631\u0639\u0627\u062a':'Donation List';donationListTab.classList.toggle('active',page==='donationList')}if(contactTab){contactTab.setAttribute('onclick',staffMode?'staffContactPage();closeMenu()':'contactPage();closeMenu()');contactTab.textContent=t('contactTab');contactTab.classList.toggle('active',page==='contact')}if(adminTabEl){adminTabEl.setAttribute('onclick',staffMode?'staffAdmin();closeMenu()':'admin();closeMenu()');adminTabEl.textContent=t('admin');adminTabEl.classList.toggle('active',page==='admin')}}\nfunction toggleMenuGroup(id,event){if(event){event.preventDefault();event.stopPropagation()}const group=document.getElementById(id);if(!group)return;const opening=!group.classList.contains('open');group.classList.toggle('open',opening);const parent=group.previousElementSibling;const arrow=parent&&parent.querySelector('.menu-arrow');if(arrow)arrow.setAttribute('aria-expanded',opening?'true':'false');requestAnimationFrame(positionMenuPanel)}\nfunction positionMenuPanel(){const p=document.getElementById('menuPanel'),b=document.getElementById('hamburgerBtn');if(!p||!b||!p.classList.contains('open'))return;const r=b.getBoundingClientRect();const gap=8;const desired=window.innerWidth<=700?320:280;const panelWidth=Math.min(desired,Math.max(240,window.innerWidth-16));p.style.width=panelWidth+'px';p.style.minWidth=panelWidth+'px';let left=r.right-panelWidth;if(left<8)left=8;if(left+panelWidth>window.innerWidth-8)left=window.innerWidth-panelWidth-8;let top=r.bottom+gap;const maxTop=Math.max(8,window.innerHeight-p.offsetHeight-8);if(top>maxTop)top=maxTop;p.style.left=Math.round(left)+'px';p.style.top=Math.round(top)+'px';}\nfunction toggleMenu(e){if(e){e.preventDefault();e.stopPropagation()}const p=document.getElementById('menuPanel'),b=document.getElementById('hamburgerBtn'),bd=document.getElementById('menuBackdrop');if(!p)return;const open=!p.classList.contains('open');if(open){p.classList.add('open');if(bd)bd.classList.add('open');p.setAttribute('aria-hidden','false');if(b)b.setAttribute('aria-expanded','true');p.style.display='block';p.style.visibility='visible';requestAnimationFrame(positionMenuPanel);}else{closeMenu();}}\nfunction closeMenu(){const p=document.getElementById('menuPanel'),b=document.getElementById('hamburgerBtn'),bd=document.getElementById('menuBackdrop');if(p){p.classList.remove('open');p.setAttribute('aria-hidden','true');p.style.display='none';p.style.visibility='hidden'}if(bd){bd.classList.remove('open');bd.setAttribute('aria-hidden','true')}if(b)b.setAttribute('aria-expanded','false')}\n(function installMenuPointerHandlers(){const bind=()=>{const b=document.getElementById('hamburgerBtn'),p=document.getElementById('menuPanel'),bd=document.getElementById('menuBackdrop');if(!b||!p||b.dataset.bound==='1')return;b.dataset.bound='1';\/* iOS Safari clips position:fixed descendants of a position:sticky ancestor (our header) to the ancestor's box, so the menu renders as an invisible sliver until the page reflows (e.g. on rotation). Moving the menu nodes to be direct children of <body> takes them out of the sticky header entirely so Safari can never clip them. *\/if(bd&&bd.parentNode!==document.body)document.body.appendChild(bd);if(p&&p.parentNode!==document.body)document.body.appendChild(p);const activate=e=>{e.preventDefault();e.stopPropagation();toggleMenu(e)};\/* Use ONE activation event. iOS Safari fires touchend and then click; binding both toggles the menu open and immediately closed. *\/b.addEventListener('click',activate);b.addEventListener('keydown',e=>{if(e.key==='Enter'||e.key===' '){activate(e)}});if(p)p.addEventListener('click',e=>e.stopPropagation());if(bd){bd.addEventListener('click',e=>{e.preventDefault();closeMenu()});}};if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',bind,{once:true});else bind();})();\nwindow.addEventListener('resize',positionMenuPanel);window.addEventListener('scroll',positionMenuPanel,{passive:true});\ndocument.addEventListener('keydown',e=>{if(e.key==='Escape')closeMenu()});\nfunction render(){const a=document.getElementById('app');applyLanguage();updateNavForMode();let meta=document.querySelector('meta[name=robots]');if(!meta){meta=document.createElement('meta');meta.name='robots';document.head.appendChild(meta)}meta.content=staffMode?'noindex,nofollow':'index,follow';document.title=staffMode&&page!=='admin'?t('staffTitle'):page==='publicSignups'?t('publicListTitle'):(language==='ar'?'\u0645\u062c\u0645\u0648\u0639\u0629 \u0627\u0644\u0633\u0627\u0645\u0631\u064a \u0627\u0644\u0635\u0627\u0644\u062d \u2014 \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u0645\u062a\u0637\u0648\u0639\u064a\u0646':'Good Samaritan Group \u2014 Volunteer Sign-Up');if(!configured()){a.innerHTML='<main class=\"wrap main\"><div class=\"box\"><h1>'+t('setupTitle')+'<\/h1><p class=\"muted\">'+t('setupText')+'<\/p><\/div><\/main>';return}if(page==='home')renderHome();else if(page==='prayer')renderPrayer();else if(page==='pictures')renderPictures();else if(page==='donations')renderDonations();else if(page==='donationSignup')renderDonationSignup();else if(page==='donationSuccess')renderDonationSuccess();else if(page==='donationList')renderDonationList();else if(page==='calendar')renderCalendar();else if(page==='bible')renderBible();else if(page==='staffHome')renderStaffHome();else if(page==='services')renderServices();else if(page==='staff')renderStaff();else if(page==='publicSignups')renderPublicSignups();else if(page==='contact')renderContact();else if(page==='success')renderSuccess();else if(page==='admin')renderAdmin();else renderSignup()}\nfunction shell(content){document.getElementById('app').innerHTML='<main class=\"wrap main\">'+content+'<\/main>'}\nfunction renderHome(){staffMode=false;registrationType='volunteer';shell(`${renderNotes(true,false)}<section class=\"home-hero\"><div class=\"home-hero-top\"><div class=\"home-photo-wrap\"><img decoding=\"async\" class=\"home-photo\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/group-photo.jpg\" alt=\"Good Samaritan Group community service\"><\/div><div class=\"home-intro\"><span class=\"home-eyebrow\">Good Samaritan Group<\/span><h1>${t('homeTitle')}<\/h1><p>${t('homeIntro')}<\/p><button class=\"primary\" onclick=\"servicesPage()\">${t('exploreServices')}<\/button><\/div><\/div><p class=\"home-verse\">${t('verse')}<\/p><h2 class=\"values-title\">${t('valuesTitle')}<\/h2><div class=\"grid values-grid\"><div class=\"card value-card\"><div class=\"icon\">\u2764\ufe0f<\/div><h2>${t('love')}<\/h2><p>${t('loveText')}<\/p><\/div><div class=\"card value-card\"><div class=\"icon\">\ud83e\udd1d<\/div><h2>${t('service')}<\/h2><p>${t('serviceText')}<\/p><\/div><div class=\"card value-card\"><div class=\"icon\">\ud83d\udc9b<\/div><h2>${t('compassion')}<\/h2><p>${t('compassionText')}<\/p><\/div><\/div><\/section>`)}\nfunction renderStaffHome(){staffMode=true;registrationType='servant';shell(`${renderNotes(true,false)}<section class=\"home-hero\"><div class=\"home-hero-top\"><div class=\"home-photo-wrap\"><img decoding=\"async\" class=\"home-photo\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/group-photo.jpg\" alt=\"Good Samaritan Group community service\"><\/div><div class=\"home-intro\"><span class=\"home-eyebrow\">Good Samaritan Group<\/span><h1>${t('homeTitle')}<\/h1><p>${t('homeIntro')}<\/p><button class=\"primary\" onclick=\"staffPage()\">${t('signupServant')}<\/button><\/div><\/div><p class=\"home-verse\">${t('verse')}<\/p><h2 class=\"values-title\">${t('valuesTitle')}<\/h2><div class=\"grid values-grid\"><div class=\"card value-card\"><div class=\"icon\">\u2764\ufe0f<\/div><h2>${t('love')}<\/h2><p>${t('loveText')}<\/p><\/div><div class=\"card value-card\"><div class=\"icon\">\ud83e\udd1d<\/div><h2>${t('service')}<\/h2><p>${t('serviceText')}<\/p><\/div><div class=\"card value-card\"><div class=\"icon\">\ud83d\udc9b<\/div><h2>${t('compassion')}<\/h2><p>${t('compassionText')}<\/p><\/div><\/div><\/section>`)}\nfunction localizedService(s){return {name:language==='ar'?(s.name_ar||s.name):(s.name||''),description:language==='ar'?(s.description_ar||s.description):(s.description||'')}}\nfunction localizedSession(x){return {label:language==='ar'?(x.label_ar||x.label):(x.label||''),location:language==='ar'?(x.location_ar||x.location):(x.location||''),need:language==='ar'?(x.need_ar||x.need):(x.need||'')}}\nfunction activeNotes(){return notes.filter(n=>n.is_active!==false)}\nfunction renderNotes(publicOnly=true,compact=false){const list=publicOnly?activeNotes():notes;if(!list.length)return '';return `<div class=\"box${compact?' home-admin-notes':''}\" style=\"margin-bottom:${compact?'18':'20'}px\"><div class=\"toolbar\"><div><h2>\ud83d\udce2 ${t('adminNotes')}<\/h2><p class=\"muted\">${t('adminNotesHelp')}<\/p><\/div><\/div>${list.map(n=>`<article class=\"admin-note ${esc(n.priority||'normal')}\"><h3>${esc(language==='ar'?(n.title_ar||n.title):n.title)}<\/h3><div>${esc(language==='ar'?(n.message_ar||n.message):n.message).replace(\/\\n\/g,'<br>')}<\/div><div class=\"note-meta\">${n.priority==='emergency'?'\ud83d\udea8 ':n.priority==='important'?'\u26a0\ufe0f ':''}${esc(n.created_at?new Date(n.created_at).toLocaleDateString(language==='ar'?'ar':'en-US'):'')}<\/div><\/article>`).join('')}<\/div>`}\nfunction sanitizePrayerHtml(html){const doc=new DOMParser().parseFromString(String(html||''),'text\/html');const allowed=['B','STRONG','BR','P','DIV','UL','OL','LI'];doc.body.querySelectorAll('*').forEach(el=>{if(!allowed.includes(el.tagName)){el.replaceWith(...Array.from(el.childNodes));}else{Array.from(el.attributes).forEach(a=>el.removeAttribute(a.name));}});return doc.body.innerHTML;}\nfunction renderPrayer(){\n  if(currentPrayerPageId){\n    const p=prayerPages.find(x=>x.id===currentPrayerPageId);\n    const c=p?prayerCategories.find(x=>x.id===p.category_id):null;\n    if(!p){currentPrayerPageId='';renderPrayer();return;}\n    currentPrayerCategoryId=p.category_id;\n    const backLabel=language==='ar'?'\u0627\u0644\u0639\u0648\u062f\u0629 \u0625\u0644\u0649 \u0627\u0644\u0641\u0626\u0629':'Back to Category';\n    const imageHtml=p.image_data?`<div class=\"prayer-public-frame\" data-x=\"${Number(p.image_x??50)}\" data-y=\"${Number(p.image_y??50)}\" data-zoom=\"${Number(p.image_zoom||1)}\"><img decoding=\"async\" class=\"prayer-public-img\" src=\"${esc(p.image_data)}\" alt=\"${esc(p.title)}\"><\/div>`:'';\n    shell(`<button class=\"back\" onclick=\"closePrayerPage()\">\u2190 ${backLabel}<\/button><article class=\"box prayer-detail\">${imageHtml}<div class=\"prayer-detail-body\"><div class=\"muted\" style=\"margin-bottom:6px\">${esc(c?.name||'Prayer')}<\/div><h1>${esc(language==='ar'?(p.title_ar||p.title):p.title)}<\/h1><div class=\"prayer-text\">${sanitizePrayerHtml(language==='ar'?(p.body_html_ar||p.body_html):p.body_html)}<\/div><\/div><\/article>`);\n    const pub=document.querySelector('.prayer-public-frame'); if(pub){const im=pub.querySelector('img'); const apply=()=>{const W=290,H=270,nw=im.naturalWidth,nh=im.naturalHeight,cover=Math.max(W\/nw,H\/nh)*Number(pub.dataset.zoom||1),iw=nw*cover,ih=nh*cover,maxL=Math.max(0,iw-W),maxT=Math.max(0,ih-H);im.style.width=iw+'px';im.style.height=ih+'px';im.style.left=(-maxL*Number(pub.dataset.x||50)\/100)+'px';im.style.top=(-maxT*Number(pub.dataset.y||50)\/100)+'px'};im.onload=apply;if(im.complete)apply()}\n\n    return;\n  }\n  if(currentPrayerCategoryId){\n    const c=prayerCategories.find(x=>x.id===currentPrayerCategoryId);\n    if(!c){currentPrayerCategoryId='';renderPrayer();return;}\n    const pages=prayerPages.filter(p=>p.category_id===c.id);\n    const cname=language==='ar'?(c.name_ar||c.name):c.name;\n    const cdesc=language==='ar'?(c.description_ar||c.description):c.description;\n    shell(`<button class=\"back\" onclick=\"closePrayerCategory()\">\u2190 ${language==='ar'?'\u0627\u0644\u0639\u0648\u062f\u0629 \u0625\u0644\u0649 \u0627\u0644\u0635\u0644\u0627\u0629':'Back to Prayer'}<\/button><div class=\"hero\"><img decoding=\"async\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/logo.png\"><h1>${esc(cname)}<\/h1>${cdesc?`<p>${esc(cdesc)}<\/p>`:''}<p class=\"muted\">${pages.length} ${pages.length===1?(language==='ar'?'\u0635\u0644\u0627\u0629':'prayer'):(language==='ar'?'\u0635\u0644\u0648\u0627\u062a':'prayers')}<\/p><\/div>${prayerError?`<div class=\"error\">${esc(prayerError)}<\/div>`:''}${pages.length?`<div class=\"grid\">${pages.map(p=>{const title=language==='ar'?(p.title_ar||p.title):p.title;const body=language==='ar'?(p.body_html_ar||p.body_html):p.body_html;const plain=sanitizePrayerHtml(body).replace(\/<[^>]+>\/g,' ').replace(\/\\s+\/g,' ').trim();return `<button type=\"button\" class=\"card prayer-link-card\" onclick=\"openPrayerPage('${esc(p.id)}','${esc(c.id)}')\"><div class=\"icon\">\ud83d\ude4f<\/div><h2>${esc(title)}<\/h2><p>${esc(plain.slice(0,150))}${plain.length>150?'\u2026':''}<\/p><div class=\"row\"><span class=\"pill\">${p.image_data?(language==='ar'?'\u0635\u0648\u0631\u0629 \u0645\u062a\u0627\u062d\u0629':'Photo included'):(language==='ar'?'\u0635\u0644\u0627\u0629':'Prayer')}<\/span><span class=\"link\">${language==='ar'?'\u0641\u062a\u062d \u2190':'Open \u2192'}<\/span><\/div><\/button>`}).join('')}<\/div>`:`<div class=\"box\" style=\"text-align:center\"><h2>${language==='ar'?'\u0644\u0627 \u062a\u0648\u062c\u062f \u0635\u0644\u0648\u0627\u062a \u0641\u064a \u0647\u0630\u0647 \u0627\u0644\u0641\u0626\u0629':'No prayers in this category yet'}<\/h2><p class=\"muted\">${language==='ar'?'\u0633\u064a\u062a\u0645 \u0625\u0636\u0627\u0641\u0629 \u0627\u0644\u0635\u0644\u0648\u0627\u062a \u0645\u0646 \u0644\u0648\u062d\u0629 \u0627\u0644\u0625\u062f\u0627\u0631\u0629.':'Prayers will appear here when the admin adds them.'}<\/p><\/div>`}`);\n    return;\n  }\n  shell(`<div class=\"hero\"><img decoding=\"async\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/logo.png\"><h1>${language==='ar'?'\u0627\u0644\u0635\u0644\u0627\u0629':'Prayer'}<\/h1><p>${language==='ar'?'\u0627\u062e\u062a\u0631 \u0641\u0626\u0629 \u062b\u0645 \u0627\u062e\u062a\u0631 \u0627\u0644\u0635\u0644\u0627\u0629 \u0627\u0644\u062a\u064a \u062a\u0631\u064a\u062f \u0642\u0631\u0627\u0621\u062a\u0647\u0627.':'Choose a category, then choose the prayer you would like to read.'}<\/p><\/div>${prayerError?`<div class=\"error\">${esc(prayerError)}<\/div>`:''}${prayerLoading?`<div class=\"box\" style=\"text-align:center\"><h2>${language==='ar'?'\u062c\u0627\u0631\u064d \u062a\u062d\u0645\u064a\u0644 \u0627\u0644\u0635\u0644\u0648\u0627\u062a\u2026':'Loading prayers\u2026'}<\/h2><\/div>`:prayerCategories.length?`<div class=\"grid\">${prayerCategories.map(c=>{const pages=prayerPages.filter(p=>p.category_id===c.id);const name=language==='ar'?(c.name_ar||c.name):c.name;const desc=language==='ar'?(c.description_ar||c.description):c.description;return `<button type=\"button\" class=\"card prayer-link-card prayer-category-card\" onclick=\"openPrayerCategory('${esc(c.id)}')\"><div class=\"icon\">\ud83d\ude4f<\/div><h2>${esc(name)}<\/h2><p>${esc(desc||'')}<\/p><div class=\"row\"><span class=\"pill\">${pages.length} ${pages.length===1?(language==='ar'?'\u0635\u0644\u0627\u0629':'prayer'):(language==='ar'?'\u0635\u0644\u0648\u0627\u062a':'prayers')}<\/span><span class=\"link\">${language==='ar'?'\u0641\u062a\u062d \u2190':'Open \u2192'}<\/span><\/div><\/button>`}).join('')}<\/div>`:`<div class=\"box\" style=\"text-align:center\"><h2>${language==='ar'?'\u0644\u0627 \u062a\u0648\u062c\u062f \u0641\u0626\u0627\u062a \u0635\u0644\u0627\u0629 \u0628\u0639\u062f':'No prayer categories yet'}<\/h2><p class=\"muted\">${language==='ar'?'\u0633\u064a\u062a\u0645 \u0625\u0636\u0627\u0641\u0629 \u0627\u0644\u0641\u0626\u0627\u062a \u0645\u0646 \u0644\u0648\u062d\u0629 \u0627\u0644\u0625\u062f\u0627\u0631\u0629.':'Prayer categories will appear here when the admin adds them.'}<\/p><\/div>`}`)\n}\nfunction openPrayerCategory(id){currentPrayerPageId='';currentPrayerCategoryId=id;history.pushState({},'',`${staffMode?'\/staff\/prayer':'\/prayer'}\/category\/${encodeURIComponent(id)}`);renderPrayer()}\nfunction closePrayerCategory(){currentPrayerPageId='';currentPrayerCategoryId='';history.pushState({},'',staffMode?'\/staff\/prayer':'\/prayer');renderPrayer()}\nfunction openPrayerPage(id,categoryId){currentPrayerPageId=id;currentPrayerCategoryId=categoryId||prayerPages.find(p=>p.id===id)?.category_id||'';history.pushState({},'',`${staffMode?'\/staff\/prayer':'\/prayer'}\/category\/${encodeURIComponent(currentPrayerCategoryId)}\/page\/${encodeURIComponent(id)}`);renderPrayer()}\nfunction closePrayerPage(){const cid=currentPrayerCategoryId;currentPrayerPageId='';const base=staffMode?'\/staff\/prayer':'\/prayer';if(cid){history.pushState({},'',`${base}\/category\/${encodeURIComponent(cid)}`)}else{history.pushState({},'',base)}renderPrayer()}\n\nfunction renderServices(){staffMode=false;registrationType='volunteer';shell('<div class=\"hero\"><img decoding=\"async\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/logo.png\"><h1>'+t('choose')+'<\/h1><p>'+t('thanks')+'<\/p><p style=\"margin-top:18px;font-weight:700;color:#a8532b\">'+t('verse')+'<\/p><\/div>'+renderNotes(true)+'<div class=\"grid\">'+services.map(s=>{const l=localizedService(s);return `<a class=\"card\" href=\"\/${esc(s.id)}\" style=\"background:${color(s.color)};text-decoration:none;color:inherit\"><div class=\"icon\">${esc(s.icon)}<\/div><h2>${esc(l.name)}<\/h2><p>${esc(l.description)}<\/p><div class=\"row\"><span class=\"pill\">${s.sessions.length} ${t('upcoming')} ${s.sessions.length===1?t('session'):t('sessions')}<\/span><span class=\"link\">${t('signUpArrow')}<\/span><\/div><\/a>`}).join('')+'<\/div><p class=\"muted\" style=\"text-align:center;margin-top:35px\">'+t('questions')+'<\/p>')}\nfunction renderStaff(){staffMode=true;registrationType='servant';shell('<div class=\"hero\"><img decoding=\"async\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/logo.png\"><h1>'+t('staffTitle')+'<\/h1><p>'+t('staffIntro')+'<\/p><p style=\"margin-top:18px;font-weight:700;color:#a8532b\">'+t('verse')+'<\/p><\/div>'+renderNotes(false)+'<div class=\"grid\">'+services.map(s=>{const l=localizedService(s);return `<a class=\"card\" href=\"\/staff\/${esc(s.id)}\" style=\"background:${color(s.color)};text-decoration:none;color:inherit\"><div class=\"icon\">${esc(s.icon)}<\/div><h2>${esc(l.name)}<\/h2><p>${esc(l.description)}<\/p><div class=\"row\"><span class=\"pill\">${s.sessions.length} ${t('upcoming')} ${s.sessions.length===1?t('session'):t('sessions')}<\/span><span class=\"link\">${t('signUpArrow')}<\/span><\/div><\/a>`}).join('')+'<\/div><p class=\"muted\" style=\"text-align:center;margin-top:35px\">'+t('questions')+'<\/p>')}\nasync function renderPublicSignups(){\n  if(staffMode){\n    try{\n      const [names]=await Promise.all([rpc('get_session_signup_names_public',{},'')]);\n      const namesBy={};(names||[]).forEach(x=>(namesBy[x.session_id]??=[]).push(x));\n      const groups=services.map(s=>{const sl=localizedService(s);const events=s.sessions.map(x=>{const all=(namesBy[x.id]||[]).slice().sort((a,b)=>new Date(a.created_at)-new Date(b.created_at));const v=all.filter(q=>(q.registration_type||'volunteer')==='volunteer'),st=all.filter(q=>q.registration_type==='servant');const l=localizedSession(x);return `<div class=\"signup-event\"><h3>${esc(l.label)}<\/h3><div class=\"signup-event-meta\">\ud83d\udcc5 ${esc(x.date)} \u00b7 \ud83d\udd50 ${esc(x.time)} \u00b7 \ud83d\udccd ${esc(l.location)}<\/div><div class=\"signup-columns\"><div class=\"signup-list-box\"><h4>\ud83d\ude4b ${t('volunteerPlural')} (${v.length})<\/h4>${v.length?`<ol>${v.map(q=>`<li>${esc(q.name)}<\/li>`).join('')}<\/ol>`:`<span class=\"muted\">${t('noPublicSignups')}<\/span>`}<\/div><div class=\"signup-list-box\"><h4>\u271d\ufe0f ${t('servantPlural')} (${st.length})<\/h4>${st.length?`<ol>${st.map(q=>`<li>${esc(q.name)}<\/li>`).join('')}<\/ol>`:`<span class=\"muted\">${t('noPublicSignups')}<\/span>`}<\/div><\/div><\/div>`}).join('');return `<div class=\"signup-group\"><h2>${esc(s.icon)} ${esc(sl.name)}<\/h2>${events}<\/div>`}).join('');shell(`<div class=\"hero\"><h1>${t('publicListTitle')}<\/h1><p>${t('staffTitle')}<\/p><\/div><div class=\"box\">${groups}<\/div>`);\n    }catch(e){renderDataError(e)}\n    return;\n  }\n  const groups=services.map(s=>{const sl=localizedService(s);const events=s.sessions.map(x=>{const l=localizedSession(x);const v=Number(x.volunteer_count||0),st=Number(x.servant_count||0);return `<div class=\"signup-event\"><h3>${esc(l.label)}<\/h3><div class=\"signup-event-meta\">\ud83d\udcc5 ${esc(x.date)} \u00b7 \ud83d\udd50 ${esc(x.time)} \u00b7 \ud83d\udccd ${esc(l.location)}<\/div><div class=\"signup-columns\"><div class=\"signup-list-box\"><h4>\ud83d\ude4b ${t('volunteerPlural')} (${v})<\/h4><span class=\"muted\">${v?`${v} ${t('registered')}`:t('noPublicSignups')}<\/span><\/div><div class=\"signup-list-box\"><h4>\u271d\ufe0f ${t('servantPlural')} (${st})<\/h4><span class=\"muted\">${st?`${st} ${t('registered')}`:t('noPublicSignups')}<\/span><\/div><\/div><\/div>`}).join('');return `<div class=\"signup-group\"><h2>${esc(s.icon)} ${esc(sl.name)}<\/h2>${events}<\/div>`}).join('');shell(`<div class=\"hero\"><h1>${t('publicListTitle')}<\/h1><p>${language==='ar'?'\u062a\u0638\u0647\u0631 \u0647\u0646\u0627 \u0623\u0639\u062f\u0627\u062f \u0627\u0644\u0645\u0633\u062c\u0644\u064a\u0646 \u0641\u0642\u0637\u060c \u0648\u0644\u0627 \u062a\u0638\u0647\u0631 \u0623\u0633\u0645\u0627\u0621 \u0627\u0644\u0645\u062a\u0637\u0648\u0639\u064a\u0646.':'Only registration counts are shown here. Volunteer names are private.'}<\/p><\/div>${renderNotes(true)}<div class=\"box\">${groups}<\/div>`)\n}\nasync function loadDonations(authToken=''){try{donations=await api('donations?select=*&order=created_at.desc',{},authToken)||[]}catch(e){donations=[];throw e}}\nasync function loadDonationSignups(){try{donationSignups=await rpc('get_donation_list_public',{},'')||[]}catch(e){donationSignups=[];throw e}}\nfunction donationPublicImage(item){return item.image_data?`<div class=\"donation-public-frame\" data-x=\"${Number(item.image_x??50)}\" data-y=\"${Number(item.image_y??50)}\" data-zoom=\"${Number(item.image_zoom||1)}\"><img decoding=\"async\" class=\"donation-public-img\" src=\"${esc(item.image_data)}\" alt=\"${esc(item.title)}\"><\/div>`:''}\nfunction applyDonationPublicFrame(){const pub=document.querySelector('.donation-public-frame');if(!pub)return;const im=pub.querySelector('img');const apply=()=>{const W=290,H=270,nw=im.naturalWidth,nh=im.naturalHeight;if(!nw||!nh)return;const cover=Math.max(W\/nw,H\/nh)*Number(pub.dataset.zoom||1),iw=nw*cover,ih=nh*cover;im.style.width=iw+'px';im.style.height=ih+'px';im.style.left=(-Math.max(0,iw-W)*(Number(pub.dataset.x||50)\/100))+'px';im.style.top=(-Math.max(0,ih-H)*(Number(pub.dataset.y||50)\/100))+'px'};im.onload=apply;if(im.complete)apply()}\nfunction donationTotals(id){const rows=donationSignups.filter(x=>x.donation_id===id);return rows.reduce((n,x)=>n+Number(x.quantity||0),0)}\nfunction donationClosed(d){if(!d)return true;const pledged=donationTotals(d.id);return !!d.is_closed||(!!d.close_when_met&&Number(d.quantity_needed||0)>0&&pledged>=Number(d.quantity_needed||0))}\nasync function donationsPage(){registrationType=staffMode?'servant':'volunteer';page='donations';history.pushState({},'', staffMode?'\/staff\/donations':'\/donations');closeMenu();render();try{await Promise.all([loadDonations(),loadDonationSignups()]);if(page==='donations')render()}catch(e){if(page==='donations')renderDataError(e)}}\nfunction renderDonations(){shell(`<div class=\"hero\"><img decoding=\"async\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/logo.png\"><h1>Donate<\/h1><p>Help us provide the items our community needs. Choose an item and sign up to donate it.<\/p><\/div>${donations.length?`<div class=\"box\">${donations.map(d=>{const pledged=donationTotals(d.id),needed=Number(d.quantity_needed||0),remaining=Math.max(0,needed-pledged),closed=donationClosed(d);return `<article class=\"donation-list-event\"><h3>${esc(d.emoji||'\ud83c\udf81')} ${esc(d.title)}<\/h3><div class=\"donation-list-meta\">\ud83d\uded2 <b>Shop:<\/b> ${esc(d.shop||'Not specified')}<br>\ud83d\udccd <b>Drop-off:<\/b> ${esc(d.dropoff_location||'Not specified')}<br>\ud83d\udce6 <b>Quantity:<\/b> ${needed} asked \u00b7 ${pledged} pledged \u00b7 ${remaining} still needed${d.note?`<br>\ud83d\udcdd <b>Note:<\/b> ${esc(d.note)}`:''}<\/div><div style=\"margin-top:12px\">${closed?`<button class=\"secondary\" disabled>Donations Closed<\/button>`:`<button class=\"primary\" onclick=\"openDonation('${esc(d.id)}')\">Sign Up to Donate<\/button>`}<\/div><\/article>`}).join('')}<\/div>`:`<div class=\"box\" style=\"text-align:center\"><h2>No donation needs right now<\/h2><p class=\"muted\">Please check back soon.<\/p><\/div>`}`)}\nfunction openDonation(id){currentService=id;page='donationSignup';history.pushState({},'',(staffMode?'\/staff\/donations\/':'\/donations\/')+encodeURIComponent(id));render()}\nfunction renderDonationSignup(){const d=donations.find(x=>x.id===currentService);if(!d){donationsPage();return}const pledged=donationTotals(d.id),needed=Number(d.quantity_needed||0),remaining=Math.max(0,needed-pledged),closed=donationClosed(d);shell(`<button class=\"back\" onclick=\"donationsPage()\">\u2190 Back to Donate<\/button><div class=\"box\" style=\"max-width:720px;margin:auto\">${donationPublicImage(d)}<h1>${esc(d.emoji||'\ud83c\udf81')} ${esc(d.title)}<\/h1><div class=\"donation-list-meta\">\ud83d\uded2 <b>Shop:<\/b> ${esc(d.shop||'Not specified')}<br>\ud83d\udccd <b>Drop-off:<\/b> ${esc(d.dropoff_location||'Not specified')}<br>\ud83d\udce6 <b>Originally asked:<\/b> ${needed}<br>\ud83e\udd1d <b>Already pledged:<\/b> ${pledged}<br>\ud83c\udfaf <b>Still needed:<\/b> ${remaining}${d.note?`<br>\ud83d\udcdd <b>Note:<\/b> ${esc(d.note)}`:''}<\/div>${closed?`<div class=\"error\" style=\"margin-top:18px\">This donation need is closed because the requested amount has been met.<\/div>`:`<form onsubmit=\"submitDonation(event,'${esc(d.id)}')\" style=\"margin-top:20px\"><label><b>Full Name *<\/b><input class=\"input\" id=\"donationName\" required placeholder=\"Full Name\"><\/label><label><b>Phone Number *<\/b><input class=\"input\" id=\"donationPhone\" required type=\"tel\" inputmode=\"tel\" autocomplete=\"tel\" placeholder=\"Phone Number\"><\/label><label><b>How many will you bring? *<\/b><input class=\"input\" id=\"donationQuantity\" required type=\"number\" min=\"1\" ${d.close_when_met?`max=\"${Math.max(1,remaining)}\"`:``} step=\"1\" inputmode=\"numeric\" placeholder=\"Quantity\"><\/label><div id=\"formerr\"><\/div><button class=\"primary\">Confirm Donation<\/button><\/form>`}<\/div>`);applyDonationPublicFrame()}\nasync function submitDonation(event,id){event.preventDefault();const d=donations.find(x=>x.id===id);const qty=Number(document.getElementById('donationQuantity').value);const remaining=Math.max(0,Number(d?.quantity_needed||0)-donationTotals(id));if(!d||donationClosed(d)||(d.close_when_met&&qty>remaining)){document.getElementById('formerr').innerHTML='<div class=\"error\">This donation need is closed or the requested amount is no longer available.<\/div>';return}const b=event.target.querySelector('button.primary');b.disabled=true;b.textContent='Submitting\u2026';try{await rpc('register_donation',{p_donation_id:id,p_name:document.getElementById('donationName').value.trim(),p_phone:document.getElementById('donationPhone').value.trim(),p_quantity:qty});await loadDonationSignups();page='donationSuccess';render()}catch(e){document.getElementById('formerr').innerHTML='<div class=\"error\">Could not complete the donation sign-up. Please try again.<\/div>';b.disabled=false;b.textContent='Confirm Donation'}}\nfunction renderDonationSuccess(){shell(`<div class=\"success\"><div class=\"emoji\">\ud83c\udf81<\/div><h1>Thank You!<\/h1><p class=\"muted\" style=\"font-size:18px\">Your donation sign-up has been received. Thank you for your generosity!<\/p><button class=\"primary\" onclick=\"donationsPage()\">Back to Donate<\/button><\/div>`)}\nasync function donationListPage(){registrationType=staffMode?'servant':'volunteer';page='donationList';history.pushState({},'',staffMode?'\/staff\/donation-list':'\/donation-list');closeMenu();render();try{await Promise.all([loadDonations(),loadDonationSignups()]);if(page==='donationList')render()}catch(e){if(page==='donationList')renderDataError(e)}}\nfunction renderDonationList(){const grouped={};donationSignups.forEach(x=>(grouped[x.donation_id]??=[]).push(x));shell(`<div class=\"hero\"><img decoding=\"async\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/logo.png\"><h1>Donation List<\/h1><p>See what our generous donors have committed to bring. Donor names are kept private.<\/p><\/div><div class=\"box\">${donations.length?donations.map(d=>{const rows=grouped[d.id]||[],pledged=rows.reduce((n,x)=>n+Number(x.quantity||0),0),remaining=Math.max(0,Number(d.quantity_needed||0)-pledged);return `<article class=\"donation-list-event\"><h3>${esc(d.emoji||'\ud83c\udf81')} ${esc(d.title)}<\/h3><div class=\"donation-list-meta\">\ud83d\udce6 ${d.quantity_needed} asked \u00b7 ${pledged} pledged \u00b7 ${remaining} still needed<\/div>${rows.length?`<div style=\"margin-top:10px\">${rows.map(x=>`<div class=\"donation-list-donor\"><b>Generous Donor<\/b><span>${esc(String(x.quantity||0))} pledged<\/span><\/div>`).join('')}<\/div>`:`<div class=\"muted\" style=\"margin-top:10px\">No donations pledged yet.<\/div>`}<\/article>`}).join(''):`<p class=\"muted\">No donation needs right now.<\/p>`}<\/div>`)}\nfunction donationForm(id=null){const d=donations.find(x=>x.id===id)||{};const x=Number(d.image_x??50),y=Number(d.image_y??50),z=Number(d.image_zoom||1);shell(`<div class=\"box\" style=\"max-width:720px;margin:auto\"><button class=\"back\" onclick=\"renderAdmin()\">\u2190 Back to Admin<\/button><h2>${id?'Edit':'Add'} Donation Need<\/h2><form id=\"donationForm\"><label><b>Emoji *<\/b><input class=\"input\" id=\"donEmoji\" required maxlength=\"8\" value=\"${esc(d.emoji||'\ud83c\udf81')}\" placeholder=\"\ud83e\udd5a\"><\/label><label><b>Food \/ Item Name *<\/b><input class=\"input\" id=\"donTitle\" required value=\"${esc(d.title||'')}\" placeholder=\"Eggs, Gloves, etc.\"><\/label><label><b>Shop (where to buy) *<\/b><input class=\"input\" id=\"donShop\" required value=\"${esc(d.shop||'')}\" placeholder=\"Shop or store name\"><\/label><label><b>Drop-off Location *<\/b><textarea class=\"input\" id=\"donDropoff\" required placeholder=\"Where the item should be dropped off\">${esc(d.dropoff_location||d.description||'')}<\/textarea><\/label><label><b>Note \/ Description<\/b><textarea class=\"input\" id=\"donNote\" placeholder=\"Please drop off within 3 days\">${esc(d.note||'')}<\/textarea><\/label><label><b>Quantity Needed *<\/b><input class=\"input\" id=\"donQuantityNeeded\" required type=\"number\" min=\"1\" step=\"1\" value=\"${esc(String(d.quantity_needed??''))}\" placeholder=\"Quantity\"><\/label><label style=\"display:block;margin:10px 0\"><input type=\"checkbox\" id=\"donCloseWhenMet\" ${d.close_when_met?'checked':''}> Close donations automatically when the requested quantity is met<\/label><label><b>Photo<\/b><input class=\"input\" id=\"donImage\" type=\"file\" accept=\"image\/*\"><\/label><div class=\"donation-image-preview\"><div class=\"donation-image-canvas\" id=\"donCanvas\"><span class=\"muted\">No image selected<\/span><\/div><\/div><p class=\"muted\" style=\"margin:8px 0\">This preview is exactly the 290 \u00d7 270 frame the donor will see after clicking Sign Up to Donate.<\/p><div class=\"two\"><label>Horizontal position <input class=\"donation-range\" id=\"donX\" type=\"range\" min=\"0\" max=\"100\" value=\"${x}\"><\/label><label>Vertical position <input class=\"donation-range\" id=\"donY\" type=\"range\" min=\"0\" max=\"100\" value=\"${y}\"><\/label><\/div><label>Zoom <input class=\"donation-range\" id=\"donZoom\" type=\"range\" min=\"1\" max=\"2.5\" step=\"0.05\" value=\"${z}\"><\/label><label style=\"display:block;margin:10px 0\"><input type=\"checkbox\" id=\"donRemove\" ${!d.image_data?'disabled':''}> Remove existing image<\/label><button class=\"primary\">Save Donation Need<\/button> <button type=\"button\" class=\"secondary\" onclick=\"renderAdmin()\">Cancel<\/button><\/form><\/div>`);initDonationEditor(d)}\nfunction initDonationEditor(d){const canvas=document.getElementById('donCanvas'),input=document.getElementById('donImage'),x=document.getElementById('donX'),y=document.getElementById('donY'),z=document.getElementById('donZoom'),remove=document.getElementById('donRemove');let imageData=d.image_data||'',nw=0,nh=0;const W=290,H=270;const clamp=(v,a,b)=>Math.max(a,Math.min(b,v));function apply(){const im=canvas.querySelector('img');if(!im||!nw||!nh)return;const cover=Math.max(W\/nw,H\/nh)*Number(z.value||1),iw=nw*cover,ih=nh*cover;im.style.width=iw+'px';im.style.height=ih+'px';im.style.left=(-Math.max(0,iw-W)*(Number(x.value)\/100))+'px';im.style.top=(-Math.max(0,ih-H)*(Number(y.value)\/100))+'px'}function preview(src){canvas.innerHTML=src?`<img decoding=\"async\" src=\"${src}\" alt=\"Donation preview\">`:'<span class=\"muted\">No image selected<\/span>';const im=canvas.querySelector('img');if(im){const ready=()=>{nw=im.naturalWidth;nh=im.naturalHeight;apply()};im.onload=ready;if(im.complete)ready()}}async function compress(file){const src=await new Promise((res,rej)=>{const r=new FileReader();r.onload=()=>res(r.result);r.onerror=rej;r.readAsDataURL(file)});const im=await new Promise((res,rej)=>{const i=new Image();i.onload=()=>res(i);i.onerror=rej;i.src=src});const scale=Math.min(1,1400\/Math.max(im.naturalWidth,im.naturalHeight));const c=document.createElement('canvas');c.width=Math.max(1,Math.round(im.naturalWidth*scale));c.height=Math.max(1,Math.round(im.naturalHeight*scale));c.getContext('2d').drawImage(im,0,0,c.width,c.height);return c.toDataURL('image\/jpeg',.82)}preview(imageData);input.addEventListener('change',async()=>{const f=input.files?.[0];if(!f)return;if(!f.type.startsWith('image\/'))return alert('Please choose an image file.');try{imageData=await compress(f);remove.checked=false;preview(imageData)}catch(e){alert('Could not read the image.')}});[x,y,z].forEach(el=>el.addEventListener('input',apply));let drag=null;canvas.addEventListener('pointerdown',e=>{if(!canvas.querySelector('img'))return;e.preventDefault();canvas.setPointerCapture(e.pointerId);drag={cx:e.clientX,cy:e.clientY,x:Number(x.value),y:Number(y.value)};canvas.classList.add('dragging')});canvas.addEventListener('pointermove',e=>{if(!drag||!nw||!nh)return;const cover=Math.max(W\/nw,H\/nh)*Number(z.value||1),iw=nw*cover,ih=nh*cover,maxL=Math.max(0,iw-W),maxT=Math.max(0,ih-H);if(maxL)x.value=clamp(drag.x-(e.clientX-drag.cx)\/maxL*100,0,100);if(maxT)y.value=clamp(drag.y-(e.clientY-drag.cy)\/maxT*100,0,100);apply()});const end=()=>{drag=null;canvas.classList.remove('dragging')};canvas.addEventListener('pointerup',end);canvas.addEventListener('pointercancel',end);document.getElementById('donationForm').addEventListener('submit',async e=>{e.preventDefault();try{await saveDonation(e,d.id||'',imageData)}catch(err){alert(err.message||'Could not save donation.')}});remove.addEventListener('change',()=>{if(remove.checked){imageData='';preview('')}})}\nasync function saveDonation(event,id,imageData){const existing=donations.find(x=>x.id===id);let image=imageData!==undefined?imageData:(existing?.image_data||'');if(document.getElementById('donRemove')?.checked)image='';await rpc('admin_upsert_donation',{p_id:id||null,p_title:document.getElementById('donTitle').value.trim(),p_description:document.getElementById('donNote').value.trim(),p_shop:document.getElementById('donShop').value.trim(),p_dropoff_location:document.getElementById('donDropoff').value.trim(),p_quantity_needed:Number(document.getElementById('donQuantityNeeded').value),p_image_data:image,p_image_x:Number(document.getElementById('donX').value),p_image_y:Number(document.getElementById('donY').value),p_image_zoom:Number(document.getElementById('donZoom').value),p_emoji:document.getElementById('donEmoji').value.trim()||'\ud83c\udf81',p_note:document.getElementById('donNote').value.trim(),p_close_when_met:document.getElementById('donCloseWhenMet').checked},token);await loadDonations(token);adminTab='donations';renderAdmin()}\nasync function removeDonation(id){if(!confirm('Delete this donation need and its sign-ups?'))return;await rpc('admin_delete_donation',{p_id:id},token);await loadDonations(token);renderAdmin()}\nfunction renderContact(){shell(`<div class=\"hero\"><h1>${t('contactTitle')}<\/h1><p>${t('questions')}<\/p><\/div><div class=\"box contact-box\"><div class=\"contact-item\"><h2>\u2709\ufe0f ${t('contactEmail')}<\/h2><a href=\"mailto:info@goodsamaritangroup.org\">info@goodsamaritangroup.org<\/a><\/div><div class=\"contact-item\"><h2>\ud83d\udccd ${t('contactAddress')}<\/h2><p>1325 John F. Kennedy Blvd, Bayonne, NJ 07002<\/p><\/div><div class=\"contact-item\"><h2>\ud83d\udcd8 ${t('contactFacebook')}<\/h2><a href=\"https:\/\/www.facebook.com\/goodsamaritangroup.org\" target=\"_blank\" rel=\"noopener noreferrer\">${t('facebookLabel')}<\/a><\/div><\/div>`)}\nfunction chooseType(type){registrationType=type;localStorage.setItem('gsg_registration_type',type);render()}\nfunction renderSignup(){const s=services.find(x=>x.id===currentService);if(!s){staffMode?staffPage():home();return}const sl=localizedService(s);const backFn=staffMode?'staffPage()':'servicesPage()';shell(`<button class=\"back\" onclick=\"${backFn}\">\u2190 ${t('back')}<\/button>${staffMode?'':renderNotes(true)}<div class=\"servicehead\" style=\"background:${color(s.color)}\"><div style=\"font-size:27px\">${esc(s.icon)}<\/div><h1>${esc(sl.name)}<\/h1><p class=\"muted\">${esc(sl.description)}<\/p><\/div><div class=\"box\"><h2>${staffMode?t('signupServant'):t('signupVolunteer')}<\/h2><div class=\"selected-type\">\u2713 ${staffMode?t('servant'):t('volunteer')}<\/div><form onsubmit=\"submitSignup(event)\">${staffMode?`<label><b>${t('carQuestion')}<\/b><select class=\"input\" id=\"hasCar\" required><option value=\"\" disabled selected>${language==='ar'?'\u0627\u062e\u062a\u0631 \u0625\u062c\u0627\u0628\u0629':'Choose an answer'}<\/option><option value=\"yes\">${t('carYes')}<\/option><option value=\"no\">${t('carNo')}<\/option><\/select><\/label>`:''}<label><b>${t('fullName')}<\/b><input class=\"input\" id=\"name\" required placeholder=\"${t('fullName').replace(' *','')}\"><\/label><label><b>${t('phone')}<\/b><input class=\"input\" id=\"phone\" required type=\"tel\" inputmode=\"tel\" autocomplete=\"tel\" placeholder=\"${t('phonePlaceholder')}\"><\/label><b>${t('selectSession')}<\/b>${s.sessions.length?s.sessions.map(x=>{const z=capacityForType(x,registrationType),l=localizedSession(x);return `<label class=\"session\" style=\"${z.full?'opacity:.62':''}\"><input type=\"radio\" name=\"session\" value=\"${esc(x.id)}\" ${z.full?'disabled':''} required> <strong>${esc(l.label)}<\/strong><small>\ud83d\udcc5 ${esc(x.date)}<br>\ud83d\udd50 ${esc(x.time)}<br>\ud83d\udccd ${esc(l.location)}<br>${t('needLabel')}: ${esc(l.need)}<br><b>${registrationType==='servant'?t('servantPlural'):t('volunteerPlural')}: ${capacityText(x,registrationType)}<\/b><\/small>${z.full?'<div class=\"error\" style=\"margin-top:8px\">'+t('registrationClosed')+'<\/div>':''}<\/label>`}).join(''):'<p class=\"muted\">'+t('noSessions')+'<\/p>'}<div id=\"formerr\"><\/div><button class=\"primary\" ${s.sessions.some(x=>!capacityForType(x,registrationType).full)?'':'disabled'}>${t('confirm')}<\/button><\/form><\/div>`)}\nasync function submitSignup(event){event.preventDefault();const form=event.target;const button=form.querySelector('button.primary');const errorBox=document.getElementById('formerr');const selected=form.querySelector('input[name=\"session\"]:checked');if(!selected){errorBox.innerHTML='<div class=\"error\">'+t('selectSession')+'<\/div>';return}button.disabled=true;button.textContent=t('submitting');errorBox.innerHTML='';try{\n  \/\/ Determine the registration type from the current route\/mode at submit time.\n  const isStaff=staffMode===true || window.location.pathname.startsWith('\/staff\/');\n  const type=isStaff?'servant':'volunteer';\n  registrationType=type;\n  const payload={p_session_id:selected.value,p_name:document.getElementById('name').value.trim(),p_phone:document.getElementById('phone').value.trim(),p_registration_type:type};\n  \/\/ The database column is NOT NULL, so volunteer sign-ups use a silent\n  \/\/ false value. The car question is still completely hidden from volunteers\n  \/\/ and is never shown or asked on the volunteer site. Staff submissions use\n  \/\/ the actual answer from the Staff-only car question.\n  payload.p_has_car=false;\n  if(isStaff){const carEl=document.getElementById('hasCar');if(!carEl||!carEl.value)throw Error('CAR_AVAILABILITY_REQUIRED');payload.p_has_car=carEl.value==='yes'}\n  await rpc('register_signup',payload);page='success';render();\n}catch(e){console.error('Registration failed:',e);const raw=String(e?.message||e||'Unknown registration error');const full=raw.includes('REGISTRATION_FULL');const friendly=full?t('alreadyFull'):(language==='ar'?'\u062a\u0639\u0630\u0631 \u0625\u062a\u0645\u0627\u0645 \u0627\u0644\u062a\u0633\u062c\u064a\u0644. \u064a\u0631\u062c\u0649 \u0627\u0644\u0645\u062d\u0627\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062e\u0631\u0649.':'Could not complete the registration. Please try again.');const detail=raw&&raw!==friendly?`<small class=\"muted\" style=\"display:block;margin-top:8px;word-break:break-word\">${esc(raw)}<\/small>`:'';errorBox.innerHTML='<div class=\"error\">'+esc(friendly)+detail+'<\/div>';button.disabled=false;button.textContent=t('confirm');if(full)setTimeout(()=>render(),500)}}\nfunction renderSuccess(){const backFn=staffMode?'staffPage()':'home()';shell('<div class=\"success\"><div class=\"emoji\">\ud83d\ude4c<\/div><h1>'+t('thankYou')+'<\/h1><p class=\"muted\" style=\"font-size:18px\">'+t('received')+'<\/p><button class=\"primary\" onclick=\"'+backFn+'\">'+t('backServices')+'<\/button> <button class=\"secondary\" onclick=\"openService(\\''+esc(currentService)+'\\')\">'+t('signAgain')+'<\/button><\/div>')}\nfunction renderDataError(e){console.error('Site data failed to load:',e);const raw=String(e?.message||e||'Unknown error');const msg=raw==='SUPABASE_CONFIG_MISSING'?(language==='ar'?'\u064a\u0631\u062c\u0649 \u0625\u0639\u062f\u0627\u062f \u0639\u0646\u0648\u0627\u0646 \u0648\u0645\u0641\u062a\u0627\u062d \u0645\u0634\u0631\u0648\u0639 Supabase \u0641\u064a config.js \u062b\u0645 \u0625\u0639\u0627\u062f\u0629 \u0631\u0641\u0639 \u0627\u0644\u0645\u0648\u0642\u0639.':'Open config.js, enter your new Supabase Project URL and Publishable\/anon key, then redeploy the site.'):readableNetworkError(e);shell('<div class=\"error\">'+esc(language==='ar'?'\u062a\u0639\u0630\u0631 \u062a\u062d\u0645\u064a\u0644 \u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0645\u0648\u0642\u0639: '+msg:'Could not load the website data: '+msg)+'<\/div><button class=\"secondary\" onclick=\"'+(staffMode?'staffHomePage()':'home()')+'\">'+t('homeTab')+'<\/button>')}\nasync function loadPrayer(){prayerError='';try{const [cats,pages]=await Promise.all([api('prayer_categories?select=*&order=sort_order.asc,name.asc',{},''),api('prayer_pages?select=*&order=sort_order.asc,created_at.asc',{},'')]);prayerCategories=cats||[];prayerPages=pages||[];}catch(e){prayerCategories=[];prayerPages=[];prayerError=language==='ar'?'\u062a\u0639\u0630\u0631 \u062a\u062d\u0645\u064a\u0644 \u0642\u0633\u0645 \u0627\u0644\u0635\u0644\u0627\u0629. \u064a\u0631\u062c\u0649 \u0627\u0644\u0645\u062d\u0627\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062e\u0631\u0649 \u0644\u0627\u062d\u0642\u064b\u0627.':'Prayer is temporarily unavailable. Please try again later.';console.warn('Prayer load failed:',e)}}\nasync function loadPrayerAdmin(){try{const [cats,pages]=await Promise.all([api('prayer_categories?select=*&order=sort_order.asc,name.asc',{},token),api('prayer_pages?select=*&order=sort_order.asc,created_at.asc',{},token)]);prayerCategories=cats||[];prayerPages=pages||[];}catch(e){throw e}}\nasync function prayerPage(event){if(event){event.preventDefault();event.stopPropagation()}registrationType=staffMode?'servant':'volunteer';page='prayer';currentPrayerPageId='';currentPrayerCategoryId='';prayerLoading=!prayerCategories.length;closeMenu();history.pushState({},'', staffMode?'\/staff\/prayer':'\/prayer');render();loadPrayer().then(()=>{prayerLoading=false;if(page==='prayer'&&!currentPrayerPageId&&!currentPrayerCategoryId)render()}).catch(e=>{prayerLoading=false;console.warn('Prayer navigation load failed:',e);if(page==='prayer')render()})}\nasync function calendarPage(event){if(event){event.preventDefault();event.stopPropagation()}registrationType=staffMode?'servant':'volunteer';page='calendar';closeMenu();history.pushState({},'', staffMode?'\/staff\/calendar':'\/calendar');render();if(!services.length){try{await load();if(page==='calendar')render()}catch(e){if(page==='calendar')renderDataError(e)}}}\nfunction renderCalendar(){\n  const today=new Date();today.setHours(0,0,0,0);\n  const allEvents=services.flatMap(s=>s.sessions.map(x=>({...x,service:s})));\n  const parsed=allEvents.map(x=>{const d=new Date(x.date);return {...x,_date:isNaN(d.getTime())?null:d}});\n  const upcoming=parsed.filter(x=>!x._date||x._date>=today).sort((a,b)=>{if(!a._date)return 1;if(!b._date)return -1;return a._date-b._date});\n  const months={};\n  upcoming.forEach(x=>{const key=x._date?`${x._date.getFullYear()}-${String(x._date.getMonth()+1).padStart(2,'0')}`:(language==='ar'?'\u062a\u0627\u0631\u064a\u062e \u063a\u064a\u0631 \u0645\u062d\u062f\u062f':'Date TBD');(months[key]??=[]).push(x)});\n  const monthLabel=key=>{if(!\/^\\d{4}-\\d{2}$\/.test(key))return key;const [y,m]=key.split('-').map(Number);return new Date(y,m-1,1).toLocaleDateString(language==='ar'?'ar':'en-US',{month:'long',year:'numeric'})};\n  const dayBadge=x=>{if(!x._date)return `<div class=\"cal-daybadge\"><span class=\"cal-daynum\">\u2022<\/span><\/div>`;return `<div class=\"cal-daybadge\"><span class=\"cal-daynum\">${x._date.getDate()}<\/span><span class=\"cal-dow\">${x._date.toLocaleDateString(language==='ar'?'ar':'en-US',{weekday:'short'})}<\/span><\/div>`};\n  shell(`<div class=\"hero\"><img decoding=\"async\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/logo.png\"><h1>${t('calendarTitle')}<\/h1><p>${t('calendarIntro')}<\/p><\/div>${Object.keys(months).length?Object.keys(months).sort((a,b)=>a.localeCompare(b)).map(key=>`<div class=\"cal-month\"><h2 class=\"cal-month-title\">${esc(monthLabel(key))}<\/h2><div class=\"cal-list\">${months[key].map(x=>{const l=localizedSession(x);const sl=localizedService(x.service);return `<a class=\"cal-event\" href=\"${staffMode?'\/staff\/':'\/'}${esc(x.service.id)}\" style=\"border-left-color:${color(x.service.color)==='#f7efe0'?'#a8532b':color(x.service.color)}\">${dayBadge(x)}<div class=\"cal-event-body\"><div class=\"cal-event-service\">${esc(x.service.icon)} ${esc(sl.name)}<\/div><h3>${esc(l.label)}<\/h3><div class=\"muted\">\ud83d\udd50 ${esc(x.time)} \u00b7 \ud83d\udccd ${esc(l.location)}<\/div><\/div><\/a>`}).join('')}<\/div><\/div>`).join(''):`<div class=\"box\" style=\"text-align:center\"><h2>${t('noUpcomingEvents')}<\/h2><\/div>`}`)\n}\nasync function biblePage(event){if(event){event.preventDefault();event.stopPropagation()}registrationType=staffMode?'servant':'volunteer';page='bible';closeMenu();history.pushState({},'', staffMode?'\/staff\/bible':'\/bible');render();if(!bibleVerses&&!bibleLoading)loadBiblePassage()}\nfunction bibleConfigured(){const k=String((window.APP_CONFIG||{}).ESV_API_KEY||C.ESV_API_KEY||'').trim();return !!k&&!k.includes('PASTE_')&&!k.includes('YOUR_')}\nfunction bibleBookIndex(name){return BIBLE_BOOKS.findIndex(b=>b.name.toLowerCase()===String(name||'').trim().toLowerCase())}\nfunction bibleBookChapterCount(name){const i=bibleBookIndex(name);return i===-1?null:BIBLE_BOOKS[i].chapters}\nasync function loadBiblePassage(){if(!bibleConfigured()){bibleError='SETUP';render();return}bibleLoading=true;bibleError='';render();try{const key=String((window.APP_CONFIG||{}).ESV_API_KEY||C.ESV_API_KEY||'').trim();const chapterCount=bibleBookChapterCount(bibleBook);const q=chapterCount===1?`${bibleBook}`:`${bibleBook} ${bibleChapter}`;const r=await fetch('https:\/\/api.esv.org\/v3\/passage\/text\/?q='+encodeURIComponent(q)+'&include-headings=false&include-footnotes=false&include-verse-numbers=true&include-short-copyright=false&include-passage-horizontal-lines=false',{headers:{Authorization:'Token '+key}});if(!r.ok)throw Error('ESV_HTTP_'+r.status);const j=await r.json();if(!j.passages||!j.passages.length)throw Error('ESV_NOT_FOUND');bibleVerses={reference:j.canonical||q,text:j.passages[0].trim()}}catch(e){console.warn('ESV passage load failed:',e);bibleError='LOAD';bibleVerses=null}bibleLoading=false;render()}\nfunction bibleGo(event){if(event)event.preventDefault();bibleVerses=null;loadBiblePassage()}\nfunction bibleChangeChapter(delta){const idx=bibleBookIndex(bibleBook);let chap=(parseInt(bibleChapter,10)||1)+delta;if(idx===-1){bibleChapter=String(Math.max(1,chap));bibleVerses=null;loadBiblePassage();return}const maxChap=BIBLE_BOOKS[idx].chapters;if(chap<1){const pIdx=idx-1;if(pIdx<0)return;bibleBook=BIBLE_BOOKS[pIdx].name;bibleChapter=String(BIBLE_BOOKS[pIdx].chapters)}else if(chap>maxChap){const nIdx=idx+1;if(nIdx>=BIBLE_BOOKS.length)return;bibleBook=BIBLE_BOOKS[nIdx].name;bibleChapter='1'}else{bibleChapter=String(chap)}bibleVerses=null;loadBiblePassage()}\nfunction bibleOpenBookPicker(event){if(event){event.preventDefault();event.stopPropagation()}bibleBookPickerOpen=true;bibleBookFilter='';render();setTimeout(()=>{const el=document.getElementById('bibleBookFilterInput');if(el)el.focus()},0)}\nfunction bibleCloseBookPicker(){bibleBookPickerOpen=false;render()}\nfunction bibleFilterBooks(v){bibleBookFilter=v;const el=document.getElementById('bibleBookList');if(el)el.innerHTML=bibleBookListHTML()}\nfunction bibleSelectBook(name){bibleBook=name;bibleChapter='1';bibleBookPickerOpen=false;bibleVerses=null;loadBiblePassage()}\nfunction bibleBookListHTML(){const f=bibleBookFilter.trim().toLowerCase();const list=BIBLE_BOOKS.filter(b=>!f||b.name.toLowerCase().includes(f));if(!list.length)return `<div class=\"bible-picker-empty\">${language==='ar'?'\u0644\u0627 \u062a\u0648\u062c\u062f \u0646\u062a\u0627\u0626\u062c':'No books found'}<\/div>`;return list.map(b=>`<button type=\"button\" class=\"bible-picker-item\" onclick=\"bibleSelectBook('${esc(b.name).replace(\/'\/g,\"\\\\'\")}')\">${esc(b.name)}<\/button>`).join('')}\nfunction renderBible(){\n  if(bibleError==='SETUP'){shell(`<div class=\"hero\"><img decoding=\"async\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/logo.png\"><h1>${t('bibleTitle')}<\/h1><\/div><div class=\"box\" style=\"text-align:center\"><h2>${t('bibleSetupTitle')}<\/h2><p class=\"muted\">${t('bibleSetupText')}<\/p><\/div>`);return}\n  const idx=bibleBookIndex(bibleBook);const atFirst=idx===0&&(parseInt(bibleChapter,10)||1)<=1;const atLast=idx===BIBLE_BOOKS.length-1&&(parseInt(bibleChapter,10)||1)>=(idx===-1?1:BIBLE_BOOKS[idx].chapters);\n  const body=bibleLoading?`<div class=\"box\" style=\"text-align:center\"><h2>${t('bibleLoading')}<\/h2><\/div>`:bibleError==='LOAD'?`<div class=\"error\">${t('bibleError')}<\/div>`:bibleVerses?`<article class=\"box bible-passage\"><h2>${esc(bibleVerses.reference)}<\/h2><div class=\"bible-text\">${esc(bibleVerses.text)}<\/div><p class=\"muted bible-copyright\" style=\"font-size:12px;margin-top:18px\">${esc(t('bibleCopyright'))}<\/p><\/article>`:'';\n  const picker=bibleBookPickerOpen?`<div class=\"bible-picker-overlay\"><div class=\"bible-picker-header\"><h3>${language==='ar'?'\u0627\u0644\u0633\u0641\u0631':'Book'}<\/h3><button type=\"button\" class=\"bible-picker-cancel\" onclick=\"bibleCloseBookPicker()\">${language==='ar'?'\u0625\u0644\u063a\u0627\u0621':'Cancel'}<\/button><\/div><div class=\"bible-picker-filter\"><input id=\"bibleBookFilterInput\" type=\"text\" placeholder=\"${language==='ar'?'\u062a\u0635\u0641\u064a\u0629 \u0627\u0644\u0623\u0633\u0641\u0627\u0631...':'Filter Books...'}\" value=\"${esc(bibleBookFilter)}\" oninput=\"bibleFilterBooks(this.value)\"><\/div><div class=\"bible-picker-list\" id=\"bibleBookList\">${bibleBookListHTML()}<\/div><\/div>`:'';\n  shell(`<div class=\"hero\"><img decoding=\"async\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/logo.png\"><h1>${t('bibleTitle')}<\/h1><p>${t('bibleIntro')}<\/p><\/div><div class=\"box\"><div class=\"bible-toolbar\"><button type=\"button\" class=\"bible-select\" onclick=\"bibleOpenBookPicker(event)\">${esc(bibleBook)} ${esc(bibleChapter)} <span class=\"caret\">\u25be<\/span><\/button><div class=\"bible-select static\">ESV<\/div><\/div><div class=\"bible-nav-row\"><button type=\"button\" class=\"bible-nav-btn\" onclick=\"bibleChangeChapter(-1)\" ${atFirst?'disabled':''}>\u2039 ${language==='ar'?'\u0627\u0644\u0633\u0627\u0628\u0642':'Previous'}<\/button><button type=\"button\" class=\"bible-nav-btn\" onclick=\"bibleChangeChapter(1)\" ${atLast?'disabled':''}>${language==='ar'?'\u0627\u0644\u062a\u0627\u0644\u064a':'Next'} \u203a<\/button><\/div><\/div>${body}${picker}`)\n}\nfunction prayerCategoryForm(existingId=null){const c=existingId?prayerCategories.find(x=>x.id===existingId):null;const s=c||{name:'',description:''};const m=document.createElement('div');m.className='modal';m.innerHTML=`<div class=\"modalbox\"><h2>${c?'Edit Prayer Category':'Add Prayer Category'}<\/h2><form><input class=\"input\" id=\"pcname\" required placeholder=\"Category name\" value=\"${esc(s.name)}\"><textarea class=\"input\" id=\"pcdesc\" placeholder=\"Description\" style=\"min-height:90px\">${esc(s.description||'')}<\/textarea><p class=\"muted\" style=\"font-size:12px;margin:-8px 0 4px\">${esc(t('autoTranslated'))}<\/p><div class=\"row\"><button type=\"button\" class=\"secondary\" onclick=\"this.closest('.modal').remove()\">Cancel<\/button><button class=\"primary\">Save Category<\/button><\/div><\/form><\/div>`;document.body.appendChild(m);m.querySelector('form').onsubmit=async e=>{e.preventDefault();const b=e.target.querySelector('.primary');b.disabled=true;try{const nextOrder=prayerCategories.reduce((n,x)=>Math.max(n,Number(x.sort_order||0)),0)+(c?0:1);const name=pcname.value.trim(),description=pcdesc.value.trim();const nameAr=(c&&name===s.name&&s.name_ar)?s.name_ar:await translateToArabic(name);const descriptionAr=(c&&description===s.description&&s.description_ar)?s.description_ar:await translateToArabic(description);await rpc('admin_upsert_prayer_category',{p_id:s.id||null,p_name:name,p_description:description,p_name_ar:nameAr,p_description_ar:descriptionAr,p_sort_order:c?Number(s.sort_order||0):nextOrder},token);m.remove();await loadPrayerAdmin();await renderAdmin()}catch(err){alert(err.message);b.disabled=false}}}\nasync function removePrayerCategory(id){if(!confirm('Delete this prayer category and all prayer pages inside it?'))return;try{await rpc('admin_delete_prayer_category',{p_id:id},token);await renderAdmin()}catch(e){alert(e.message)}}\nfunction prayerPageForm(existingId=null,categoryId=''){\n  const p=existingId?prayerPages.find(x=>x.id===existingId):null;\n  const s=p||{category_id:categoryId||prayerCategories[0]?.id||'',title:'',body_html:'',image_data:'',image_x:50,image_y:50,image_zoom:1};\n  const m=document.createElement('div');m.className='modal';\n  m.innerHTML=`<div class=\"modalbox\"><h2>${p?'Edit Prayer Page':'Add Prayer Page'}<\/h2><form id=\"prayerpageform\">\n  <label><b>Category<\/b><\/label><select class=\"input\" id=\"ppcat\" required>${prayerCategories.map(c=>`<option value=\"${esc(c.id)}\" ${c.id===s.category_id?'selected':''}>${esc(c.name)}<\/option>`).join('')}<\/select>\n  <label><b>Title<\/b><\/label><input class=\"input\" id=\"pptitle\" required placeholder=\"Prayer title\" value=\"${esc(s.title)}\">\n  <label><b>Prayer Text<\/b><\/label><div class=\"prayer-toolbar\"><button type=\"button\" class=\"secondary\" id=\"ppbold\"><b>B<\/b> Bold<\/button><\/div><div id=\"ppcontent\" class=\"prayer-editor\" contenteditable=\"true\">${s.body_html||''}<\/div>\n  <p class=\"muted\" style=\"font-size:12px;margin:10px 0 4px\">${esc(t('autoTranslated'))}<\/p>\n  <label style=\"display:block;margin-top:16px\"><b>Photo<\/b><\/label>\n  <div class=\"prayer-dropzone\" id=\"ppdrop\">Drag & drop a photo here, or click to choose one<input id=\"ppimage\" type=\"file\" accept=\"image\/*\" hidden><\/div>\n  <div class=\"prayer-image-preview\" id=\"pppreview\"><div class=\"prayer-image-canvas\" id=\"ppcanvas\"><span class=\"muted\" id=\"ppempty\">No image selected<\/span><\/div><\/div>\n  <p class=\"muted\" style=\"margin:8px 0\">Drag the photo directly inside the 290 \u00d7 270 frame to position it. The sliders give precise control.<\/p>\n  <div class=\"two\"><label>Horizontal position <input class=\"prayer-range\" id=\"ppx\" type=\"range\" min=\"0\" max=\"100\" value=\"${Number(s.image_x??50)}\"><\/label><label>Vertical position <input class=\"prayer-range\" id=\"ppy\" type=\"range\" min=\"0\" max=\"100\" value=\"${Number(s.image_y??50)}\"><\/label><\/div>\n  <label>Zoom <input class=\"prayer-range\" id=\"ppzoom\" type=\"range\" min=\"1\" max=\"2.5\" step=\"0.05\" value=\"${Number(s.image_zoom||1)}\"><\/label>\n  <label style=\"display:block;margin:10px 0\"><input type=\"checkbox\" id=\"ppremove\" ${!s.image_data?'disabled':''}> Remove existing image<\/label>\n  <div class=\"row\"><button type=\"button\" class=\"secondary\" id=\"ppcancel\">Cancel<\/button><button class=\"primary\" id=\"ppsave\">Save Prayer<\/button><\/div>\n  <\/form><\/div>`;\n  document.body.appendChild(m);\n  const form=m.querySelector('#prayerpageform'), canvas=m.querySelector('#ppcanvas'), image=m.querySelector('#ppimage'), drop=m.querySelector('#ppdrop'), px=m.querySelector('#ppx'), py=m.querySelector('#ppy'), zoom=m.querySelector('#ppzoom'), content=m.querySelector('#ppcontent'), empty=m.querySelector('#ppempty');\n  let imageData=s.image_data||''; let naturalW=0,naturalH=0; const W=290,H=270;\n  function clamp(v,a,b){return Math.max(a,Math.min(b,v))}\n  function applyImagePosition(){const im=m.querySelector('#pppreviewimg');if(!im||!naturalW||!naturalH)return;const cover=Math.max(W\/naturalW,H\/naturalH);const scale=cover*Number(zoom.value||1);const iw=naturalW*scale,ih=naturalH*scale;const maxLeft=Math.max(0,iw-W),maxTop=Math.max(0,ih-H);const left=-maxLeft*(Number(px.value||50)\/100);const top=-maxTop*(Number(py.value||50)\/100);im.style.width=iw+'px';im.style.height=ih+'px';im.style.left=left+'px';im.style.top=top+'px'}\n  function updatePreview(src){canvas.innerHTML=src?`<img decoding=\"async\" id=\"pppreviewimg\" src=\"${src}\" alt=\"Prayer photo preview\">`:'<span class=\"muted\" id=\"ppempty\">No image selected<\/span>';if(src){const im=m.querySelector('#pppreviewimg');im.onload=()=>{naturalW=im.naturalWidth;naturalH=im.naturalHeight;applyImagePosition()};if(im.complete){naturalW=im.naturalWidth;naturalH=im.naturalHeight;applyImagePosition()}}}\n  async function compress(file){if(!file||!file.type.startsWith('image\/'))throw Error('Please choose an image file.');if(file.size>20*1024*1024)throw Error('Please choose an image smaller than 20 MB.');const src=await new Promise((res,rej)=>{const r=new FileReader();r.onload=()=>res(r.result);r.onerror=()=>rej(Error('Could not read the image.'));r.readAsDataURL(file)});const img=await new Promise((res,rej)=>{const i=new Image();i.onload=()=>res(i);i.onerror=()=>rej(Error('Could not open the image.'));i.src=src});const max=1400,scale=Math.min(1,max\/Math.max(img.naturalWidth,img.naturalHeight));const c=document.createElement('canvas');c.width=Math.max(1,Math.round(img.naturalWidth*scale));c.height=Math.max(1,Math.round(img.naturalHeight*scale));c.getContext('2d').drawImage(img,0,0,c.width,c.height);return c.toDataURL('image\/jpeg',.82)}\n  async function choose(file){if(!file)return;try{imageData=await compress(file);m.querySelector('#ppremove').checked=false;updatePreview(imageData)}catch(e){alert(e.message)}}\n  drop.addEventListener('click',()=>image.click());drop.addEventListener('dragover',e=>{e.preventDefault();drop.classList.add('dragover')});drop.addEventListener('dragleave',()=>drop.classList.remove('dragover'));drop.addEventListener('drop',e=>{e.preventDefault();drop.classList.remove('dragover');choose(e.dataTransfer.files?.[0])});image.addEventListener('change',()=>choose(image.files?.[0]));\n  m.querySelector('#ppbold').addEventListener('mousedown',e=>e.preventDefault());m.querySelector('#ppbold').addEventListener('click',()=>{content.focus();document.execCommand('bold',false,null)});[px,py,zoom].forEach(el=>el.addEventListener('input',applyImagePosition));m.querySelector('#ppcancel').onclick=()=>m.remove();\n  let drag=null;canvas.addEventListener('pointerdown',e=>{const im=m.querySelector('#pppreviewimg');if(!im)return;e.preventDefault();canvas.setPointerCapture(e.pointerId);drag={x:e.clientX,y:e.clientY,px:Number(px.value),py:Number(py.value)};canvas.classList.add('dragging')});canvas.addEventListener('pointermove',e=>{if(!drag)return;e.preventDefault();const im=m.querySelector('#pppreviewimg');if(!im||!naturalW||!naturalH)return;const cover=Math.max(W\/naturalW,H\/naturalH);const scale=cover*Number(zoom.value||1);const maxLeft=Math.max(0,naturalW*scale-W),maxTop=Math.max(0,naturalH*scale-H);px.value=clamp(drag.px-(e.clientX-drag.x)\/Math.max(1,maxLeft)*100,0,100);py.value=clamp(drag.py-(e.clientY-drag.y)\/Math.max(1,maxTop)*100,0,100);applyImagePosition()});const endDrag=()=>{drag=null;canvas.classList.remove('dragging')};canvas.addEventListener('pointerup',endDrag);canvas.addEventListener('pointercancel',endDrag);canvas.addEventListener('pointerleave',()=>{if(drag)endDrag()});\n  if(s.image_data)updatePreview(s.image_data);\n  form.onsubmit=async e=>{e.preventDefault();const b=m.querySelector('#ppsave');b.disabled=true;b.textContent='Saving\u2026';try{if(m.querySelector('#ppremove').checked)imageData='';const nextOrder=prayerPages.filter(x=>x.category_id===m.querySelector('#ppcat').value).reduce((n,x)=>Math.max(n,Number(x.sort_order||0)),0)+(p?0:1);const title=m.querySelector('#pptitle').value.trim();const bodyHtml=sanitizePrayerHtml(content.innerHTML);let titleAr=(p&&title===s.title&&s.title_ar)?s.title_ar:await translateToArabic(title);let bodyHtmlAr=(p&&bodyHtml===s.body_html&&s.body_html_ar)?s.body_html_ar:'';if(!bodyHtmlAr){const plainBody=bodyHtml.replace(\/<[^>]+>\/g,' ').replace(\/\\s+\/g,' ').trim();const translated=await translateToArabic(plainBody);bodyHtmlAr=translated?esc(translated):''}await rpc('admin_upsert_prayer_page',{p_id:s.id||null,p_category_id:m.querySelector('#ppcat').value,p_title:title,p_body_html:bodyHtml,p_image_data:imageData,p_image_x:Number(px.value),p_image_y:Number(py.value),p_image_zoom:Number(zoom.value),p_title_ar:titleAr,p_body_html_ar:bodyHtmlAr,p_sort_order:p?Number(s.sort_order||0):nextOrder},token);m.remove();await loadPrayerAdmin();await renderAdmin()}catch(err){alert(err.message||'Could not save prayer page.');b.disabled=false;b.textContent='Save Prayer'}}\n}\nasync function removePrayerPage(id){if(!confirm('Delete this prayer page?'))return;try{await rpc('admin_delete_prayer_page',{p_id:id},token);await renderAdmin()}catch(e){alert(e.message)}}\nfunction renderPrayerAdmin(){return `<div class=\"box\"><div class=\"toolbar\"><div><h2>\ud83d\ude4f Prayer<\/h2><p class=\"muted\">Create prayer categories and pages. Each page can have bold text and a 290 \u00d7 270 image with position and zoom controls.<\/p><\/div><button class=\"primary\" onclick=\"prayerCategoryForm()\">+ Add Category<\/button><\/div>${prayerCategories.map(c=>`<div class=\"prayer-admin-category\"><div class=\"row\"><div><h3 style=\"margin:0\">${esc(c.name)}<\/h3>${c.description?`<div class=\"muted\">${esc(c.description)}<\/div>`:''}<\/div><div><button class=\"secondary\" onclick=\"prayerCategoryForm('${esc(c.id)}')\">Edit<\/button> <button class=\"danger\" onclick=\"removePrayerCategory('${esc(c.id)}')\">Delete<\/button><\/div><\/div><div style=\"margin-top:10px\"><button class=\"secondary\" onclick=\"prayerPageForm(null,'${esc(c.id)}')\">+ Add Prayer Page<\/button><\/div>${prayerPages.filter(p=>p.category_id===c.id).map(p=>`<div class=\"prayer-admin-page\"><div class=\"row\"><div><b>${esc(p.title)}<\/b><div class=\"muted\" style=\"font-size:12px\">${p.image_data?'Image attached':'No image'}<\/div><\/div><div><button class=\"secondary\" onclick=\"prayerPageForm('${esc(p.id)}')\">Edit<\/button> <button class=\"danger\" onclick=\"removePrayerPage('${esc(p.id)}')\">Delete<\/button><\/div><\/div><\/div>`).join('')}<\/div>`).join('')||'<div class=\"box\"><p class=\"muted\">No prayer categories yet. Create your first category above.<\/p><\/div>'}<\/div>`}\n\nasync function loadPictures(auth=''){\n  picturesError='';\n  try{\n    pictures=await api('pictures?select=*&order=sort_order.asc,created_at.desc',{},auth)||[];\n  }catch(e){\n    pictures=[];\n    picturesError=language==='ar'?'\u062a\u0639\u0630\u0631 \u062a\u062d\u0645\u064a\u0644 \u0627\u0644\u0635\u0648\u0631.':'Pictures are temporarily unavailable.';\n    console.warn('Pictures load failed:',e);\n  }\n}\nasync function picturesPage(event){\n  if(event){event.preventDefault();event.stopPropagation()}\n  registrationType=staffMode?'servant':'volunteer'; page='pictures'; closeMenu();\n  history.pushState({},'',staffMode?'\/staff\/pictures':'\/pictures');\n  picturesLoading=true; render();\n  await loadPictures();\n  picturesLoading=false;\n  if(page==='pictures')render();\n}\nfunction renderPictures(){\n  const frame=(p,admin=false)=>{\n    const W=760,H=500;\n    return `<div class=\"${admin?'picture-admin-preview':'picture-frame'}\" data-x=\"${Number(p.image_x??50)}\" data-y=\"${Number(p.image_y??50)}\" data-zoom=\"${Number(p.image_zoom||1)}\"><img decoding=\"async\" class=\"${admin?'':'picture-img'}\" src=\"${esc(p.image_data)}\" alt=\"${esc(p.title)}\"><\/div>`;\n  };\n  if(picturesLoading){shell(`<div class=\"hero\"><h1>${t('picturesTitle')}<\/h1><p>${t('picturesIntro')}<\/p><\/div><div class=\"box\" style=\"text-align:center\"><h2>Loading pictures\u2026<\/h2><\/div>`);return}\n  shell(`<div class=\"hero\"><img decoding=\"async\" src=\"https:\/\/goodsamaritangroup.org\/wp-content\/plugins\/good-samaritan-group\/\/assets\/logo.png\"><h1>${t('picturesTitle')}<\/h1><p>${t('picturesIntro')}<\/p><\/div>${picturesError?`<div class=\"error\">${esc(picturesError)}<\/div>`:''}${pictures.length?`<div class=\"pictures-grid\">${pictures.map(p=>`<article class=\"card picture-card\">${frame(p)}<div style=\"padding:20px 22px\"><h2 style=\"margin-top:0\">${esc(language==='ar'?(p.title_ar||p.title):p.title)}<\/h2>${(language==='ar'?(p.description_ar||p.description):p.description)?`<p style=\"min-height:0\">${esc(language==='ar'?(p.description_ar||p.description):p.description)}<\/p>`:''}<\/div><\/article>`).join('')}<\/div>`:`<div class=\"box\" style=\"text-align:center\"><h2>${t('noPictures')}<\/h2><\/div>`}`);\n  document.querySelectorAll('.picture-frame').forEach(frameEl=>{\n    const im=frameEl.querySelector('img'); if(!im)return;\n    const apply=()=>{const W=frameEl.clientWidth,H=frameEl.clientHeight,nw=im.naturalWidth,nh=im.naturalHeight;if(!nw||!nh)return;const cover=Math.max(W\/nw,H\/nh)*Number(frameEl.dataset.zoom||1),iw=nw*cover,ih=nh*cover,maxL=Math.max(0,iw-W),maxT=Math.max(0,ih-H);im.style.width=iw+'px';im.style.height=ih+'px';im.style.left=(-maxL*Number(frameEl.dataset.x||50)\/100)+'px';im.style.top=(-maxT*Number(frameEl.dataset.y||50)\/100)+'px'};im.onload=apply;if(im.complete)apply();\n  });\n}\nfunction pictureForm(existingId=null){\n  const p=existingId?pictures.find(x=>x.id===existingId):null;\n  const s=p||{title:'',description:'',title_ar:'',description_ar:'',image_data:'',image_x:50,image_y:50,image_zoom:1,sort_order:0};\n  const m=document.createElement('div');m.className='modal';\n  m.innerHTML=`<div class=\"modalbox picture-admin-modalbox\"><h2>${p?'Edit Picture':'Add Picture'}<\/h2><form id=\"pictureform\">\n  <label><b>${t('pictureTitle')}<\/b><\/label><input class=\"input\" id=\"pictitle\" required value=\"${esc(s.title)}\">\n  <label><b>${t('pictureDescription')}<\/b><\/label><textarea class=\"input\" id=\"picdesc\" rows=\"3\">${esc(s.description||'')}<\/textarea>\n  <label style=\"display:block;margin-top:8px\"><b>${t('picturePhoto')}<\/b><\/label>\n  <div class=\"picture-dropzone\" id=\"picdrop\">${t('picturePhotoHelp')}<input id=\"picimage\" type=\"file\" accept=\"image\/*\" hidden><\/div>\n  <div class=\"picture-admin-preview\" id=\"picpreview\"><div class=\"picture-admin-canvas\" id=\"piccanvas\"><span class=\"muted\">No image selected<\/span><\/div><\/div>\n  <div class=\"two\"><label>Horizontal position <input class=\"prayer-range\" id=\"picx\" type=\"range\" min=\"0\" max=\"100\" value=\"${Number(s.image_x??50)}\"><\/label><label>Vertical position <input class=\"prayer-range\" id=\"picy\" type=\"range\" min=\"0\" max=\"100\" value=\"${Number(s.image_y??50)}\"><\/label><\/div>\n  <label>Zoom <input class=\"prayer-range\" id=\"piczoom\" type=\"range\" min=\"1\" max=\"2.5\" step=\"0.05\" value=\"${Number(s.image_zoom||1)}\"><\/label>\n  <label style=\"display:block;margin:10px 0\"><input type=\"checkbox\" id=\"picremove\" ${!s.image_data?'disabled':''}> Remove existing image<\/label>\n  <div class=\"row\"><button type=\"button\" class=\"secondary\" id=\"piccancel\">Cancel<\/button><button class=\"primary\" id=\"picsave\">${t('savePicture')}<\/button><\/div>\n  <\/form><\/div>`;\n  document.body.appendChild(m);\n  const form=m.querySelector('#pictureform'),canvas=m.querySelector('#piccanvas'),image=m.querySelector('#picimage'),drop=m.querySelector('#picdrop'),px=m.querySelector('#picx'),py=m.querySelector('#picy'),zoom=m.querySelector('#piczoom');\n  let imageData=s.image_data||'',naturalW=0,naturalH=0;const W=760,H=500;\n  const clamp=(v,a,b)=>Math.max(a,Math.min(b,v));\n  function apply(){const im=canvas.querySelector('img');if(!im||!naturalW||!naturalH)return;const RW=canvas.clientWidth||W,RH=canvas.clientHeight||H;const cover=Math.max(RW\/naturalW,RH\/naturalH)*Number(zoom.value||1),iw=naturalW*cover,ih=naturalH*cover,maxL=Math.max(0,iw-W),maxT=Math.max(0,ih-H);im.style.width=iw+'px';im.style.height=ih+'px';im.style.left=(-maxL*Number(px.value||50)\/100)+'px';im.style.top=(-maxT*Number(py.value||50)\/100)+'px'}\n  function preview(src){canvas.innerHTML=src?`<img decoding=\"async\" src=\"${src}\" alt=\"Picture preview\">`:'<span class=\"muted\">No image selected<\/span>';const im=canvas.querySelector('img');if(im){im.onload=()=>{naturalW=im.naturalWidth;naturalH=im.naturalHeight;apply()};if(im.complete){naturalW=im.naturalWidth;naturalH=im.naturalHeight;apply()}}}\n  async function compress(file){if(!file||!file.type.startsWith('image\/'))throw Error('Please choose an image file.');if(file.size>20*1024*1024)throw Error('Please choose an image smaller than 20 MB.');const src=await new Promise((res,rej)=>{const r=new FileReader();r.onload=()=>res(r.result);r.onerror=()=>rej(Error('Could not read the image.'));r.readAsDataURL(file)});const img=await new Promise((res,rej)=>{const i=new Image();i.onload=()=>res(i);i.onerror=()=>rej(Error('Could not open the image.'));i.src=src});const max=1800,scale=Math.min(1,max\/Math.max(img.naturalWidth,img.naturalHeight));const c=document.createElement('canvas');c.width=Math.max(1,Math.round(img.naturalWidth*scale));c.height=Math.max(1,Math.round(img.naturalHeight*scale));c.getContext('2d').drawImage(img,0,0,c.width,c.height);return c.toDataURL('image\/jpeg',.84)}\n  async function choose(file){if(!file)return;try{imageData=await compress(file);m.querySelector('#picremove').checked=false;preview(imageData)}catch(e){alert(e.message)}}\n  drop.addEventListener('click',()=>image.click());drop.addEventListener('dragover',e=>{e.preventDefault()});drop.addEventListener('drop',e=>{e.preventDefault();choose(e.dataTransfer.files?.[0])});image.addEventListener('change',()=>choose(image.files?.[0]));[px,py,zoom].forEach(el=>el.addEventListener('input',apply));\n  let drag=null;canvas.addEventListener('pointerdown',e=>{const im=canvas.querySelector('img');if(!im)return;canvas.setPointerCapture?.(e.pointerId);drag={x:e.clientX,y:e.clientY,px:Number(px.value),py:Number(py.value)};canvas.classList.add('dragging')});\n  canvas.addEventListener('pointermove',e=>{if(!drag)return;e.preventDefault();const im=canvas.querySelector('img');if(!im||!naturalW||!naturalH)return;const RW=canvas.clientWidth||W,RH=canvas.clientHeight||H;const scale=Math.max(RW\/naturalW,RH\/naturalH)*Number(zoom.value||1),maxL=Math.max(0,naturalW*scale-RW),maxT=Math.max(0,naturalH*scale-RH);px.value=clamp(drag.px-(e.clientX-drag.x)\/Math.max(1,maxL)*100,0,100);py.value=clamp(drag.py-(e.clientY-drag.y)\/Math.max(1,maxT)*100,0,100);apply()});\n  const end=()=>{drag=null;canvas.classList.remove('dragging')};canvas.addEventListener('pointerup',end);canvas.addEventListener('pointercancel',end);\n  if(imageData)preview(imageData);\n  m.querySelector('#piccancel').onclick=()=>m.remove();\n  form.onsubmit=async e=>{e.preventDefault();const b=m.querySelector('#picsave');b.disabled=true;b.textContent='Saving\u2026';try{if(m.querySelector('#picremove').checked)imageData='';const title=m.querySelector('#pictitle').value.trim(),description=m.querySelector('#picdesc').value.trim();const titleAr=(p&&title===s.title&&s.title_ar)?s.title_ar:await translateToArabic(title);const descriptionAr=(p&&description===s.description&&s.description_ar)?s.description_ar:await translateToArabic(description);const nextOrder=p?Number(s.sort_order||0):pictures.reduce((n,x)=>Math.max(n,Number(x.sort_order||0)),0)+1;await rpc('admin_upsert_picture',{p_id:s.id||null,p_title:title,p_description:description,p_image_data:imageData,p_image_x:Number(px.value),p_image_y:Number(py.value),p_image_zoom:Number(zoom.value),p_title_ar:titleAr,p_description_ar:descriptionAr,p_sort_order:nextOrder},token);m.remove();await loadPictures(token);await renderAdmin()}catch(err){alert(err.message||'Could not save picture.');b.disabled=false;b.textContent=t('savePicture')}}\n}\nfunction removePicture(id){if(!confirm(t('deletePictureConfirm')))return;rpc('admin_delete_picture',{p_id:id},token).then(()=>{loadPictures(token).then(renderAdmin)}).catch(e=>alert(e.message))}\nfunction renderPicturesAdmin(){return `<div class=\"box\"><div class=\"toolbar\"><div><h2>\ud83d\uddbc\ufe0f ${t('picturesTitle')}<\/h2><p class=\"muted\">${t('picturesIntro')} Each picture uses the exact 760 \u00d7 500 display frame with zoom and position controls.<\/p><\/div><button class=\"primary\" onclick=\"pictureForm()\"> ${t('addPicture')}<\/button><\/div>${pictures.length?pictures.map(p=>`<div class=\"event\"><div><b>${esc(p.title)}<\/b><br><small>${p.image_data?'Image attached':'No image'}<\/small><\/div><div><button class=\"secondary\" onclick=\"pictureForm('${esc(p.id)}')\">${t('edit')}<\/button> <button class=\"danger\" onclick=\"removePicture('${esc(p.id)}')\">${t('delete')}<\/button><\/div><\/div>`).join(''):`<p class=\"muted\">${t('noPictures')}<\/p>`}<\/div>`}\nfunction admin(){staffMode=false;page='admin';history.pushState({},'', '\/admin');render()}function staffAdmin(){staffMode=true;registrationType='servant';page='admin';history.pushState({},'', '\/staff\/admin');render()}async function home(){staffMode=false;registrationType='volunteer';history.pushState({},'', '\/');page='home';try{await load();render()}catch(e){renderDataError(e)}}async function servicesPage(){staffMode=false;registrationType='volunteer';history.pushState({},'', '\/sign-up');page='services';closeMenu();render();if(!services.length){try{await load();if(page==='services')render()}catch(e){if(page==='services')renderDataError(e)}}}async function staffPage(){staffMode=true;registrationType='servant';history.pushState({},'', '\/staff\/sign-up');page='staff';try{await load();render()}catch(e){renderDataError(e)}}async function staffHomePage(){staffMode=true;registrationType='servant';history.pushState({},'', '\/staff\/home');page='staffHome';try{await load();render()}catch(e){renderDataError(e)}}function signupListPage(){staffMode=false;history.pushState({},'', '\/signups');page='publicSignups';render()}function staffSignupListPage(){staffMode=true;registrationType='servant';history.pushState({},'', '\/staff\/signups');page='publicSignups';render()}function contactPage(){staffMode=false;history.pushState({},'', '\/contact');page='contact';render()}function staffContactPage(){staffMode=true;registrationType='servant';history.pushState({},'', '\/staff\/contact');page='contact';render()}async function openService(id){currentService=id;if(staffMode)registrationType='servant';else registrationType='volunteer';history.pushState({},'',(staffMode?'\/staff\/':'\/')+id);page=id;try{await load();render()}catch(e){renderDataError(e)}}async function setAdminTab(tab){adminTab=tab;if(tab==='prayer'){try{await loadPrayerAdmin()}catch(e){alert(e.message)}}else if(tab==='pictures'){try{await loadPictures(token)}catch(e){alert(e.message)}}else if(tab==='donations'){try{await loadDonations(token)}catch(e){alert(e.message)}}else if(tab==='donationList'){try{await loadDonations(token);await loadDonationSignups()}catch(e){alert(e.message)}}renderAdmin()}\nasync function exportDonationList(){\n  if(!token)return;\n  try{\n    const ds=await rpc('get_donation_signups_admin',{},token)||[];\n    const generated=new Date();\n    const dateLabel=generated.toLocaleDateString(undefined,{year:'numeric',month:'long',day:'numeric'});\n    const filename='good-samaritan-donation-list-'+generated.toISOString().slice(0,10)+'.pdf';\n    const byId=new Map(donations.map(d=>[d.id,d]));\n    const groups={};\n    ds.forEach(x=>{const title=x.donation_title||byId.get(x.donation_id)?.title||'Donation';(groups[title]??=[]).push(x)});\n    if(!window.jspdf||!window.jspdf.jsPDF){\n      const w=window.open('','_blank'); if(!w){alert('Please allow pop-ups to export the PDF.');return;}\n      const eh=v=>String(v??'').replace(\/[&<>\"']\/g,m=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[m]));\n      w.document.write(`<!doctype html><html><head><title>Donation List<\/title><style>body{font-family:Arial,sans-serif;margin:32px;color:#221c15}h1{color:#a8532b;margin:0 0 5px}.meta{color:#6d6152;margin-bottom:22px}.group{break-inside:avoid;margin-bottom:22px}h2{font-size:16px;color:#a8532b;border-bottom:1px solid #e3d7bd;padding-bottom:5px}table{width:100%;border-collapse:collapse;font-size:10px}th,td{border:1px solid #ddd;padding:7px;text-align:left}th{background:#f5eee7}@page{size:letter;margin:.55in}<\/style><\/head><body><h1>Donation List<\/h1><div class=\"meta\">${ds.length} pledge${ds.length===1?'':'s'} \u00b7 Generated ${eh(dateLabel)}<\/div>${Object.entries(groups).map(([title,rows])=>`<div class=\"group\"><h2>${eh(title)}<\/h2><table><thead><tr><th>#<\/th><th>Donor<\/th><th>Phone<\/th><th>Quantity<\/th><th>Signed Up<\/th><\/tr><\/thead><tbody>${rows.map((x,i)=>`<tr><td>${i+1}<\/td><td>${eh(x.name)}<\/td><td>${eh(x.phone||'')}<\/td><td>${eh(x.quantity||0)}<\/td><td>${eh(x.created_at?new Date(x.created_at).toLocaleString():'')}<\/td><\/tr>`).join('')}<\/tbody><\/table><\/div>`).join('')}<\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"class_list":["post-335","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/goodsamaritangroup.org\/index.php\/wp-json\/wp\/v2\/pages\/335","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/goodsamaritangroup.org\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/goodsamaritangroup.org\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/goodsamaritangroup.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/goodsamaritangroup.org\/index.php\/wp-json\/wp\/v2\/comments?post=335"}],"version-history":[{"count":1,"href":"https:\/\/goodsamaritangroup.org\/index.php\/wp-json\/wp\/v2\/pages\/335\/revisions"}],"predecessor-version":[{"id":336,"href":"https:\/\/goodsamaritangroup.org\/index.php\/wp-json\/wp\/v2\/pages\/335\/revisions\/336"}],"wp:attachment":[{"href":"https:\/\/goodsamaritangroup.org\/index.php\/wp-json\/wp\/v2\/media?parent=335"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}