diff --git a/.eslintcache b/.eslintcache index 5bb6b65..645bc4a 100644 --- a/.eslintcache +++ b/.eslintcache @@ -1 +1 @@ -[{"E:\\Document\\Coding\\SecScore\\eslint.config.mjs":"1","E:\\Document\\Coding\\SecScore\\src\\App.tsx":"2","E:\\Document\\Coding\\SecScore\\src\\ClientContext.ts":"3","E:\\Document\\Coding\\SecScore\\src\\components\\BoardManager.tsx":"4","E:\\Document\\Coding\\SecScore\\src\\components\\ContentArea.tsx":"5","E:\\Document\\Coding\\SecScore\\src\\components\\EventHistory.tsx":"6","E:\\Document\\Coding\\SecScore\\src\\components\\Home.tsx":"7","E:\\Document\\Coding\\SecScore\\src\\components\\Leaderboard.tsx":"8","E:\\Document\\Coding\\SecScore\\src\\components\\OOBE\\OOBE.tsx":"9","E:\\Document\\Coding\\SecScore\\src\\components\\OOBE\\OOBEBackground.tsx":"10","E:\\Document\\Coding\\SecScore\\src\\components\\ReasonManager.tsx":"11","E:\\Document\\Coding\\SecScore\\src\\components\\RewardExchange.tsx":"12","E:\\Document\\Coding\\SecScore\\src\\components\\RewardSettings.tsx":"13","E:\\Document\\Coding\\SecScore\\src\\components\\ScoreManager.tsx":"14","E:\\Document\\Coding\\SecScore\\src\\components\\Settings.tsx":"15","E:\\Document\\Coding\\SecScore\\src\\components\\SettlementHistory.tsx":"16","E:\\Document\\Coding\\SecScore\\src\\components\\Sidebar.tsx":"17","E:\\Document\\Coding\\SecScore\\src\\components\\StudentManager.tsx":"18","E:\\Document\\Coding\\SecScore\\src\\components\\TagEditorDialog.tsx":"19","E:\\Document\\Coding\\SecScore\\src\\components\\ThemeEditor.tsx":"20","E:\\Document\\Coding\\SecScore\\src\\components\\ThemeQuickSettings.tsx":"21","E:\\Document\\Coding\\SecScore\\src\\components\\TitleBar.tsx":"22","E:\\Document\\Coding\\SecScore\\src\\components\\Versions.tsx":"23","E:\\Document\\Coding\\SecScore\\src\\components\\WindowControls.tsx":"24","E:\\Document\\Coding\\SecScore\\src\\components\\Wizard.tsx":"25","E:\\Document\\Coding\\SecScore\\src\\contexts\\ServiceContext.tsx":"26","E:\\Document\\Coding\\SecScore\\src\\contexts\\ThemeContext.tsx":"27","E:\\Document\\Coding\\SecScore\\src\\contexts\\ThemeEditorContext.tsx":"28","E:\\Document\\Coding\\SecScore\\src\\env.d.ts":"29","E:\\Document\\Coding\\SecScore\\src\\hooks\\useResponsive.ts":"30","E:\\Document\\Coding\\SecScore\\src\\i18n\\index.ts":"31","E:\\Document\\Coding\\SecScore\\src\\main.tsx":"32","E:\\Document\\Coding\\SecScore\\src\\preload\\types.ts":"33","E:\\Document\\Coding\\SecScore\\src\\react-19-patch.ts":"34","E:\\Document\\Coding\\SecScore\\src\\services\\StudentService.ts":"35","E:\\Document\\Coding\\SecScore\\src\\shared\\kernel.ts":"36","E:\\Document\\Coding\\SecScore\\src\\shared\\mobileNavigation.ts":"37","E:\\Document\\Coding\\SecScore\\src\\utils\\color.ts":"38","E:\\Document\\Coding\\SecScore\\src\\utils\\studentAvatar.ts":"39","E:\\Document\\Coding\\SecScore\\src\\workers\\xlsxWorker.ts":"40","E:\\Document\\Coding\\SecScore\\vite.config.ts":"41","E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\ActionEditor.tsx":"42","E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\AutoScoreUtils.ts":"43","E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\IntervalValueCodec.ts":"44","E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\IntervalValueWidget.tsx":"45","E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\TriggerRuleBuilder.tsx":"46","E:\\Document\\Coding\\SecScore\\src\\components\\AutoScoreManager.tsx":"47","E:\\Document\\Coding\\SecScore\\src\\components\\OAuth\\OAuthCallback.tsx":"48","E:\\Document\\Coding\\SecScore\\src\\components\\OAuth\\OAuthLogin.tsx":"49","E:\\Document\\Coding\\SecScore\\src\\components\\SectlCloudStorageManager.tsx":"50","E:\\Document\\Coding\\SecScore\\src\\components\\SectlLoginButton.tsx":"51","E:\\Document\\Coding\\SecScore\\src\\components\\SectlSettingsPanel.tsx":"52","E:\\Document\\Coding\\SecScore\\src\\contexts\\SectlContext.tsx":"53","E:\\Document\\Coding\\SecScore\\src\\services\\sectl.ts":"54","E:\\Document\\Coding\\SecScore\\src\\services\\sectlAuth.ts":"55","E:\\Document\\Coding\\SecScore\\src\\services\\sectlCloudStorage.ts":"56","E:\\Document\\Coding\\SecScore\\src\\services\\sectlKVStorage.ts":"57","E:\\Document\\Coding\\SecScore\\src\\services\\sectlNotification.ts":"58","E:\\Document\\Coding\\SecScore\\src\\views\\SectlCloudView.tsx":"59","E:\\Document\\Coding\\SecScore\\src\\components\\ScoreSyncPanel.tsx":"60","E:\\Document\\Coding\\SecScore\\src\\services\\scoreSyncService.ts":"61"},{"size":1413,"mtime":1774084765386,"results":"62","hashOfConfig":"63"},{"size":39361,"mtime":1775381637091,"results":"64","hashOfConfig":"65"},{"size":124,"mtime":1774084765537,"results":"66","hashOfConfig":"65"},{"size":47714,"mtime":1774704827018,"results":"67","hashOfConfig":"65"},{"size":12989,"mtime":1774784139058,"results":"68","hashOfConfig":"65"},{"size":2044,"mtime":1774084765557,"results":"69","hashOfConfig":"65"},{"size":90881,"mtime":1774704827750,"results":"70","hashOfConfig":"65"},{"size":8101,"mtime":1774084765561,"results":"71","hashOfConfig":"65"},{"size":36271,"mtime":1774176288912,"results":"72","hashOfConfig":"65"},{"size":4203,"mtime":1774084765566,"results":"73","hashOfConfig":"65"},{"size":5983,"mtime":1774084765569,"results":"74","hashOfConfig":"65"},{"size":9360,"mtime":1774084765571,"results":"75","hashOfConfig":"65"},{"size":6151,"mtime":1774084765572,"results":"76","hashOfConfig":"65"},{"size":12301,"mtime":1774084765573,"results":"77","hashOfConfig":"65"},{"size":61661,"mtime":1775381637096,"results":"78","hashOfConfig":"65"},{"size":5950,"mtime":1774084765578,"results":"79","hashOfConfig":"65"},{"size":10480,"mtime":1774784139062,"results":"80","hashOfConfig":"65"},{"size":79058,"mtime":1774704830361,"results":"81","hashOfConfig":"65"},{"size":6331,"mtime":1774084765584,"results":"82","hashOfConfig":"65"},{"size":8079,"mtime":1774084765586,"results":"83","hashOfConfig":"65"},{"size":10954,"mtime":1774084765587,"results":"84","hashOfConfig":"65"},{"size":3858,"mtime":1774084765589,"results":"85","hashOfConfig":"65"},{"size":431,"mtime":1774084765590,"results":"86","hashOfConfig":"65"},{"size":2367,"mtime":1774084765592,"results":"87","hashOfConfig":"65"},{"size":1560,"mtime":1774084765594,"results":"88","hashOfConfig":"65"},{"size":362,"mtime":1774084765604,"results":"89","hashOfConfig":"65"},{"size":5985,"mtime":1774084765606,"results":"90","hashOfConfig":"65"},{"size":2824,"mtime":1774084765608,"results":"91","hashOfConfig":"65"},{"size":38,"mtime":1774084765611,"results":"92","hashOfConfig":"65"},{"size":2097,"mtime":1774084765613,"results":"93","hashOfConfig":"65"},{"size":1533,"mtime":1774084765616,"results":"94","hashOfConfig":"65"},{"size":6919,"mtime":1774704831300,"results":"95","hashOfConfig":"65"},{"size":21171,"mtime":1775381637100,"results":"96","hashOfConfig":"65"},{"size":1150,"mtime":1774084765630,"results":"97","hashOfConfig":"65"},{"size":667,"mtime":1774084765638,"results":"98","hashOfConfig":"65"},{"size":3061,"mtime":1774176077013,"results":"99","hashOfConfig":"65"},{"size":1810,"mtime":1774784139078,"results":"100","hashOfConfig":"65"},{"size":3256,"mtime":1774084765655,"results":"101","hashOfConfig":"65"},{"size":1115,"mtime":1774084765658,"results":"102","hashOfConfig":"65"},{"size":947,"mtime":1774084765660,"results":"103","hashOfConfig":"65"},{"size":709,"mtime":1774665241507,"results":"104","hashOfConfig":"65"},{"size":4473,"mtime":1775279880382,"results":"105","hashOfConfig":"65"},{"size":11159,"mtime":1775279880492,"results":"106","hashOfConfig":"65"},{"size":2126,"mtime":1775224756075,"results":"107","hashOfConfig":"65"},{"size":3055,"mtime":1775224756077,"results":"108","hashOfConfig":"65"},{"size":1749,"mtime":1775279880567,"results":"109","hashOfConfig":"65"},{"size":13679,"mtime":1775279880826,"results":"110","hashOfConfig":"65"},{"size":1047,"mtime":1775224756086,"results":"111","hashOfConfig":"65"},{"size":7055,"mtime":1775382856947,"results":"112","hashOfConfig":"65"},{"size":8410,"mtime":1775383418692,"results":"113","hashOfConfig":"65"},{"size":1661,"mtime":1775382857634,"results":"114","hashOfConfig":"65"},{"size":4807,"mtime":1775383469000,"results":"115","hashOfConfig":"65"},{"size":3773,"mtime":1775383419736,"results":"116","hashOfConfig":"65"},{"size":683,"mtime":1775383317477,"results":"117","hashOfConfig":"65"},{"size":9500,"mtime":1775383420349,"results":"118","hashOfConfig":"65"},{"size":14984,"mtime":1775382860520,"results":"119","hashOfConfig":"65"},{"size":6315,"mtime":1775382860555,"results":"120","hashOfConfig":"65"},{"size":5437,"mtime":1775382860586,"results":"121","hashOfConfig":"65"},{"size":429,"mtime":1775383291875,"results":"122","hashOfConfig":"65"},{"size":8435,"mtime":1775383536457,"results":"123","hashOfConfig":"65"},{"size":7067,"mtime":1775383420279,"results":"124","hashOfConfig":"65"},{"filePath":"125","messages":"126","suppressedMessages":"127","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"oyxevq",{"filePath":"128","messages":"129","suppressedMessages":"130","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"f6a32r",{"filePath":"131","messages":"132","suppressedMessages":"133","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"134","messages":"135","suppressedMessages":"136","errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"137","messages":"138","suppressedMessages":"139","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"140","messages":"141","suppressedMessages":"142","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"143","messages":"144","suppressedMessages":"145","errorCount":3,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"146","messages":"147","suppressedMessages":"148","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"149","messages":"150","suppressedMessages":"151","errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"152","messages":"153","suppressedMessages":"154","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"155","messages":"156","suppressedMessages":"157","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"158","messages":"159","suppressedMessages":"160","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"161","messages":"162","suppressedMessages":"163","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"164","messages":"165","suppressedMessages":"166","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"167","messages":"168","suppressedMessages":"169","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"170","messages":"171","suppressedMessages":"172","errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"173","messages":"174","suppressedMessages":"175","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"176","messages":"177","suppressedMessages":"178","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"179","messages":"180","suppressedMessages":"181","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"182","messages":"183","suppressedMessages":"184","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"185","messages":"186","suppressedMessages":"187","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"188","messages":"189","suppressedMessages":"190","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"191","messages":"192","suppressedMessages":"193","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"194","messages":"195","suppressedMessages":"196","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"197","messages":"198","suppressedMessages":"199","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"200","messages":"201","suppressedMessages":"202","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"203","messages":"204","suppressedMessages":"205","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"206","messages":"207","suppressedMessages":"208","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"209","messages":"210","suppressedMessages":"211","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"212","messages":"213","suppressedMessages":"214","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"215","messages":"216","suppressedMessages":"217","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"218","messages":"219","suppressedMessages":"220","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"221","messages":"222","suppressedMessages":"223","errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"224","messages":"225","suppressedMessages":"226","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"227","messages":"228","suppressedMessages":"229","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"230","messages":"231","suppressedMessages":"232","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"233","messages":"234","suppressedMessages":"235","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"236","messages":"237","suppressedMessages":"238","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"239","messages":"240","suppressedMessages":"241","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"242","messages":"243","suppressedMessages":"244","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"245","messages":"246","suppressedMessages":"247","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"248","messages":"249","suppressedMessages":"250","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"251","messages":"252","suppressedMessages":"253","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"254","messages":"255","suppressedMessages":"256","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"257","messages":"258","suppressedMessages":"259","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"260","messages":"261","suppressedMessages":"262","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"263","messages":"264","suppressedMessages":"265","errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"266","messages":"267","suppressedMessages":"268","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"269","messages":"270","suppressedMessages":"271","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"272","messages":"273","suppressedMessages":"274","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"275","messages":"276","suppressedMessages":"277","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"278","messages":"279","suppressedMessages":"280","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"281","messages":"282","suppressedMessages":"283","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"284","messages":"285","suppressedMessages":"286","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"287","messages":"288","suppressedMessages":"289","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"290","messages":"291","suppressedMessages":"292","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"293","messages":"294","suppressedMessages":"295","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"296","messages":"297","suppressedMessages":"298","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"299","messages":"300","suppressedMessages":"301","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"302","messages":"303","suppressedMessages":"304","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"305","messages":"306","suppressedMessages":"307","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"E:\\Document\\Coding\\SecScore\\eslint.config.mjs",[],[],"E:\\Document\\Coding\\SecScore\\src\\App.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\ClientContext.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\BoardManager.tsx",["308","309"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ContentArea.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\EventHistory.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Home.tsx",["310","311","312","313","314","315"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Leaderboard.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\OOBE\\OOBE.tsx",["316","317"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\OOBE\\OOBEBackground.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ReasonManager.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\RewardExchange.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\RewardSettings.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ScoreManager.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Settings.tsx",["318"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\SettlementHistory.tsx",["319","320"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Sidebar.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\StudentManager.tsx",["321"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\TagEditorDialog.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ThemeEditor.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ThemeQuickSettings.tsx",["322"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\TitleBar.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Versions.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\WindowControls.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Wizard.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\contexts\\ServiceContext.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\contexts\\ThemeContext.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\contexts\\ThemeEditorContext.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\env.d.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\hooks\\useResponsive.ts",["323"],[],"E:\\Document\\Coding\\SecScore\\src\\i18n\\index.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\main.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\preload\\types.ts",["324"],[],"E:\\Document\\Coding\\SecScore\\src\\react-19-patch.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\services\\StudentService.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\shared\\kernel.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\shared\\mobileNavigation.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\utils\\color.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\utils\\studentAvatar.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\workers\\xlsxWorker.ts",[],[],"E:\\Document\\Coding\\SecScore\\vite.config.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\ActionEditor.tsx",["325"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\AutoScoreUtils.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\IntervalValueCodec.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\IntervalValueWidget.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\TriggerRuleBuilder.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\AutoScoreManager.tsx",["326","327"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\OAuth\\OAuthCallback.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\OAuth\\OAuthLogin.tsx",["328"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\SectlCloudStorageManager.tsx",["329"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\SectlLoginButton.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\SectlSettingsPanel.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\contexts\\SectlContext.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\services\\sectl.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\services\\sectlAuth.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\services\\sectlCloudStorage.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\services\\sectlKVStorage.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\services\\sectlNotification.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\views\\SectlCloudView.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ScoreSyncPanel.tsx",["330"],[],"E:\\Document\\Coding\\SecScore\\src\\services\\scoreSyncService.ts",[],[],{"ruleId":"331","severity":1,"message":"332","line":626,"column":6,"nodeType":"333","endLine":626,"endColumn":44,"suggestions":"334"},{"ruleId":"331","severity":1,"message":"332","line":634,"column":6,"nodeType":"333","endLine":634,"endColumn":59,"suggestions":"335"},{"ruleId":"331","severity":1,"message":"336","line":532,"column":6,"nodeType":"333","endLine":532,"endColumn":76,"suggestions":"337"},{"ruleId":"338","severity":2,"message":"339","line":544,"column":34,"nodeType":null,"endLine":556,"endColumn":4},{"ruleId":"338","severity":2,"message":"339","line":544,"column":34,"nodeType":null,"endLine":556,"endColumn":4},{"ruleId":"331","severity":1,"message":"340","line":556,"column":6,"nodeType":"333","endLine":556,"endColumn":15,"suggestions":"341"},{"ruleId":"338","severity":2,"message":"342","line":1627,"column":5,"nodeType":null,"endLine":1650,"endColumn":6},{"ruleId":"331","severity":1,"message":"343","line":1710,"column":6,"nodeType":"333","endLine":1710,"endColumn":8,"suggestions":"344"},{"ruleId":"331","severity":1,"message":"345","line":160,"column":6,"nodeType":"333","endLine":160,"endColumn":20,"suggestions":"346"},{"ruleId":"331","severity":1,"message":"347","line":334,"column":5,"nodeType":"333","endLine":334,"endColumn":27,"suggestions":"348"},{"ruleId":"331","severity":1,"message":"349","line":380,"column":6,"nodeType":"333","endLine":380,"endColumn":8,"suggestions":"350"},{"ruleId":"331","severity":1,"message":"351","line":54,"column":6,"nodeType":"333","endLine":54,"endColumn":18,"suggestions":"352"},{"ruleId":"331","severity":1,"message":"340","line":106,"column":5,"nodeType":"333","endLine":106,"endColumn":7,"suggestions":"353"},{"ruleId":"331","severity":1,"message":"354","line":1351,"column":6,"nodeType":"333","endLine":1351,"endColumn":50,"suggestions":"355"},{"ruleId":"331","severity":1,"message":"345","line":100,"column":6,"nodeType":"333","endLine":100,"endColumn":20,"suggestions":"356"},{"ruleId":"331","severity":1,"message":"357","line":25,"column":9,"nodeType":"358","endLine":25,"endColumn":70},{"ruleId":"359","severity":2,"message":"360","line":627,"column":38,"nodeType":"361","messageId":"362","endLine":627,"endColumn":43},{"ruleId":"331","severity":1,"message":"363","line":23,"column":9,"nodeType":"358","endLine":23,"endColumn":63},{"ruleId":"331","severity":1,"message":"340","line":74,"column":5,"nodeType":"333","endLine":74,"endColumn":55,"suggestions":"364"},{"ruleId":"331","severity":1,"message":"365","line":157,"column":6,"nodeType":"333","endLine":157,"endColumn":15,"suggestions":"366"},{"ruleId":"331","severity":1,"message":"367","line":149,"column":6,"nodeType":"333","endLine":149,"endColumn":8,"suggestions":"368"},{"ruleId":"331","severity":1,"message":"369","line":79,"column":6,"nodeType":"333","endLine":79,"endColumn":23,"suggestions":"370"},{"ruleId":"331","severity":1,"message":"371","line":79,"column":6,"nodeType":"333","endLine":79,"endColumn":23,"suggestions":"372"},"react-hooks/exhaustive-deps","React Hook useEffect has a missing dependency: 'activeBoard'. Either include it or remove the dependency array.","ArrayExpression",["373"],["374"],"React Hook useMemo has an unnecessary dependency: 'layoutType'. Either exclude it or remove the dependency array.",["375"],"react-hooks/preserve-manual-memoization","Compilation Skipped: Existing memoization could not be preserved\n\nReact Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `t`, but the source dependencies were [reasons]. Inferred different dependency than source.\n\nE:\\Document\\Coding\\SecScore\\src\\components\\Home.tsx:544:34\n 542 | }, [groupedStudents])\n 543 |\n> 544 | const groupedReasons = useMemo(() => {\n | ^^^^^^^\n> 545 | const groups: Record = {}\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 546 | reasons.forEach((r) => {\n …\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 555 | })\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 556 | }, [reasons])\n | ^^^^ Could not preserve existing manual memoization\n 557 |\n 558 | const selectedStudents = useMemo(() => {\n 559 | if (selectedStudentIds.length === 0) return []","React Hook useMemo has a missing dependency: 't'. Either include it or remove the dependency array.",["376"],"Compilation Skipped: Existing memoization could not be preserved\n\nReact Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. This value was memoized in source but not in compilation output.\n\nE:\\Document\\Coding\\SecScore\\src\\components\\Home.tsx:1627:5\n 1625 |\n 1626 | const handleNavAction = useCallback(\n> 1627 | (clientY: number) => {\n | ^^^^^^^^^^^^^^^^^^^^^^\n> 1628 | if (!navContainerRef.current) return\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 1629 | const rect = navContainerRef.current.getBoundingClientRect()\n …\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 1649 | }\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 1650 | },\n | ^^^^^^ Could not preserve existing memoization\n 1651 | [groupedStudents, quickNavLayout.itemSize, quickNavLayout.paddingY, triggerNavHaptic]\n 1652 | )\n 1653 |","React Hook useEffect has missing dependencies: 'onGlobalMouseMove' and 'onGlobalMouseUp'. Either include them or remove the dependency array.",["377"],"React Hook useEffect has a missing dependency: 't'. Either include it or remove the dependency array.",["378"],"React Hook useCallback has missing dependencies: 'showOobeMessage' and 't'. Either include them or remove the dependency array.",["379"],"React Hook useEffect has a missing dependency: 'loadAll'. Either include it or remove the dependency array.",["380"],"React Hook useCallback has a missing dependency: 't'. Either include it or remove the dependency array.",["381"],["382"],"React Hook useMemo has missing dependencies: 'handleDelete', 'handleOpenAvatarEditor', 'handleOpenGroupEditor', and 'handleOpenTagEditor'. Either include them or remove the dependency array.",["383"],["384"],"The 'breakpoints' object makes the dependencies of useEffect Hook (at line 49) change on every render. Move it inside the useEffect callback. Alternatively, wrap the initialization of 'breakpoints' in its own useMemo() Hook.","VariableDeclarator","@typescript-eslint/no-unused-vars","'_args' is defined but never used.","Identifier","unusedVar","The 'safeValue' conditional could make the dependencies of useMemo Hook (at line 58) change on every render. To fix this, wrap the initialization of 'safeValue' in its own useMemo() Hook.",["385"],"React Hook useEffect has missing dependencies: 'fetchRules', 'fetchStudents', and 'fetchTags'. Either include them or remove the dependency array.",["386"],"React Hook useEffect has a missing dependency: 'handleOAuthCallback'. Either include it or remove the dependency array.",["387"],"React Hook useEffect has missing dependencies: 'loadFiles' and 'loadStorageUsage'. Either include them or remove the dependency array.",["388"],"React Hook useEffect has a missing dependency: 'checkCloudStatus'. Either include it or remove the dependency array.",["389"],{"desc":"390","fix":"391"},{"desc":"392","fix":"393"},{"desc":"394","fix":"395"},{"desc":"396","fix":"397"},{"desc":"398","fix":"399"},{"desc":"400","fix":"401"},{"desc":"402","fix":"403"},{"desc":"404","fix":"405"},{"desc":"406","fix":"407"},{"desc":"408","fix":"409"},{"desc":"410","fix":"411"},{"desc":"400","fix":"412"},{"desc":"413","fix":"414"},{"desc":"415","fix":"416"},{"desc":"417","fix":"418"},{"desc":"419","fix":"420"},{"desc":"421","fix":"422"},"Update the dependencies array to be: [activeBoard, activeBoard.id, activeBoard.layout]",{"range":"423","text":"424"},"Update the dependencies array to be: [activeBoard, activeBoard.id, listConfigSignature, runAllInBoard]",{"range":"425","text":"426"},"Update the dependencies array to be: [sortedStudents, sortType, searchKeyword, getGroupName, t]",{"range":"427","text":"428"},"Update the dependencies array to be: [reasons, t]",{"range":"429","text":"430"},"Update the dependencies array to be: [onGlobalMouseMove, onGlobalMouseUp]",{"range":"431","text":"432"},"Update the dependencies array to be: [currentTheme, t]",{"range":"433","text":"434"},"Update the dependencies array to be: [students, showOobeMessage, t]",{"range":"435","text":"436"},"Update the dependencies array to be: [loadAll]",{"range":"437","text":"438"},"Update the dependencies array to be: [messageApi, t]",{"range":"439","text":"440"},"Update the dependencies array to be: [t]",{"range":"441","text":"442"},"Update the dependencies array to be: [t, isMobile, canEdit, handleOpenTagEditor, handleOpenGroupEditor, handleOpenAvatarEditor, handleDelete]",{"range":"443","text":"444"},{"range":"445","text":"434"},"Update the dependencies array to be: [t, tagOptions]",{"range":"446","text":"447"},"Update the dependencies array to be: [canEdit, fetchRules, fetchStudents, fetchTags]",{"range":"448","text":"449"},"Update the dependencies array to be: [handleOAuthCallback]",{"range":"450","text":"451"},"Update the dependencies array to be: [isAuthenticated, loadFiles, loadStorageUsage]",{"range":"452","text":"453"},"Update the dependencies array to be: [checkCloudStatus, isAuthenticated]",{"range":"454","text":"455"},[18048,18086],"[activeBoard, activeBoard.id, activeBoard.layout]",[18296,18349],"[activeBoard, activeBoard.id, listConfigSignature, runAllInBoard]",[16069,16139],"[sortedStudents, sortType, searchKeyword, getGroupName, t]",[16914,16923],"[reasons, t]",[53173,53175],"[onGlobalMouseMove, onGlobalMouseUp]",[4674,4688],"[currentTheme, t]",[10389,10411],"[students, showOobeMessage, t]",[12150,12152],"[loadAll]",[1697,1709],"[messageApi, t]",[3343,3345],"[t]",[45580,45624],"[t, isMobile, canEdit, handleOpenTagEditor, handleOpenGroupEditor, handleOpenAvatarEditor, handleDelete]",[3185,3199],[1661,1711],"[t, tagOptions]",[4022,4031],"[canEdit, fetchRules, fetchStudents, fetchTags]",[4249,4251],"[handleOAuthCallback]",[1826,1843],"[isAuthenticated, loadFiles, loadStorageUsage]",[1803,1820],"[checkCloudStatus, isAuthenticated]"] \ No newline at end of file +[{"E:\\Document\\Coding\\SecScore\\eslint.config.mjs":"1","E:\\Document\\Coding\\SecScore\\src\\App.tsx":"2","E:\\Document\\Coding\\SecScore\\src\\ClientContext.ts":"3","E:\\Document\\Coding\\SecScore\\src\\components\\BoardManager.tsx":"4","E:\\Document\\Coding\\SecScore\\src\\components\\ContentArea.tsx":"5","E:\\Document\\Coding\\SecScore\\src\\components\\EventHistory.tsx":"6","E:\\Document\\Coding\\SecScore\\src\\components\\Home.tsx":"7","E:\\Document\\Coding\\SecScore\\src\\components\\Leaderboard.tsx":"8","E:\\Document\\Coding\\SecScore\\src\\components\\OOBE\\OOBE.tsx":"9","E:\\Document\\Coding\\SecScore\\src\\components\\OOBE\\OOBEBackground.tsx":"10","E:\\Document\\Coding\\SecScore\\src\\components\\ReasonManager.tsx":"11","E:\\Document\\Coding\\SecScore\\src\\components\\RewardExchange.tsx":"12","E:\\Document\\Coding\\SecScore\\src\\components\\RewardSettings.tsx":"13","E:\\Document\\Coding\\SecScore\\src\\components\\ScoreManager.tsx":"14","E:\\Document\\Coding\\SecScore\\src\\components\\Settings.tsx":"15","E:\\Document\\Coding\\SecScore\\src\\components\\SettlementHistory.tsx":"16","E:\\Document\\Coding\\SecScore\\src\\components\\Sidebar.tsx":"17","E:\\Document\\Coding\\SecScore\\src\\components\\StudentManager.tsx":"18","E:\\Document\\Coding\\SecScore\\src\\components\\TagEditorDialog.tsx":"19","E:\\Document\\Coding\\SecScore\\src\\components\\ThemeEditor.tsx":"20","E:\\Document\\Coding\\SecScore\\src\\components\\ThemeQuickSettings.tsx":"21","E:\\Document\\Coding\\SecScore\\src\\components\\TitleBar.tsx":"22","E:\\Document\\Coding\\SecScore\\src\\components\\Versions.tsx":"23","E:\\Document\\Coding\\SecScore\\src\\components\\WindowControls.tsx":"24","E:\\Document\\Coding\\SecScore\\src\\components\\Wizard.tsx":"25","E:\\Document\\Coding\\SecScore\\src\\contexts\\ServiceContext.tsx":"26","E:\\Document\\Coding\\SecScore\\src\\contexts\\ThemeContext.tsx":"27","E:\\Document\\Coding\\SecScore\\src\\contexts\\ThemeEditorContext.tsx":"28","E:\\Document\\Coding\\SecScore\\src\\env.d.ts":"29","E:\\Document\\Coding\\SecScore\\src\\hooks\\useResponsive.ts":"30","E:\\Document\\Coding\\SecScore\\src\\i18n\\index.ts":"31","E:\\Document\\Coding\\SecScore\\src\\main.tsx":"32","E:\\Document\\Coding\\SecScore\\src\\preload\\types.ts":"33","E:\\Document\\Coding\\SecScore\\src\\react-19-patch.ts":"34","E:\\Document\\Coding\\SecScore\\src\\services\\StudentService.ts":"35","E:\\Document\\Coding\\SecScore\\src\\shared\\kernel.ts":"36","E:\\Document\\Coding\\SecScore\\src\\shared\\mobileNavigation.ts":"37","E:\\Document\\Coding\\SecScore\\src\\utils\\color.ts":"38","E:\\Document\\Coding\\SecScore\\src\\utils\\studentAvatar.ts":"39","E:\\Document\\Coding\\SecScore\\src\\workers\\xlsxWorker.ts":"40","E:\\Document\\Coding\\SecScore\\vite.config.ts":"41","E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\ActionEditor.tsx":"42","E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\AutoScoreUtils.ts":"43","E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\IntervalValueCodec.ts":"44","E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\IntervalValueWidget.tsx":"45","E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\TriggerRuleBuilder.tsx":"46","E:\\Document\\Coding\\SecScore\\src\\components\\AutoScoreManager.tsx":"47","E:\\Document\\Coding\\SecScore\\src\\components\\OAuth\\OAuthCallback.tsx":"48","E:\\Document\\Coding\\SecScore\\src\\components\\OAuth\\OAuthLogin.tsx":"49","E:\\Document\\Coding\\SecScore\\src\\components\\SectlCloudStorageManager.tsx":"50","E:\\Document\\Coding\\SecScore\\src\\components\\SectlLoginButton.tsx":"51","E:\\Document\\Coding\\SecScore\\src\\components\\SectlSettingsPanel.tsx":"52","E:\\Document\\Coding\\SecScore\\src\\contexts\\SectlContext.tsx":"53","E:\\Document\\Coding\\SecScore\\src\\services\\sectl.ts":"54","E:\\Document\\Coding\\SecScore\\src\\services\\sectlAuth.ts":"55","E:\\Document\\Coding\\SecScore\\src\\services\\sectlCloudStorage.ts":"56","E:\\Document\\Coding\\SecScore\\src\\services\\sectlKVStorage.ts":"57","E:\\Document\\Coding\\SecScore\\src\\services\\sectlNotification.ts":"58","E:\\Document\\Coding\\SecScore\\src\\views\\SectlCloudView.tsx":"59","E:\\Document\\Coding\\SecScore\\src\\components\\ScoreSyncPanel.tsx":"60","E:\\Document\\Coding\\SecScore\\src\\services\\scoreSyncService.ts":"61","E:\\Document\\Coding\\SecScore\\src\\shared\\fontFamily.ts":"62"},{"size":1413,"mtime":1774084765386,"results":"63","hashOfConfig":"64"},{"size":38733,"mtime":1775878592415,"results":"65","hashOfConfig":"66"},{"size":124,"mtime":1774084765537,"results":"67","hashOfConfig":"66"},{"size":47714,"mtime":1774704827018,"results":"68","hashOfConfig":"66"},{"size":12989,"mtime":1774784139058,"results":"69","hashOfConfig":"66"},{"size":2044,"mtime":1774084765557,"results":"70","hashOfConfig":"66"},{"size":90881,"mtime":1774704827750,"results":"71","hashOfConfig":"66"},{"size":8101,"mtime":1774084765561,"results":"72","hashOfConfig":"66"},{"size":36271,"mtime":1774176288912,"results":"73","hashOfConfig":"66"},{"size":4203,"mtime":1774084765566,"results":"74","hashOfConfig":"66"},{"size":5983,"mtime":1774084765569,"results":"75","hashOfConfig":"66"},{"size":9360,"mtime":1774084765571,"results":"76","hashOfConfig":"66"},{"size":6151,"mtime":1774084765572,"results":"77","hashOfConfig":"66"},{"size":13165,"mtime":1775882074040,"results":"78","hashOfConfig":"66"},{"size":61700,"mtime":1775878592604,"results":"79","hashOfConfig":"66"},{"size":5950,"mtime":1774084765578,"results":"80","hashOfConfig":"66"},{"size":10480,"mtime":1774784139062,"results":"81","hashOfConfig":"66"},{"size":79058,"mtime":1774704830361,"results":"82","hashOfConfig":"66"},{"size":6331,"mtime":1774084765584,"results":"83","hashOfConfig":"66"},{"size":8079,"mtime":1774084765586,"results":"84","hashOfConfig":"66"},{"size":10954,"mtime":1774084765587,"results":"85","hashOfConfig":"66"},{"size":3858,"mtime":1774084765589,"results":"86","hashOfConfig":"66"},{"size":431,"mtime":1774084765590,"results":"87","hashOfConfig":"66"},{"size":2367,"mtime":1774084765592,"results":"88","hashOfConfig":"66"},{"size":1560,"mtime":1774084765594,"results":"89","hashOfConfig":"66"},{"size":362,"mtime":1774084765604,"results":"90","hashOfConfig":"66"},{"size":5985,"mtime":1774084765606,"results":"91","hashOfConfig":"66"},{"size":2824,"mtime":1774084765608,"results":"92","hashOfConfig":"66"},{"size":38,"mtime":1774084765611,"results":"93","hashOfConfig":"66"},{"size":2097,"mtime":1774084765613,"results":"94","hashOfConfig":"66"},{"size":2771,"mtime":1775828716269,"results":"95","hashOfConfig":"66"},{"size":6919,"mtime":1774704831300,"results":"96","hashOfConfig":"66"},{"size":23522,"mtime":1775885815810,"results":"97","hashOfConfig":"66"},{"size":1150,"mtime":1774084765630,"results":"98","hashOfConfig":"66"},{"size":667,"mtime":1774084765638,"results":"99","hashOfConfig":"66"},{"size":3061,"mtime":1774176077013,"results":"100","hashOfConfig":"66"},{"size":1810,"mtime":1774784139078,"results":"101","hashOfConfig":"66"},{"size":3256,"mtime":1774084765655,"results":"102","hashOfConfig":"66"},{"size":1115,"mtime":1774084765658,"results":"103","hashOfConfig":"66"},{"size":947,"mtime":1774084765660,"results":"104","hashOfConfig":"66"},{"size":709,"mtime":1774665241507,"results":"105","hashOfConfig":"66"},{"size":4778,"mtime":1775878592427,"results":"106","hashOfConfig":"66"},{"size":17053,"mtime":1775885815750,"results":"107","hashOfConfig":"66"},{"size":3739,"mtime":1775878592450,"results":"108","hashOfConfig":"66"},{"size":3033,"mtime":1775882069874,"results":"109","hashOfConfig":"66"},{"size":1907,"mtime":1775878592519,"results":"110","hashOfConfig":"66"},{"size":29665,"mtime":1775905018094,"results":"111","hashOfConfig":"66"},{"size":1047,"mtime":1775224756086,"results":"112","hashOfConfig":"66"},{"size":7484,"mtime":1775904980121,"results":"113","hashOfConfig":"66"},{"size":8410,"mtime":1775383418692,"results":"114","hashOfConfig":"66"},{"size":1661,"mtime":1775382857634,"results":"115","hashOfConfig":"66"},{"size":4807,"mtime":1775383469000,"results":"116","hashOfConfig":"66"},{"size":3773,"mtime":1775383419736,"results":"117","hashOfConfig":"66"},{"size":683,"mtime":1775383317477,"results":"118","hashOfConfig":"66"},{"size":9500,"mtime":1775383420349,"results":"119","hashOfConfig":"66"},{"size":14984,"mtime":1775382860520,"results":"120","hashOfConfig":"66"},{"size":6315,"mtime":1775382860555,"results":"121","hashOfConfig":"66"},{"size":5437,"mtime":1775382860586,"results":"122","hashOfConfig":"66"},{"size":429,"mtime":1775383291875,"results":"123","hashOfConfig":"66"},{"size":8415,"mtime":1775828714587,"results":"124","hashOfConfig":"66"},{"size":7067,"mtime":1775383420279,"results":"125","hashOfConfig":"66"},{"size":1359,"mtime":1775878592716,"results":"126","hashOfConfig":"66"},{"filePath":"127","messages":"128","suppressedMessages":"129","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"oyxevq",{"filePath":"130","messages":"131","suppressedMessages":"132","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"f6a32r",{"filePath":"133","messages":"134","suppressedMessages":"135","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"136","messages":"137","suppressedMessages":"138","errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"139","messages":"140","suppressedMessages":"141","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"142","messages":"143","suppressedMessages":"144","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"145","messages":"146","suppressedMessages":"147","errorCount":3,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"148","messages":"149","suppressedMessages":"150","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"151","messages":"152","suppressedMessages":"153","errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"154","messages":"155","suppressedMessages":"156","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"157","messages":"158","suppressedMessages":"159","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"160","messages":"161","suppressedMessages":"162","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"163","messages":"164","suppressedMessages":"165","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"166","messages":"167","suppressedMessages":"168","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"169","messages":"170","suppressedMessages":"171","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"172","messages":"173","suppressedMessages":"174","errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"175","messages":"176","suppressedMessages":"177","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"178","messages":"179","suppressedMessages":"180","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"181","messages":"182","suppressedMessages":"183","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"184","messages":"185","suppressedMessages":"186","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"187","messages":"188","suppressedMessages":"189","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"190","messages":"191","suppressedMessages":"192","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"193","messages":"194","suppressedMessages":"195","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"196","messages":"197","suppressedMessages":"198","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"199","messages":"200","suppressedMessages":"201","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"202","messages":"203","suppressedMessages":"204","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"205","messages":"206","suppressedMessages":"207","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"208","messages":"209","suppressedMessages":"210","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"211","messages":"212","suppressedMessages":"213","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"214","messages":"215","suppressedMessages":"216","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"217","messages":"218","suppressedMessages":"219","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"220","messages":"221","suppressedMessages":"222","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"223","messages":"224","suppressedMessages":"225","errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"226","messages":"227","suppressedMessages":"228","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"229","messages":"230","suppressedMessages":"231","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"232","messages":"233","suppressedMessages":"234","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"235","messages":"236","suppressedMessages":"237","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"238","messages":"239","suppressedMessages":"240","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"241","messages":"242","suppressedMessages":"243","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"244","messages":"245","suppressedMessages":"246","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"247","messages":"248","suppressedMessages":"249","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"250","messages":"251","suppressedMessages":"252","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"253","messages":"254","suppressedMessages":"255","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"256","messages":"257","suppressedMessages":"258","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"259","messages":"260","suppressedMessages":"261","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"262","messages":"263","suppressedMessages":"264","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"265","messages":"266","suppressedMessages":"267","errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"268","messages":"269","suppressedMessages":"270","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"271","messages":"272","suppressedMessages":"273","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"274","messages":"275","suppressedMessages":"276","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"277","messages":"278","suppressedMessages":"279","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"280","messages":"281","suppressedMessages":"282","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"283","messages":"284","suppressedMessages":"285","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"286","messages":"287","suppressedMessages":"288","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"289","messages":"290","suppressedMessages":"291","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"292","messages":"293","suppressedMessages":"294","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"295","messages":"296","suppressedMessages":"297","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"298","messages":"299","suppressedMessages":"300","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"301","messages":"302","suppressedMessages":"303","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"304","messages":"305","suppressedMessages":"306","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"307","messages":"308","suppressedMessages":"309","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"310","messages":"311","suppressedMessages":"312","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"E:\\Document\\Coding\\SecScore\\eslint.config.mjs",[],[],"E:\\Document\\Coding\\SecScore\\src\\App.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\ClientContext.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\BoardManager.tsx",["313","314"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ContentArea.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\EventHistory.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Home.tsx",["315","316","317","318","319","320"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Leaderboard.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\OOBE\\OOBE.tsx",["321","322"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\OOBE\\OOBEBackground.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ReasonManager.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\RewardExchange.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\RewardSettings.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ScoreManager.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Settings.tsx",["323"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\SettlementHistory.tsx",["324","325"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Sidebar.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\StudentManager.tsx",["326"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\TagEditorDialog.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ThemeEditor.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ThemeQuickSettings.tsx",["327"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\TitleBar.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Versions.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\WindowControls.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Wizard.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\contexts\\ServiceContext.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\contexts\\ThemeContext.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\contexts\\ThemeEditorContext.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\env.d.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\hooks\\useResponsive.ts",["328"],[],"E:\\Document\\Coding\\SecScore\\src\\i18n\\index.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\main.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\preload\\types.ts",["329"],[],"E:\\Document\\Coding\\SecScore\\src\\react-19-patch.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\services\\StudentService.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\shared\\kernel.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\shared\\mobileNavigation.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\utils\\color.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\utils\\studentAvatar.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\workers\\xlsxWorker.ts",[],[],"E:\\Document\\Coding\\SecScore\\vite.config.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\ActionEditor.tsx",["330"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\AutoScoreUtils.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\IntervalValueCodec.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\IntervalValueWidget.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\AutoScore\\TriggerRuleBuilder.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\AutoScoreManager.tsx",["331","332","333"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\OAuth\\OAuthCallback.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\OAuth\\OAuthLogin.tsx",["334"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\SectlCloudStorageManager.tsx",["335"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\SectlLoginButton.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\SectlSettingsPanel.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\contexts\\SectlContext.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\services\\sectl.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\services\\sectlAuth.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\services\\sectlCloudStorage.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\services\\sectlKVStorage.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\services\\sectlNotification.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\views\\SectlCloudView.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ScoreSyncPanel.tsx",["336"],[],"E:\\Document\\Coding\\SecScore\\src\\services\\scoreSyncService.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\shared\\fontFamily.ts",[],[],{"ruleId":"337","severity":1,"message":"338","line":626,"column":6,"nodeType":"339","endLine":626,"endColumn":44,"suggestions":"340"},{"ruleId":"337","severity":1,"message":"338","line":634,"column":6,"nodeType":"339","endLine":634,"endColumn":59,"suggestions":"341"},{"ruleId":"337","severity":1,"message":"342","line":532,"column":6,"nodeType":"339","endLine":532,"endColumn":76,"suggestions":"343"},{"ruleId":"344","severity":2,"message":"345","line":544,"column":34,"nodeType":null,"endLine":556,"endColumn":4},{"ruleId":"344","severity":2,"message":"345","line":544,"column":34,"nodeType":null,"endLine":556,"endColumn":4},{"ruleId":"337","severity":1,"message":"346","line":556,"column":6,"nodeType":"339","endLine":556,"endColumn":15,"suggestions":"347"},{"ruleId":"344","severity":2,"message":"348","line":1627,"column":5,"nodeType":null,"endLine":1650,"endColumn":6},{"ruleId":"337","severity":1,"message":"349","line":1710,"column":6,"nodeType":"339","endLine":1710,"endColumn":8,"suggestions":"350"},{"ruleId":"337","severity":1,"message":"351","line":160,"column":6,"nodeType":"339","endLine":160,"endColumn":20,"suggestions":"352"},{"ruleId":"337","severity":1,"message":"353","line":334,"column":5,"nodeType":"339","endLine":334,"endColumn":27,"suggestions":"354"},{"ruleId":"337","severity":1,"message":"355","line":377,"column":6,"nodeType":"339","endLine":377,"endColumn":8,"suggestions":"356"},{"ruleId":"337","severity":1,"message":"357","line":54,"column":6,"nodeType":"339","endLine":54,"endColumn":18,"suggestions":"358"},{"ruleId":"337","severity":1,"message":"346","line":106,"column":5,"nodeType":"339","endLine":106,"endColumn":7,"suggestions":"359"},{"ruleId":"337","severity":1,"message":"360","line":1351,"column":6,"nodeType":"339","endLine":1351,"endColumn":50,"suggestions":"361"},{"ruleId":"337","severity":1,"message":"351","line":100,"column":6,"nodeType":"339","endLine":100,"endColumn":20,"suggestions":"362"},{"ruleId":"337","severity":1,"message":"363","line":25,"column":9,"nodeType":"364","endLine":25,"endColumn":70},{"ruleId":"365","severity":2,"message":"366","line":705,"column":38,"nodeType":"367","messageId":"368","endLine":705,"endColumn":43},{"ruleId":"337","severity":1,"message":"369","line":23,"column":9,"nodeType":"364","endLine":23,"endColumn":63},{"ruleId":"337","severity":1,"message":"346","line":166,"column":5,"nodeType":"339","endLine":166,"endColumn":55,"suggestions":"370"},{"ruleId":"337","severity":1,"message":"371","line":328,"column":6,"nodeType":"339","endLine":328,"endColumn":15,"suggestions":"372"},{"ruleId":"337","severity":1,"message":"373","line":392,"column":6,"nodeType":"339","endLine":392,"endColumn":55,"suggestions":"374"},{"ruleId":"337","severity":1,"message":"375","line":163,"column":6,"nodeType":"339","endLine":163,"endColumn":8,"suggestions":"376"},{"ruleId":"337","severity":1,"message":"377","line":79,"column":6,"nodeType":"339","endLine":79,"endColumn":23,"suggestions":"378"},{"ruleId":"337","severity":1,"message":"379","line":69,"column":6,"nodeType":"339","endLine":69,"endColumn":23,"suggestions":"380"},"react-hooks/exhaustive-deps","React Hook useEffect has a missing dependency: 'activeBoard'. Either include it or remove the dependency array.","ArrayExpression",["381"],["382"],"React Hook useMemo has an unnecessary dependency: 'layoutType'. Either exclude it or remove the dependency array.",["383"],"react-hooks/preserve-manual-memoization","Compilation Skipped: Existing memoization could not be preserved\n\nReact Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `t`, but the source dependencies were [reasons]. Inferred different dependency than source.\n\nE:\\Document\\Coding\\SecScore\\src\\components\\Home.tsx:544:34\n 542 | }, [groupedStudents])\n 543 |\n> 544 | const groupedReasons = useMemo(() => {\n | ^^^^^^^\n> 545 | const groups: Record = {}\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 546 | reasons.forEach((r) => {\n …\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 555 | })\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 556 | }, [reasons])\n | ^^^^ Could not preserve existing manual memoization\n 557 |\n 558 | const selectedStudents = useMemo(() => {\n 559 | if (selectedStudentIds.length === 0) return []","React Hook useMemo has a missing dependency: 't'. Either include it or remove the dependency array.",["384"],"Compilation Skipped: Existing memoization could not be preserved\n\nReact Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. This value was memoized in source but not in compilation output.\n\nE:\\Document\\Coding\\SecScore\\src\\components\\Home.tsx:1627:5\n 1625 |\n 1626 | const handleNavAction = useCallback(\n> 1627 | (clientY: number) => {\n | ^^^^^^^^^^^^^^^^^^^^^^\n> 1628 | if (!navContainerRef.current) return\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 1629 | const rect = navContainerRef.current.getBoundingClientRect()\n …\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 1649 | }\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 1650 | },\n | ^^^^^^ Could not preserve existing memoization\n 1651 | [groupedStudents, quickNavLayout.itemSize, quickNavLayout.paddingY, triggerNavHaptic]\n 1652 | )\n 1653 |","React Hook useEffect has missing dependencies: 'onGlobalMouseMove' and 'onGlobalMouseUp'. Either include them or remove the dependency array.",["385"],"React Hook useEffect has a missing dependency: 't'. Either include it or remove the dependency array.",["386"],"React Hook useCallback has missing dependencies: 'showOobeMessage' and 't'. Either include them or remove the dependency array.",["387"],"React Hook useEffect has a missing dependency: 'loadAll'. Either include it or remove the dependency array.",["388"],"React Hook useCallback has a missing dependency: 't'. Either include it or remove the dependency array.",["389"],["390"],"React Hook useMemo has missing dependencies: 'handleDelete', 'handleOpenAvatarEditor', 'handleOpenGroupEditor', and 'handleOpenTagEditor'. Either include them or remove the dependency array.",["391"],["392"],"The 'breakpoints' object makes the dependencies of useEffect Hook (at line 49) change on every render. Move it inside the useEffect callback. Alternatively, wrap the initialization of 'breakpoints' in its own useMemo() Hook.","VariableDeclarator","@typescript-eslint/no-unused-vars","'_args' is defined but never used.","Identifier","unusedVar","The 'safeValue' conditional could make the dependencies of useMemo Hook (at line 59) change on every render. To fix this, wrap the initialization of 'safeValue' in its own useMemo() Hook.",["393"],"React Hook useEffect has missing dependencies: 'fetchBatches', 'fetchRules', 'fetchStudents', and 'fetchTags'. Either include them or remove the dependency array.",["394"],"React Hook useEffect has missing dependencies: 'fetchBatches' and 'fetchRules'. Either include them or remove the dependency array.",["395"],"React Hook useEffect has a missing dependency: 'handleOAuthCallback'. Either include it or remove the dependency array.",["396"],"React Hook useEffect has missing dependencies: 'loadFiles' and 'loadStorageUsage'. Either include them or remove the dependency array.",["397"],"React Hook useEffect has a missing dependency: 'checkCloudStatus'. Either include it or remove the dependency array.",["398"],{"desc":"399","fix":"400"},{"desc":"401","fix":"402"},{"desc":"403","fix":"404"},{"desc":"405","fix":"406"},{"desc":"407","fix":"408"},{"desc":"409","fix":"410"},{"desc":"411","fix":"412"},{"desc":"413","fix":"414"},{"desc":"415","fix":"416"},{"desc":"417","fix":"418"},{"desc":"419","fix":"420"},{"desc":"409","fix":"421"},{"desc":"422","fix":"423"},{"desc":"424","fix":"425"},{"desc":"426","fix":"427"},{"desc":"428","fix":"429"},{"desc":"430","fix":"431"},{"desc":"432","fix":"433"},"Update the dependencies array to be: [activeBoard, activeBoard.id, activeBoard.layout]",{"range":"434","text":"435"},"Update the dependencies array to be: [activeBoard, activeBoard.id, listConfigSignature, runAllInBoard]",{"range":"436","text":"437"},"Update the dependencies array to be: [sortedStudents, sortType, searchKeyword, getGroupName, t]",{"range":"438","text":"439"},"Update the dependencies array to be: [reasons, t]",{"range":"440","text":"441"},"Update the dependencies array to be: [onGlobalMouseMove, onGlobalMouseUp]",{"range":"442","text":"443"},"Update the dependencies array to be: [currentTheme, t]",{"range":"444","text":"445"},"Update the dependencies array to be: [students, showOobeMessage, t]",{"range":"446","text":"447"},"Update the dependencies array to be: [loadAll]",{"range":"448","text":"449"},"Update the dependencies array to be: [messageApi, t]",{"range":"450","text":"451"},"Update the dependencies array to be: [t]",{"range":"452","text":"453"},"Update the dependencies array to be: [t, isMobile, canEdit, handleOpenTagEditor, handleOpenGroupEditor, handleOpenAvatarEditor, handleDelete]",{"range":"454","text":"455"},{"range":"456","text":"445"},"Update the dependencies array to be: [t, tagOptions]",{"range":"457","text":"458"},"Update the dependencies array to be: [canEdit, fetchBatches, fetchRules, fetchStudents, fetchTags]",{"range":"459","text":"460"},"Update the dependencies array to be: [backfillPrompted, canEdit, fetchBatches, fetchRules, messageApi, rules, t]",{"range":"461","text":"462"},"Update the dependencies array to be: [handleOAuthCallback]",{"range":"463","text":"464"},"Update the dependencies array to be: [isAuthenticated, loadFiles, loadStorageUsage]",{"range":"465","text":"466"},"Update the dependencies array to be: [checkCloudStatus, isAuthenticated]",{"range":"467","text":"468"},[18048,18086],"[activeBoard, activeBoard.id, activeBoard.layout]",[18296,18349],"[activeBoard, activeBoard.id, listConfigSignature, runAllInBoard]",[16069,16139],"[sortedStudents, sortType, searchKeyword, getGroupName, t]",[16914,16923],"[reasons, t]",[53173,53175],"[onGlobalMouseMove, onGlobalMouseUp]",[4674,4688],"[currentTheme, t]",[10389,10411],"[students, showOobeMessage, t]",[12089,12091],"[loadAll]",[1697,1709],"[messageApi, t]",[3343,3345],"[t]",[45580,45624],"[t, isMobile, canEdit, handleOpenTagEditor, handleOpenGroupEditor, handleOpenAvatarEditor, handleDelete]",[3185,3199],[4185,4235],"[t, tagOptions]",[9126,9135],"[canEdit, fetchBatches, fetchRules, fetchStudents, fetchTags]",[11298,11347],"[backfillPrompted, canEdit, fetchBatches, fetchRules, messageApi, rules, t]",[4414,4416],"[handleOAuthCallback]",[1826,1843],"[isAuthenticated, loadFiles, loadStorageUsage]",[1783,1800],"[checkCloudStatus, isAuthenticated]"] \ No newline at end of file diff --git a/src-tauri/src/commands/auth.rs b/src-tauri/src/commands/auth.rs index f054240..3ee96b2 100644 --- a/src-tauri/src/commands/auth.rs +++ b/src-tauri/src/commands/auth.rs @@ -81,6 +81,7 @@ pub struct OAuthIntrospectResponse { pub struct OAuthAuthorizationUrlResponse { pub url: String, pub state: String, + pub code_verifier: String, } fn get_iv_hex() -> String { @@ -325,6 +326,29 @@ pub async fn auth_clear_all( } } +/// 生成 PKCE code_verifier +fn generate_code_verifier() -> String { + use rand::Rng; + let mut rng = rand::thread_rng(); + let random_bytes: Vec = (0..32).map(|_| rng.gen()).collect(); + base64::Engine::encode( + &base64::engine::general_purpose::URL_SAFE_NO_PAD, + &random_bytes, + ) +} + +/// 生成 PKCE code_challenge (S256) +fn generate_code_challenge(verifier: &str) -> String { + use sha2::{Digest, Sha256}; + let mut hasher = Sha256::new(); + hasher.update(verifier.as_bytes()); + let result = hasher.finalize(); + base64::Engine::encode( + &base64::engine::general_purpose::URL_SAFE_NO_PAD, + &result, + ) +} + #[tauri::command] pub async fn oauth_get_authorization_url( platform_id: String, @@ -341,16 +365,22 @@ pub async fn oauth_get_authorization_url( ) }); + // 生成 PKCE 参数 + let code_verifier = generate_code_verifier(); + let code_challenge = generate_code_challenge(&code_verifier); + let url = format!( - "https://sectl.top/oauth/authorize?client_id={}&redirect_uri={}&response_type=code&state={}", + "https://sectl.top/oauth/authorize?client_id={}&redirect_uri={}&response_type=code&state={}&code_challenge={}&code_challenge_method=S256", platform_id, urlencoding::encode(&callback_url), - urlencoding::encode(&state) + urlencoding::encode(&state), + urlencoding::encode(&code_challenge) ); Ok(IpcResponse::success(OAuthAuthorizationUrlResponse { url, state, + code_verifier, })) } @@ -360,6 +390,7 @@ pub async fn oauth_exchange_code( platform_id: String, platform_secret: String, callback_url: String, + code_verifier: String, state: State<'_, Arc>>, ) -> Result, String> { println!( @@ -375,6 +406,7 @@ pub async fn oauth_exchange_code( "client_id": &platform_id, "client_secret": &platform_secret, "redirect_uri": &callback_url, + "code_verifier": &code_verifier, }); println!("[OAuth] 请求参数:{:?}", payload); @@ -485,6 +517,11 @@ pub async fn oauth_get_user_info( access_token: String, state: State<'_, Arc>>, ) -> Result, String> { + println!( + "[OAuth] 获取用户信息 - access_token: {}...", + &access_token[..20.min(access_token.len())] + ); + let state_guard = state.read(); let client = &state_guard.http_client; @@ -495,17 +532,36 @@ pub async fn oauth_get_user_info( .await .map_err(|e| format!("Request failed: {}", e))?; + println!("[OAuth] 用户信息响应状态: {}", response.status()); + if !response.status().is_success() { let error_text = response .text() .await .unwrap_or_else(|_| "Unknown error".to_string()); - return Ok(IpcResponse::error(&error_text)); + println!("[OAuth] 用户信息响应错误: {}", error_text); + // 尝试解析 JSON 错误,提取 error_description 或 error + let error_message = + if let Ok(json_err) = serde_json::from_str::(&error_text) { + json_err + .get("error_description") + .or_else(|| json_err.get("error")) + .and_then(|v| v.as_str()) + .unwrap_or(&error_text) + .to_string() + } else { + error_text + }; + return Ok(IpcResponse::error(&error_message)); } - let user_info: OAuthUserInfo = response - .json() + let response_text = response + .text() .await + .map_err(|e| format!("Failed to read response: {}", e))?; + println!("[OAuth] 用户信息响应内容: {}", response_text); + + let user_info: OAuthUserInfo = serde_json::from_str(&response_text) .map_err(|e| format!("Failed to parse response: {}", e))?; Ok(IpcResponse::success(user_info)) diff --git a/src-tauri/src/services/auto_score.rs b/src-tauri/src/services/auto_score.rs index 4cd4407..a78fa5b 100644 --- a/src-tauri/src/services/auto_score.rs +++ b/src-tauri/src/services/auto_score.rs @@ -1567,7 +1567,9 @@ pub async fn apply_offline_backfill( } requested_runs_by_rule .entry(item.rule_id) - .and_modify(|value| *value = (*value + capped).min(AUTO_SCORE_BACKFILL_MAX_RUNS_PER_RULE)) + .and_modify(|value| { + *value = (*value + capped).min(AUTO_SCORE_BACKFILL_MAX_RUNS_PER_RULE) + }) .or_insert(capped); } if requested_runs_by_rule.is_empty() { @@ -1610,7 +1612,8 @@ pub async fn apply_offline_backfill( changed = true; for _ in 0..replay_runs { - let stats = execute_rule(&conn, rule, &execution_batches, ExecutionMode::Backfill).await?; + let stats = + execute_rule(&conn, rule, &execution_batches, ExecutionMode::Backfill).await?; result.applied_runs += 1; result.affected_students += stats.affected_students; result.created_events += stats.created_events; @@ -1682,7 +1685,9 @@ async fn execute_rule( if let Some(max_runs) = rule.execution.max_runs_per_day { let today_runs = execution_batches .iter() - .filter(|batch| batch.rule_id == rule.id && !batch.rolled_back && is_same_utc_day(&batch.run_at)) + .filter(|batch| { + batch.rule_id == rule.id && !batch.rolled_back && is_same_utc_day(&batch.run_at) + }) .count() as i64; if today_runs >= max_runs { return Ok(RuleExecutionStats::default()); @@ -1700,7 +1705,9 @@ async fn execute_rule( let mut daily_score_delta_used: i64 = execution_batches .iter() - .filter(|batch| batch.rule_id == rule.id && !batch.rolled_back && is_same_utc_day(&batch.run_at)) + .filter(|batch| { + batch.rule_id == rule.id && !batch.rolled_back && is_same_utc_day(&batch.run_at) + }) .map(|batch| batch.score_delta_total.abs()) .sum(); diff --git a/src/components/AutoScoreManager.tsx b/src/components/AutoScoreManager.tsx index 8012d48..1994ac4 100644 --- a/src/components/AutoScoreManager.tsx +++ b/src/components/AutoScoreManager.tsx @@ -73,7 +73,9 @@ interface BackfillPlanItem { ruleName: string } -const buildOfflineBackfillPlan = (rules: AutoScoreRule[]): { +const buildOfflineBackfillPlan = ( + rules: AutoScoreRule[] +): { items: BackfillPlanItem[] totalRuns: number from: dayjs.Dayjs | null @@ -87,12 +89,15 @@ const buildOfflineBackfillPlan = (rules: AutoScoreRule[]): { for (const rule of rules) { if (!rule.enabled) continue - const intervalTrigger = rule.triggers.find((trigger) => trigger.event === "interval_time_passed") + const intervalTrigger = rule.triggers.find( + (trigger) => trigger.event === "interval_time_passed" + ) if (!intervalTrigger) continue const intervalValue = parseIntervalTriggerValue(intervalTrigger.value) if (!intervalValue) continue - const intervalMinutes = intervalValue.days * 24 * 60 + intervalValue.hours * 60 + intervalValue.minutes + const intervalMinutes = + intervalValue.days * 24 * 60 + intervalValue.hours * 60 + intervalValue.minutes if (intervalMinutes <= 0) continue const startAt = rule.execution?.startAt ? dayjs(rule.execution.startAt) : null @@ -218,7 +223,8 @@ function AutoScoreManager({ canEdit }: AutoScoreManagerProps): React.JSX.Element return t("autoScore.startAtHint") } - const intervalMinutes = intervalValue.days * 24 * 60 + intervalValue.hours * 60 + intervalValue.minutes + const intervalMinutes = + intervalValue.days * 24 * 60 + intervalValue.hours * 60 + intervalValue.minutes if (intervalMinutes <= 0) { return t("autoScore.startAtHint") } diff --git a/src/components/Leaderboard.tsx b/src/components/Leaderboard.tsx index 1d3fd48..eefeb2d 100644 --- a/src/components/Leaderboard.tsx +++ b/src/components/Leaderboard.tsx @@ -76,60 +76,58 @@ export const Leaderboard: React.FC = () => { } const handleExport = () => { - setTimeout(() => { - const title = - timeRange === "today" - ? t("leaderboard.today") - : timeRange === "week" - ? t("leaderboard.week") - : t("leaderboard.month") + const title = + timeRange === "today" + ? t("leaderboard.today") + : timeRange === "week" + ? t("leaderboard.week") + : t("leaderboard.month") - const sanitizeCell = (v: unknown) => { - if (typeof v !== "string") return v - if (/^[=+\-@]/.test(v)) return `'${v}` - return v - } + const sanitizeCell = (v: unknown) => { + if (typeof v !== "string") return v + if (/^[=+\-@]/.test(v)) return `'${v}` + return v + } - const sheetData = [ - [ - t("leaderboard.rank"), - t("leaderboard.name"), - t("leaderboard.totalScore"), - `${title}${t("leaderboard.change")}`, - ], - ...data.map((item, index) => [ - index + 1, - sanitizeCell(item.name), - item.score, - item.range_change, - ]), - ] + const sheetData = [ + [ + t("leaderboard.rank"), + t("leaderboard.name"), + t("leaderboard.totalScore"), + `${title}${t("leaderboard.change")}`, + ], + ...data.map((item, index) => [ + index + 1, + sanitizeCell(item.name), + item.score, + item.range_change, + ]), + ] - const ws = XLSX.utils.aoa_to_sheet(sheetData) - ws["!cols"] = [{ wch: 6 }, { wch: 14 }, { wch: 10 }, { wch: 10 }] + const ws = XLSX.utils.aoa_to_sheet(sheetData) + ws["!cols"] = [{ wch: 6 }, { wch: 14 }, { wch: 10 }, { wch: 10 }] - const wb = XLSX.utils.book_new() - XLSX.utils.book_append_sheet(wb, ws, t("leaderboard.title")) + const wb = XLSX.utils.book_new() + XLSX.utils.book_append_sheet(wb, ws, t("leaderboard.title")) - const xlsxBytes = XLSX.write(wb, { bookType: "xlsx", type: "array" }) - const blob = new Blob([xlsxBytes], { - type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - }) + const xlsxBytes = XLSX.write(wb, { bookType: "xlsx", type: "array" }) + const blob = new Blob([xlsxBytes], { + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + }) - const link = document.createElement("a") - const url = URL.createObjectURL(blob) - link.setAttribute("href", url) - link.setAttribute( - "download", - `${t("leaderboard.title")}_${timeRange}_${new Date().toISOString().slice(0, 10)}.xlsx` - ) - link.style.visibility = "hidden" - document.body.appendChild(link) - link.click() - document.body.removeChild(link) - URL.revokeObjectURL(url) - messageApi.success(t("leaderboard.exportSuccess")) - }, 0) + const link = document.createElement("a") + const url = URL.createObjectURL(blob) + link.setAttribute("href", url) + link.setAttribute( + "download", + `${t("leaderboard.title")}_${timeRange}_${new Date().toISOString().slice(0, 10)}.xlsx` + ) + link.style.visibility = "hidden" + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + URL.revokeObjectURL(url) + messageApi.success(t("leaderboard.exportSuccess")) } const columns: ColumnsType = [ diff --git a/src/components/OAuth/OAuthLogin.tsx b/src/components/OAuth/OAuthLogin.tsx index 897769a..cedcce2 100644 --- a/src/components/OAuth/OAuthLogin.tsx +++ b/src/components/OAuth/OAuthLogin.tsx @@ -1,5 +1,5 @@ import { Button, message, Modal, Space, Spin } from "antd" -import { useEffect, useRef, useState } from "react" +import { useEffect, useState } from "react" import { useTranslation } from "react-i18next" import { open } from "@tauri-apps/plugin-shell" import { listen, UnlistenFn } from "@tauri-apps/api/event" @@ -28,10 +28,14 @@ interface OAuthCallbackResult { error_description?: string } +// 全局锁,确保同一时间只有一个回调在处理 +let isProcessingCallback = false +// 全局监听器引用,确保只有一个监听器 +let globalUnlisten: UnlistenFn | null = null + export function OAuthLogin({ visible, onClose, onSuccess }: OAuthLoginProps) { const { t } = useTranslation() const [loading, setLoading] = useState(false) - const callbackUnlistenRef = useRef(null) // 使用 sessionStorage 存储 state,防止组件重新渲染导致丢失 const getExpectedState = () => sessionStorage.getItem("oauth_expected_state") const setExpectedState = (state: string) => sessionStorage.setItem("oauth_expected_state", state) @@ -55,6 +59,12 @@ export function OAuthLogin({ visible, onClose, onSuccess }: OAuthLoginProps) { } const handleOAuthCallback = async (result: OAuthCallbackResult) => { + // 全局锁检查,防止重复处理 + if (isProcessingCallback) { + console.log("[OAuth] 回调正在处理中,跳过") + return + } + console.log("[OAuth] 收到回调:", result) const config = getOAuthConfig() if (!config) { @@ -63,6 +73,8 @@ export function OAuthLogin({ visible, onClose, onSuccess }: OAuthLoginProps) { } try { + isProcessingCallback = true + if (result.error) { console.error("[OAuth] 错误:", result.error, result.error_description) message.error(result.error_description || result.error || "授权失败") @@ -85,12 +97,23 @@ export function OAuthLogin({ visible, onClose, onSuccess }: OAuthLoginProps) { const api = (window as any).api const callbackUrl = "http://127.0.0.1:16888/oauth/callback" + // 获取存储的 code_verifier + const codeVerifier = sessionStorage.getItem("oauth_code_verifier") + if (!codeVerifier) { + message.error("安全验证失败:缺少 code_verifier") + setLoading(false) + return + } + + console.log("[OAuth] 开始换取 token...") const tokenRes = await api.oauthExchangeCode( result.code, config.platform_id, config.platform_secret, - callbackUrl + callbackUrl, + codeVerifier ) + console.log("[OAuth] token 响应:", tokenRes) if (!tokenRes.success) { message.error(tokenRes.message || "获取访问令牌失败") @@ -98,7 +121,9 @@ export function OAuthLogin({ visible, onClose, onSuccess }: OAuthLoginProps) { return } + console.log("[OAuth] 开始获取用户信息...") const userRes = await api.oauthGetUserInfo(tokenRes.data.access_token) + console.log("[OAuth] 用户信息响应:", userRes) if (!userRes.success) { message.error(userRes.message || "获取用户信息失败") @@ -106,33 +131,46 @@ export function OAuthLogin({ visible, onClose, onSuccess }: OAuthLoginProps) { return } + console.log("[OAuth] 登录成功,清理资源...") await api.oauthStopCallbackServer() clearExpectedState() + sessionStorage.removeItem("oauth_code_verifier") + console.log("[OAuth] 调用 onSuccess...") onSuccess(userRes.data) + console.log("[OAuth] 调用 onClose...") onClose() } } catch (error: any) { + console.error("[OAuth] 处理回调时发生错误:", error) message.error(error.message || "登录失败") } finally { + console.log("[OAuth] 回调处理完成,重置状态") setLoading(false) + // 延迟释放锁,确保其他可能的重复事件被忽略 + setTimeout(() => { + isProcessingCallback = false + console.log("[OAuth] 全局锁已释放") + }, 1000) } } useEffect(() => { const setupListener = async () => { + // 如果已经有全局监听器,不再创建新的 + if (globalUnlisten) { + console.log("[OAuth] 全局监听器已存在,跳过创建") + return + } + try { const unlisten = await listen("oauth-callback", async (event) => { console.log("[OAuth] Event listener 收到 payload:", event.payload) if (event.payload) { - // 立即取消监听,防止重复触发 - if (callbackUnlistenRef.current) { - callbackUnlistenRef.current() - callbackUnlistenRef.current = null - } await handleOAuthCallback(event.payload) } }) - callbackUnlistenRef.current = unlisten + globalUnlisten = unlisten + console.log("[OAuth] 全局监听器已创建") } catch (error) { console.error("Failed to setup OAuth callback listener:", error) } @@ -140,12 +178,9 @@ export function OAuthLogin({ visible, onClose, onSuccess }: OAuthLoginProps) { setupListener() - return () => { - if (callbackUnlistenRef.current) { - callbackUnlistenRef.current() - callbackUnlistenRef.current = null - } - } + // 组件卸载时不取消监听,保持全局监听 + // 只在应用完全关闭时才清理 + // eslint-disable-next-line react-hooks/exhaustive-deps }, []) const handleOAuthLogin = async () => { @@ -183,6 +218,10 @@ export function OAuthLogin({ visible, onClose, onSuccess }: OAuthLoginProps) { return } + // 存储 code_verifier 用于后续换取 token + sessionStorage.setItem("oauth_code_verifier", urlRes.data.code_verifier) + console.log("[OAuth] code_verifier 已存储") + await open(urlRes.data.url) } catch (error: any) { message.error(error.message || "登录失败") diff --git a/src/preload/types.ts b/src/preload/types.ts index 97cb791..98abd59 100644 --- a/src/preload/types.ts +++ b/src/preload/types.ts @@ -437,6 +437,7 @@ const api = { data: { url: string state: string + code_verifier: string } message?: string }> => invoke("oauth_get_authorization_url", { platformId, callbackUrl, state }), @@ -444,7 +445,8 @@ const api = { code: string, platformId: string, platformSecret: string, - callbackUrl: string + callbackUrl: string, + codeVerifier: string ): Promise<{ success: boolean data: { @@ -454,7 +456,8 @@ const api = { expires_in: number } message?: string - }> => invoke("oauth_exchange_code", { code, platformId, platformSecret, callbackUrl }), + }> => + invoke("oauth_exchange_code", { code, platformId, platformSecret, callbackUrl, codeVerifier }), oauthGetUserInfo: ( accessToken: string ): Promise<{