1// ãã³ãã¬ã¼ããã£ã¬ã¯ããªã®URIãåå¾ 2const getTemplateDirectoryUri = () => { 3 // window.templateDirectoryUriãæªå®ç¾©ã®å ´åã¯é å»¶ãã¦åè©¦è¡ 4 if (typeof window.templateDirectoryUri === 'undefined') { 5 console.warn('window.templateDirectoryUriãæªå®ç¾©ã§ããããã©ã«ããã¹ã使ç¨ãã¾ãã'); 6 return ''; 7 } 8 return window.templateDirectoryUri || ''; 9}; 10 11// é³å£°ãã¡ã¤ã«ã®ãã¹ãçæãã颿° 12window.getSoundPath = (soundFile) => { 13 const templateUri = getTemplateDirectoryUri(); 14 const path = templateUri ? `${templateUri}/assets/sound/${soundFile}` : `sound/${soundFile}`; 15 return path; 16}; 17 18// window.templateDirectoryUriãå¾ããè¨å®ãããå ´åã®é å»¶åæå 19const initializeTemplateUri = () => { 20 if (typeof window.templateDirectoryUri !== 'undefined' && window.templateDirectoryUri) { 21 console.log('window.templateDirectoryUriãè¨å®ããã¾ãã:', window.templateDirectoryUri); 22 // CONFIGã®é³å£°ãªãã·ã§ã³ãåçæ 23 if (window.CONFIG && window.CONFIG.soundOptions) { 24 window.CONFIG.soundOptions.forEach(sound => { 25 if (sound.sound && sound.sound.startsWith('sound/')) { 26 sound.sound = window.getSoundPath(sound.sound.replace('sound/', '')); 27 } 28 }); 29 } 30 } 31}; 32 33// DOMContentLoadedå¾ã«é å»¶åæåãå®è¡ 34if (document.readyState === 'loading') { 35 document.addEventListener('DOMContentLoaded', initializeTemplateUri); 36} else { 37 initializeTemplateUri(); 38} 39 40// è¨å®ã¨å®æ° 41window.CONFIG = { 42 // ããã¤ã¹æ¤åº 43 isIPhone: /iPhone|iPad|iPod/.test(navigator.userAgent), 44 isMobile: /iPhone|iPad|iPod|Android/.test(navigator.userAgent), 45 46 // 決æ¸è¨å® 47 payment: { 48 // Stripe決æ¸ãã¼ã¸ã®URLï¼ã¦ã¼ã¶ã¼ç»é²ã»èª²éèªå°æã«ä½¿ç¨ï¼ 49 stripeCheckoutUrl: '/registration' 50 }, 51 52 // ãããªè¨å® 53 video: { 54 desktop: { width: 1280, height: 720 }, 55 mobile: { widthRatio: 1, heightRatio: 0.6 } 56 }, 57 58 59 60 // è¨èªè¨å® 61 languages: { 62 japanese: { name: 'æ¥æ¬èª', flag: 'ð¯ðµ', code: 'ja' }, 63 english: { name: 'English', flag: 'ðºð¸', code: 'en' }, 64 spanish: { name: 'Español', flag: 'ðªð¸', code: 'es' }, 65 korean: { name: 'íêµë§', flag: 'ð°ð·', code: 'kr' } 66 }, 67 68 // ã¢ããªè¡¨ç¤ºè¨å® 69 app: { 70 // ãã¼ã¿/ãã¼ã¸ã§ã³ã©ãã«ï¼front-page ã® BETA 表示ã«åæ ï¼ 71 betaLabel: 'BETA 0.4' 72 }, 73 74 // ç¾å¨ã®è¨èªè¨å® 75 currentLanguage: 'japanese', 76 77 // é³å£°è¨å® 78 soundOptions: [ 79 { 80 id: 'cheese_bandou', 81 name: 'ãã¤ãã¼ãº 01', 82 sound: window.getSoundPath('01_cheese_bandou.m4a'), 83 emoji: 'ð§', 84 shutterTiming: [3.4, 3.8, 4.2, 7.0, 7.4, 7.9], 85 category: 'japanese' 86 }, 87 { 88 id: 'cheese_miyabi', 89 name: 'ãã¤ãã¼ãº 02', 90 sound: window.getSoundPath('02_cheese_miyabi.m4a'), 91 emoji: 'ð§', 92 shutterTiming: [6.2, 6.3, 7.3, 9.2, 10.14, 10.6, 11.05], 93 category: 'japanese' 94 }, 95 { 96 id: 'kids_photographer', 97 name: 'ãããºãã©ãã°ã©ãã¡ã¼', 98 sound: window.getSoundPath('03_kids_photographer.m4a'), 99 emoji: 'ð·', 100 shutterTiming: [5.8, 6.1, 6.6, 7.1, 7.6, 8.9, 10.2, 11.0, 11.5, 13.4, 13.8], 101 category: 'japanese' 102 }, 103 { 104 id: 'elephant_lion_kurita', 105 name: 'ãããã', 106 sound: window.getSoundPath('04_elephant_lion_kurita.m4a'), 107 emoji: 'ð', 108 shutterTiming: [6.7, 7.2, 7.6, 7.9, 13.1, 13.4, 13.8], 109 category: 'japanese' 110 }, 111 { 112 id: 'cheese_long_yanaga', 113 name: 'ãå§ãã', 114 sound: window.getSoundPath('05_cheese_long_yanaga.m4a'), 115 emoji: 'ð©', 116 shutterTiming: [6.0, 12.2, 12.6, 16.2, 17.05], 117 category: 'japanese' 118 }, 119 { 120 id: 'funny_face_koharu', 121 name: 'å¤é¡', 122 sound: window.getSoundPath('06_funny_face_koharu.m4a'), 123 emoji: 'ð', 124 shutterTiming: [6.9, 7.2, 7.8, 13.0, 13.4, 15.9, 16.4, 16.8], 125 category: 'japanese' 126 }, 127 { 128 id: 'yeah_habakeito', 129 name: 'YEAH', 130 sound: window.getSoundPath('07_yeah_habakeito.m4a'),
131 emoji: 'ð', 132 shutterTiming: [5.1, 6.4, 9.3, 9.7, 10.1, 10.5, 19.8, 21.6, 23.2, 24.8, 27.0, 27.5, 27.9, 28.3, 28.8], 133 category: 'japanese' 134 }, 135 { 136 id: 'toy_01', 137 name: 'ããã¡ã 01', 138 sound: window.getSoundPath('09_toy_01.m4a'), 139 emoji: 'ð§¸', 140 shutterTiming: [0.2, 2.2, 3.1, 5.0, 5.2, 6.2, 7.0, 9.0, 9.2, 11.1, 11.2], 141 category: 'japanese' 142 }, 143 { 144 id: 'toy_02', 145 name: 'ããã¡ã 02', 146 sound: window.getSoundPath('10_toy_02.m4a'), 147 emoji: 'ð', 148 shutterTiming: [1.0, 1.2, 2.2, 4.1, 5.1, 8.0, 9.0, 11.0, 12.0, 13.1, 14.0], 149 category: 'japanese' 150 }, 151 { 152 id: 'dog_01', 153 name: 'ãã¬', 154 sound: window.getSoundPath('11_dog_01.m4a'), 155 emoji: 'ð', 156 shutterTiming: [0.2, 1.2, 2.0, 2.1, 4.0, 4.2, 6.1, 6.2], 157 category: 'japanese' 158 }, 159 { 160 id: 'english_cheese', 161 name: 'Cheese', 162 sound: window.getSoundPath('english/01_cheese.m4a'), 163 emoji: 'ð§', 164 shutterTiming: [3.7, 4.1, 4.6, 8.2, 8.6, 10.7,11.1, 13.9, 14.8,15.7,16.7,17.9], 165 category: 'english' 166 }, 167 { 168 id: 'english_peekaboo', 169 name: 'Peekaboo', 170 sound: window.getSoundPath('english/02_peekaboo.m4a'), 171 emoji: 'ð', 172 shutterTiming: [5.0, 5.4, 9.4, 9.9, 13.6, 14.1, 16.2, 16.6, 19.4, 19.9, 22.8, 23.2, 23.7, 24.1], 173 category: 'english' 174 }, 175 { 176 id: 'english_animal', 177 name: 'Animal Sounds', 178 sound: window.getSoundPath('english/03_animal.m4a'), 179 emoji: 'ð¦', 180 shutterTiming: [3.2, 3.6, 5.9, 6.3, 9.6, 10.0, 16.3, 16.7, 23.1, 23.6, 24.0], 181 category: 'english' 182 }, 183 { 184 id: 'english_funny_face', 185 name: 'Funny Face', 186 sound: window.getSoundPath('english/04_funny_face.m4a'), 187 emoji: 'ð', 188 shutterTiming: [3.7, 4.2, 4.6, 8.5, 9.0, 13.5, 14.0, 14.5, 19.1, 19.5,24.2,24.7, 25.1, 29.6, 30.0, 30.5], 189 category: 'english' 190 }, 191 { 192 id: 'english_fishface', 193 name: 'Fish Face', 194 sound: window.getSoundPath('english/05_fishface.m4a'), 195 emoji: 'ð', 196 shutterTiming: [6.0, 6.5, 9.7, 10.2, 13.0, 13.5, 15.1, 15.6, 18.9, 19.4, 19.9, 20.4, 23.8, 24.2,24.7, 25.1, 30.3,30.8], 197 category: 'english' 198 }, 199 { 200 id: 'korean_pose', 201 name: 'Pose', 202 sound: window.getSoundPath('korean/01_pose.m4a'), 203 emoji: 'ðº', 204 shutterTiming: [3.1, 4, 4.1, 4.2, 8, 10.2, 13.1, 13.2, 14, 14.15, 18, 18.2, 23, 23.2, 24.1, 25], 205 category: 'korean' 206 }, 207 { 208 id: 'korean_smile', 209 name: 'Smile', 210 sound: window.getSoundPath('korean/02_smile.m4a'), 211 emoji: 'ð', 212 shutterTiming: [3.1, 8, 8.2, 9, 9.1, 14.2, 15, 15.2, 20.8, 20.22, 21.1, 23, 23], 213 category: 'korean' 214 }, 215 { 216 id: 'korean_wink', 217 name: 'Wink', 218 sound: window.getSoundPath('korean/03_wink.m4a'), 219 emoji: 'ð', 220 shutterTiming: [3.1, 8, 8.1, 8.2, 12.1, 13, 13.2, 17.2, 23.2, 24.1, 25], 221 category: 'korean' 222 }, 223 { 224 id: 'korean_heart', 225 name: 'Heart', 226 sound: window.getSoundPath('korean/04_heart.m4a'), 227 emoji: 'â¥ï¸', 228 shutterTiming: [3.1, 5.1, 5.2, 9.2, 10, 10.2, 11, 14, 14.2, 15, 15.2, 18.1, 19, 19.2, 20], 229 category: 'korean' 230 }, 231 { 232 id: 'no_sound', 233 name: 'é³å£°ãªã', 234 sound: '', 235 emoji: 'ð', 236 shutterTiming: [0], 237 category: 'japanese' 238 }, 239 { 240 id: 'no_sound_english', 241 name: 'No Sound', 242 sound: '', 243 emoji: 'ð', 244 shutterTiming: [0], 245 category: 'english' 246 } 247 , 248 { 249 id: 'no_sound_korean', 250 name: '무ì', 251 sound: '', 252 emoji: 'ð', 253 shutterTiming: [0], 254 category: 'korean' 255 } 256 ], 257 258 // ããã©ã«ãé³å£°è¨å® 259 defaultSound: 'cheese_bandou', 260 261 262 263 // 表æ åæã®åºæºå¤ 264 expression: { 265 baseMouthSize: 5, 266 baseEyeSize: 8, 267 baseEyebrowHeight: 80, 268 baseCheekHeight: 120 269 }, 270 271 // åç管ç 272 photo: { 273 maxPhotos: 999, 274 jpegQuality: 0.95 275 }, 276 277 // 決æ¸è¨å® 278 payment: { 279 // Stripe決æ¸ãã¼ã¸ã®URLï¼ã¦ã¼ã¶ã¼ç»é²ã»èª²éèªå°æã«ä½¿ç¨ï¼ 280 stripeCheckoutUrl: '/registration' 281 } 282}; 283 284// iPhoneç¨ã®è¨å®èª¿æ´ 285window.getIPhoneAdjustedConfig = function() { 286 if (!window.CONFIG.isIPhone) return window.CONFIG; 287 288 return { 289 ...window.CONFIG, 290 expression: { 291 ...window.CONFIG.expression, 292 baseMouthSize: 15, 293 baseEyeSize: 8, 294 baseEyebrowHeight: 80, 295 baseCheekHeight: 120 296 } 297 }; 298}; 299 300// ãã¼ã«ã«ã¹ãã¬ã¼ã¸ããåæè¨èªãé©ç¨ï¼URLããåªå 度ã¯ä½ãï¼ 301(function applyInitialLanguageFromStorage() { 302 try { 303 var saved = localStorage.getItem('sc_language'); 304 if (!saved) return; 305 if (window.CONFIG && window.CONFIG.languages && window.CONFIG.languages[saved]) { 306 window.CONFIG.currentLanguage = saved; 307 } 308 } catch (_) {} 309})(); 310 311// ç°¡æç¿»è¨³è¾æ¸ã¨ãã«ãã¼ 312window.I18N = { 313 japanese: { 314 'confirm.reload_camera': 'ã«ã¡ã©ã®åé¡ã解決ããããããã¼ã¸ããªãã¼ããã¾ããï¼', 315 'confirm.reload_audio': 'é³å£°ã®åé¡ã解決ããããããã¼ã¸ããªãã¼ããã¾ããï¼', 316 'error.camera.default': 'Webã«ã¡ã©ã«ã¢ã¯ã»ã¹ã§ãã¾ãããæ¥ç¶ã権éã確èªãã¦ãã ããã', 317 'error.camera.notAllowed': 'ãã©ã¦ã¶ã®ã«ã¡ã©è¨±å¯ãæå¦ããã¦ãã¾ããè¨å®ãã許å¯ãã¦ãã ããã', 318 'error.camera.notFound': 'ã«ã¡ã©ããã¤ã¹ãè¦ã¤ããã¾ãããæ¥ç¶ãããã¤ã¹è¨å®ã確èªãã¦ãã ããã', 319 'error.camera.notReadable': 'å¥ã®ã¢ããªã§ã«ã¡ã©ã使ç¨ä¸ã®å¯è½æ§ãããã¾ããã¢ããªãéãã¦å試
319è¡ãã¦ãã ããã', 320 'error.audio.default': 'é³å£°ãã¡ã¤ã«ã®èªã¿è¾¼ã¿ã«å¤±æãã¾ããããããã¯ã¼ã¯æ¥ç¶ã確èªãã¦ãã ããã', 321 'error.audio.encoding': 'é³å£°ãã¡ã¤ã«ã®å½¢å¼ããµãã¼ãããã¦ãã¾ããã', 322 'error.audio.network': 'ãããã¯ã¼ã¯ã¨ã©ã¼ãçºçãã¾ãããæ¥ç¶ã確èªãã¦ãã ããã', 323 'logo.removal.confirm': 'ãã´ãé表示ã«ããã«ã¯ææãã©ã³ã¸ã®ç»é²ãå¿ è¦ã§ãã\n\næé: Â¥500 (ç¨è¾¼)\n\nææãã©ã³ã«ã¢ããã°ã¬ã¼ããã¾ããï¼', 324 'upgrade.confirm': 'ææãã©ã³ã«ã¢ããã°ã¬ã¼ããã¾ããï¼\n\næé: Â¥500 (ç¨è¾¼)\nç¹å ¸: ãã´é表示æ©è½ãå©ç¨ã§ãã¾ã\n\nç»é²ãã¼ã¸ã«ç§»åãã¾ãã', 325 'plan.paid': 'ææãã©ã³', 326 'plan.free': 'ç¡æãã©ã³', 327 'plan.paid.desc': 'ãã¹ã¦ã®æ©è½ããå©ç¨ããã ãã¾ã', 328 'plan.free.desc': 'åºæ¬çãªæ©è½ããå©ç¨ããã ãã¾ã', 329 'feature.available': 'å©ç¨å¯è½', 330 'feature.paid_only': 'ææãã©ã³éå®', 331 // UI translations 332 'i18n.banner.title': 'ææãã©ã³ã§ãã´é表示ã«ã§ãã¾ã', 333 'i18n.banner.subtitle': 'Â¥500(ç¨è¾¼) ã§æ®å½±ä¸ã»æ®å½±ç»åã®ãã´ãåé¤', 334 'i18n.logo.label': 'ãã´ã表示ãã', 335 'i18n.logo.desc': 'æ®å½±ä¸ã®ç»é¢ã¨æ®å½±ããç»åã®å·¦ä¸ã«SmileCapãã´ã表示ãã¾ã', 336 'i18n.countdown.label': 'ã«ã¦ã³ããã¦ã³ã表示ãã', 337 'i18n.countdown.desc': 'æ®å½±æã«5ç§ã®ã«ã¦ã³ããã¦ã³ã表示ãã¾ã', 338 'i18n.startup.title': 'å±±ä¸å¹¸è¼ããã®ãã声ã§åçãæ®ãã!', 339 'i18n.startup.p1': '1. é³å£°ãONã«ãã¦ãã ããã', 340 'i18n.startup.p2': '2. ããã¼ã¢ã¼ããOFFã«ãã¦ãã ããã', 341 'i18n.startup.p3': '3. è¨å®ã§ãã声ã鏿ã§ãã¾ãã', 342 'i18n.startup.p4': 'ããã§ã¯ã楽ãã¿ãã ãã!', 343 'i18n.startup.start': 'START', 344 'i18n.voiceAlert.japanese': 'ãã®é³å£°ã¯å±±ä¸å¹¸è¼ããã®é³å£°ã§ã¯ããã¾ãã', 345 'i18n.upgrade.title': 'ðææãã©ã³ã«åãæ¿ããã¾ãã', 346 'i18n.upgrade.p1': 'SmileCapãã¬ãã¢ã ãã©ã³ã¸ã®ã¢ããã°ã¬ã¼ããå®äºãã¾ããã', 347 'i18n.upgrade.p2': 'ãã´ãé表示ã«ãã¾ããï¼', 348 'i18n.upgrade.hideLogo': 'ãã´ãé表示ã«ãã', 349 'i18n.upgrade.keepLater': 'å¾ã§è¨å®ãã', 350 'i18n.cameraError.title': 'ð·ã«ã¡ã©ãè¦ã¤ããã¾ãã', 351 'i18n.audioError.title': 'ðé³å£°ãèªã¿è¾¼ãã¾ãã', 352 'i18n.common.retry': 'å試è¡', 353 'i18n.common.close': 'éãã', 354 'i18n.gallery.title': 'æ®å½±ããåç', 355 'i18n.gallery.multi': 'check_box', 356 'i18n.gallery.save': '鏿ããåçãä¿å', 357 'i18n.gallery.delete': 'delete', 358 'i18n.category.coki': 'ðµ CO-KI', 359 'i18n.category.pawticket': 'ð« PawTicket', 360 'i18n.category.shokuji': 'ð½ï¸ Shokuji', 361 'i18n.category.japanese': 'ð¯ðµ JP', 362 'i18n.category.english': 'ðºð¸ EN', 363 'i18n.category.korean': 'ð°ð· KR', 364 // Logo removal dialog 365 'i18n.logoRemoval.message': 'ãã´ãé表示ã«ããã«ã¯ææãã©ã³ã¸ã®ç»é²ãå¿ è¦ã§ã', 366 'i18n.logoRemoval.priceNote': '(ç¨è¾¼)', 367 'i18n.logoRemoval.description': 'ææãã©ã³ã§ã¯ãæ®å½±ããç»åããSmileCapãã´ãåé¤ã§ãã¾ãã', 368 'i18n.logoRemoval.cancel': 'ãã£ã³ã»ã«', 369 'i18n.logoRemoval.confirm': 'ææãã©ã³ã«ã¢ããã°ã¬ã¼ã' 370 }, 371 english: { 372 'confirm.reload_camera': 'Reload the page to resolve the camera issue?', 373 'confirm.reload_audio': 'Reload the page to resolve the audio issue?', 374 'error.camera.default': 'Cannot access the webcam. Check connection and permissions.', 375 'error.camera.notAllowed': 'Camera permission is denied. Please allow it in your browser settings.', 376 'error.camera.notFound': 'No camera device found. Check the connection and device settings.', 377 'error.camera.notReadable': 'Camera may be in use by another app. Close it and try again.', 378 'error.audio.default': 'Failed to load audio. Please check your network connection.', 379 'error.audio.encoding': 'The audio format is not supported.', 380 'error.audio.network': 'A network error occurred. Please check your connection.', 381 'logo.removal.confirm': 'Hiding the logo requires a paid plan.\n\nPrice: Â¥500 (tax included)\n\nWould you like to upgrade now?', 382 'upgrade.confirm': 'Upgrade to the paid plan?\n\nPrice: Â¥500 (tax included)\nBenefit: Hide logo feature\n\nYou will be redirected to the registration page.', 383 'plan.paid': 'Paid Plan', 384 'plan.free': 'Free Plan', 385 'plan.paid.desc': 'All features are available.', 386 'plan.free.desc': 'Basic features are available.', 387 'feature.available': 'Available', 388 'feature.paid_only': 'Paid plan only', 389 // UI translations 390 'i18n.banner.title': 'Hide logo with Paid Plan', 391 'i18n.banner.subtitle': 'Remove logo from live view and photos for Â¥500', 392 'i18n.logo.label': 'Show logo', 393 'i18n.logo.desc': 'Show SmileCap logo at bottom-left on live view and photos.', 394 'i18n.countdown.label': 'Show countdown', 395 'i18n.countdown.desc': 'Show a 5-second countdown when shooting.', 396 'i18n.startup.title': 'Take photos with Yukiteru Yamashita\'s voice prompts!', 397 'i18n.startup.p1': '1. Please turn sound ON (audio will play).', 398 'i18n.startup.p2': '2. Please turn Silent Mode OFF.', 399 'i18n.startup.p3': '3. You can select voice prompts in Settings.', 400 'i18n.startup.p4': 'Enjoy!', 401 'i18n.startup.start': 'START', 402 'i18n.voiceAlert.english': 'This voice is not by Yukiteru Yamashita.', 403 'i18n.upgrade.title': 'ðUpgraded to Paid Plan', 404 'i18n.upgrade.p1': 'Your SmileCap Premium upgrade is complete.', 405 'i18n.upgrade.p2': 'Hide the logo now?', 406 'i18n.upgrade.hideLogo': 'Hide logo', 407 'i18n.upgrade.keepLater': 'Decide later', 408 'i18n.cameraError.title': 'ð·Camera not found', 409 'i18n.audioError.title': 'ðAudio cannot be loaded', 410 'i18n.common.retry': 'Retry', 411 'i18n.common.close': 'Close', 412 'i18n.gallery.title': 'Captured Photos', 413 'i18n.gallery.multi': 'check_box', 414 'i18n.gallery.save': 'Save selected photos', 415 'i18n.gallery.delete': 'delete', 416 'i18n.category.coki': 'ðµ CO-KI', 417 'i18n.category.pawticket': 'ð« PawTicket', 418 'i18n.category.shokuji': 'ð½ï¸ Shokuji', 419 'i18n.category.japanese': 'ð¯ðµ JP', 420 'i18n.category.english': 'ðºð¸ EN', 421 'i18n.category.korean': 'ð°ð· KR', 422 // Logo removal dialog 423 'i18n.logoRemoval.message': 'Hiding the logo requires a paid plan', 424 'i18n.logoRemoval.priceNote': '(tax included)', 425 'i18n.logoRemoval.description': 'With the paid plan, you can remove the SmileCap logo from captured photos.', 426 'i18n.logoRemoval.cancel': 'Cancel', 427 'i18n.logoRemoval.confirm': 'Upgrade to Paid Plan' 428 }, 429 spanish: { 430 'confirm.reload_camera': '¿Recargar la página para resolver el problema de la cámara?', 431 'confirm.reload_audio': '¿Recargar la página para resolver el problema de audio?', 432 'error.camera.default': 'No se puede acceder a la cámara. Verifique la conexión y permisos.',
433 'error.camera.notAllowed': 'Permiso de cámara denegado. PermÃtalo en la configuración del navegador.', 434 'error.camera.notFound': 'No se encontró cámara. Verifique la conexión y la configuración del dispositivo.', 435 'error.camera.notReadable': 'La cámara puede estar en uso por otra aplicación. Ciérrela e inténtelo de nuevo.', 436 'error.audio.default': 'Error al cargar el audio. Verifique su conexión a internet.', 437 'error.audio.encoding': 'Formato de audio no compatible.', 438 'error.audio.network': 'Se produjo un error de red. Verifique su conexión.', 439 'logo.removal.confirm': 'Ocultar el logotipo requiere un plan de pago.\n\nPrecio: Â¥500 (impuestos incluidos)\n\n¿Desea actualizar ahora?', 440 'upgrade.confirm': '¿Actualizar al plan de pago?\n\nPrecio: Â¥500 (impuestos incluidos)\nBeneficio: función para ocultar el logotipo\n\nSerá redirigido a la página de registro.', 441 'plan.paid': 'Plan de pago', 442 'plan.free': 'Plan gratuito', 443 'plan.paid.desc': 'Todas las funciones disponibles.', 444 'plan.free.desc': 'Funciones básicas disponibles.', 445 'feature.available': 'Disponible', 446 'feature.paid_only': 'Solo plan de pago', 447 // UI translations 448 'i18n.banner.title': 'Oculta el logo con el plan de pago', 449 'i18n.banner.subtitle': 'Elimina el logo de la vista y fotos por Â¥500', 450 'i18n.logo.label': 'Mostrar logo', 451 'i18n.logo.desc': 'Mostrar el logo de SmileCap en la esquina inferior izquierda.', 452 'i18n.countdown.label': 'Mostrar cuenta regresiva', 453 'i18n.countdown.desc': 'Mostrar cuenta regresiva de 5 segundos al disparar.', 454 'i18n.startup.title': 'ðµDisfruta con el sonido activado', 455 'i18n.startup.p1': 'Sonidos divertidos durante la toma.', 456 'i18n.startup.p2': 'Para una mejor experiencia, activa el sonido.', 457 'i18n.startup.start': 'INICIAR', 458 'i18n.upgrade.title': 'ðActualizado al plan de pago', 459 'i18n.upgrade.p1': 'La actualización a SmileCap Premium se ha completado.',
460 'i18n.upgrade.p2': '¿Ocultar el logo ahora?', 461 'i18n.upgrade.hideLogo': 'Ocultar logo', 462 'i18n.upgrade.keepLater': 'Decidir después', 463 'i18n.cameraError.title': 'ð·Cámara no encontrada', 464 'i18n.audioError.title': 'ðNo se puede cargar el audio', 465 'i18n.common.retry': 'Reintentar', 466 'i18n.common.close': 'Cerrar', 467 'i18n.gallery.title': 'Fotos capturadas', 468 'i18n.gallery.multi': 'check_box', 469 'i18n.gallery.save': 'Guardar fotos seleccionadas', 470 'i18n.gallery.delete': 'delete', 471 'i18n.category.japanese': 'ð¯ðµ JP', 472 'i18n.category.english': 'ðºð¸ EN', 473 'i18n.category.korean': 'ð°ð· KR', 474 // Logo removal dialog 475 'i18n.logoRemoval.message': 'Ocultar el logotipo requiere un plan de pago', 476 'i18n.logoRemoval.priceNote': '(impuestos incluidos)', 477 'i18n.logoRemoval.description': 'Con el plan de pago, puedes eliminar el logo de SmileCap de las fotos.', 478 'i18n.logoRemoval.cancel': 'Cancelar', 479 'i18n.logoRemoval.confirm': 'Actualizar al plan de pago' 480 }, 481 korean: { 482 'confirm.reload_camera': 'ì¹´ë©ë¼ 문ì 를 í´ê²°í기 ìí´ íì´ì§ë¥¼ ìë¡ê³ 침íìê² ìµëê¹?', 483 'confirm.reload_audio': 'ì¤ëì¤ ë¬¸ì 를 í´ê²°í기 ìí´ íì´ì§ë¥¼ ìë¡ê³ 침íìê² ìµëê¹?', 484 'error.camera.default': 'ì¹ìº ì ì ê·¼í ì ììµëë¤. ì°ê²°ê³¼ ê¶íì íì¸íì¸ì.', 485 'error.camera.notAllowed': 'ì¹´ë©ë¼ ê¶íì´ ê±°ë¶ëììµëë¤. ë¸ë¼ì°ì ì¤ì ìì íì©íì¸ì.', 486 'error.camera.notFound': 'ì¹´ë©ë¼ ì¥ì¹ë¥¼ ì°¾ì ì ììµëë¤. ì°ê²°ê³¼ ì¥ì¹ ì¤ì ì íì¸íì¸ì.', 487 'error.camera.notReadable': 'ë¤ë¥¸ ì±ìì ì¹´ë©ë¼ë¥¼ ì¬ì© ì¤ì¼ ì ììµëë¤. ì¢ ë£ í ë¤ì ìëíì¸ì.', 488 'error.audio.default': 'ì¤ëì¤ë¥¼ ë¶ë¬ì¤ì§ 못íìµëë¤. ë¤í¸ìí¬ ì°ê²°ì íì¸íì¸ì.', 489 'error.audio.encoding': 'ì§ìëì§ ìë ì¤ëì¤ íìì ëë¤.', 490 'error.audio.network': 'ë¤í¸ìí¬ ì¤ë¥ê° ë°ìíìµëë¤. ì°ê²°ì íì¸íì¸ì.', 491 'logo.removal.confirm': 'ë¡ê³ 를 ì¨ê¸°ë ¤ë©´ ì ë£ íëì´ íìí©ëë¤.\n\nê°ê²©: Â¥500 (ì¸ê¸ í¬í¨)\n\nì§ê¸ ì ê·¸ë ì´ëíìê² ìµëê¹?', 492 'upgrade.confirm': 'ì ë£ íëì¼ë¡ ì ê·¸ë ì´ëíìê² ìµëê¹?\n\nê°ê²©: Â¥500 (ì¸ê¸ í¬í¨)\níí: ë¡ê³ ì¨ê¹ 기ë¥\n\në±ë¡ íì´ì§ë¡ ì´ëí©ëë¤.', 493 'plan.paid': 'ì ë£ íë', 494 'plan.free': 'ë¬´ë£ íë', 495 'plan.paid.desc': '모ë 기ë¥ì ì¬ì©í ì ììµëë¤.', 496 'plan.free.desc': '기본 기ë¥ì ì¬ì©í ì ììµëë¤.', 497 'feature.available': 'ì´ì© ê°ë¥', 498 'feature.paid_only': 'ì ë£ íë ì ì©', 499 // UI translations 500 'i18n.banner.title': 'ì ë£ íëì¼ë¡ ë¡ê³ ì¨ê¸°ê¸°', 501 'i18n.banner.subtitle': 'ë¼ì´ë¸/ì¬ì§ìì ë¡ê³ ì ê±° (Â¥500)', 502 'i18n.logo.label': 'ë¡ê³ íì', 503 'i18n.logo.desc': 'ë¼ì´ë¸ íë©´ê³¼ ì¬ì§ ì¼ìª½ íë¨ì ë¡ê³ 를 íìí©ëë¤.', 504 'i18n.countdown.label': 'ì¹´ì´í¸ë¤ì´ íì', 505 'i18n.countdown.desc': 'ì´¬ì ì 5ì´ ì¹´ì´í¸ë¤ì´ì íìí©ëë¤.', 506 'i18n.startup.title': 'ðµì¬ì´ë를 ì¼ê³ ì¦ê¸°ì¸ì', 507 'i18n.startup.p1': 'ì´¬ì ì ì¬ë¯¸ìë ì¬ì´ëê° ì¬ìë©ëë¤.', 508 'i18n.startup.p2': 'ë ëì ê²½íì ìí´ ì¬ì´ë를 ì¼ ì£¼ì¸ì.', 509 'i18n.startup.start': 'ìì', 510 'i18n.upgrade.title': 'ðì ë£ íëì¼ë¡ ì ê·¸ë ì´ëë¨', 511 'i18n.upgrade.p1': 'SmileCap í리미ì ì ê·¸ë ì´ëê° ìë£ëììµëë¤.', 512 'i18n.upgrade.p2': 'ì§ê¸ ë¡ê³ 를 ì¨ê¸¸ê¹ì?', 513 'i18n.upgrade.hideLogo': 'ë¡ê³ ì¨ê¸°ê¸°', 514 'i18n.upgrade.keepLater': 'ëì¤ì ê²°ì ', 515 'i18n.cameraError.title': 'ð·ì¹´ë©ë¼ë¥¼ ì°¾ì ì ììµëë¤', 516 'i18n.audioError.title': 'ðì¤ëì¤ë¥¼ ë¶ë¬ì¬ ì ììµëë¤', 517 'i18n.common.retry': 'ë¤ì ìë', 518 'i18n.common.close': 'ë«ê¸°', 519 'i18n.gallery.title': 'ì´¬ìí ì¬ì§', 520 'i18n.gallery.multi': 'check_box', 521 'i18n.gallery.save': 'ì íí ì¬ì§ ì ì¥', 522 'i18n.gallery.delete': 'delete', 523 'i18n.category.japanese': 'ð¯ðµ JP', 524 'i18n.category.english': 'ðºð¸ EN', 525 'i18n.category.korean': 'ð°ð· KR', 526 // Logo removal dialog 527 'i18n.logoRemoval.message': 'ë¡ê³ 를 ì¨ê¸°ë ¤ë©´ ì ë£ íëì´ íìí©ëë¤', 528 'i18n.logoRemoval.priceNote': '(ì¸ê¸ í¬í¨)', 529 'i18n.logoRemoval.description': 'ì ë£ íëììë ì´¬ìí ì¬ì§ìì SmileCap ë¡ê³ 를 ì ê±°í ì ììµëë¤.', 530 'i18n.logoRemoval.cancel': 'ì·¨ì', 531 'i18n.logoRemoval.confirm': 'ì ë£ íëì¼ë¡ ì ê·¸ë ì´ë' 532 } 533}; 534 535window.t = function(key) { 536 try { 537 var langKey = window.getCurrentLanguage ? window.getCurrentLanguage() : 'japanese'; 538 var dict = window.I18N[langKey] || window.I18N.japanese; 539 return (dict && dict[key]) || (window.I18N.japanese[key] || key); 540 } catch (_) { 541 return key; 542 } 543}; 544 545// URLãã©ã¡ã¼ã¿ããåæè¨èªãé©ç¨ 546(function applyInitialLanguageFromQuery() { 547 try { 548 var params = new URLSearchParams(window.location.search || ''); 549 // la ã¾ã㯠lang ããµãã¼ã 550 var raw = params.get('la') || params.get('lang'); 551 if (!raw) return; 552 553 // æ£è¦åï¼å°æåï¼ 554 var code = String(raw).trim().toLowerCase(); 555 556 // è¨èªã³ã¼ã/ãã¼ã®ãããã³ã°
557 // 許å¯ã³ã¼ã: ja, en, es, cn(=zh), kr(=ko) 558 var codeToKey = { 559 'ja': 'japanese', 560 'en': 'english', 561 'es': 'spanish', 562 'cn': 'japanese', // ããã©ã«ã: ä¸å½èªæªå®è£ ã®ããæ¥æ¬èªã«ãã©ã¼ã«ãã㯠563 'zh': 'japanese', // åä¸ 564 'kr': 'korean', 565 'ko': 'korean' 566 }; 567 568 // ç´æ¥ãã¼æå®ã«ã対å¿ï¼japanese/english/spanish/koreanï¼ 569 var directKeys = ['japanese', 'english', 'spanish', 'korean']; 570 571 var targetKey = null; 572 if (codeToKey[code]) { 573 targetKey = codeToKey[code]; 574 } else if (directKeys.indexOf(code) !== -1) { 575 targetKey = code; 576 } 577 578 if (targetKey && window.CONFIG.languages[targetKey]) { 579 window.CONFIG.currentLanguage = targetKey; 580 try { localStorage.setItem('sc_language', targetKey); } catch (_) {} 581 // ãããããã¦ã³ãåå¨ããå ´åã¯åæï¼å¾æ®µã®DOMèªã¿è¾¼ã¿å¾ã§ãå¹ãããé å»¶ï¼ 582 setTimeout(function() { 583 try { 584 var select = document.getElementById('languageSelect'); 585 if (select) select.value = targetKey; 586 // é³å£°ã«ã¼ãã®åçæãä¿ãã¤ãã³ãï¼åå¨ããã°ï¼ 587 if (window.faceLandmarksApp && typeof window.faceLandmarksApp.updateSoundOptionsDisplay === 'function') { 588 window.faceLandmarksApp.updateSoundOptionsDisplay(); 589 } 590 } catch (e) {} 591 }, 0); 592 } 593 } catch (e) { 594 // 失ææã¯é»ã£ã¦ã¹ããã 595 } 596})(); 597 598// è¨èªè¨å®ãåå¾ãã颿° 599window.getLanguages = function() { 600 return window.CONFIG.languages; 601} 602 603// ç¾å¨ã®è¨èªãåå¾ãã颿° 604window.getCurrentLanguage = function() { 605 return window.CONFIG.currentLanguage; 606} 607 608// è¨èªãè¨å®ãã颿° 609window.setCurrentLanguage = function(language) { 610 if (window.CONFIG.languages[language]) { 611 window.CONFIG.currentLanguage = language; 612 try { localStorage.setItem('sc_language', language); } catch (_) {} 613 return true; 614 } 615 return false; 616} 617 618// é³å£°ãªãã·ã§ã³ãåå¾ãã颿° 619window.getSoundOptions = function() { 620 // ããã¸ã§ã¯ãè¨å®ã®soundOptionsããã§ã㯠621 if (typeof window.ProjectConfigManager !== 'undefined') { 622 const projectSoundOptions = window.ProjectConfigManager.get('soundOptions'); 623 if (projectSoundOptions && projectSoundOptions.length > 0) { 624 // ããã¸ã§ã¯ãè¨å®ã®é³å£°ãã¹ãå®å ¨ãªãã¹ã«å¤æ 625 const processedProjectSounds = projectSoundOptions.map(option => { 626 if (!option.sound) return option; 627 628 // æ¢ã«å®å ¨URLã®å ´åã¯ãã®ã¾ã¾ 629 if (option.sound.startsWith('http')) { 630 return option; 631 } 632 633 // /assets/ã§å§ã¾ããã¹ã¯templateDirectoryUriãä»ä¸ 634 if (option.sound.startsWith('/assets/')) { 635 const templateUri = window.templateDirectoryUri || getTemplateDirectoryUri(); 636 if (templateUri) { 637 return { 638 ...option, 639 sound: templateUri + option.sound 640 }; 641 } 642 } 643 644 // ç¸å¯¾ãã¹ã®å ´åã¯getSoundPathã§å¦ç 645 if (!option.sound.includes('/assets/sound/')) { 646 return { 647 ...option, 648 sound: window.getSoundPath(option.sound) 649 }; 650 } 651 652 // ãã®ä»ã®å ´åã¯ãã®ã¾ã¾ 653 return option; 654 }); 655 656 console.log('ð¢ ããã¸ã§ã¯ãé³å£°ãªãã·ã§ã³:', processedProjectSounds.map(o => ({ id: o.id, sound: o.sound, category: o.category }))); 657 658 // ããã¸ã§ã¯ãè¨å®ã®soundOptionsã¨ããã©ã«ãã®soundOptionsããã¼ã¸ 659 const mergedSounds = [...processedProjectSounds, ...window.CONFIG.soundOptions]; 660 661 // ããã¸ã§ã¯ãè¨å®ã®ã«ãã´ãªã©ãã«ã翻訳ã«è¿½å 662 const projectConfig = window.ProjectConfigManager.getCurrentConfig(); 663 if (projectConfig && projectConfig.soundCategory) { 664 const categoryId = projectConfig.soundCategory.id; 665 const labels = projectConfig.soundCategory.label; 666 667 // æ¥æ¬èªã¨è±èªã®ç¿»è¨³ã«è¿½å 668 if (window.CONFIG.languages.japanese) {
669 window.CONFIG.languages.japanese[`i18n.category.${categoryId}`] = labels.japanese || labels.english; 670 } 671 if (window.CONFIG.languages.english) { 672 window.CONFIG.languages.english[`i18n.category.${categoryId}`] = labels.english || labels.japanese; 673 } 674 } 675 676 return mergedSounds; 677 } 678 } 679 return window.CONFIG.soundOptions; 680} 681 682// ããã©ã«ãé³å£°ãåå¾ãã颿° 683window.getDefaultSound = function() { 684 // ããã¸ã§ã¯ãè¨å®ã®ããã©ã«ãé³å£°ããã§ã㯠685 if (typeof window.ProjectConfigManager !== 'undefined') { 686 const projectDefaultSound = window.ProjectConfigManager.get('defaults.selectedSound'); 687 if (projectDefaultSound) { 688 return projectDefaultSound; 689 } 690 } 691 return window.CONFIG.defaultSound; 692} 693 694// é³å£°IDããé³å£°è¨å®ãåå¾ãã颿° 695window.getSoundOptionById = function(id) { 696 const allSoundOptions = window.getSoundOptions(); 697 return allSoundOptions.find(option => option.id === id); 698} 699 700// é³å£°åãåå¾ãã颿° 701window.getSoundName = function(soundOption, language = null) { 702 return soundOption.name || soundOption.id; 703} 704 705 706// é³å£°ãªãã·ã§ã³ã®HTMLãçæãã颿° 707window.generateSoundOptionsHTML = function(language = null) { 708 const soundOptions = window.getSoundOptions(); 709 const defaultSound = window.getDefaultSound(); 710 const currentLang = language || window.getCurrentLanguage(); 711 712 return soundOptions.map(option => { 713 const isSelected = option.id === defaultSound; 714 const selectedClass = isSelected ? 'selected' : ''; 715 const soundName = window.getSoundName(option, currentLang); 716 717 return ` 718 <div class="sound-option ${selectedClass}" 719 data-sound-id="${option.id}" 720 data-sound="${option.sound}" 721 data-shutter-timing="${option.shutterTiming ? option.shutterTiming.join(',') : '0'}"> 722 <div class="sound-image"> 723 <span style="font-size: 60px;">${option.emoji}</span> 724 </div> 725 <span class="sound-name">${soundName}</span> 726 </div> 727 `; 728 }).join(''); 729} 730 731 732 733 734 735
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.