Spaces:
Running
Running
| <html lang="he" dir="rtl"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>מנהל משימות מערכת</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <style> | |
| @keyframes float { | |
| 0%, 100% { transform: translate(0, 0) rotate(0deg); } | |
| 50% { transform: translate(-20px, -20px) rotate(180deg); } | |
| } | |
| @keyframes spin { | |
| to { transform: rotate(360deg); } | |
| } | |
| .grid-pattern { | |
| background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>'); | |
| animation: float 20s ease-in-out infinite; | |
| } | |
| .spinner { | |
| display: inline-block; | |
| width: 16px; | |
| height: 16px; | |
| border: 2px solid rgba(255, 255, 255, 0.3); | |
| border-radius: 50%; | |
| border-top-color: #fff; | |
| animation: spin 1s ease-in-out infinite; | |
| vertical-align: middle; | |
| margin-left: 5px; | |
| margin-right: 3px; | |
| } | |
| .btn-hover-effect::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: -100%; | |
| width: 100%; | |
| height: 100%; | |
| background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); | |
| transition: left 0.5s ease-in-out; | |
| z-index: 1; | |
| } | |
| .btn-hover-effect:hover::before { | |
| left: 100%; | |
| } | |
| .tooltip { | |
| visibility: hidden; | |
| opacity: 0; | |
| transition: opacity 0.2s, visibility 0.2s; | |
| pointer-events: none; | |
| } | |
| .tooltip.visible { | |
| visibility: visible; | |
| opacity: 1; | |
| } | |
| .modal { | |
| display: none; | |
| } | |
| .modal.active { | |
| display: flex; | |
| } | |
| .gradient-header { | |
| background: linear-gradient(135deg, #61AFEF 0%, #98C379 100%); | |
| } | |
| .gradient-primary { | |
| background: linear-gradient(135deg, #61AFEF, #528ED1); | |
| } | |
| .gradient-teal { | |
| background: linear-gradient(135deg, #56B6C2, #408D97); | |
| } | |
| .gradient-success { | |
| background: linear-gradient(135deg, #98C379, #7FA761); | |
| } | |
| .gradient-danger { | |
| background: linear-gradient(135deg, #E06C75, #C85A63); | |
| } | |
| .gradient-warning { | |
| background: linear-gradient(135deg, #E6C07B, #D1A863); | |
| } | |
| .gradient-secondary { | |
| background: linear-gradient(135deg, #5C6370, #4A505C); | |
| } | |
| .gradient-save { | |
| background: linear-gradient(135deg, #4b7bec, #3867d6); | |
| } | |
| .text-success { | |
| color: #98C379; | |
| } | |
| .text-error { | |
| color: #E06C75; | |
| } | |
| .text-warning { | |
| color: #E6C07B; | |
| } | |
| .text-info { | |
| color: #61AFEF; | |
| } | |
| .bg-glass { | |
| background: rgba(62, 68, 81, 0.3); | |
| backdrop-filter: blur(10px); | |
| } | |
| .bg-section { | |
| background: rgba(33, 37, 43, 0.6); | |
| } | |
| .bg-section-header { | |
| background: rgba(97, 175, 239, 0.1); | |
| } | |
| .bg-disclaimer { | |
| background-color: rgba(230, 192, 123, 0.1); | |
| } | |
| .bg-api-section { | |
| background: rgba(224, 108, 117, 0.1); | |
| } | |
| .border-section { | |
| border-color: rgba(97, 175, 239, 0.2); | |
| } | |
| .border-api-section { | |
| border-color: rgba(224, 108, 117, 0.3); | |
| } | |
| .shadow-section { | |
| box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); | |
| } | |
| .shadow-section-hover { | |
| box-shadow: 0 4px 16px rgba(97, 175, 239, 0.1); | |
| } | |
| .shadow-btn-hover { | |
| box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3); | |
| } | |
| .shadow-tooltip { | |
| box-shadow: 0 3px 8px rgba(0,0,0,0.4); | |
| } | |
| .shadow-modal { | |
| box-shadow: 0 5px 15px rgba(0,0,0,0.5); | |
| } | |
| .shadow-input-focus { | |
| box-shadow: 0 0 0 3px rgba(97, 175, 239, 0.2); | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen bg-gradient-to-br from-[#282C34] to-[#21252B] text-[#ABB2BF] font-sans p-5"> | |
| <div class="max-w-4xl mx-auto bg-glass rounded-xl shadow-section overflow-hidden"> | |
| <!-- Header --> | |
| <div class="gradient-header text-white text-center p-8 relative overflow-hidden"> | |
| <div class="absolute inset-0 grid-pattern"></div> | |
| <h1 class="text-4xl font-bold mb-2 relative z-10 text-shadow">✨ בוט מערכת: משימות אוטומטיות ✨</h1> | |
| <div class="text-lg opacity-90 relative z-10">המרת הוראות לקוד BAT אוטומטי</div> | |
| </div> | |
| <!-- Main Content --> | |
| <div class="p-6"> | |
| <!-- API Section --> | |
| <div class="bg-api-section border border-api-section rounded-lg p-4 mb-6" id="apiSection"> | |
| <div class="font-bold text-[#E06C75] mb-2">🔑 הגדרת מפתח Google Gemini API</div> | |
| <div class="text-sm mb-2"> | |
| כדי להשתמש בתוכנה, יש צורך במפתח API של Google Gemini.<br> | |
| ניתן להשיג מפתח בחינם בכתובת: | |
| <a href="https://aistudio.google.com/app/apikey" target="_blank" class="text-[#61AFEF] underline">https://aistudio.google.com/app/apikey</a> | |
| </div> | |
| <input type="password" id="apiKeyInput" class="w-full p-2 bg-[#3E4451] border border-[#5C6370] rounded text-[#ABB2BF] text-sm mt-2 focus:outline-none focus:border-[#E06C75]" placeholder="הזן את מפתח ה-API שלך כאן"> | |
| <div class="flex gap-3 flex-wrap justify-center mt-3"> | |
| <button class="btn-hover-effect relative overflow-hidden px-4 py-2 rounded-lg font-bold text-white gradient-success min-w-[120px]" onclick="saveApiKey()"> | |
| <span class="relative z-10">שמור מפתח</span> | |
| </button> | |
| <button class="btn-hover-effect relative overflow-hidden px-4 py-2 rounded-lg font-bold text-white gradient-secondary min-w-[120px]" onclick="changeApiKey()"> | |
| <span class="relative z-10">שנה מפתח</span> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Command Input Section --> | |
| <div class="bg-section border border-section rounded-lg mb-5 transition-all hover:border-[rgba(97,175,239,0.4)] hover:shadow-section-hover"> | |
| <div class="bg-section-header border-b border-section-header p-3 font-bold text-[#61AFEF]">אמור לי מה לעשות</div> | |
| <div class="p-4"> | |
| <textarea id="commandInput" class="w-full min-h-[120px] bg-[#3E4451] border-2 border-transparent rounded-lg p-3 text-[#ABB2BF] resize-y transition-all focus:outline-none focus:border-[#61AFEF] focus:shadow-input-focus focus:bg-[#434951]" placeholder="הקלד את המשימה שלך (לדוגמה: 'צור תיקייה 'פרויקטים' בשולחן העבודה')"></textarea> | |
| <div class="flex gap-3 flex-wrap justify-center mt-4"> | |
| <button id="createButton" class="btn-hover-effect relative overflow-hidden px-4 py-2 rounded-lg font-bold text-white gradient-primary min-w-[120px]"> | |
| <span class="relative z-10">תכנן פעולה</span> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Script Output Section --> | |
| <div class="bg-section border border-section rounded-lg mb-5 transition-all hover:border-[rgba(97,175,239,0.4)] hover:shadow-section-hover"> | |
| <div class="bg-section-header border-b border-section-header p-3 font-bold text-[#61AFEF]">תוכנית הפעולה שלי</div> | |
| <div class="p-4"> | |
| <div id="scriptOutput" class="w-full min-h-[200px] bg-[#21252B] border border-[#3E4451] rounded-lg p-3 font-mono text-[#D1D0C5] whitespace-pre-wrap overflow-y-auto">המתן לתוכנית פעולה...</div> | |
| <div class="flex gap-3 flex-wrap justify-center mt-4"> | |
| <button id="saveWithPickerButton" class="btn-hover-effect relative overflow-hidden px-4 py-2 rounded-lg font-bold text-white gradient-save min-w-[120px]" data-tooltip="שמירה דרך 'בחירת קובץ' של הדפדפן (מומלץ ל-Chrome/Edge). <span class='font-bold text-[#E06C75]'>לרוב תופיע אזהרת SmartScreen</span> (מידע נוסף > הפעל בכל מקרה)."> | |
| <span class="relative z-10">שמור סקריפט כ...</span> | |
| </button> | |
| <button id="downloadDirectButton" class="btn-hover-effect relative overflow-hidden px-4 py-2 rounded-lg font-bold text-white gradient-danger min-w-[120px]" data-tooltip="הורדה ישירה ומהירה. <span class='font-bold text-[#E06C75]'>ידרוש 'ביטול חסימה' במאפייני הקובץ</span>."> | |
| <span class="relative z-10">הורד סקריפט (.bat)</span> | |
| </button> | |
| <button id="copyManualButton" class="btn-hover-effect relative overflow-hidden px-4 py-2 rounded-lg font-bold text-white gradient-success min-w-[120px]" data-tooltip="העתק את הסקריפט והדבק בפנקס רשימות כדי ליצור קובץ <code class='bg-[#3E4451] px-1 rounded text-[#E6C07B]'>.bat</code> בעצמך. <span class='font-bold text-[#E06C75]'>הדרך הבטוחה ביותר למנוע חסימות אוטומטיות.</span>" onclick="copyScriptManual()"> | |
| <span class="relative z-10">העתק לשמירה ידנית</span> | |
| </button> | |
| <button id="copyToConsoleButton" class="btn-hover-effect relative overflow-hidden px-4 py-2 rounded-lg font-bold text-white gradient-teal min-w-[120px]" data-tooltip="העתק את הפקודות להדבקה ישירה בחלון CMD או PowerShell. <span class='font-bold text-[#E06C75]'>ללא יצירת קבצים כלל.</span>" onclick="copyToConsole()"> | |
| <span class="relative z-10">העתק פקודות למסוף</span> | |
| </button> | |
| </div> | |
| <div class="flex gap-3 flex-wrap justify-center mt-5"> | |
| <button id="editButton" class="btn-hover-effect relative overflow-hidden px-4 py-2 rounded-lg font-bold text-white gradient-warning min-w-[120px]" onclick="toggleEdit()"> | |
| <span class="relative z-10">שנה תוכנית</span> | |
| </button> | |
| <button id="clearButton" class="btn-hover-effect relative overflow-hidden px-4 py-2 rounded-lg font-bold text-white gradient-secondary min-w-[120px]" onclick="clearInput()"> | |
| <span class="relative z-10">אפס משימה</span> | |
| </button> | |
| </div> | |
| <div class="text-sm text-[#E6C07B] mt-5 text-center p-2 bg-disclaimer border border-[rgba(230,192,123,0.3)] rounded"> | |
| <strong class="text-[#E06C75]">כתב ויתור:</strong> השימוש בסקריפטים שנוצרו הוא על אחריות המשתמש בלבד. הרצת סקריפטים, במיוחד כאלה שהורדו מהאינטרנט או נוצרו אוטומטית, עלולה להיות מסוכנת. ודא שאתה מבין את הפעולות שהסקריפט מבצע לפני הרצתו. מנגנוני האבטחה של Windows (כמו SmartScreen או הצורך ב"ביטול חסימה") נועדו להגן עליך וייתכן שיופיעו בעת ניסיון ההרצה. | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Status Bar --> | |
| <div class="flex justify-between items-center p-3 bg-[rgba(33,37,43,0.8)] border-t border-[rgba(97,175,239,0.2)] text-sm"> | |
| <div class="text-[#5C6370]">גרסה: 1.5.8 Web (Full Logic & Accurate Modals)</div> | |
| <div id="statusMessage" class="text-right text-[#ABB2BF]">אני מוכן. תן לי הוראה!</div> | |
| </div> | |
| </div> | |
| <!-- Tooltip --> | |
| <div id="globalTooltip" class="tooltip fixed z-[1001] w-56 bg-[#21252B] text-[#ABB2BF] text-center rounded p-2 border border-[#61AFEF] shadow-tooltip"></div> | |
| <!-- Modals --> | |
| <div id="manualSaveModal" class="modal fixed inset-0 z-[1000] bg-[rgba(0,0,0,0.6)] pt-16 hidden items-start justify-center"> | |
| <div class="bg-[#2c313a] rounded-lg p-6 border border-[#61AFEF] shadow-modal w-[90%] max-w-2xl relative"> | |
| <span class="absolute top-3 right-4 text-3xl font-bold text-[#ABB2BF] hover:text-[#E06C75] cursor-pointer" onclick="closeModal('manualSaveModal')">×</span> | |
| <h3 class="text-[#61AFEF] mb-3 border-b border-[#3E4451] pb-2">הוראות לשמירה ידנית של סקריפט (.bat)</h3> | |
| <p class="mb-2 leading-relaxed">הסקריפט הועתק ללוח הגזירים שלך. כדי ליצור קובץ BAT להרצה:</p> | |
| <ul class="list-disc pr-5 mb-2 leading-relaxed"> | |
| <li class="mb-1">פתח עורך טקסט פשוט (כמו "פנקס רשימות" או Notepad).</li> | |
| <li class="mb-1">הדבק את הסקריפט (Ctrl+V או לחיצה ימנית > הדבק).</li> | |
| <li class="mb-1">לחץ על "קובץ" (File) > "שמור בשם..." (Save As...).</li> | |
| <li class="mb-1">בחלון השמירה: | |
| <ul class="list-disc pr-5 mt-1"> | |
| <li class="mb-1">בחר מיקום לשמירת הקובץ.</li> | |
| <li class="mb-1">בשדה "שם הקובץ" (File name), הקלד שם לקובץ עם סיומת <code class="bg-[#3E4451] px-1 rounded text-[#E6C07B]">.bat</code> (לדוגמה: <code class="bg-[#3E4451] px-1 rounded text-[#E6C07B]">my_script.bat</code>).</li> | |
| <li class="mb-1"><span class="font-bold text-[#E06C75]">חשוב:</span> בשדה "שמור כסוג" (Save as type), בחר "כל הקבצים (*.*)" או "All Files (*.*)".</li> | |
| </ul> | |
| </li> | |
| <li class="mb-1">לחץ על "שמור" (Save).</li> | |
| <li>כעת תוכל להריץ את הקובץ שיצרת. ייתכן שתידרש "לבטל חסימה" של הקובץ במאפיינים שלו או לאשר דרך SmartScreen.</li> | |
| </ul> | |
| </div> | |
| </div> | |
| <div id="postActionModal" class="modal fixed inset-0 z-[1000] bg-[rgba(0,0,0,0.6)] pt-16 hidden items-start justify-center"> | |
| <div class="bg-[#2c313a] rounded-lg p-6 border border-[#61AFEF] shadow-modal w-[90%] max-w-2xl relative"> | |
| <span class="absolute top-3 right-4 text-3xl font-bold text-[#ABB2BF] hover:text-[#E06C75] cursor-pointer" onclick="closeModal('postActionModal')">×</span> | |
| <h3 id="postActionModalTitle" class="text-[#61AFEF] mb-3 border-b border-[#3E4451] pb-2">הנחיות לאחר פעולה</h3> | |
| <p id="postActionModalIntro" class="mb-2 leading-relaxed">קובץ הסקריפט נוצר. ייתכן ש-Windows יציג אזהרות אבטחה.</p> | |
| <div id="smartScreenInstructions"> | |
| <p class="font-bold mb-2">אם מופיעה אזהרת SmartScreen:</p> | |
| <ul class="list-disc pr-5 mb-2 leading-relaxed"> | |
| <li class="mb-1">לחץ על "מידע נוסף" (More info).</li> | |
| <li>לחץ על "הפעל בכל מקרה" (Run anyway).</li> | |
| </ul> | |
| </div> | |
| <div id="unblockFileInstructions" class="mt-3"> | |
| <p class="font-bold mb-2">אם נדרש "ביטול חסימה" ידני של הקובץ:</p> | |
| <ul class="list-disc pr-5 mb-2 leading-relaxed"> | |
| <li class="mb-1">אתר את הקובץ במחשבך.</li> | |
| <li class="mb-1">לחץ עליו באמצעות לחצן העכבר הימני ובחר "מאפיינים" (Properties).</li> | |
| <li class="mb-1">בלשונית "כללי" (General), בחלק התחתון, חפש תיבת סימון "בטל חסימה" (Unblock).</li> | |
| <li>אם התיבה קיימת, סמן אותה, לחץ "החל" (Apply) ו"אישור" (OK).</li> | |
| </ul> | |
| </div> | |
| <p class="mt-3 leading-relaxed">לאחר ביצוע הפעולות הנדרשות, תוכל להריץ את הקובץ.</p> | |
| </div> | |
| </div> | |
| <div id="consoleModal" class="modal fixed inset-0 z-[1000] bg-[rgba(0,0,0,0.6)] pt-16 hidden items-start justify-center"> | |
| <div class="bg-[#2c313a] rounded-lg p-6 border border-[#61AFEF] shadow-modal w-[90%] max-w-2xl relative"> | |
| <span class="absolute top-3 right-4 text-3xl font-bold text-[#ABB2BF] hover:text-[#E06C75] cursor-pointer" onclick="closeModal('consoleModal')">×</span> | |
| <h3 class="text-[#61AFEF] mb-3 border-b border-[#3E4451] pb-2">הוראות להרצת פקודות במסוף (CMD/PowerShell)</h3> | |
| <p class="mb-2 leading-relaxed">פקודות הסקריפט הועתקו ללוח הגזירים שלך.</p> | |
| <ul class="list-disc pr-5 mb-2 leading-relaxed"> | |
| <li class="mb-1">פתח את שורת הפקודה (CMD) או PowerShell.</li> | |
| <li class="mb-1">בחלון המסוף, הדבק את הפקודות.</li> | |
| <li>לחץ Enter כדי להריץ.</li> | |
| </ul> | |
| <p class="font-bold text-[#E06C75]">שים לב:</p> | |
| <p class="leading-relaxed">ייתכן שיידרשו הרשאות מנהל. לא כל סקריפט יתאים להדבקה ישירה.</p> | |
| </div> | |
| </div> | |
| <script> | |
| // Global variables | |
| let apiKey = ''; | |
| let isEditing = false; | |
| let currentScript = ''; | |
| const globalTooltipElement = document.getElementById('globalTooltip'); | |
| // Tooltip Functions | |
| function showTooltip(event, text) { | |
| if (!globalTooltipElement || !text) return; | |
| globalTooltipElement.innerHTML = text; | |
| globalTooltipElement.classList.add('visible'); | |
| const targetRect = event.currentTarget.getBoundingClientRect(); | |
| const tooltipRect = globalTooltipElement.getBoundingClientRect(); | |
| let top = targetRect.top - tooltipRect.height - 10; | |
| let left = targetRect.left + (targetRect.width / 2) - (tooltipRect.width / 2); | |
| if (top < 0) top = targetRect.bottom + 10; | |
| if (left < 0) left = 5; | |
| if (left + tooltipRect.width > window.innerWidth) left = window.innerWidth - tooltipRect.width - 5; | |
| globalTooltipElement.style.top = `${top + window.scrollY}px`; | |
| globalTooltipElement.style.left = `${left + window.scrollX}px`; | |
| } | |
| function hideTooltip() { | |
| if (!globalTooltipElement) return; | |
| globalTooltipElement.classList.remove('visible'); | |
| } | |
| // Modal Functions | |
| function closeModal(modalId) { | |
| document.getElementById(modalId).classList.remove('active'); | |
| } | |
| function openModal(modalId, actionType = null) { | |
| const modal = document.getElementById(modalId); | |
| if (!modal) return; | |
| if (modalId === 'postActionModal' && actionType) { | |
| const title = modal.querySelector('#postActionModalTitle'); | |
| const intro = modal.querySelector('#postActionModalIntro'); | |
| const smartScreenDiv = modal.querySelector('#smartScreenInstructions'); | |
| const unblockFileDiv = modal.querySelector('#unblockFileInstructions'); | |
| if (actionType === 'saveWithPicker') { | |
| if (title) title.textContent = "הנחיות לאחר 'שמירה כ...'"; | |
| if (intro) intro.textContent = "הסקריפט נשמר למחשבך. סביר שתופיע אזהרת SmartScreen:"; | |
| if (smartScreenDiv) smartScreenDiv.style.display = 'block'; | |
| if (unblockFileDiv) unblockFileDiv.style.display = 'none'; | |
| } else if (actionType === 'traditionalDownload') { | |
| if (title) title.textContent = "הנחיות לאחר 'הורדה ישירה'"; | |
| if (intro) intro.textContent = "הסקריפט הורד למחשבך. כמעט תמיד תידרש לבטל את חסימתו:"; | |
| if (smartScreenDiv) smartScreenDiv.style.display = 'block'; | |
| if (unblockFileDiv) unblockFileDiv.style.display = 'block'; | |
| } | |
| } | |
| modal.classList.add('active'); | |
| } | |
| // Event Listeners | |
| window.onclick = function(event) { | |
| if (event.target.classList.contains('modal')) { | |
| event.target.classList.remove('active'); | |
| } | |
| } | |
| document.addEventListener('keydown', function(event) { | |
| if (event.key === "Escape") { | |
| document.querySelectorAll('.modal').forEach(modal => modal.classList.remove('active')); | |
| } | |
| }); | |
| // Core Application Logic | |
| window.addEventListener('load', function() { | |
| const savedApiKey = localStorage.getItem('gemini_api_key'); | |
| const apiSection = document.getElementById('apiSection'); | |
| if (savedApiKey) { | |
| apiKey = savedApiKey; | |
| document.getElementById('apiKeyInput').value = apiKey; | |
| if(apiSection) apiSection.classList.add('hidden'); | |
| setStatusMessage('מפתח API נטען בהצלחה.', 'success'); | |
| } else { | |
| if(apiSection) apiSection.classList.remove('hidden'); | |
| setStatusMessage('אנא הזן מפתח API כדי להתחיל.', 'warning'); | |
| } | |
| // Tooltip setup | |
| document.querySelectorAll('[data-tooltip]').forEach(button => { | |
| const tooltipText = button.getAttribute('data-tooltip'); | |
| if (tooltipText) { | |
| button.addEventListener('mouseover', (event) => showTooltip(event, tooltipText)); | |
| button.addEventListener('mouseout', hideTooltip); | |
| button.addEventListener('focus', (event) => showTooltip(event, tooltipText)); | |
| button.addEventListener('blur', hideTooltip); | |
| } | |
| }); | |
| // Button event listeners | |
| document.getElementById('createButton').addEventListener('click', createScript); | |
| document.getElementById('saveWithPickerButton').addEventListener('click', saveScriptWithPicker); | |
| document.getElementById('downloadDirectButton').addEventListener('click', traditionalDownloadScript); | |
| // Auto-resize textarea | |
| const commandInputArea = document.getElementById('commandInput'); | |
| if(commandInputArea) { | |
| commandInputArea.addEventListener('input', function() { | |
| this.style.height = 'auto'; | |
| this.style.height = Math.max(120, this.scrollHeight) + 'px'; | |
| }); | |
| } | |
| // Ctrl+Enter to submit | |
| document.addEventListener('keydown', function(e) { | |
| if (e.ctrlKey && e.key === 'Enter') { | |
| if (document.activeElement === document.getElementById('commandInput')) { | |
| e.preventDefault(); | |
| createScript(); | |
| } | |
| } | |
| }); | |
| }); | |
| function setStatusMessage(message, type = 'info') { | |
| const statusElement = document.getElementById('statusMessage'); | |
| statusElement.textContent = message; | |
| statusElement.className = `text-right ${type === 'success' ? 'text-success' : | |
| type === 'error' ? 'text-error' : | |
| type === 'warning' ? 'text-warning' : 'text-info'}`; | |
| } | |
| function saveApiKey() { | |
| const keyInput = document.getElementById('apiKeyInput'); | |
| const key = keyInput.value.trim(); | |
| if (!key) { | |
| alert('אנא הזן מפתח API תקף.'); | |
| return; | |
| } | |
| apiKey = key; | |
| localStorage.setItem('gemini_api_key', key); | |
| const apiSection = document.getElementById('apiSection'); | |
| if(apiSection) apiSection.classList.add('hidden'); | |
| setStatusMessage('מפתח API נשמר בהצלחה!', 'success'); | |
| } | |
| function changeApiKey() { | |
| const apiSection = document.getElementById('apiSection'); | |
| if(apiSection) apiSection.classList.remove('hidden'); | |
| document.getElementById('apiKeyInput').value = apiKey; | |
| document.getElementById('apiKeyInput').focus(); | |
| } | |
| function setButtonLoading(buttonId, isLoading) { | |
| const button = document.getElementById(buttonId); | |
| if (!button) return; | |
| if (isLoading) { | |
| button.disabled = true; | |
| if (!button.dataset.originalHTML) { | |
| button.dataset.originalHTML = button.innerHTML; | |
| } | |
| button.innerHTML = '<span class="relative z-10"><span class="spinner"></span>מעבד...</span>'; | |
| } else { | |
| button.disabled = false; | |
| if (button.dataset.originalHTML) { | |
| button.innerHTML = button.dataset.originalHTML; | |
| } | |
| } | |
| } | |
| async function callGeminiAPI(userCommand) { | |
| if (!apiKey) { | |
| console.error("API Key is missing in callGeminiAPI. Current value:", apiKey); | |
| throw new Error('מפתח API אינו זמין. אנא הגדר אותו תחילה דרך "שנה מפתח".'); | |
| } | |
| const prompt = `אתה עוזר וירטואלי שמתמחה ביצירת קוד BAT עבור מערכת הפעלה Windows מפקודות בשפה טבעית בעברית. הקוד שאתה יוצר חייב להיות נקי, יעיל, ומוכן להרצה. ודא שהקוד לא מכיל עטיפות כמו \`\`\`batch או \`\`\` או כל טקסט הסבר נוסף. רק הקוד עצמו. כלול פקודת \`chcp 65001\` בתחילת הסקריפט כדי לתמוך בקידוד עברית. הוסף גם פקודת \`chcp 437\` בסוף הסקריפט כדי להחזיר את הקידוד המקורי. הוסף פקודת PAUSE בסוף הקוד כדי שהחלון לא ייסגר מיד. אם הפקודה בשפה טבעית אינה מובנת או שאינה ניתנת לתרגום לקוד BAT, החזר הודעת שגיאה קצרה בתוך קוד BAT שאומרת זאת בעברית. הפקודה בשפה טבעית: ${userCommand}`; | |
| const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=${apiKey}`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ contents: [{ parts: [{ text: prompt }] }] }) | |
| }); | |
| if (!response.ok) { | |
| const errorData = await response.json().catch(() => ({ error: { message: "תגובת שגיאה לא תקינה מהשרת" } })); | |
| const errorMessage = errorData?.error?.message || `${response.status} - ${response.statusText}`; | |
| console.error('API Error Response:', errorData); | |
| throw new Error(`שגיאת API: ${errorMessage}`); | |
| } | |
| const data = await response.json(); | |
| if (!data.candidates?.[0]?.content?.parts?.[0]?.text) { | |
| console.error('Invalid API Response Structure:', data); | |
| throw new Error('תגובה לא תקינה מה-API (מבנה לא צפוי)'); | |
| } | |
| let script = data.candidates[0].content.parts[0].text.trim(); | |
| if (script.startsWith('```batch')) script = script.substring(8); | |
| if (script.startsWith('```')) script = script.substring(3); | |
| if (script.endsWith('```')) script = script.substring(0, script.length - 3); | |
| return script.trim(); | |
| } | |
| async function createScript() { | |
| const userCommand = document.getElementById('commandInput').value.trim(); | |
| if (!userCommand) { | |
| alert('אנא הזן פקודה בשפה חופשית.'); | |
| setStatusMessage('שגיאה: אנא הזן פקודה.', 'error'); | |
| return; | |
| } | |
| if (!apiKey) { | |
| alert('מפתח ה-API של Gemini אינו זמין. אנא הגדר אותו תחילה.'); | |
| setStatusMessage('שגיאה: מפתח API חסר.', 'error'); | |
| changeApiKey(); | |
| return; | |
| } | |
| const buttonId = 'createButton'; | |
| setButtonLoading(buttonId, true); | |
| setStatusMessage('מפענח את בקשתך...', 'info'); | |
| const outputElement = document.getElementById('scriptOutput'); | |
| const editorElement = document.getElementById('scriptEditor'); | |
| try { | |
| const scriptText = await callGeminiAPI(userCommand); | |
| currentScript = scriptText; | |
| if (isEditing && editorElement) { | |
| editorElement.value = scriptText; | |
| } else if (outputElement) { | |
| outputElement.textContent = scriptText; | |
| } | |
| setStatusMessage('תוכנית הפעולה מוכנה!', 'success'); | |
| } catch (error) { | |
| console.error('Error generating script:', error); | |
| const displayError = `שגיאה ביצירת הסקריפט:\n${error.message}`; | |
| if (isEditing && editorElement) { | |
| editorElement.value = displayError; | |
| } else if (outputElement) { | |
| outputElement.textContent = displayError; | |
| } | |
| setStatusMessage(`אירעה שגיאה: ${error.message}`, 'error'); | |
| } finally { | |
| setButtonLoading(buttonId, false); | |
| } | |
| } | |
| function getScriptContentForAction() { | |
| const editorElement = document.getElementById('scriptEditor'); | |
| const outputElement = document.getElementById('scriptOutput'); | |
| let scriptText = ''; | |
| if (isEditing && editorElement) { | |
| scriptText = editorElement.value.trim(); | |
| } else if (outputElement) { | |
| scriptText = outputElement.textContent.trim(); | |
| } else { | |
| scriptText = currentScript.trim(); | |
| } | |
| if (!scriptText || scriptText === 'המתן לתוכנית פעולה...' || scriptText.startsWith('שגיאה ביצירת הסקריפט')) { | |
| alert('אין תוכנית פעולה תקינה זמינה.'); | |
| setStatusMessage('שגיאה: אין תוכנית פעולה תקינה.', 'error'); | |
| return null; | |
| } | |
| return scriptText; | |
| } | |
| async function saveScriptWithPicker() { | |
| const scriptContent = getScriptContentForAction(); | |
| if (!scriptContent) return; | |
| const buttonId = 'saveWithPickerButton'; | |
| setButtonLoading(buttonId, true); | |
| const suggestedName = 'system_task.bat'; | |
| if (window.showSaveFilePicker) { | |
| try { | |
| const fileHandle = await window.showSaveFilePicker({ | |
| suggestedName: suggestedName, | |
| types: [{ | |
| description: 'Batch Files', | |
| accept: { | |
| 'application/x-bat': ['.bat'], | |
| 'text/plain': ['.bat', '.txt'] | |
| } | |
| }], | |
| startIn: 'downloads' | |
| }); | |
| const writable = await fileHandle.createWritable(); | |
| await writable.write(scriptContent); | |
| await writable.close(); | |
| setStatusMessage('הסקריפט נשמר בהצלחה!', 'success'); | |
| openModal('postActionModal', 'saveWithPicker'); | |
| } catch (err) { | |
| if (err.name !== 'AbortError') { | |
| console.error('Error saving with File System Access API:', err); | |
| setStatusMessage('שגיאה בשמירת הקובץ. מנסה הורדה רגילה...', 'error'); | |
| traditionalDownload(scriptContent, suggestedName, false); | |
| } else { | |
| setStatusMessage('שמירת הקובץ בוטלה.', 'info'); | |
| } | |
| } finally { | |
| setButtonLoading(buttonId, false); | |
| } | |
| } else { | |
| setStatusMessage('דפדפן לא תומך בשמירה ישירה, מנסה הורדה רגילה...', 'warning'); | |
| traditionalDownload(scriptContent, suggestedName, false); | |
| setButtonLoading(buttonId, false); | |
| } | |
| } | |
| function traditionalDownloadScript() { | |
| const scriptContent = getScriptContentForAction(); | |
| if (!scriptContent) return; | |
| const buttonId = 'downloadDirectButton'; | |
| setButtonLoading(buttonId, true); | |
| traditionalDownload(scriptContent, 'system_task.bat', true); | |
| setTimeout(() => { setButtonLoading(buttonId, false); }, 100); | |
| } | |
| function traditionalDownload(content, filename, isPrimaryActionFromButton) { | |
| const blob = new Blob([content], { type: 'application/x-bat;charset=utf-8' }); | |
| const url = window.URL.createObjectURL(blob); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| a.download = filename; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| window.URL.revokeObjectURL(url); | |
| if(isPrimaryActionFromButton) { | |
| setStatusMessage('הקובץ נשלח להורדה.', 'success'); | |
| } | |
| openModal('postActionModal', 'traditionalDownload'); | |
| } | |
| function copyScriptManual() { | |
| const scriptContent = getScriptContentForAction(); | |
| if (!scriptContent) return; | |
| const buttonId = 'copyManualButton'; | |
| setButtonLoading(buttonId, true); | |
| navigator.clipboard.writeText(scriptContent) | |
| .then(() => { | |
| setStatusMessage('הסקריפט הועתק.', 'success'); | |
| openModal('manualSaveModal'); | |
| }) | |
| .catch(err => { | |
| console.error('Error copying to clipboard:', err); | |
| alert('שגיאה בהעתקה ללוח הגזירים.'); | |
| setStatusMessage('שגיאה בהעתקה ללוח.', 'error'); | |
| }) | |
| .finally(() => { | |
| setButtonLoading(buttonId, false); | |
| }); | |
| } | |
| function copyToConsole() { | |
| const scriptContent = getScriptContentForAction(); | |
| if (!scriptContent) return; | |
| const buttonId = 'copyToConsoleButton'; | |
| setButtonLoading(buttonId, true); | |
| navigator.clipboard.writeText(scriptContent) | |
| .then(() => { | |
| setStatusMessage('הפקודות הועתקו.', 'success'); | |
| openModal('consoleModal'); | |
| }) | |
| .catch(err => { | |
| console.error('Error copying to clipboard:', err); | |
| alert('שגיאה בהעתקה ללוח הגזירים.'); | |
| setStatusMessage('שגיאה בהעתקה ללוח.', 'error'); | |
| }) | |
| .finally(() => { | |
| setButtonLoading(buttonId, false); | |
| }); | |
| } | |
| function toggleEdit() { | |
| const outputContainer = document.getElementById('scriptOutput')?.parentNode || | |
| document.getElementById('scriptEditor')?.parentNode; | |
| if (!outputContainer && !document.querySelector('.section-content #scriptOutput') && | |
| !document.querySelector('.section-content #scriptEditor')) { | |
| console.error("Cannot find output container for edit toggle."); | |
| return; | |
| } | |
| const actualOutputContainer = outputContainer || document.querySelector('.section-content'); | |
| if (!actualOutputContainer) { | |
| console.error("Fallback output container not found."); | |
| return; | |
| } | |
| const editButton = document.getElementById('editButton'); | |
| const outputElement = document.getElementById('scriptOutput'); | |
| const editorElement = document.getElementById('scriptEditor'); | |
| if (!isEditing) { | |
| const textarea = document.createElement('textarea'); | |
| textarea.className = 'w-full min-h-[200px] bg-[#21252B] border border-[#3E4451] rounded-lg p-3 font-mono text-[#D1D0C5] whitespace-pre-wrap overflow-y-auto resize-y'; | |
| textarea.style.resize = 'vertical'; | |
| textarea.value = outputElement ? outputElement.textContent : currentScript; | |
| textarea.id = 'scriptEditor'; | |
| if (outputElement) { | |
| outputElement.parentNode.replaceChild(textarea, outputElement); | |
| } else { | |
| if(editorElement) editorElement.remove(); | |
| const firstButtonGroup = actualOutputContainer.querySelector('.button-group'); | |
| if(firstButtonGroup) { | |
| actualOutputContainer.insertBefore(textarea, firstButtonGroup); | |
| } else { | |
| actualOutputContainer.appendChild(textarea); | |
| } | |
| } | |
| textarea.focus(); | |
| if(editButton) editButton.innerHTML = '<span class="relative z-10">סגור עריכה</span>'; | |
| isEditing = true; | |
| setStatusMessage('אני במצב עריכה ידנית.', 'warning'); | |
| } else { | |
| if (!editorElement) { | |
| isEditing = false; | |
| setStatusMessage('שגיאה: אזור העריכה לא נמצא.', 'error'); | |
| if(!outputElement) { | |
| const newDivFallback = document.createElement('div'); | |
| newDivFallback.className = 'w-full min-h-[200px] bg-[#21252B] border border-[#3E4451] rounded-lg p-3 font-mono text-[#D1D0C5] whitespace-pre-wrap overflow-y-auto'; | |
| newDivFallback.id = 'scriptOutput'; | |
| newDivFallback.textContent = currentScript || 'המתן לתוכנית פעולה...'; | |
| const firstButtonGroup = actualOutputContainer.querySelector('.button-group'); | |
| if(firstButtonGroup) { | |
| actualOutputContainer.insertBefore(newDivFallback, firstButtonGroup); | |
| } else { | |
| actualOutputContainer.appendChild(newDivFallback); | |
| } | |
| } | |
| if(editButton) editButton.innerHTML = '<span class="relative z-10">שנה תוכנית</span>'; | |
| return; | |
| } | |
| const newDiv = document.createElement('div'); | |
| newDiv.className = 'w-full min-h-[200px] bg-[#21252B] border border-[#3E4451] rounded-lg p-3 font-mono text-[#D1D0C5] whitespace-pre-wrap overflow-y-auto'; | |
| newDiv.id = 'scriptOutput'; | |
| newDiv.textContent = editorElement.value; | |
| currentScript = editorElement.value; | |
| editorElement.parentNode.replaceChild(newDiv, editorElement); | |
| if(editButton) editButton.innerHTML = '<span class="relative z-10">שנה תוכנית</span>'; | |
| isEditing = false; | |
| setStatusMessage('חזרתי למצב אוטומטי.', 'info'); | |
| } | |
| } | |
| function clearInput() { | |
| document.getElementById('commandInput').value = ''; | |
| const outputElement = document.getElementById('scriptOutput'); | |
| const editorElement = document.getElementById('scriptEditor'); | |
| const defaultOutputText = 'המתן לתוכנית פעולה...'; | |
| if (isEditing && editorElement) { | |
| editorElement.value = defaultOutputText; | |
| } else if (outputElement) { | |
| outputElement.textContent = defaultOutputText; | |
| } | |
| currentScript = ''; | |
| setStatusMessage('המשימה נוקתה. מחכה להוראותיך.', 'info'); | |
| } | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Lotzi/command-bot" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |