Full Code of Co2333/myyearwithgit for AI

main 214da7dfa44e cached
120 files
350.2 KB
94.1k tokens
1 requests
Download .txt
Showing preview only (402K chars total). Download the full file or copy to clipboard to get everything.
Repository: Co2333/myyearwithgit
Branch: main
Commit: 214da7dfa44e
Files: 120
Total size: 350.2 KB

Directory structure:
gitextract_qpqfygjk/

├── .gitignore
├── .gitmodules
├── .root
├── LICENSE
├── MyYearWithGit/
│   ├── App/
│   │   ├── App.swift
│   │   ├── Assets.xcassets/
│   │   │   ├── AccentColor.colorset/
│   │   │   │   └── Contents.json
│   │   │   ├── AppIcon.appiconset/
│   │   │   │   └── Contents.json
│   │   │   ├── Contents.json
│   │   │   ├── badge.imageset/
│   │   │   │   └── Contents.json
│   │   │   ├── bitbucket.imageset/
│   │   │   │   └── Contents.json
│   │   │   ├── git.imageset/
│   │   │   │   └── Contents.json
│   │   │   ├── github.imageset/
│   │   │   │   └── Contents.json
│   │   │   ├── gitlab.imageset/
│   │   │   │   └── Contents.json
│   │   │   ├── qrcode.imageset/
│   │   │   │   └── Contents.json
│   │   │   └── sfexp/
│   │   │       ├── Contents.json
│   │   │       ├── custom.aqi.high.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.aqi.low.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.aqi.medium.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.circle.fill.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.bolt.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.bolt.rain.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.drizzle.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.fog.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.hail.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.heavyrain.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.moon.bolt.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.moon.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.moon.rain.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.rain.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.sleet.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.snow.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.sun.bolt.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.sun.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.sun.rain.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.humidity.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.hurricane.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.moon.circle.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.moon.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.moon.stars.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.smoke.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.snowflake.circle.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.snowflake.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sparkles.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sun.and.horizon.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sun.dust.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sun.haze.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sun.max.circle.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sun.max.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sun.min.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sunrise.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sunset.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.thermometer.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.thermometer.snowflake.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.thermometer.sun.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.tornado.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.tropicalstorm.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.wind.imageset/
│   │   │       │   └── Contents.json
│   │   │       └── custom.wind.snow.imageset/
│   │   │           └── Contents.json
│   │   ├── Hooker.m
│   │   ├── InfoPlist.xcstrings
│   │   ├── Localizable.xcstrings
│   │   └── main.swift
│   ├── Data/
│   │   ├── Analyser/
│   │   │   ├── CommitFilter.swift
│   │   │   ├── DictionaryBuilder.swift
│   │   │   ├── GitDiff.swift
│   │   │   ├── GitLog.swift
│   │   │   ├── GitRepoResult.swift
│   │   │   └── RepoAnalyser.swift
│   │   ├── Api/
│   │   │   ├── ApiProtocol.swift
│   │   │   ├── BitbucketApi.swift
│   │   │   ├── GitHubApi.swift
│   │   │   └── GitLabApi.swift
│   │   ├── Generic/
│   │   │   ├── AuxiliaryExecute.swift
│   │   │   ├── Exts.swift
│   │   │   ├── SourceLanguage.swift
│   │   │   ├── SourcePackage.swift.swift
│   │   │   ├── SourceRegister.swift
│   │   │   ├── User.swift
│   │   │   └── UserDefault.swift.swift
│   │   └── ResultPackage/
│   │       ├── DicCounter.swift
│   │       ├── RS0.swift
│   │       ├── RS1.swift
│   │       ├── RS2.swift
│   │       ├── RS3.swift
│   │       ├── RS4.swift
│   │       ├── RS5.swift
│   │       ├── RS6.swift
│   │       ├── RS7.swift
│   │       ├── RS8.swift
│   │       ├── RS9.swift
│   │       ├── RSProtocol.swift.swift
│   │       └── ResultPackage.swift
│   ├── Entitlements.entitlements
│   ├── Info.plist
│   └── View/
│       ├── Configuration/
│       │   ├── BitbucketSheet.swift
│       │   ├── CommitFilterSheet.swift
│       │   ├── ConfigEmailSheet.swift
│       │   ├── GitHubRepoSheet.swift
│       │   ├── GitLabRepoSheet.swift
│       │   ├── LocalRepoSheet.swift
│       │   ├── MainSheet.swift
│       │   └── PickSourceSheet.swift
│       ├── Generic/
│       │   ├── AnalysisView.swift
│       │   ├── MainView.swift
│       │   ├── ResultView.swift
│       │   └── ThanksView.swift
│       ├── Helper/
│       │   ├── CodeTiles.swift
│       │   ├── SheetTemplate.swift
│       │   ├── TextIncrementEffectView.swift
│       │   ├── TextTypeEffectView.swift
│       │   └── sha256sum.swift
│       └── NavigatorView.swift
├── MyYearWithGit.xcodeproj/
│   └── project.pbxproj
├── MyYearWithGit.xcworkspace/
│   ├── contents.xcworkspacedata
│   └── xcshareddata/
│       ├── IDEWorkspaceChecks.plist
│       └── swiftpm/
│           └── Package.resolved
├── README.md
└── Resources/
    ├── MyYearWithGit.xd
    └── i18n/
        └── en/
            └── README.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3
!default.xcworkspace
*.dSYM
*.dSYM.zip
*.hmap
*.ipa
*.lcov
*.lock
*.log
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
*.pid
*.pid.lock
*.seed
*.swp
*.tgz
*.tsbuildinfo
*.xccheckout
*.xcscmblueprint
*.xcuserstate
*~.nib
.AppleDB
.AppleDesktop
.AppleDouble
.DS_Store
.DocumentRevisions-V100
.LSOverride
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
._*
.apdisk
.build
.bundle
.cache
.cache/
.com.apple.timemachine.donotpresent
.dynamodb/
.env
.env.test
.eslintcache
.fseventsd
.fusebox/
.grunt
.idea
.lock-wscript
.next
.node_repl_history
.npm
.nuxt
.nyc_output
.parcel-cache
.pnp.*
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
.serverless/
.swiftpm
.tern-port
.vscode-test
.vuepress/dist
.yarn-integrity
.yarn/build-state.yml
.yarn/cache
.yarn/unplugged
/*.gcno
Artifacts/
CI
CI-Pods.tar
Carthage/Build
Carthage/Build/
DerivedData
DerivedData/
Icon
Network Trash Folder
Pipeline/Dockers/Buildtime/
Podfile.lock
Pods/
Temporary Items
artifacts/
bower_components
build/
build/Release
coverage
default.profraw
dist
dockerbuild
dockermnt
fastlane/Preview.html
fastlane/report.xml
fastlane/screenshots/**/*.png
fastlane/test_output
iOSInjectionProject/
jspm_packages/
lerna-debug.log*
lib-cov
logs
node_modules/
npm-debug.log*
pids
profile
project.xcworkspace
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
temp/
temps/
web_modules/
xcuserdata
xcuserdata/
yarn-debug.log*
yarn-error.log*

/Git/GitBuild


================================================
FILE: .gitmodules
================================================
[submodule "Git/Core"]
	path = Git/Core
	url = https://github.com/git/git


================================================
FILE: .root
================================================


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2021 Lakr Aream

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

================================================
FILE: MyYearWithGit/App/App.swift
================================================
//
//  App.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/26.
//

import AppKit
import SwiftUI

let preferredApplicationSize = CGSize(width: 750, height: 450)
let preferredTitleSize: CGFloat = 32

// just in case if we are going to use it later
let currentBootWorkingDir: String = FileManager
    .default
    .currentDirectoryPath

let processCount: Int = {
    var count = ProcessInfo
        .processInfo
        .processorCount
    if count < 0 { count = 1 }
    return count
}()

struct MyYearWithGitApp: App {
    init() {
        unprotectWindowFromClose()
        do {
            let command = AuxiliaryExecuteWrapper.spawn(
                command: AuxiliaryExecuteWrapper.git,
                args: [
                    "version",
                ],
                timeout: 0
            ) { _ in }
            if !command.1.contains("git version") {
                DispatchQueue.main.async {
                    let alert = NSAlert()
                    alert.alertStyle = .critical
                    alert.messageText = NSLocalizedString("git 似乎没有安装,程序可能不工作。", comment: "")
                    alert.addButton(withTitle: NSLocalizedString("确定", comment: ""))
                    alert.beginSheetModal(for: NSApp.keyWindow ?? NSWindow()) { _ in
                    }
                }
            }
        }
    }

    var body: some Scene {
        WindowGroup { content }
            .windowStyle(.hiddenTitleBar)
            .commands { CommandGroup(replacing: .newItem) {} }
            .restrictWindowResizing()
    }

    // fixed size for better control over layout effect
    var content: some View {
        NavigatorView()
            .ignoresSafeArea()
            .frame(
                width: preferredApplicationSize.width,
                height: preferredApplicationSize.height,
                alignment: .center
            )
            .onReceive(NotificationCenter.default.publisher(for: NSApplication.willUpdateNotification), perform: { _ in
                hideWindowRelatedButtons()
            })
    }

    func hideWindowRelatedButtons() {
        for window in NSApplication.shared.windows {
            window.standardWindowButton(NSWindow.ButtonType.zoomButton)?.isHidden = true
            window.standardWindowButton(NSWindow.ButtonType.miniaturizeButton)?.isHidden = true
        }
    }
}

private extension Scene {
    func restrictWindowResizing() -> some Scene {
        if #available(macOS 13.0, *) {
            return self.windowResizability(.contentSize)
        }
        return self
    }
}

extension View {
    func makeHoverPointer() -> some View {
        onHover { hover in
            if hover {
                NSCursor.pointingHand.push()
            } else {
                NSCursor.pop()
            }
        }
    }
}

func unprotectWindowFromClose() {
    UserDefaults.standard.set(false, forKey: "wiki.qaq.window.confirm.close")
}

func protectWindowFromClose() {
    UserDefaults.standard.set(true, forKey: "wiki.qaq.window.confirm.close")
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/AccentColor.colorset/Contents.json
================================================
{
  "colors" : [
    {
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
    "images": [
        {
            "size": "16x16",
            "idiom": "mac",
            "filename": "icon-16.png",
            "scale": "1x"
        },
        {
            "size": "16x16",
            "idiom": "mac",
            "filename": "icon-16@2x.png",
            "scale": "2x"
        },
        {
            "size": "32x32",
            "idiom": "mac",
            "filename": "icon-32.png",
            "scale": "1x"
        },
        {
            "size": "32x32",
            "idiom": "mac",
            "filename": "icon-32@2x.png",
            "scale": "2x"
        },
        {
            "size": "128x128",
            "idiom": "mac",
            "filename": "icon-128.png",
            "scale": "1x"
        },
        {
            "size": "128x128",
            "idiom": "mac",
            "filename": "icon-128@2x.png",
            "scale": "2x"
        },
        {
            "size": "256x256",
            "idiom": "mac",
            "filename": "icon-256.png",
            "scale": "1x"
        },
        {
            "size": "256x256",
            "idiom": "mac",
            "filename": "icon-256@2x.png",
            "scale": "2x"
        },
        {
            "size": "512x512",
            "idiom": "mac",
            "filename": "icon-512.png",
            "scale": "1x"
        },
        {
            "size": "512x512",
            "idiom": "mac",
            "filename": "icon-512@2x.png",
            "scale": "2x"
        }
    ],
    "info": {
        "version": 1,
        "author": "icon.wuruihong.com"
    }
}

================================================
FILE: MyYearWithGit/App/Assets.xcassets/Contents.json
================================================
{
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/badge.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "wall.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/bitbucket.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "bitbucket_icon.svg",
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/git.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "git.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/github.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "GitHub-Mark-120px-plus.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/gitlab.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "gitlab.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/qrcode.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "39__700a529aa6d6df65e62f2f7def773e06_e86fdd9ba31ec0fd57ed3c79bb536bdb.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/Contents.json
================================================
{
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.aqi.high.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.aqi.high.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.aqi.low.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.aqi.low.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.aqi.medium.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.aqi.medium.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.circle.fill.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.circle.fill.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.bolt.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.bolt.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.bolt.rain.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.bolt.rain.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.drizzle.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.drizzle.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.fog.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.fog.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.hail.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.hail.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.heavyrain.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.heavyrain.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.moon.bolt.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.moon.bolt.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.moon.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.moon.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.moon.rain.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.moon.rain.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.rain.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.rain.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.sleet.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.sleet.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.snow.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.snow.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.sun.bolt.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.sun.bolt.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.sun.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.sun.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.sun.rain.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.cloud.sun.rain.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.humidity.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.humidity.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.hurricane.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.hurricane.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.moon.circle.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.moon.circle.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.moon.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.moon.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.moon.stars.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.moon.stars.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.smoke.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.smoke.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.snowflake.circle.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.snowflake.circle.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.snowflake.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.snowflake.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.sparkles.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.sparkles.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.sun.and.horizon.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.sun.and.horizon.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.sun.dust.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.sun.dust.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.sun.haze.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.sun.haze.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.sun.max.circle.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.sun.max.circle.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.sun.max.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.sun.max.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.sun.min.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.sun.min.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.sunrise.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.sunrise.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.sunset.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.sunset.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.thermometer.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.thermometer.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.thermometer.snowflake.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.thermometer.snowflake.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.thermometer.sun.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.thermometer.sun.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.tornado.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.tornado.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.tropicalstorm.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.tropicalstorm.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.wind.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.wind.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Assets.xcassets/sfexp/custom.wind.snow.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "custom.wind.snow.png",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "template-rendering-intent" : "original"
  }
}


================================================
FILE: MyYearWithGit/App/Hooker.m
================================================
//
//  AskBeforeCloseMyWindow.swift
//
//
//  Created by Lakr Aream on 2021/11/30.
//

#import <AppKit/AppKit.h>
#import <objc/runtime.h>

static void HookMessage(Class cls, SEL selName, IMP replaced, IMP *orig) {
    Method origMethod = class_getInstanceMethod(cls, selName);
    if (!origMethod) {
        printf("nullprt origMethod, check class and selector name\n");
        return;
    }
    *orig = method_setImplementation(origMethod, replaced);
#ifdef DEBUG
    printf("HookMessage %p -> %p <%s>\n", orig, replaced, [NSStringFromClass(cls) UTF8String]);
#endif
}

static void (*original_NSWindow_close)(NSWindow *self, SEL _cmd);
static void replaced_NSWindow_close(NSWindow *self, SEL _cmd)
{
    NSString *className = NSStringFromClass([self class]);
    if (![className isEqualToString:@"SwiftUI.SwiftUIWindow"]) {
        original_NSWindow_close(self, _cmd);
        return;
    }
    
    // check if we need to perform this action
    NSString *userDefaultKey = @"wiki.qaq.window.confirm.close";
    if ([[[NSUserDefaults standardUserDefaults] valueForKey:userDefaultKey] boolValue] != YES) {
        original_NSWindow_close(self, _cmd);
        exit(0);
        return;
    }
    
    NSAlert *alert = [[NSAlert alloc] init];
    [alert setAlertStyle:NSAlertStyleCritical];
    [alert setMessageText:NSLocalizedString(@"关闭窗口将不会保存你的分析记录。", nil)];
    [alert addButtonWithTitle:NSLocalizedString(@"关闭", nil)];
    [alert addButtonWithTitle:NSLocalizedString(@"取消", nil)];
    NSWindow *window = [NSApp keyWindow];
    if (window) {
        [alert beginSheetModalForWindow:window completionHandler:^(NSModalResponse returnCode) {
            if (returnCode == NSAlertFirstButtonReturn) {
                exit(0);
            }
        }];
    } else {
        if ([alert runModal] == NSAlertFirstButtonReturn) {
            exit(0);
        }
    }
    return;
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"

__attribute__((constructor))
static void makeMyMagicWork(void) {
    // do our magic
    HookMessage(
        objc_getClass("NSWindow"),
        NSSelectorFromString(@"close"),
        (IMP)&replaced_NSWindow_close,
        (IMP *)&original_NSWindow_close
    );
}

#pragma clang diagnostic pop


================================================
FILE: MyYearWithGit/App/InfoPlist.xcstrings
================================================
{
  "sourceLanguage" : "zh-Hans",
  "strings" : {
    "CFBundleDisplayName" : {
      "comment" : "Bundle display name",
      "extractionState" : "extracted_with_value",
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Git Year"
          }
        },
        "zh-Hans" : {
          "stringUnit" : {
            "state" : "new",
            "value" : "年度代码"
          }
        }
      }
    },
    "CFBundleName" : {
      "comment" : "Bundle name",
      "extractionState" : "extracted_with_value",
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "My Year w/ Git"
          }
        },
        "zh-Hans" : {
          "stringUnit" : {
            "state" : "new",
            "value" : "MyYearWithGit"
          }
        }
      }
    },
    "NSHumanReadableCopyright" : {
      "comment" : "Copyright (human-readable)",
      "extractionState" : "extracted_with_value",
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Copyright © 2024 @Lakr233's Team. All Rights Reserved."
          }
        },
        "zh-Hans" : {
          "stringUnit" : {
            "state" : "new",
            "value" : "标准件厂长@砍砍"
          }
        }
      }
    },
    "年度代码报告" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Annually Code Report"
          }
        },
        "zh-Hans" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "年度代码报告"
          }
        }
      }
    }
  },
  "version" : "1.0"
}

================================================
FILE: MyYearWithGit/App/Localizable.xcstrings
================================================
{
  "sourceLanguage" : "zh-Hans",
  "strings" : {
    "" : {
      "shouldTranslate" : false
    },
    " %@ " : {
      "shouldTranslate" : false
    },
    " %lld " : {
      "shouldTranslate" : false
    },
    "**制作名单**\n\n此项目由 [标准件厂长@砍砍](https://twitter.com/Lakr233) 发起,设计,并完成撰写。\n\n与此同时,感谢 [Cyandev](https://twitter.com/unixzii) [拾一](https://twitter.com/__oquery) [82Flex](https://twitter.com/82flex) 与我一同前行。排名不分先后。\n\n**软件许可证**\n\n此项目使用了 [Octokit](https://github.com/nerdishbynature/octokit.swift) 与 [RequestKit](https://github.com/nerdishbynature/RequestKit.git) 来处理 GitHub 相关 Api,请参考他们的使用许可。\n\n此项目使用了来自 [Git](https://git-scm.com/downloads/logos) [GitHub](https://github.com/logos) [GitLab](https://about.gitlab.com/press/press-kit/) [Bitbucket](https://Bitbucket.org/) 的相关图标,请参考他们的使用许可。\n\n2021 冬,最后更新于 2024 年。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "**Made by List**\n\nThis project was initiated, designed, and written by [@Lakr233](https://twitter.com/Lakr233).\n\nAt the same time, thanks to [Cyandev](https://twitter.com/unixzii), [拾一](https://twitter.com/__oquery), and [82Flex](https://twitter.com/82flex) for working with me. The ranking is in no particular order.\n\n**Software Licenses**\n\nThis project uses [Octokit](https://github.com/nerdishbynature/octokit.swift) and [RequestKit](https://github.com/nerdishbynature/RequestKit.git) to handle GitHub-related APIs. Please refer to their respective licenses for use.\n\nThis project uses related icons from [Git](https://git-scm.com/downloads/logos), [GitHub](https://github.com/logos), [GitLab](https://about.gitlab.com/press/press-kit/), and [Bitbucket](https://Bitbucket.org/). Please refer to their respective licenses for use.\n\nWinter 2021, last updated in 2024.\n"
          }
        }
      }
    },
    "%@" : {
      "shouldTranslate" : false
    },
    "%@  行" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "%@ Line(s)"
          }
        }
      }
    },
    "%@ - %@" : {
      "localizations" : {
        "zh-Hans" : {
          "stringUnit" : {
            "state" : "new",
            "value" : "%1$@ - %2$@"
          }
        }
      },
      "shouldTranslate" : false
    },
    "%@ 年" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "%@ Year"
          }
        }
      }
    },
    "%@ 年 x %@" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "%1$@ x %2$@"
          }
        },
        "zh-Hans" : {
          "stringUnit" : {
            "state" : "new",
            "value" : "%1$@ 年 x %2$@"
          }
        }
      }
    },
    "%@ 是我今年的代言词。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "%@ tagged my year."
          }
        }
      }
    },
    "%@的年度代码报告" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "%@’s Annually Code Report"
          }
        }
      }
    },
    "%lld" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "%lld"
          }
        }
      },
      "shouldTranslate" : false
    },
    "%lld 月 %lld 日" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "%1$lld @ %2$lld th"
          }
        },
        "zh-Hans" : {
          "stringUnit" : {
            "state" : "new",
            "value" : "%1$lld 月 %2$lld 日"
          }
        }
      }
    },
    "© %lld 标准件厂长@砍砍 & 他的朋友们" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Copyright © %lld @Lakr233's Team. All Rights Reserved."
          }
        }
      }
    },
    "↓ 向下滑动开启报告 ↓" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "↓ Open My Git Letter ↓"
          }
        }
      }
    },
    ">>" : {
      "shouldTranslate" : false
    },
    "Bitbucket" : {
      "shouldTranslate" : false
    },
    "Bufeature 制造机" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Bufeature Maker"
          }
        }
      }
    },
    "Bufeature: <noun> bug feature, feature with bug." : {
      "shouldTranslate" : false
    },
    "ghp_xxxxxx" : {
      "shouldTranslate" : false
    },
    "Git" : {
      "shouldTranslate" : false
    },
    "git 似乎没有安装,程序可能不工作。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "It looks like git was not installed, this program may not work."
          }
        }
      }
    },
    "GitHub" : {
      "shouldTranslate" : false
    },
    "GitLab" : {
      "shouldTranslate" : false
    },
    "https://your.git.lab.example.com" : {
      "shouldTranslate" : false
    },
    "namespace::" : {
      "shouldTranslate" : false
    },
    "xxxxxx" : {
      "shouldTranslate" : false
    },
    "上串下跳的提交,是开心,是愉悦,还是害怕,或者担心呢?" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "The erratic commits — are they driven by joy, pleasure, fear, or perhaps worry?"
          }
        }
      }
    },
    "下午" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Afternoon"
          }
        }
      }
    },
    "个人访问令牌" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Personal Access Token"
          }
        }
      }
    },
    "中午" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Noon"
          }
        }
      }
    },
    "人们说色即是空,空即是色。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Form is emptiness, and emptiness is form."
          }
        }
      }
    },
    "今年,我获得了不少成就。下面是我愿意和你分享的一些。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "This year, I achieved quite a few things. Here are some I’d like to share with you."
          }
        }
      }
    },
    "今年有一天的提交次数超过五十次" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Having a day committed over 50 times."
          }
        }
      }
    },
    "今年有一天的提交次数超过百次" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Having a day committed over 100 times."
          }
        }
      }
    },
    "今年有且只有一次提交" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Being Single"
          }
        }
      }
    },
    "今年没有写代码" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Never Code This Year"
          }
        }
      }
    },
    "今年的提交中熟练使用了超过六种语言" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "More then 6 language was used this year."
          }
        }
      }
    },
    "仓库因你增添了 %@ 行代码,也减去了 %@ 行的重量。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Repository added %1$@ line(s) of code made by your hand, while removed %2$@ line(s), also made by your hand."
          }
        },
        "zh-Hans" : {
          "stringUnit" : {
            "state" : "new",
            "value" : "仓库因你增添了 %1$@ 行代码,也减去了 %2$@ 行的重量。"
          }
        }
      }
    },
    "他们也陪我走过一段旅程。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "They have also accompanied me on a journey."
          }
        }
      }
    },
    "他们说多少不重要,因为我的提交,每一次都心意满满。😮" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "They say the number doesn’t matter, because each of my commits is filled with intention. 😮"
          }
        }
      }
    },
    "他是我最好的伙伴。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "He is my best partner."
          }
        }
      }
    },
    "代码里,这些词经常出现" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "In your code, by your mind. These words are frequent."
          }
        }
      }
    },
    "以获取 App 专用密码。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "to obtain the App-specific password."
          }
        }
      }
    },
    "以获取个人访问令牌。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "to obtain a personal access token."
          }
        }
      }
    },
    "休养生息" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Taking Break"
          }
        }
      }
    },
    "你可添加本地或远端的仓库,不用担心仓库重复,相同的提交哈希仅计算一次。\n远端仓库在分析时会被载入本地临时文件夹内,分析完成以后会从本地删除。\n你可能需要额外的步骤来获取远端仓库的访问令牌,登录时会自动添加邮件地址。\n克隆仅支持使用 HTTPS 协议。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "You can add local or remote repositories without worrying about duplication. The same commit hash will only be counted once.\nRemote repositories will be loaded into a local temporary folder during analysis and will be deleted locally after the analysis is complete.\nYou may need additional steps to obtain an access token for remote repositories. Your email address will be automatically added during login.\nCloning only supports the HTTPS protocol. "
          }
        }
      }
    },
    "你看到了吗,这一页,有 1010 行空行呢。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Did you see this? This page has 1010 blank lines."
          }
        }
      }
    },
    "修得的福报,是我一生最大的欢喜。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "The good karma I’ve earned is the greatest joy of my life."
          }
        }
      }
    },
    "偷得浮生半日闲,可不能再修福报啦!" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Having a half of the day off keyboard, no more coding!"
          }
        }
      }
    },
    "全勤战士" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Perfect Attendance Warrior"
          }
        }
      }
    },
    "全年提交热力图" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Annual Commit Heatmap"
          }
        }
      }
    },
    "全年每天都有提交记录" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Committed every single day of the year"
          }
        }
      }
    },
    "共 %lld 个仓库" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "%lld repository in total"
          }
        }
      }
    },
    "关闭" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Close"
          }
        }
      }
    },
    "关闭窗口将不会保存你的分析记录。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Close this window will delete your analysis record."
          }
        }
      }
    },
    "凌晨" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Early Morning"
          }
        }
      }
    },
    "分析过程中不可载入数据,请稍后再试。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Data can not be loaded while in analysis."
          }
        }
      }
    },
    "删除" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Delete"
          }
        }
      }
    },
    "删除关键词" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Delete the keyword."
          }
        }
      }
    },
    "删除包含 <关键词> 的仓库,区分大小写。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Delete repositories containing the <Keyword>, case-sensitive."
          }
        }
      }
    },
    "勤劳努力" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Some Hardworking"
          }
        }
      }
    },
    "卷卷卷卷卷卷" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Haaarrrddd Wooorrrkkk"
          }
        }
      }
    },
    "发奋图强" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Hard Work"
          }
        }
      }
    },
    "取消" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Cancel"
          }
        }
      }
    },
    "可能敲代码,正是我的乐趣吧。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Writing code might just be my source of joy."
          }
        }
      }
    },
    "喜欢在下午茶时间提交代码" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Likes to submit code during afternoon tea time"
          }
        }
      }
    },
    "喜欢在中午提交代码" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Likes to submit code during the noon"
          }
        }
      }
    },
    "喜欢在午夜时分提交代码" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Likes to submit code during the early morning"
          }
        }
      }
    },
    "喜欢在早晨提交代码" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Likes to submit code during the morning"
          }
        }
      }
    },
    "喜欢在晚上提交代码" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Likes to submit code during the evening"
          }
        }
      }
    },
    "喜欢在晚饭时间提交代码" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Likes to submit code during dinner time"
          }
        }
      }
    },
    "回过头来看看这一年,似乎付出了不少。咱一共活跃了 %@ 天。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Looking back on this year, it seems quite a lot of effort was put in. We were active for %@ days.\n"
          }
        }
      }
    },
    "回过头来看看这一年,咱一共活跃了 %@ 天。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Looking back on this year, we were active for %@ days.\n"
          }
        }
      }
    },
    "在 %@ 年" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "In the year %@"
          }
        }
      }
    },
    "在代码或者提交备注中使用了不少的脏话" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "A fair amount of profanity was used in the code or commit messages."
          }
        }
      }
    },
    "在代码或者提交备注中使用的最多的词语是脏话" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "The most frequently used word in code or commit messages is profanity."
          }
        }
      }
    },
    "在剩余的时光里," : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "In the remaining time,"
          }
        }
      }
    },
    "在这一年里,我使用这门语言提交了 %@ 行代码。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "In this year, I have submitted %@ lines of code using this language."
          }
        }
      }
    },
    "在这短短的一天里,你一共提交了 %@ 次代码。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "In just this short day, you have made %@ commits."
          }
        }
      }
    },
    "在这里输入表达式" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Enter expression here."
          }
        }
      }
    },
    "地址" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Address"
          }
        }
      }
    },
    "夜猫子" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Night Owl"
          }
        }
      }
    },
    "大概是很特别的一天。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Looks like a special day."
          }
        }
      }
    },
    "天啦噜!我的摸鱼流量超过了 100TB 呢!" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Oh my goodness! My “slacking off” bandwidth has exceeded 100TB!"
          }
        }
      }
    },
    "天才第一步" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "First Step"
          }
        }
      }
    },
    "如果不计算周末的日子,则是 %@ 次。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "If weekends are not counted, it will be %@ times."
          }
        }
      }
    },
    "如果说代码是有温度的字符,那仓库便是咱的小太阳~ 🤫" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "If code is made up of characters with warmth, then the repository is our little sun~ 🤫"
          }
        }
      }
    },
    "完成" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Done"
          }
        }
      }
    },
    "导出分析数据" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Export Analysis Data"
          }
        }
      }
    },
    "小试牛刀" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Try My Best"
          }
        }
      }
    },
    "干饭人!干饭魂!" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Lets Have Launch First"
          }
        }
      }
    },
    "平均而言,我一天提交代码 %@ 次。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "On average, %@ commit(s) was made over day to day."
          }
        }
      }
    },
    "应用密码" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "App Passwrod"
          }
        }
      }
    },
    "应该是太冷门了吧,数据库里找不到对应的语言。🥲" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "It’s probably too obscure, that’s why the language can’t be found in the database. 🥲"
          }
        }
      }
    },
    "开启我的年度报告" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Open My Annual Report"
          }
        }
      }
    },
    "感谢我的仓库们,他们记录着我生活的点点滴滴。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Many thanks to our repository, the kept our records."
          }
        }
      }
    },
    "成就墙" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Achievements"
          }
        }
      }
    },
    "我不知道你写了什么" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "I’m not sure what you wrote either."
          }
        }
      }
    },
    "我也不知道你来这里干什么" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "I don’t know why you’ve here."
          }
        }
      }
    },
    "我从来不摸鱼,因为没有鱼给我摸。🐟" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "I never slack off, because there’s no fish for me to touch. 🐟"
          }
        }
      }
    },
    "我们将会列出你的全部仓库地址供你挑选,稍后克隆到本地为分析作准备。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "We will list all your repository addresses for you to choose from, and later clone them to your local machine to prepare for analysis."
          }
        }
      }
    },
    "我会写很多很多的单词,很多很多的句子。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "I can write many, many words, many, many sentences."
          }
        }
      }
    },
    "我最喜欢在 %@ 的时候提交代码,总共提交了 %lld 次。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "I love submitting code when %1$@, and I have made a total of %2$lld commits."
          }
        },
        "zh-Hans" : {
          "stringUnit" : {
            "state" : "new",
            "value" : "我最喜欢在 %1$@ 的时候提交代码,总共提交了 %2$lld 次。"
          }
        }
      }
    },
    "我和我的代码,还有这一年。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "My code, my journey, and this year."
          }
        }
      }
    },
    "我很专一,没有使用过其他的语言。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "I am very dedicated and have never used any other language."
          }
        }
      }
    },
    "我想你也会很喜欢的,我如此说道,我如此和你说道。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "I think you will like it too, as I say this, I say it to you."
          }
        }
      }
    },
    "我是卷王本王 🤪" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "I am the King of Competition! 🤪"
          }
        }
      }
    },
    "我是卷王王中王本王" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "King of Compete"
          }
        }
      }
    },
    "我是奥特曼" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "I’m Altman"
          }
        }
      }
    },
    "我的 Bufeature 做好了吗?" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Is my Bufeature ready?"
          }
        }
      }
    },
    "我的年度代码总结" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "My Annual Code Summary"
          }
        }
      }
    },
    "我着实不能理解其中的含义。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "I truly cannot understand the meaning behind it."
          }
        }
      }
    },
    "打印" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Print"
          }
        }
      }
    },
    "扫码开启你的专属年度代码提交报告" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Scan the QR code to unlock your personalized annual code commit report."
          }
        }
      }
    },
    "排除列表" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Exclude List"
          }
        }
      }
    },
    "提交的次数为负数" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Negative Commits"
          }
        }
      }
    },
    "提交记录告诉咱:" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "The commit history tells us:"
          }
        }
      }
    },
    "提交记录里,这些词经常出现" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "These words often appear in the commit history:"
          }
        }
      }
    },
    "数据源" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Data Source"
          }
        }
      }
    },
    "文件名关键词" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Filename Keyword"
          }
        }
      }
    },
    "文件名关键词 匹配大小写" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Filename Keyword & Case Sensitive"
          }
        }
      }
    },
    "文件名正则表达式完整匹配" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Filename Regex Full Match"
          }
        }
      }
    },
    "文明语言大师" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Civilized Language Master"
          }
        }
      }
    },
    "文明语言学者" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Civilized Language Scholar"
          }
        }
      }
    },
    "无名氏" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Anonymous"
          }
        }
      }
    },
    "早晨" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Morning"
          }
        }
      }
    },
    "早睡早起身体好" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Early to bed, early to rise, healthy body."
          }
        }
      }
    },
    "时光印记" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Time Traces"
          }
        }
      }
    },
    "星星有月亮,代码回家有仓库,而你有我相伴。😛" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "The stars have the moon, code has repositories to return to, and you have me by your side. 😛"
          }
        }
      }
    },
    "星爸爸和气氛组的关怀" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "The coffee shop is necessary"
          }
        }
      }
    },
    "是的,我又在摸鱼 🥺" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Haha, I see! Sometimes a little break is needed! 😅"
          }
        }
      }
    },
    "晚上" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Night"
          }
        }
      }
    },
    "晚饭的吃好" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Dinner the Best"
          }
        }
      }
    },
    "晚餐时间" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Dinner Time"
          }
        }
      }
    },
    "有 %@ 个周末的日子,我在仓库留下了身影。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "There are %@ weekends, and I’ve left my mark in the repository."
          }
        }
      }
    },
    "有一些些提交" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Committed Some Sometimes"
          }
        }
      }
    },
    "有一些提交" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Committed Sometimes"
          }
        }
      }
    },
    "有很多很多很多很多的提交" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Many Many Many Commits"
          }
        }
      }
    },
    "有很多提交" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Many Commits"
          }
        }
      }
    },
    "未找到有效的仓库。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "No valid repository found."
          }
        }
      }
    },
    "本地仓库" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Local Repository"
          }
        }
      }
    },
    "校验码: 0x%@" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Checksum: 0x%@"
          }
        }
      }
    },
    "正在从 Bitbucket 下载仓库 %@..." : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Downloading repository %@ from Bitbucket…"
          }
        }
      }
    },
    "正在从 Github 下载仓库 %@..." : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Downloading repository %@ from GitHub…"
          }
        }
      }
    },
    "正在从 GitLab 下载仓库 %@..." : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Downloading repository %@ from GitLab…"
          }
        }
      }
    },
    "正在分析 %@..." : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Analysis %@…"
          }
        }
      }
    },
    "正在创建分析副本 %@..." : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Creating analysis copy %@…"
          }
        }
      }
    },
    "正在处理..." : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Processing…"
          }
        }
      }
    },
    "正在查找代码仓库..." : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Searching for code repositories…"
          }
        }
      }
    },
    "正在生成汇总..." : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Generating Summary…"
          }
        }
      }
    },
    "正在解析数据..." : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Decoding data…"
          }
        }
      }
    },
    "此年度报告支持以下数据源" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "This report supports following data source"
          }
        }
      }
    },
    "每月代码量统计" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Monthly Code Statistics"
          }
        }
      }
    },
    "没有可用的数据源,分析被取消。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "No data source available."
          }
        }
      }
    },
    "没有可用的数据源,请点击上面的按钮来添加。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "No available data sources. Please click the button above to add."
          }
        }
      }
    },
    "添加" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Add"
          }
        }
      }
    },
    "添加来自 Bitbucket 的仓库" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Add Repository @Bitbucket"
          }
        }
      }
    },
    "添加来自 GitHub 的仓库" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Add Repository @GitHub"
          }
        }
      }
    },
    "添加来自 GitLab 的仓库" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Add Repository @GitLab"
          }
        }
      }
    },
    "添加来自本地的仓库" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Add Repository @localhost"
          }
        }
      }
    },
    "狗急了会跳墙,我急了会骂娘。一天这么多次的提交,肯定是有人被我骂得很惨吧。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "A cornered dog will jump over a wall, and when I’m pushed, I start swearing. With so many commits in a day, someone must’ve caught the brunt of my wrath, huh?"
          }
        }
      }
    },
    "生成截图" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Generate Screenshot"
          }
        }
      }
    },
    "用户名" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Username"
          }
        }
      }
    },
    "由 标准件厂长@砍砍 制作" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Made by @Lakr233"
          }
        }
      }
    },
    "睡前故事" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Nightmare Story"
          }
        }
      }
    },
    "确定" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "OK"
          }
        }
      }
    },
    "空行能让我的代码变得好看,我很喜欢。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Blank lines make my code look better, and I like it."
          }
        }
      }
    },
    "签到不是胡闹" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Sign Up & Wake Up."
          }
        }
      }
    },
    "编程语言大师" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Master of Programing Language"
          }
        }
      }
    },
    "编辑" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Edit"
          }
        }
      }
    },
    "致谢" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Acknowledgement"
          }
        }
      }
    },
    "若要忽略指定的文件,请在此处填写。\n我们将会传入提交文件的相对路径与你的排除项逐一进行匹配。\n若有一项满足,则该文件不会被记入。此次提交的其他文件仍会进行统计。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "If you wish to ignore specific files, please enter them here.\nWe will match the relative path of the submitted files with your exclusions one by one.\nIf any of the exclusions match, the file will not be counted. The other files in this submission will still be included in the statistics."
          }
        }
      }
    },
    "若要添加提交邮件地址,请在下方的文本框中输入。一次仅能输入一个,且只支持小写字符。\n若提交的电子邮件地址不在该列表内,则不会计算此次提交。\n我们会为你保存电子邮件地址记录,仅需配置一次即可。\n登录到 GitHub 或 GitLab 账号会自动添加账号所属的电子邮件地址。\n若有不愿使用的电子邮件地址,请在配置完成仓库以后,再来此处删除。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "To add a commit email address, please enter it in the text box below. Only one email address can be entered at a time, and it must be in lowercase characters.\nIf the submitted email address is not in the list, the commit will not be counted.\nWe will save the email address record for you, and you only need to configure it once.\nLogging into your GitHub or GitLab account will automatically add the email address associated with the account.\nIf there is an email address you wish not to use, please come back to delete it after the repository configuration is complete."
          }
        }
      }
    },
    "若要连接到 Bitbucket,请参考" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "To connect to Bitbucket, please refer to:"
          }
        }
      }
    },
    "若要连接到 GitHub,请参考" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "To connect to GitHub, please refer to:"
          }
        }
      }
    },
    "若要连接到 GitLab,请参考" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "To connect to GitLab, please refer to:"
          }
        }
      }
    },
    "获取数据" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Fetch Data"
          }
        }
      }
    },
    "语言大师的称号,非你莫属!" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "The title of Language Master is yours and yours alone! 🙌"
          }
        }
      }
    },
    "请为 App 专用密码添加 Account 和 Repositories 的 Read 权限。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Please grant the App-specific password Read access to Account and Repositories."
          }
        }
      }
    },
    "请为令牌添加 read_user, read_api, read_repository 权限,需要服务端支持 v4 api。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Please grant the token read_user, read_api, and read_repository permissions, and ensure the server supports the v4 API."
          }
        }
      }
    },
    "请为令牌添加 repo 和 user 的全部权限。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Please grant the token full repo and user permissions."
          }
        }
      }
    },
    "请选择一个需要分析的仓库的来源,我们将在稍后填写具体信息。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Please select the source of the repository to be analyzed. Specific details will be filled in later."
          }
        }
      }
    },
    "请选择一些文件夹,我们将从中搜索仓库。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Please select some folders from which we will search for repositories."
          }
        }
      }
    },
    "路径中存在文件名" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Path Keyword"
          }
        }
      }
    },
    "路径中存在文件名 匹配大小写" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Path Keyword & Case Sensitive"
          }
        }
      }
    },
    "路径关键词" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Path"
          }
        }
      }
    },
    "路径关键词 匹配大小写" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Path & Case Sensitive"
          }
        }
      }
    },
    "输入昵称 可选" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Enter Nickname (Optional)"
          }
        }
      }
    },
    "输入电子邮件地址" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Enter Email Address"
          }
        }
      }
    },
    "辛苦啦 🥲" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Thank you for your hard work! 🥲"
          }
        }
      }
    },
    "过滤器" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Filter"
          }
        }
      }
    },
    "还有 %lld 种语言..." : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "And %lld more languages..."
          }
        }
      }
    },
    "这一天,是忙碌的自己,没吃好,没睡好。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "This day is the busy version of myself — didn’t eat well, didn’t sleep well."
          }
        }
      }
    },
    "这一年,咱一共卷了 %@ 天。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "This year, I’ve been competitive for a total of %@ days."
          }
        }
      }
    },
    "这一年的周末,我都没有提交代码。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "I didn’t commit any code on the weekends this year."
          }
        }
      }
    },
    "这一年里,我总共进行了 %@ 次代码提交。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "In this year, I made a total of %@ code commits."
          }
        }
      }
    },
    "这份文档" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "This document"
          }
        }
      }
    },
    "这会删除分析记录。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "This will delete analysis record."
          }
        }
      }
    },
    "这是我今年写的空行的数量。空行,没错,就是只有空格或者什么都没有的那一行。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "This is the number of empty lines I wrote this year. Empty lines, yes, the ones that only have spaces or nothing at all."
          }
        }
      }
    },
    "这是我最常用的语言。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "This is the language I use most often."
          }
        }
      }
    },
    "这是我在代码中最常写到的单词,他出现了 %lld 次。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "This is the word I most frequently wrote in my code, and it appeared %lld times."
          }
        }
      }
    },
    "这是我在代码提交记录中最常写到的单词,他出现了 %lld 次。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "This is the word I most frequently wrote in my commit history, and it appeared %lld times."
          }
        }
      }
    },
    "这相当于好几百只 🐳🐳🐳🐳🐳🐳 从我身边游过" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "That’s like several hundred 🐳🐳🐳🐳🐳🐳 swimming past me!"
          }
        }
      }
    },
    "选择..." : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Select…"
          }
        }
      }
    },
    "邮件地址" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Email Address"
          }
        }
      }
    },
    "配置排除项" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Configure Excludes"
          }
        }
      }
    },
    "配置邮箱地址" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Configure Commit Email"
          }
        }
      }
    },
    "重新开始" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Start Over"
          }
        }
      }
    },
    "风雨兼程,目的地是我向往的星辰大海。🥺" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "While the world sleep, we dream about the ocean with star. 🥺"
          }
        }
      }
    },
    "风雨兼程的 Coding 旅途,一天中我最忙碌的时段。" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Was the busy day. Was the busy hour."
          }
        }
      }
    },
    "黑客是我的外号,我总能找到属于我的 🚩! 是 🏳️‍⚧️ 还是 🏳️‍🌈 呢?" : {
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Hacker is my nickname—I always manage to claim my own 🚩! But is it 🏳️‍⚧️ or 🏳️‍🌈? 😉"
          }
        }
      }
    }
  },
  "version" : "1.0"
}

================================================
FILE: MyYearWithGit/App/main.swift
================================================
//
//  main.swift
//  MyYearWithGit
//
//  Created by 秋星桥 on 2024/12/17.
//

import Foundation

let requiredYear = 2025

setenv("GIT_TERMINAL_PROMPT", "0", 1)
setenv("GIT_LFS_SKIP_SMUDGE", "1", 1)

AuxiliaryExecuteWrapper.setupExecutables()

MyYearWithGitApp.main()


================================================
FILE: MyYearWithGit/Data/Analyser/CommitFilter.swift
================================================
//
//  CommitFilter.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/12/1.
//

import AppKit
import Foundation

class CommitFileFilter {
    static let shared = CommitFileFilter()

    private init() {
        if let str = UserDefaults.standard.value(forKey: "wiki.qaq.block.list") as? String,
           let data = str.data(using: .utf8),
           let object = try? JSONDecoder().decode([BlockItem].self, from: data)
        {
            commitBlockList = object
        }
    }

    var commitBlockList: [BlockItem] = [] {
        didSet {
            if let jsonData = try? JSONEncoder().encode(commitBlockList),
               let json = String(data: jsonData, encoding: .utf8)
            {
                UserDefaults.standard.set(json, forKey: "wiki.qaq.block.list")
            }
        }
    }

    enum BlockType: String, Codable, CaseIterable, HumanReadable {
        case nameKeyWord
        case nameKeyWordCaseSensitive
        case pathKeyWord
        case pathKeyWordCaseSensitive
        case pathComponentFullMatch
        case pathComponentFullMatchCaseSensitive
        case nameRegExFullMatch

        func readableDescription() -> String {
            switch self {
            case .nameKeyWord:
                NSLocalizedString("文件名关键词", comment: "")
            case .nameKeyWordCaseSensitive:
                NSLocalizedString("文件名关键词 匹配大小写", comment: "")
            case .pathKeyWord:
                NSLocalizedString("路径关键词", comment: "")
            case .pathKeyWordCaseSensitive:
                NSLocalizedString("路径关键词 匹配大小写", comment: "")
            case .pathComponentFullMatch:
                NSLocalizedString("路径中存在文件名", comment: "")
            case .pathComponentFullMatchCaseSensitive:
                NSLocalizedString("路径中存在文件名 匹配大小写", comment: "")
            case .nameRegExFullMatch:
                NSLocalizedString("文件名正则表达式完整匹配", comment: "")
            }
        }
    }

    typealias Passed = Bool
    struct BlockItem: Codable, Equatable {
        let type: BlockType
        let value: String

        typealias Matched = Bool
        func match(_ location: URL) -> Matched {
            switch type {
            case .nameKeyWord:
                return location
                    .lastPathComponent
                    .lowercased()
                    .contains(value.lowercased())

            case .nameKeyWordCaseSensitive:
                return location
                    .lastPathComponent
                    .contains(value)

            case .pathKeyWord:
                return location
                    .deletingLastPathComponent()
                    .path
                    .lowercased()
                    .contains(value.lowercased())

            case .pathKeyWordCaseSensitive:
                return location
                    .deletingLastPathComponent()
                    .path
                    .contains(value)

            case .pathComponentFullMatch:
                let items = location
                    .deletingLastPathComponent()
                    .pathComponents
                    .map { $0.lowercased() }
                for item in items where item == value.lowercased() {
                    return true
                }
                return false

            case .pathComponentFullMatchCaseSensitive:
                let items = location
                    .deletingLastPathComponent()
                    .pathComponents
                for item in items where item == value {
                    return true
                }
                return false

            case .nameRegExFullMatch:
                let val = location
                    .path
                    .lowercased()
                return regExMatch(for: val, in: location.lastPathComponent)
            }
        }

        func regExMatch(for regex: String, in text: String) -> Bool {
            do {
                let regex = try NSRegularExpression(pattern: regex)
                let nsString = text as NSString
                let results = regex.matches(in: text, range: NSRange(location: 0, length: nsString.length))
                return !results.isEmpty
            } catch {
                print("invalid regex: \(error.localizedDescription)")
                return false
            }
        }
    }

    func filter(_ location: URL) -> Passed {
        for blocker in commitBlockList where blocker.match(location) {
            print(
                """
                ignoring file \(location.path) matching rule \(blocker.type.readableDescription()) \(blocker.value)
                """
            )
            return false
        }
        return true
    }
}


================================================
FILE: MyYearWithGit/Data/Analyser/DictionaryBuilder.swift
================================================
//
//  DictionaryBuilder.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/29.
//

import Foundation

class DictionaryBuilder {
    static let sharedIncrease = DictionaryBuilder()
    static let sharedDecrease = DictionaryBuilder()
    static let sharedCommit = DictionaryBuilder()
    private init() {}

    var currentSession = UUID()
    var dictionary: [String: Int] = [:]

    var trimCounter = 1024

    func beginSession() -> UUID {
        let session = UUID()
        currentSession = session
        dictionary = [:]
        return session
    }

    private let lock = NSLock()

    func feed(buffer: String, session: UUID) {
        lock.lock()
        defer {
            lock.unlock()
        }
        guard session == currentSession else {
            return
        }
        buffer.enumerateSubstringsByWordsWithCamelCase { substring, _, _, _ in
            guard let substring,
                  substring.count > 3,
                  substring.elegantForDictonary,
                  Double(substring) == nil
            else {
                return
            }
            if self.dictionary[substring.lowercased(), default: 0] > 2_147_483_647 {
                return
            }
            self.dictionary[substring.lowercased(), default: 0] += 1
            self.trimCounter -= 1
            if self.trimCounter < 0 {
                self.trimCounter = 1024
            }
            if self.trimCounter == 1024 {
                self.trimMemory()
            }
        }
    }

    func trimMemory() {
        var currentTrimCount = 0 // why would it be zero? for robust
        while dictionary.keys.count > 65535 {
            var currentTrimPassCount = 0
            for key in dictionary.keys {
                let value = dictionary[key, default: 0]
                if value == currentTrimCount {
                    dictionary.removeValue(forKey: key)
                    currentTrimPassCount += 1
                }
            }
            currentTrimCount += 1
            print("trimming dictionary passed \(currentTrimPassCount)")
        }
    }

    func commitSession(session: UUID) -> [String: Int] {
        guard session == currentSession else {
            return [:]
        }
        let copy = dictionary
        _ = beginSession()
        return copy
    }
}

private let invalidCharacters = [
    CharacterSet.controlCharacters,
    CharacterSet.illegalCharacters,
    CharacterSet.controlCharacters,
    CharacterSet.whitespacesAndNewlines,
    CharacterSet.punctuationCharacters,
    CharacterSet.decimalDigits,
]

private extension String {
    var elegantForDictonary: Bool {
        if isEmpty {
            return false
        }
        for charSet in invalidCharacters {
            if rangeOfCharacter(from: charSet) != nil {
                return false
            }
        }
        return true
    }
}


================================================
FILE: MyYearWithGit/Data/Analyser/GitDiff.swift
================================================
//
//  GitDiff.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/28.
//

import Foundation

extension RepoAnalyser {
    struct GitCommitResult: Codable {
        // these are emails
        let email: String
//        let auther: String
//        let coAuthers: [String]
        // ...
        let date: Date
        // diff analysis
        let diffFiles: [GitFileDiff]
        struct GitFileDiff: Codable {
            // using the latest
            // eg .c changed to .swift, then we say it is a .swift
            let language: SourceLanguage?
            // file mode
            let mode: DiffMode
            // the emptyLine counted
            let emptyLineAdded: Int
            // add/remove
            let increasedLine: Int
            let decreasedLine: Int

            enum DiffMode: String, Codable {
                case modify
                case add
                case delete
            }
        }
    }

    func grabGitCommitDetail(withHash commitHash: String) -> [GitCommitResult.GitFileDiff] {
        let command = AuxiliaryExecuteWrapper.spawn(
            command: AuxiliaryExecuteWrapper.git,
            args: [
                "diff",
                "\(commitHash)^!",
            ], timeout: 30
        ) { _ in
        }
        
        // Check if git diff command failed
        guard command.0 == 0 else {
            print("git diff failed for commit \(commitHash), exit code: \(command.0)", to: &standardError)
            if !command.2.isEmpty {
                print("stderr: \(command.2)", to: &standardError)
            }
            return []
        }
        
        let diff = command
            .1
            .trimmingCharacters(in: .whitespacesAndNewlines)
        
        // Handle empty diff (e.g., merge commit with no changes)
        guard !diff.isEmpty else {
            return []
        }
        
        var result = [GitCommitResult.GitFileDiff]()

        var currentFileDiff: GitCommitResult.GitFileDiff?
        var currentStatus: CurrentStatus = .none
        var currentBuffer: [String] = []
        enum CurrentStatus: String {
            case none
            case header
            case body
        }

        func commitBuffer(str: String) {
            currentBuffer.append(str)
        }

        // when commit header, we construct a GitCommitResult.GitFileDiff
        func commitHeaderForAnalysis() {
            // get the first line we submit to the buffer
            // it will either be ["add", "delete", "rename"]
            // otherwise will be "index"
            guard let decisionLine = currentBuffer.first,
                  let decisionWord = decisionLine.components(separatedBy: " ").first
            else {
                print("no decision can make")
                return
            }

            var language: SourceLanguage?
            var mode: GitCommitResult.GitFileDiff.DiffMode?
            var fileName: String?
            switch decisionWord {
            case "index", "old":
                /*
                 - 0 : "old mode 100755"
                 - 1 : "new mode 100644"
                 - 2 : "index a4a32c1c..24295f0c"
                 */
                mode = .modify
                for line in currentBuffer where line.hasPrefix("+++ ") {
                    var path = String(line.dropFirst("+++ ".count))
                    while path.hasPrefix(" ") {
                        path.removeFirst()
                    }
                    // Safety check: prevent infinite loop
                    let originalPathLength = path.count
                    var removedChars = 0
                    while !path.hasPrefix("/"), path.count > 0, removedChars < originalPathLength {
                        path.removeFirst()
                        removedChars += 1
                    }
                    guard path.count > 0, path.hasPrefix("/") else {
                        print("unknown file <\(line)>", to: &standardError)
                        return
                    }
//                    print(path)
                    let url = URL(fileURLWithPath: path)
                    if !CommitFileFilter.shared.filter(url) { break }
                    fileName = url.lastPathComponent
                    language = SourceLanguage
                        .languageDecision(withFileExtension: url.pathExtension)
                    break
                }
            case "new":
                mode = .add
                for line in currentBuffer where line.hasPrefix("+++ ") {
                    var path = String(line.dropFirst("+++ ".count))
                    while path.hasPrefix(" ") {
                        path.removeFirst()
                    }
                    // Safety check: prevent infinite loop
                    let originalPathLength = path.count
                    var removedChars = 0
                    while !path.hasPrefix("/"), path.count > 0, removedChars < originalPathLength {
                        path.removeFirst()
                        removedChars += 1
                    }
                    guard path.count > 0, path.hasPrefix("/") else {
                        print("unknown file <\(line)>", to: &standardError)
                        return
                    }
//                    print(path)
                    let url = URL(fileURLWithPath: path)
                    if !CommitFileFilter.shared.filter(url) { break }
                    fileName = url.lastPathComponent
                    language = SourceLanguage
                        .languageDecision(withFileExtension: url.pathExtension)
                    break
                }
            case "similarity":
                /*
                 eg:
                 diff --git a/osfmk/corecrypto/ccn/src/ccn_set.c b/iokit/Kernel/IOPMGR.cpp
                 similarity index 80%
                 rename from osfmk/corecrypto/ccn/src/ccn_set.c
                 rename to iokit/Kernel/IOPMGR.cpp
                 index e288733..4fd29c3 100644
                 */
                mode = .modify
                for line in currentBuffer where line.hasPrefix("rename to") {
                    var path = String(line.dropFirst("rename to".count))
                    while path.hasPrefix(" ") {
                        path.removeFirst()
                    }
                    // Safety check: prevent infinite loop
                    let originalPathLength = path.count
                    var removedChars = 0
                    while !path.hasPrefix("/"), path.count > 0, removedChars < originalPathLength {
                        path.removeFirst()
                        removedChars += 1
                    }
                    guard path.count > 0, path.hasPrefix("/") else {
                        print("unknown file <\(line)>", to: &standardError)
                        return
                    }
//                    print(path)
                    let url = URL(fileURLWithPath: path)
                    if !CommitFileFilter.shared.filter(url) { break }
                    fileName = url.lastPathComponent
                    language = SourceLanguage
                        .languageDecision(withFileExtension: url.pathExtension)
                    break
                }
            case "deleted":
                mode = .delete
                for line in currentBuffer where line.hasPrefix("--- ") {
                    var path = String(line.dropFirst("--- ".count))
                    while path.hasPrefix(" ") {
                        path.removeFirst()
                    }
                    // Safety check: prevent infinite loop
                    let originalPathLength = path.count
                    var removedChars = 0
                    while !path.hasPrefix("/"), path.count > 0, removedChars < originalPathLength {
                        path.removeFirst()
                        removedChars += 1
                    }
                    guard path.count > 0, path.hasPrefix("/") else {
                        print("unknown file <\(line)>", to: &standardError)
                        return
                    }
//                    print(path)
                    let url = URL(fileURLWithPath: path)
                    if !CommitFileFilter.shared.filter(url) { break }
                    fileName = url.lastPathComponent
                    language = SourceLanguage
                        .languageDecision(withFileExtension: url.pathExtension)
                    break
                }
            default:
                print("unknown header [\(decisionWord)]", to: &standardError)
                print(currentBuffer.joined(separator: " "), to: &standardError)
                return
            }
            guard fileName != nil, let mode else {
                return
            }
            currentFileDiff = .init(
                language: language,
                mode: mode,
                emptyLineAdded: 0,
                increasedLine: 0,
                decreasedLine: 0
            )
        }

        // when commit the body, we add up the value in currentFileDiff
        func commitBodyForAnalysis() {
            guard currentBuffer.count > 0 else {
                return
            }
            guard let currentDiff = currentFileDiff else {
                // no header, drop data
                print("missing header, dropping data body", to: &standardError)
                return
            }
            var emptyLineAdded = currentDiff.emptyLineAdded
            var increasedLine = currentDiff.increasedLine
            var decreasedLine = currentDiff.decreasedLine
            for line in currentBuffer {
                var line = line
                if line.hasPrefix("+") {
                    // added
                    line.removeFirst()
                    increasedLine += 1
                    if line.trimmingCharacters(in: .whitespacesAndNewlines).count < 1 {
                        emptyLineAdded += 1
                    }
                    DictionaryBuilder
                        .sharedIncrease
                        .feed(buffer: line, session: dictonaryIncreaseSession)
                } else if line.hasPrefix("-") {
                    // removed
                    line.removeFirst()
                    decreasedLine += 1
                    DictionaryBuilder
                        .sharedIncrease
                        .feed(buffer: line, session: dictonaryDecreaseSession)
                } else {
                    // ignore
                    continue
                }
            }

            currentFileDiff = .init(
                language: currentDiff.language,
                mode: currentDiff.mode,
                emptyLineAdded: emptyLineAdded,
                increasedLine: increasedLine,
                decreasedLine: decreasedLine
            )
            // clean the body before we double this analysis
            currentBuffer = []
        }

        // when commit the barrier, reset the header, push the result if needed
        func commitBodyBarrier() {
            commitBodyForAnalysis()
            // submit to result if needed
            if let currentFileDiff {
                result.append(currentFileDiff)
            }
            currentFileDiff = nil
        }

        func commitSwitch(status: CurrentStatus) {
            // previous status is used for selector
            let privStatus = currentStatus
            currentStatus = status
            switch privStatus {
            case .none:
                break
            case .header:
                commitHeaderForAnalysis()
            case .body:
                commitBodyForAnalysis()
            }
            // now we switch the status
            switch status {
            case .none:
                if privStatus == .body {
                    commitBodyBarrier()
                    // reset the buffers
                    currentStatus = .none
                    currentBuffer = []
                }
            case .header:
                // avoid crashing if two header nested together
                if privStatus == .body {
                    commitBodyBarrier()
                    // now we are in the header
                    // nothing to do tho
                    currentStatus = .header
                    currentBuffer = []
                }
            case .body:
                // commit the header and do the switch
                currentStatus = .body
                currentBuffer = []
            }
        }

        currentBuffer = []
        currentStatus = .none
        for line in diff.components(separatedBy: "\n") {
            autoreleasepool {
                if line.hasPrefix("diff --git ") || line.hasPrefix("diff --cc ") {
                    commitSwitch(status: .header)
                    return
                }
                if line.hasPrefix("@@") {
                    commitSwitch(status: .body)
                    return
                }
                commitBuffer(str: line)
            }
        }
        // for the last block
        commitSwitch(status: .none)

        // final result generator

        return result
    }
}


================================================
FILE: MyYearWithGit/Data/Analyser/GitLog.swift
================================================
//
//  GitLog.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/28.
//

import Foundation

private let jsonDecoder = JSONDecoder()

extension RepoAnalyser {
    struct GitLogElement {
        let hash: String
        let autherEmail: String
        let date: String
        let note: String
    }

    func grabGitCommitLog() -> [GitLogElement]? {
        let command = AuxiliaryExecuteWrapper.spawn(
            command: AuxiliaryExecuteWrapper.git,
            args: [
                "log",
                "--all",
            ], timeout: 0
        ) { _ in
        }
        let output = command
            .1
            .trimmingCharacters(in: .whitespacesAndNewlines)

        var results = [GitLogElement]()

        var currentHash: String?
        var date: String?
        var autherEmail: String?
        var lineBuffer = [String]()

        func submitBarrier() {
            defer {
                currentHash = nil
                date = nil
                autherEmail = nil
                lineBuffer = []
            }
            guard let currentHash,
                  let date,
                  let autherEmail
            else {
                return
            }
            let commitLog = lineBuffer
                .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
                .filter { $0.count > 0 }
                .joined(separator: "\n")
            let build = GitLogElement(
                hash: currentHash,
                autherEmail: autherEmail,
                date: date,
                note: commitLog
            )
            results.append(build)
//            print(build)
        }

        for line in output.components(separatedBy: "\n") {
            if line.hasPrefix("commit ") {
                submitBarrier()
                currentHash = line
                    .components(separatedBy: " ")
                    .last?
                    .lowercased() // <- LOWER CASE HERE, IT'S HASH
                continue
            }
            if line.hasPrefix("Author: ") {
                let trim = String(line.dropFirst("Author:".count))
                autherEmail = trim
                    .components(separatedBy: "<")
                    .last?
                    .components(separatedBy: ">")
                    .first?
                    .lowercased()
                continue
            }
            if line.hasPrefix("Date:") {
                var line = String(line.dropFirst("Date:".count))
                while line.hasPrefix(" ") {
                    line.removeFirst()
                }
                date = line
                continue
            }
            lineBuffer.append(line)
        }
        submitBarrier()

        if results.count == 0 {
            return nil
        }
        return results
    }
}


================================================
FILE: MyYearWithGit/Data/Analyser/GitRepoResult.swift
================================================
//
//  GitRepoResult.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/28.
//

import Foundation

extension RepoAnalyser {
    struct GitRepoResult: Codable {
        let commits: [GitCommitResult]
    }

    func generateResultPackage(with result: ResultPackage.DataSource) -> ResultPackage {
        let resultPackage = ResultPackage(data: result)
        resultPackage.update(with: result)
        return resultPackage
    }
}


================================================
FILE: MyYearWithGit/Data/Analyser/RepoAnalyser.swift
================================================
//
//  RepoAnalyser.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/27.
//

import Foundation

// Sun Apr 19 01:20:44 2020 +0800

private let dateFormatters: [DateFormatter] = [
    "E MMM d HH:mm:ss yyyy Z",
    "E MMM d HH:mm:ss yyyy",
    "E, d MMM yyyy HH:mm:ss Z",
    "MM-dd-yyyy HH:mm",
    "EEEE, MMM d, yyyy",
]
.map { createFormatter($0) }

private func createFormatter(_ str: String) -> DateFormatter {
    let dateFormatter = DateFormatter()
    dateFormatter.locale = Locale(identifier: "en_US_POSIX")
    dateFormatter.dateFormat = str
    return dateFormatter
}

private func decodeDate(_ str: String) -> Date? {
    for formatter in dateFormatters {
        if let date = formatter.date(from: str) {
            return date
        }
    }
    return nil
}

private let calender = Calendar.current

class RepoAnalyser {
    static let shared = RepoAnalyser()
    private init() {}

    var currentSession = UUID()
    var currentResults = FinalReportCodeable(repos: [])
    var dictonaryIncreaseSession = UUID()
    var dictonaryDecreaseSession = UUID()
    var dictonaryCommitMessage = UUID()
    var requiredEmails = [String]()
    var commitHash: Set<String> = []

    struct FinalReportCodeable: Codable {
        var repos: [GitRepoResult]
    }

    func beginSession() -> UUID {
        let session = UUID()
        currentSession = session
        currentResults = FinalReportCodeable(repos: [])
        requiredEmails = []
        commitHash = []
        dictonaryIncreaseSession = DictionaryBuilder
            .sharedIncrease
            .beginSession()
        dictonaryDecreaseSession = DictionaryBuilder
            .sharedDecrease
            .beginSession()
        dictonaryCommitMessage = DictionaryBuilder
            .sharedCommit
            .beginSession()
        return session
    }

    func submitEmails(with: [String]) {
        requiredEmails = with
    }

    func analysis(at: URL, session: UUID) {
        guard session == currentSession else {
            return
        }
        defer {
            FileManager.default.changeCurrentDirectoryPath("/")
            // delete the repo after analysis
            try? FileManager.default.removeItem(at: at)
        }
        FileManager.default.changeCurrentDirectoryPath(at.path)
        // call git log

        guard let currentCommitLogs = grabGitCommitLog() else {
            print("failed to code git log, giving up!")
            return
        }
        var commitResults = [GitCommitResult]()

        // MARK: MULTI_THREAD

        let lock = NSLock()
        let queue = DispatchQueue(label: "wiki.qaq.git", attributes: .concurrent)
        let group = DispatchGroup()
        let boom = DispatchSemaphore(value: processCount)

        for currentCommitLog in currentCommitLogs {
            let currentCommitLog = currentCommitLog
            guard requiredEmails.contains(currentCommitLog.autherEmail),
                  let date = decodeDate(currentCommitLog.date),
                  let year = calender.dateComponents([.year], from: date).year,
                  year == requiredYear
            else {
                continue
            }
            guard !commitHash.contains(currentCommitLog.hash) else {
                continue
            }
            commitHash.insert(currentCommitLog.hash)
            autoreleasepool {
                // MARK: MULTI_THREAD

                group.enter()
                boom.wait()

                // MARK: EXEC

                queue.async {
                    print("calling analysis on commit \(currentCommitLog.hash) with \(currentCommitLog.autherEmail)")
                    let commitDiffs = self.grabGitCommitDetail(withHash: currentCommitLog.hash)
                    let commitResult = GitCommitResult(
                        email: currentCommitLog.autherEmail,
                        date: date,
                        diffFiles: commitDiffs
                    )

                    // DictionaryBuilder has it's own lock when feeding data
                    DictionaryBuilder
                        .sharedCommit
                        .feed(buffer: currentCommitLog.note, session: self.dictonaryCommitMessage)

                    lock.lock()
                    commitResults.append(commitResult)
                    lock.unlock()

                    // MARK: MULTI_THREAD

                    boom.signal()
                    group.leave()
                }
            }
        }
        guard commitResults.count > 0 else {
            print("no data was generated from repo \(at.path), skipping submit")
            return
        }
        print("analysis completed, submitting \(commitResults.count) result to repo")
        let repoResult = GitRepoResult(commits: commitResults)
        currentResults.repos.append(repoResult)
    }

    func commitResult() -> ResultPackage {
        print("compiling result for \(currentResults.repos.count) repos")
        let dataSource = ResultPackage.DataSource(
            repoResult: currentResults,
            dictionaryIncrease: DictionaryBuilder
                .sharedIncrease
                .commitSession(session: dictonaryIncreaseSession),
            dictionaryDecrease: DictionaryBuilder
                .sharedDecrease
                .commitSession(session: dictonaryDecreaseSession),
            dictionaryCommit: DictionaryBuilder
                .sharedCommit
                .commitSession(session: dictonaryCommitMessage)
        )
        let resultPackage = generateResultPackage(with: dataSource)
        _ = beginSession() // clear everything
        return resultPackage
    }
}


================================================
FILE: MyYearWithGit/Data/Api/ApiProtocol.swift
================================================
//
//  ApiProtocol.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/12/5.
//

import Foundation

protocol GitApi {
    func validate() throws
    func repositories() throws -> [URL]
}

enum ApiError: Error, LocalizedError {
    case emptyData
    case invalidUrl
    case invalidUser
    case network(reason: String)
    case statusCode(code: Int)
    case response(reason: String)

    public var errorDescription: String? {
        switch self {
        case .emptyData:
            "未找到有效的数据,请再试一次。"
        case .invalidUrl:
            "错误的 URL 数据,请再试一次。"
        case .invalidUser:
            "无效的用户信息,请再试一次。"
        case let .network(reason):
            "无法连接到服务器: \(reason)"
        case let .statusCode(code):
            "服务器返回未知状态: \(code) \(HTTPURLResponse.localizedString(forStatusCode: code))"
        case let .response(reason):
            "服务器返回错误信息:\(reason)"
        }
    }
}


================================================
FILE: MyYearWithGit/Data/Api/BitbucketApi.swift
================================================
//
//  BitbucketApi.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/12/3.
//

import Foundation

private let bbEndpoint = URL(string: "https://api.bitbucket.org/")!
private let bbCloneBase = URL(string: "https://bitbucket.org/")!

class BitbucketApi: GitApi {
    let config: Config
    struct Config {
        let token: String
    }

    // user info from validation
    var userId: String?
    var userName: String?

    init(config: Config) {
        self.config = config
    }

    // nil = invalid, otherwise "" but not nil
    func validate() throws {
        let userRequest = createRequest(withPaths: [
            "user",
        ])
        var result = false
        var error: Error?
        let sem = DispatchSemaphore(value: 0)
        URLSession
            .shared
            .dataTask(with: userRequest) { data, resp, err in
                defer { sem.signal() }

                // connection error
                if let err {
                    error = ApiError.network(reason: err.localizedDescription)
                    return
                }

                // unknown status code
                if let resp = resp as? HTTPURLResponse, resp.statusCode != 200 {
                    error = ApiError.statusCode(code: resp.statusCode)
                }

                // json decodable as dict
                guard let data,
                      let dic = try? JSONSerialization
                      .jsonObject(
                          with: data, options: .allowFragments
                      ) as? [String: Any]
                else {
                    return
                }

                // not an error
                if error == nil {
                    if let name = dic["username"] as? String {
                        self.userName = name
                    }
                    if let id = dic["account_id"] as? String {
                        self.userId = id
                        result = true
                    }
                }

                // server has detailed error description or messages
                if let errorDict = dic["error"] as? [String: Any] {
                    if let errorDetail = errorDict["detail"] as? String,
                       let errorMessage = errorDict["message"] as? String
                    {
                        error = ApiError.response(reason: "\(errorDetail) (\(errorMessage))")
                    }
                }
            }
            .resume()
        let emailRequest = createRequest(withPaths: [
            "user",
            "emails",
        ])
        URLSession
            .shared
            .dataTask(with: emailRequest) { data, resp, err in
                defer { sem.signal() }

                // connection error
                if let err {
                    error = ApiError.network(reason: err.localizedDescription)
                    return
                }

                // unknown status code
                if let resp = resp as? HTTPURLResponse, resp.statusCode != 200 {
                    error = ApiError.statusCode(code: resp.statusCode)
                }

                // json decodable as dict
                guard let data,
                      let dic = try? JSONSerialization
                      .jsonObject(
                          with: data, options: .allowFragments
                      ) as? [String: Any]
                else {
                    return
                }

                // not an error
                if error == nil {
                    if let emailValues = dic["values"] as? [[String: Any]] {
                        emailValues
                            .compactMap { $0["email"] as? String }
                            .forEach { User.current.email.insert($0) }
                    }
                }

                // server has detailed error description or messages
                if let errorDict = dic["error"] as? [String: Any] {
                    if let errorDetail = errorDict["detail"] as? String,
                       let errorMessage = errorDict["message"] as? String
                    {
                        error = ApiError.response(reason: "\(errorDetail) (\(errorMessage))")
                    }
                }
            }.resume()

        sem.wait() // URLSession default timeout is 60 * 2 = 120 secs

        if let error {
            throw error
        }

        sem.wait()

        if let error {
            throw error
        }

        guard result else {
            throw ApiError.invalidUser
        }
    }

    func repositories() throws -> [URL] {
        var result = Set<URL>()
        for workspace in try workspaces() {
            var endpoints = Set<URL>(arrayLiteral: workspace)
            while let endpoint = endpoints.popFirst() {
                var error: Error?
                let sem = DispatchSemaphore(value: 0)
                URLSession
                    .shared
                    .dataTask(with: createRequest(withURL: endpoint)) { data, resp, err in
                        defer { sem.signal() }

                        // connection error
                        if let err {
                            error = ApiError.network(reason: err.localizedDescription)
                            return
                        }

                        // unknown status code
                        if let resp = resp as? HTTPURLResponse, resp.statusCode != 200 {
                            error = ApiError.statusCode(code: resp.statusCode)
                        }

                        // json decodable as dict
                        guard let data,
                              let dic = try? JSONSerialization
                              .jsonObject(
                                  with: data, options: .allowFragments
                              ) as? [String: Any]
                        else {
                            return
                        }

                        // not an error
                        if error == nil {
                            if let retValues = dic["values"] as? [[String: Any]] {
                                let repoHrefs = retValues.compactMap { retVal in
                                    ((retVal["links"] as? [String: Any])?["clone"] as? [[String: String]])?.first(where: { $0["name"] == "https" })?["href"]
                                }
                                let repoURLs = repoHrefs.compactMap { URL(string: $0) }
                                result.formUnion(repoURLs)
                            }
                            if let nextHref = dic["next"] as? String, let nextURL = URL(string: nextHref) {
                                endpoints.insert(nextURL)
                            }
                        }

                        // server has detailed error description or messages
                        if let errorDict = dic["error"] as? [String: Any] {
                            if let errorDetail = errorDict["detail"] as? String,
                               let errorMessage = errorDict["message"] as? String
                            {
                                error = ApiError.response(reason: "\(errorDetail) (\(errorMessage))")
                            }
                        }
                    }.resume()
                sem.wait()
                if let error {
                    throw error
                }
            }
        }
        guard result.count > 0 else {
            throw ApiError.emptyData
        }
        return [URL](result).map { bbCloneBase.appendingPathComponent(String($0.path.dropFirst())) }
    }

    func workspaces() throws -> [URL] {
        var endpoints = Set<URL>(arrayLiteral: bbEndpoint.appendingPathComponent("2.0").appendingPathComponent("workspaces"))
        var result = Set<URL>()
        while let endpoint = endpoints.popFirst() {
            var error: Error?
            let sem = DispatchSemaphore(value: 0)
            URLSession
                .shared
                .dataTask(with: createRequest(withURL: endpoint)) { data, resp, err in
                    defer { sem.signal() }

                    // connection error
                    if let err {
                        error = ApiError.network(reason: err.localizedDescription)
                        return
                    }

                    // unknown status code
                    if let resp = resp as? HTTPURLResponse, resp.statusCode != 200 {
                        error = ApiError.statusCode(code: resp.statusCode)
                    }

                    // json decodable as dict
                    guard let data,
                          let dic = try? JSONSerialization
                          .jsonObject(
                              with: data, options: .allowFragments
                          ) as? [String: Any]
                    else {
                        return
                    }

                    // not an error
                    if error == nil {
                        if let retValues = dic["values"] as? [[String: Any]] {
                            let repoHrefs = retValues.compactMap { (($0["links"] as? [String: Any])?["repositories"] as? [String: String])?["href"] }
                            let repoURLs = repoHrefs.compactMap { URL(string: $0) }
                            result.formUnion(repoURLs)
                        }
                        if let nextHref = dic["next"] as? String, let nextURL = URL(string: nextHref) {
                            endpoints.insert(nextURL)
                        }
                    }

                    // server has detailed error description or messages
                    if let errorDict = dic["error"] as? [String: Any] {
                        if let errorDetail = errorDict["detail"] as? String,
                           let errorMessage = errorDict["message"] as? String
                        {
                            error = ApiError.response(reason: "\(errorDetail) (\(errorMessage))")
                        }
                    }
                }.resume()
            sem.wait()
            if let error {
                throw error
            }
        }
        guard result.count > 0 else {
            throw ApiError.emptyData
        }
        return [URL](result)
    }

    func createURL(withPaths paths: [String], withParameters parameters: [String: String]? = nil) -> URL {
        var endpoint = bbEndpoint
            .appendingPathComponent("2.0")
        for path in paths {
            endpoint.appendPathComponent(path)
        }
        if let parameters {
            endpoint = endpoint.appendingQueryParameters(parameters)
        }
        return endpoint
    }

    func createRequest(withPaths paths: [String], withParameters parameters: [String: String]? = nil) -> URLRequest {
        createRequest(withURL: createURL(withPaths: paths, withParameters: parameters))
    }

    func createRequest(withURL url: URL) -> URLRequest {
        let endpoint = url
        let basicToken = config.token.data(using: .utf8)!.base64EncodedString()
        var request = URLRequest(url: endpoint)
        request.httpMethod = "GET"
        request.setValue("Basic \(basicToken)", forHTTPHeaderField: "Authorization")
        return request
    }
}


================================================
FILE: MyYearWithGit/Data/Api/GitHubApi.swift
================================================
//
//  GitHubApi.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/12/5.
//

import Foundation
import OctoKit
import RequestKit

class GitHubApi: GitApi {
    let config: Config
    struct Config {
        let token: String
    }

    init(config: Config) {
        self.config = config
    }

    var api: Octokit?

    func checkError(_ err: Error?) -> Error? {
        var error: Error?
        let errObj = (err as NSError?)?.userInfo[RequestKit.RequestKitErrorKey]
        if let errObj = errObj as? [String: Any],
           let errMsg = errObj["message"] as? String
        {
            if let errDoc = errObj["documentation_url"] as? String {
                error = ApiError.response(reason: "\(errMsg) (See: \(errDoc))")
            } else {
                error = ApiError.response(reason: errMsg)
            }
        } else if let errObj = errObj as? String {
            error = ApiError.response(reason: errObj)
        } else if let err = err as? URLError {
            error = ApiError.network(reason: err.localizedDescription)
        } else {
            error = err
        }
        return error
    }

    func validate() throws {
        let config = TokenConfiguration(config.token)
        var validated = false
        let sem = DispatchSemaphore(value: 0)
        let core = Octokit(config)
        var error: Error?
        core.me { [weak self] response in
            defer { sem.signal() }
            switch response {
            case let .success(userObject):
                validated = true
                if let email = userObject.email {
                    User.current.email.insert(email)
                }
            case let .failure(err):
                error = self?.checkError(err)
            }
        }
        sem.wait()
        if let error {
            throw error
        }
        if validated {
            api = core
        }
        guard validated else {
            throw ApiError.invalidUser
        }
    }

    func repositories() throws -> [URL] {
        guard let api else {
            return []
        }
        var result: Set<URL> = []
        var page = 1
        repeat {
            do {
                let repos = try repositoryFor(page: page, api: api)
                repos.forEach { result.insert($0) }
                if repos.count > 0, page <= 65535 {
                    page += 1
                } else {
                    page = -1
                }
            } catch {
                throw error
            }
        } while page != -1
        return [URL](result)
    }

    func repositoryFor(page: Int, api: Octokit) throws -> [URL] {
        var result: Set<URL> = []
        let sem = DispatchSemaphore(value: 0)
        var error: Error?
        api.repositories(page: String(page), perPage: "100") { [weak self] response in
            defer { sem.signal() }
            switch response {
            case let .success(repository):
                for repo in repository {
                    guard let location = repo.cloneURL,
                          let url = URL(string: location)
                    else {
                        continue
                    }
                    result.insert(url)
                }
            case let .failure(err):
                error = self?.checkError(err)
            }
        }
        sem.wait()
        if let error {
            throw error
        }
        print("GitHub repository for page \(page) returned \(result.count) results")
        return [URL](result)
    }
}


================================================
FILE: MyYearWithGit/Data/Api/GitLabApi.swift
================================================
//
//  GitLabApi.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/27.
//

import Foundation

class GitLabApi: GitApi {
    let config: Config
    struct Config {
        let endpoint: URL
        let token: String
    }

    // user info from validation
    var userId: Int?
    var userName: String?

    init(config: Config) {
        self.config = config
    }

    // nil = invalid, otherwise "" but not nil
    func validate() throws {
        let request = createRequest(withPaths: [
            "user",
        ])
        var result = false
        var error: Error?
        let sem = DispatchSemaphore(value: 0)
        URLSession
            .shared
            .dataTask(with: request) { data, resp, err in
                defer { sem.signal() }

                // connection error
                if let err {
                    error = ApiError.network(reason: err.localizedDescription)
                    return
                }

                // unknown status code
                if let resp = resp as? HTTPURLResponse, resp.statusCode != 200 {
                    error = ApiError.statusCode(code: resp.statusCode)
                }

                // json decodable as dict
                guard let data,
                      let dic = try? JSONSerialization
                      .jsonObject(
                          with: data, options: .allowFragments
                      ) as? [String: Any]
                else {
                    return
                }

                // not an error
                if error == nil {
                    if let name = dic["name"] as? String {
                        self.userName = name
                    }
                    if let id = dic["id"] as? Int {
                        self.userId = id
                        result = true
                    }
                    if let email = dic["email"] as? String {
                        User.current.email.insert(email)
                    }
                    if let email = dic["commit_email"] as? String {
                        User.current.email.insert(email)
                    }
                }

                // server has detailed error description or messages
                if let errorVal = dic["error"] as? String,
                   let errorReason = dic["error_description"] as? String
                {
                    error = ApiError.response(reason: "\(errorReason) (\(errorVal))")
                } else if let errorMessage = dic["message"] as? String {
                    error = ApiError.response(reason: "\(errorMessage)")
                }
            }
            .resume()
        sem.wait()

        if let error {
            throw error
        }

        guard result else {
            throw ApiError.invalidUser
        }
    }

    func repositories() throws -> [URL] {
        var endpoints = Set<URL>(arrayLiteral: createURL(
            withPaths: [
                "projects",
            ],
            withParameters: [
                "min_access_level": "30", // developer access level
                "pagination": "keyset",
                "per_page": "100",
                "order_by": "id",
                "sort": "asc",
            ]
        ))

        var result = [URL]()
        var error: Error?
        while let endpoint = endpoints.popFirst() {
            let sem = DispatchSemaphore(value: 0)
            URLSession
                .shared
                .dataTask(with: createRequest(withURL: endpoint)) { [weak self] data, resp, err in
                    defer { sem.signal() }

                    // connection error
                    if let err {
                        error = ApiError.network(reason: err.localizedDescription)
                        return
                    }

                    // unknown status code
                    if let resp = resp as? HTTPURLResponse, resp.statusCode != 200 {
                        error = ApiError.statusCode(code: resp.statusCode)
                    }

                    // json decodable as arr
                    guard let data,
                          let dic = try? JSONSerialization
                          .jsonObject(
                              with: data, options: .allowFragments
                          ) as? [[String: Any]]
                    else {
                        return
                    }

                    // not an error
                    if error == nil {
                        for value in dic {
                            if let gitUrlStr = value["http_url_to_repo"] as? String,
                               let gitUrl = URL(string: gitUrlStr)
                            {
                                result.append(gitUrl)
                            }
                        }
                        if let resp = resp as? HTTPURLResponse,
                           let linkVal = resp.value(forHTTPHeaderField: "Link")?.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines),
                           linkVal.hasSuffix("rel=\"next\"")
                        {
                            var linkHref = String(linkVal.dropLast("rel=\"next\"".count))
                                .trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
                            if linkHref.hasPrefix("<") {
                                linkHref = String(linkHref.dropFirst("<".count))
                            }
                            if linkHref.hasSuffix(">;") {
                                linkHref = String(linkHref.dropLast(">;".count))
                            }
                            if let linkURL = URL(string: linkHref),
                               let linkQuery = linkURL.queryParameters,
                               let replURL = self?.config.endpoint.appendingPathComponent(String(linkURL.path.dropFirst())).appendingQueryParameters(linkQuery)
                            {
                                endpoints.insert(replURL)
                            }
                        }
                    }
                }
                .resume()
            sem.wait()
        }

        if let error {
            throw error
        }

        guard result.count > 0 else {
            throw ApiError.emptyData
        }
        return result
    }

    func createURL(withPaths paths: [String], withParameters parameters: [String: String]? = nil) -> URL {
        var endpoint = config
            .endpoint
            .appendingPathComponent("api")
            .appendingPathComponent("v4")
        for path in paths {
            endpoint.appendPathComponent(path)
        }
        if let parameters {
            endpoint = endpoint.appendingQueryParameters(parameters)
        }
        return endpoint
    }

    func createRequest(withPaths paths: [String], withParameters parameters: [String: String]? = nil) -> URLRequest {
        createRequest(withURL: createURL(withPaths: paths, withParameters: parameters))
    }

    func createRequest(withURL url: URL) -> URLRequest {
        let endpoint = url
        var request = URLRequest(url: endpoint)
        request.httpMethod = "GET"
        request.setValue(config.token, forHTTPHeaderField: "PRIVATE-TOKEN")
        return request
    }
}


================================================
FILE: MyYearWithGit/Data/Generic/AuxiliaryExecute.swift
================================================
//
//  AuxiliaryExecute.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/27.
//

import AuxiliaryExecute
import Foundation

enum AuxiliaryExecuteWrapper {
    private(set) static var git: String = "/usr/bin/git"

    static func setupExecutables() {
        var binaryLookupTable = [String: URL]()
        let binarySearchPath = [
            "/usr/local/bin",
            "/usr/bin",
            "/bin",
        ]
        var searchPaths = binarySearchPath.map { URL(fileURLWithPath: $0) }
        while !searchPaths.isEmpty {
            let path = searchPaths.removeFirst()
            
            var isDir = ObjCBool(false)
            guard FileManager.default.fileExists(atPath: path.path, isDirectory: &isDir) else {
                continue
            }
            if isDir.boolValue {
                let items = (try? FileManager.default.contentsOfDirectory(atPath: path.path)) ?? []
                for item in items {
                    let url = path.appendingPathComponent(item)
                    searchPaths.append(url)
                }
            } else {
                binaryLookupTable[path.lastPathComponent] = path
            }
        }

        if let git = binaryLookupTable["git"] {
            self.git = git.path
            print("setting up binary git at \(git.path)")
        } else {
            fatalError()
        }
    }

    @discardableResult
    static func spawn(command: String,
                      args: [String],
                      timeout: Int,
                      output: @escaping (String) -> Void)
        -> (Int, String, String)
    {
        print("exec: \(command) " + args.joined(separator: " ") + " timeout: \(timeout)")
        let recipe = AuxiliaryExecute.spawn(
            command: command,
            args: args,
            timeout: Double(timeout),
            output: output
        )
        return (recipe.exitCode, recipe.stdout, recipe.stderr)
    }
}


================================================
FILE: MyYearWithGit/Data/Generic/Exts.swift
================================================
//
//  Exts.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/26.
//

import Foundation

protocol HumanReadable {
    func readableDescription() -> String
}

var standardError = FileHandle.standardError

extension FileHandle: @retroactive TextOutputStream {
    public func write(_ string: String) {
        let data = Data(string.utf8)
        write(data)
    }
}

extension URL {
    var queryParameters: [String: String]? {
        guard let components = URLComponents(url: self, resolvingAgainstBaseURL: false),
              let queryItems = components.queryItems else { return nil }

        var items: [String: String] = [:]

        for queryItem in queryItems {
            items[queryItem.name] = queryItem.value
        }

        return items
    }

    func appendingQueryParameters(_ parameters: [String: String]) -> URL {
        var urlComponents = URLComponents(url: self, resolvingAgainstBaseURL: true)!
        urlComponents.queryItems = (urlComponents.queryItems ?? []) + parameters
            .map { URLQueryItem(name: $0, value: $1) }
        return urlComponents.url!
    }
}

extension String {
    private static let camelCaseRegex = try! NSRegularExpression(
        pattern: "([a-z](?=[A-Z]))",
        options: []
    )

    func enumerateSubstringsByWordsWithCamelCase(
        _ body: @escaping (
            _ substring: String?,
            _ substringRange: Range<Self.Index>,
            _ enclosingRange: Range<Self.Index>,
            inout Bool
        ) -> Void
    ) -> Void {
        var processingBuffer = self
        processingBuffer = processingBuffer.replacingOccurrences(of: ".", with: " ")
        processingBuffer = processingBuffer.replacingOccurrences(of: "-", with: " ")
        processingBuffer = processingBuffer.replacingOccurrences(of: "_", with: " ")
        processingBuffer = String.camelCaseRegex.stringByReplacingMatches(
            in: processingBuffer,
            options: [],
            range: NSRange(location: 0, length: processingBuffer.utf16.count),
            withTemplate: "$1 "
        )
        processingBuffer = processingBuffer.lowercased()
        let newBody: (
            _ substring: String?,
            _ substringRange: Range<Self.Index>,
            _ enclosingRange: Range<Self.Index>,
            inout Bool
        ) -> Void = { (substring, substringRange, enclosingRange, stop) in
            let newSubstring = substring?.lowercased()
            body(newSubstring, substringRange, enclosingRange, &stop)
        }
        processingBuffer.enumerateSubstrings(
            in: processingBuffer.startIndex...,
            options: .byWords,
            newBody
        )
    }
}


================================================
FILE: MyYearWithGit/Data/Generic/SourceLanguage.swift
================================================
//
//  SourceLanguage.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/28.
//

import Foundation

enum SourceLanguage: String, Codable, HumanReadable {
    static func languageDecision(withFileExtension pathExtension: String) -> Self? {
        switch pathExtension.lowercased() {
        case "c":
            .c
        case "cs", "csharp":
            .csharp
        case "cpp", "cc", "cxx", "c++":
            .cpp
        case "css":
            .css
        case "dart":
            .dart
        case "ex":
            .elixir
        case "go":
            .go
        case "groovy", "gvy", "gy", "gsh":
            .groovy
        case "html", "htm":
            .html
        case "java", "jav", "j":
            .java
        case "js", "jsx":
            .javascript
        case "kt", "ktm":
            .kotlin
        case "m", "mm":
            .objc
        case "pl":
            .perl
        case "php":
            .php
        case "ps1":
            .powershell
        case "py":
            .python
        case "rb":
            .rbuy
        case "rs":
            .rust
        case "scala", "sc":
            .scala
        case "sh", "command":
            .shell
        case "swift":
            .swift
        case "ts", "tsx":
            .typescript
        case "vue":
            .vue
        default:
            nil
        }
    }

    case c
    case csharp
    case cpp
    case css
    case dart
    case elixir
    case go
    case groovy
    case html
    case java
    case javascript
    case kotlin
    case objc
    case perl
    case php
    case powershell
    case python
    case rbuy
    case rust
    case scala
    case shell
    case swift
    case typescript
    case vue

    func readableDescription() -> String {
        switch self {
        case .c:
            "C"
        case .csharp:
            "C#"
        case .cpp:
            "C++"
        case .css:
            "CSS"
        case .dart:
            "Dart"
        case .elixir:
            "Elixir"
        case .go:
            "Go"
        case .groovy:
            "Groovy"
        case .html:
            "HTML"
        case .java:
            "Java"
        case .javascript:
            "JavaScript"
        case .kotlin:
            "Kotlin"
        case .objc:
            "Objective-C"
        case .perl:
            "Perl"
        case .php:
            "PHP"
        case .powershell:
            "PowerShell"
        case .python:
            "Python"
        case .rbuy:
            "Ruby"
        case .rust:
            "Rust"
        case .scala:
            "Scala"
        case .shell:
            "Shell"
        case .swift:
            "Swift"
        case .typescript:
            "TypeScript"
        case .vue:
            "Vue"
        }
    }
}


================================================
FILE: MyYearWithGit/Data/Generic/SourcePackage.swift.swift
================================================
//
//  SourcePackage.swift.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/27.
//

import Foundation

extension Notification.Name {
    static let postAnalysis = Notification.Name("wiki.qaq.source.done")
}

struct SourcePackage {
    let tempDir: URL
    let representedObjects: [SourceRegistrationData]

    init(sources: [SourceRegistrationData]) {
        tempDir = {
            let tempDir = NSTemporaryDirectory()
            let uuid = UUID().uuidString
            let location = URL(fileURLWithPath: tempDir)
                .appendingPathComponent("wiki.qaq.myyearwithgit")
                .appendingPathComponent(uuid)
            try? FileManager.default.removeItem(at: location)
            do {
                try FileManager
                    .default
                    .createDirectory(
                        at: location,
                        withIntermediateDirectories: true,
                        attributes: nil
                    )
            } catch {
                fatalError("error when creating analysis temp bundle \(error.localizedDescription)")
            }
            return location
        }()
        representedObjects = sources
    }

    func postToAnalysis() {
        NotificationCenter.default.post(name: .postAnalysis, object: self)
    }
}


================================================
FILE: MyYearWithGit/Data/Generic/SourceRegister.swift
================================================
//
//  SourceRegister.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/26.
//

import Foundation

enum SourceRegisters: String, CaseIterable, Codable, HumanReadable {
    // MARK: CASE

    case local
    case github
    case gitlab
    case bitbucket

    // MARK: PROTOCOL

    func readableDescription() -> String {
        switch self {
        case .local:
            NSLocalizedString("本地仓库", comment: "")
        case .github:
            "GitHub"
        case .gitlab:
            "GitLab"
        case .bitbucket:
            "Bitbucket"
        }
    }
}

struct SourceRegistrationData: Codable, Identifiable, Hashable {
    var id = UUID()

    static func == (lhs: SourceRegistrationData, rhs: SourceRegistrationData) -> Bool {
        lhs.id == rhs.id
    }

    let register: SourceRegisters
    let mainUrl: URL
    let repos: [RepoElement]

    struct RepoElement: Codable, Hashable {
        var representedData: [RepresentedKeys: String]

        init(localUrl: URL) {
            representedData = [
                .localUrl: localUrl.path,
                .identifier: UUID().uuidString,
            ]
        }

        init(remoteUrl: URL, username: String, token: String) {
            representedData = [
                .remoteUrl: remoteUrl.absoluteString,
                .username: username,
                .token: token,
                .identifier: UUID().uuidString,
            ]
        }

        enum RepresentedKeys: String, Codable {
            case remoteUrl
            case localUrl

            case username
            case token

            case identifier
        }
    }
}


================================================
FILE: MyYearWithGit/Data/Generic/User.swift
================================================
//
//  User.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/12/4.
//

import Foundation

private let userDefaultKey = "wiki.qaq.mywg.emails"

class User {
    static let current = User()

    public var email: Set<String> = [] {
        didSet {
            if let data = try? JSONEncoder().encode(email) {
                UserDefaults.standard.set(data, forKey: userDefaultKey)
            }
        }
    }

    @UserDefaultsWrapper(key: "wiki.qaq.mywg.name", defaultValue: "anonymous")
    public var namespace: String

    private init() {
        if let data = UserDefaults.standard.value(forKey: userDefaultKey) as? Data,
           let build = try? JSONDecoder().decode([String].self, from: data)
        {
            email = Set<String>(build)
        }
        let command = AuxiliaryExecuteWrapper.spawn(
            command: AuxiliaryExecuteWrapper.git,
            args: ["config", "user.email"],
            timeout: 1
        ) { str in
            print(str)
        }
        let gitEmail = command
            .1
            .trimmingCharacters(in: .whitespacesAndNewlines)
        if gitEmail.count > 0 {
            print("found email: \(gitEmail)")
            email.insert(gitEmail)
        }
    }
}


================================================
FILE: MyYearWithGit/Data/Generic/UserDefault.swift.swift
================================================
//
//  UserDefault.swift.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/12/4.
//

import Foundation

@propertyWrapper
public struct UserDefaultsWrapper<Value> {
    let key: String
    let defaultValue: Value
    var storage: UserDefaults = .standard

    public init(key: String, defaultValue: Value, storage: UserDefaults = .standard) {
        self.key = key
        self.defaultValue = defaultValue
        self.storage = storage
    }

    public var wrappedValue: Value {
        get {
            let value = storage.value(forKey: key) as? Value
            return value ?? defaultValue
        }
        set {
            storage.setValue(newValue, forKey: key)
        }
    }
}

public extension UserDefaultsWrapper where Value: ExpressibleByNilLiteral {
    init(key: String, storage: UserDefaults = .standard) {
        self.init(key: key, defaultValue: nil, storage: storage)
    }
}


================================================
FILE: MyYearWithGit/Data/ResultPackage/DicCounter.swift
================================================
//
//  DicCounter.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/29.
//

import Foundation

enum DicCounter {
    static func mostUsedKeyword<T>(from dic: [T: Int]) -> (T, Int)? {
        var searchKey: T?
        var searchKeyCount = -1
        for key in dic.keys {
            let count = dic[key, default: 0]
            if count > searchKeyCount {
                searchKey = key
                searchKeyCount = count
            }
        }
        guard let key = searchKey else {
            return nil
        }
        return (key, searchKeyCount)
    }

    static func mostUsedKeywords(from dic: [String: Int], count: Int) -> [String] {
        var resultBuilder = [(String, Int)](repeating: ("", -1), count: count)
        for key in dic.keys {
            let count = dic[key, default: 0]
            inner: for index in 0 ..< resultBuilder.count where resultBuilder[index].1 < count {
                resultBuilder[index] = (key, count)
                break inner
            }
        }
        return resultBuilder
            .filter { $0.1 > 0 }
            .map(\.0)
    }
}


================================================
FILE: MyYearWithGit/Data/ResultPackage/RS0.swift
================================================
//
//  RS0.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/28.
//

import Foundation
import SwiftUI

class ResultSection0: ResultSection {
    var reportHash: String = ""
    var clipDataItems: [Int: Int] = [:]

    func update(with scannerResult: ResultPackage.DataSource) -> ResultSectionUpdateRecipe? {
        clipDataItems = [:]
        // update the data

        reportHash = ""
        // dictionaries are unsorted
        // which means we do not considering it stable
        // so, we use some numbers inside them to do the calculate
        var hashSeedCounter: [UInt64] = []

        func countSeed(val: Int) {
            if let convertor = UInt64(exactly: val) {
                // fuck, i'm not caring about overflow anymore
                hashSeedCounter.append(convertor)
            }
        }
        for repo in scannerResult.repoResult.repos {
            for commit in repo.commits {
                for diff in commit.diffFiles {
                    countSeed(val: diff.increasedLine)
                    countSeed(val: diff.decreasedLine)
                    countSeed(val: diff.emptyLineAdded)
                }
            }
        }

        let cal = Calendar.current
        for repo in scannerResult.repoResult.repos {
            for commit in repo.commits {
                let date = commit.date
                if let day = cal.ordinality(of: .day, in: .year, for: date) {
                    clipDataItems[day, default: 0] += 1
                    countSeed(val: day * 114_514)
                }
            }
        }
        print("calendar result: \(clipDataItems)")

        // no more overflow on big numbers!
        reportHash = hashSeedCounter
            .sorted()
            .map { String($0) }
            .joined(separator: "")
            .sha256
            .uppercase

        while reportHash.count > 16 {
            reportHash.removeFirst()
        }
        print("generated report hash 0x\(reportHash)")

        return nil
    }

    func makeView() -> AnyView {
        AnyView(AssociatedView(
            clipData: clipDataItems,
            reportHash: reportHash,
            animated: true
        ))
    }

    func makeScreenShotView() -> AnyView {
        AnyView(AssociatedView(
            clipData: clipDataItems,
            reportHash: reportHash,
            animated: false
        ))
    }

    struct AssociatedView: View {
        let clipData: [Int: Int]
        let reportHash: String
        let animated: Bool

        @State var isInPresentation: Bool = false

        var body: some View {
            GeometryReader { r in
                ZStack {
                    Rectangle()
                        .foregroundColor(Color(NSColor.textBackgroundColor))
                        .shadow(color: .black.opacity(0.1), radius: 4, x: 0, y: 0)
                    container
                        .padding(25)
                        .frame(
                            width: r.size.width,
                            height: r.size.height,
                            alignment: .center
                        )
                }
                .frame(
                    width: r.size.width,
                    height: r.size.height,
                    alignment: .center
                )
            }
        }

        var container: some View {
            HStack {
                CodeTiles(commits: clipData, animated: animated)
                rightContainer
            }
        }

        var rightContainer: some View {
            VStack(alignment: .leading, spacing: 10) {
                Spacer()
                let name = User.current.namespace
                if name.count > 0 {
                    Text("\(String(requiredYear)) 年 x \(name)")
                        .font(.system(size: 12, weight: .semibold, design: .rounded))
                } else {
                    Text("\(String(requiredYear)) 年")
                        .font(.system(size: 12, weight: .semibold, design: .rounded))
                }
                Text("我和我的代码,还有这一年。")
                    .font(.system(size: 25, weight: .semibold, design: .rounded))
                Divider()
                Text("校验码: 0x\(reportHash.uppercase)")
                    .font(.system(size: 14, weight: .semibold, design: .monospaced))
                    .opacity(0.5)
                Spacer()
            }
            .overlay(
                VStack {
                    HStack {
                        Spacer()
                        Image("git")
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(width: 40, height: 40)
                    }
                    Spacer()
                }
            )
            .padding()
        }
    }
}


================================================
FILE: MyYearWithGit/Data/ResultPackage/RS1.swift
================================================
//
//  RS1.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/29.
//

import Foundation
import SwiftUI

private let calender = Calendar.current

class ResultSection1: ResultSection {
    var totalCommit: Int = 0
    var commitIncreaseLine: Int = 0
    var commitDecreaseLine: Int = 0
    var totalCommitDay: Int = 0

    func update(with scannerResult: ResultPackage.DataSource) -> ResultSectionUpdateRecipe? {
        totalCommit = scannerResult
            .repoResult
            .repos
            .map(\.commits.count)
            .reduce(0, +)
        commitIncreaseLine = 0
        commitDecreaseLine = 0
        var commitDay = Set<Int>() // day of the year
        for repo in scannerResult.repoResult.repos {
            for commit in repo.commits {
                commitIncreaseLine += commit
                    .diffFiles
                    .map(\.increasedLine)
                    .reduce(0, +)
                commitDecreaseLine += commit
                    .diffFiles
                    .map(\.decreasedLine)
                    .reduce(0, +)
                if let day = calender.ordinality(of: .day, in: .year, for: commit.date) {
                    commitDay.insert(day)
                }
            }
        }
        totalCommitDay = commitDay.count

        return totoalCommitToDesc(totalCommit: totalCommit, totoalAdd: commitIncreaseLine)
    }

    func makeView() -> AnyView {
        AnyView(AssociatedView(
            totalCommit: totalCommit,
            commitIncreaseLine: commitIncreaseLine,
            commitDecreaseLine: commitDecreaseLine,
            totalCommitDay: totalCommitDay
        ))
    }

    func makeScreenShotView() -> AnyView {
        makeView()
    }

    struct AssociatedView: View {
        let totalCommit: Int
        let commitIncreaseLine: Int
        let commitDecreaseLine: Int
        let totalCommitDay: Int

        let preferredContextSize: CGFloat = 12
        let preferredContentHeight: CGFloat = 30

        var body: some View {
            Group {
                container
                    .padding(50)
            }
        }

        var container: some View {
            VStack(alignment: .leading, spacing: 0) {
                Group {
                    Text("在 \(String(requiredYear)) 年")
                        .frame(height: preferredContentHeight)
                    Text("\(makeYearDescription()) 是我今年的代言词。")
                        .frame(height: preferredContentHeight)
                }

                Group {
                    Spacer()
                        .frame(height: 20)
                    Text("这一年里,我总共进行了 \(makeBigNumber(totalCommit)) 次代码提交。")
                        .frame(height: preferredContentHeight)
                    Text("感谢我的仓库们,他们记录着我生活的点点滴滴。")
                        .frame(height: preferredContentHeight)
                }

                Group {
                    Spacer()
                        .frame(height: 20)
                    Text("提交记录告诉咱:")
                        .frame(height: preferredContentHeight)
                    Text("仓库因你增添了 \(makeAdd(commitIncreaseLine)) 行代码,也减去了 \(makeDelete(commitDecreaseLine)) 行的重量。")
                        .fixedSize(horizontal: false, vertical: true)
                        .frame(height: preferredContentHeight)
                }

                Group {
                    Spacer()
                        .frame(height: 20)
                    if totalCommit < 0 {
                        Text("回过头来看看这一年,咱一共活跃了 \(makeBigNumber(totalCommitDay)) 天。")
                            .frame(height: preferredContentHeight)
                        Text("黑客是我的外号,我总能找到属于我的 🚩! 是 🏳️‍⚧️ 还是 🏳️‍🌈 呢?")
                            .frame(height: preferredContentHeight)
                    } else if totalCommit > 1000 {
                        Text("这一年,咱一共卷了 \(makeBigNumber(totalCommitDay)) 天。")
                            .frame(height: preferredContentHeight)
                        Text("风雨兼程,目的地是我向往的星辰大海。🥺")
                            .frame(height: preferredContentHeight)
                    } else if totalCommit > 365 {
                        Text("回过头来看看这一年,似乎付出了不少。咱一共活跃了 \(makeBigNumber(totalCommitDay)) 天。")
                            .frame(height: preferredContentHeight)
                        Text("如果说代码是有温度的字符,那仓库便是咱的小太阳~ 🤫")
                            .frame(height: preferredContentHeight)
                    } else if totalCommit > 50 {
                        Text("回过头来看看这一年,咱一共活跃了 \(makeBigNumber(totalCommitDay)) 天。")
                            .frame(height: preferredContentHeight)
                        Text("星星有月亮,代码回家有仓库,而你有我相伴。😛")
                            .frame(height: preferredContentHeight)
                    } else {
                        Text("回过头来看看这一年,咱一共活跃了 \(makeBigNumber(totalCommitDay)) 天。")
                            .frame(height: preferredContentHeight)
                        Text("他们说多少不重要,因为我的提交,每一次都心意满满。😮")
                    }
                }

                Group {
                    Divider()
                        .hidden()
                }
            }
            .font(.system(size: preferredContextSize, weight: .semibold, design: .rounded))
        }

        func makeBigNumber(_ number: Int) -> Text {
            Text(" \(number) ")
                .font(.system(size: preferredContextSize * 2, weight: .semibold, design: .rounded))
                .foregroundColor(Color.blue)
        }

        func makeAdd(_ number: Int) -> Text {
            Text(" \(number) ")
                .font(.system(size: preferredContextSize * 2, weight: .semibold, design: .rounded))
                .foregroundColor(.green)
        }

        func makeDelete(_ number: Int) -> Text {
            Text(" \(number) ")
                .font(.system(size: preferredContextSize * 2, weight: .semibold, design: .rounded))
                .foregroundColor(.red)
        }

        func makeYearDescription() -> Text {
            Text(
                totoalCommitToDesc(
                    totalCommit: totalCommit,
                    totoalAdd: commitIncreaseLine
                )
                .achievement
                .name
            )
            .font(.system(size: preferredContextSize * 2, weight: .semibold, design: .rounded))
        }
    }
}

private func totoalCommitToDesc(totalCommit: Int, totoalAdd: Int) -> ResultSectionUpdateRecipe {
    if totalCommit < 0 {
        return .init(achievement: .init(
            name: "flag{Hack_m3_1n_th3_b0x!}",
            describe: NSLocalizedString("提交的次数为负数", comment: "")
        ))
    }
    if totalCommit == 0 {
        return .init(achievement: .init(
            name: NSLocalizedString("我也不知道你来这里干什么", comment: ""),
            describe: NSLocalizedString("今年没有写代码", comment: "")
        ))
    }
    if totalCommit == 1 {
        return .init(achievement: .init(
            name: NSLocalizedString("签到不是胡闹", comment: ""),
            describe: NSLocalizedString("今年有且只有一次提交", comment: "")
        ))
    }
    let score = totalCommit * 10 + totoalAdd
    if (0 ... 500).contains(score) {
        return .init(achievement: .init(
            name: NSLocalizedString("休养生息", comment: ""),
            describe: NSLocalizedString("有一些提交", comment: "")
        ))
    }
    if (500 ... 1000).contains(score) {
        return .init(achievement: .init(
            name: NSLocalizedString("小试牛刀", comment: ""),
            describe: NSLocalizedString("有一些些提交", comment: "")
        ))
    }
    if (1000 ... 10000).contains(score) {
        return .init(achievement: .init(
            name: NSLocalizedString("勤劳努力", comment: ""),
            describe: NSLocalizedString("有很多提交", comment: "")
        ))
    }
    if (10000 ... 100_000).contains(score) {
        return .init(achievement: .init(
            name: NSLocalizedString("发奋图强", comment: ""),
            describe: NSLocalizedString("有很多很多很多很多的提交", comment: "")
        ))
    }
    return .init(achievement: .init(
        name: NSLocalizedString("卷卷卷卷卷卷", comment: ""),
        describe: NSLocalizedString("我是卷王王中王本王", comment: "")
    ))
}


================================================
FILE: MyYearWithGit/Data/ResultPackage/RS2.swift
================================================
//
//  RS2.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/29.
//

import Foundation
import SwiftUI

class ResultSection2: ResultSection {
    var mostUsedLanguage: SourceLanguage?
    var howManyLine: Int = 0
    var otherUsedLanguages: [SourceLanguage] = []
    var languageStats: [(language: SourceLanguage, lines: Int)] = [] // 新增:所有语言统计

    func update(with scannerResult: ResultPackage.DataSource) -> ResultSectionUpdateRecipe? {
        mostUsedLanguage = nil
        howManyLine = 0
        otherUsedLanguages = []
        languageStats = [] // 重置统计数据

        var languageBuilder: [SourceLanguage: Int] = [:]
        for repo in scannerResult.repoResult.repos {
            for commit in repo.commits {
                for file in commit.diffFiles {
                    if let language = file.language {
                        // count add only
                        languageBuilder[language, default: 0] += file.increasedLine
                    }
                }
            }
        }
        
        // 按行数从高到低排序所有语言
        languageStats = languageBuilder.map { (language: $0.key, lines: $0.value) }
            .sorted { $0.lines > $1.lines }
        
        var mostUsed: SourceLanguage?
        var mostUsedCount: Int = -1
        for key in languageBuilder.keys {
            let count = languageBuilder[key, default: 0]
            // if contain multiple result, first come first use
            if count > mostUsedCount {
                mostUsed = key
                mostUsedCount = count
            }
        }

        if let mostUsed {
            mostUsedLanguage = mostUsed
            howManyLine = mostUsedCount

            // don't count those tiny things
            // required at lease 0.05 percent of most used
            // so if a guy write 1000 line of code, then 5 line of other is required
            // or, if 128 line is written, then check!
            for key in languageBuilder.keys where key != mostUsed {
                let count = languageBuilder[key, default: 0]
                if count > Int(Double(howManyLine) * 0.05) || count > 128 {
                    otherUsedLanguages.append(key)
                }
            }
        }

        if otherUsedLanguages.count + 1 >= 6 {
            return .init(achievement: .init(
                name: NSLocalizedString("编程语言大师", comment: ""),
                describe: NSLocalizedString("今年的提交中熟练使用了超过六种语言", comment: "")
            )
            )
        }
        return nil
    }

    func makeView() -> AnyView {
        AnyView(AssociatedView(
            mostUsedLanguage: mostUsedLanguage,
            howManyLine: howManyLine,
            otherUsedLanguages: otherUsedLanguages,
            languageStats: languageStats // 传递统计数据
        ))
    }

    func makeScreenShotView() -> AnyView {
        makeView()
    }

    struct AssociatedView: View {
        let mostUsedLanguage: SourceLanguage?
        let howManyLine: Int
        let otherUsedLanguages: [SourceLanguage]
        let languageStats: [(language: SourceLanguage, lines: Int)] // 新增参数

        let preferredContextSize: CGFloat = 12
        let preferredContentHeight: CGFloat = 30

        var body: some View {
            Group {
                container
                    .padding(50)
            }
        }

        var container: some View {
            HStack(alignment: .top, spacing: 30) {
                // 左侧:文字描述
                textContent
                    .frame(maxWidth: .infinity, alignment: .leading)
                
                // 右侧:柱状图
                if !languageStats.isEmpty {
                    chartContent
                        .frame(width: 200)
                }
            }
        }
        
        var textContent: some View {
            VStack(alignment: .leading, spacing: 0) {
                if let mostUsedLanguage {
                    Group {
                        Text(mostUsedLanguage.readableDescription())
                            .font(.system(size: preferredContextSize * 2, weight: .semibold, design: .rounded))
                            .frame(height: preferredContentHeight)
                        Text("这是我最常用的语言。")
                            .frame(height: preferredContentHeight)
                    }
                    Group {
                        Spacer()
                            .frame(height: 20)
                        Text("在这一年里,我使用这门语言提交了 \(makeBigNumber(howManyLine)) 行代码。")
                            .frame(height: preferredContentHeight)
                        Text("他是我最好的伙伴。")
                    }

                    Group {
                        if otherUsedLanguages.count > 0 {
                            Spacer()
                                .frame(height: 20)
                            Text("在剩余的时光里,")
                                .frame(height: preferredContentHeight)
                            Text(
                                otherUsedLanguages
                                    .map { $0.readableDescription() }
                                    .shuffled()
                                    .joined(separator: ",  ")
                            )
                            .font(.system(size: preferredContextSize * 1.2, weight: .semibold, design: .rounded))
                            .foregroundColor(.purple)
                            Text("他们也陪我走过一段旅程。")
                                .frame(height: preferredContentHeight)
                        } else {
                            Spacer()
                                .frame(height: 20)
                            Text("我很专一,没有使用过其他的语言。")
                                .frame(height: preferredContentHeight)
                        }
                    }

                    Group {
                        if otherUsedLanguages.count > 6 {
                            Spacer()
                                .frame(height: 20)
                            Text("语言大师的称号,非你莫属!")
                        }
                    }

                } else {
                    Text("我不知道你写了什么")
                        .font(.system(size: preferredContextSize * 2, weight: .semibold, design: .rounded))
                        .frame(height: preferredContentHeight)
                    Text("应该是太冷门了吧,数据库里找不到对应的语言。🥲")
                        .frame(height: preferredContentHeight)
                }

                Group {
                    Divider()
                        .hidden()
                }
            }
            .font(.system(size: preferredContextSize, weight: .semibold, design: .rounded))
        }
        
        // 新增:柱状图视图
        var chartContent: some View {
            VStack(alignment: .leading, spacing: 8) {
                // 获取最大值用于计算比例
                let maxLines = languageStats.first?.lines ?? 1
                
                // 显示前8种语言(如果有的话)
                ForEach(Array(languageStats.prefix(8).enumerated()), id: \.element.language) { index, stat in
                    VStack(alignment: .leading, spacing: 2) {
                        HStack(spacing: 4) {
                            Text(stat.language.readableDescription())
                                .font(.system(size: 9, weight: .medium, design: .rounded))
                                .frame(width: 60, alignment: .leading)
                                .lineLimit(1)
                            
                            Text("\(stat.lines)")
                                .font(.system(size: 8, weight: .regular, design: .monospaced))
                                .foregroundColor(.secondary)
                        }
                        
                        // 横向柱状条
                        GeometryReader { geometry in
                            ZStack(alignment: .leading) {
                                // 背景条
                                RoundedRectangle(cornerRadius: 3)
                                    .fill(Color.gray.opacity(0.2))
                                    .frame(width: geometry.size.width, height: 12)
                                
                                // 数据条
                                RoundedRectangle(cornerRadius: 3)
                                    .fill(
                                        LinearGradient(
                                            gradient: Gradient(colors: [
                                                getColorForIndex(index),
                                                getColorForIndex(index).opacity(0.7)
                                            ]),
                                            startPoint: .leading,
                                            endPoint: .trailing
                                        )
                                    )
                                    .frame(
                                        width: geometry.size.width * CGFloat(stat.lines) / CGFloat(maxLines),
                                        height: 12
                                    )
                            }
                        }
                        .frame(height: 12)
                    }
                }
                
                if languageStats.count > 8 {
                    Text("还有 \(languageStats.count - 8) 种语言...")
                        .font(.system(size: 8, weight: .regular, design: .rounded))
                        .foregroundColor(.secondary)
                        .padding(.top, 4)
                }
            }
        }
        
        // 为不同的柱状条分配颜色
        func getColorForIndex(_ index: Int) -> Color {
            let colors: [Color] = [
                .blue, .green, .orange, .purple, .pink, .red, .yellow, .cyan
            ]
            return colors[index % colors.count]
        }

        func makeBigNumber(_ number: Int) -> Text {
            Text(" \(number) ")
                .font(.system(size: preferredContextSize * 2, weight: .semibold, design: .rounded))
                .foregroundColor(Color.orange)
        }
    }
}


================================================
FILE: MyYearWithGit/Data/ResultPackage/RS3.swift
================================================
//
//  RS3.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/29.
//

import Foundation
import SwiftUI

private let calender = Calendar.current

class ResultSection3: ResultSection {
    var commitDateInDay: CommitDateInDay = .midnight
    var commitDateInDayCount: Int = 0
    var averageCommitPerDay: Double = 0
    var averageCommitPerWeekday: Double = 0
    var weekendCommitCount: Int = 0

    func update(with scannerResult: ResultPackage.DataSource) -> ResultSectionUpdateRecipe? {
        var counter = [CommitDateInDay: Int]()
        var totalCounter = 0
        var weekendCounter: Set<Int> = []
        for repo in scannerResult.repoResult.repos {
            for commit in repo.commits {
                totalCounter += 1
                let date = commit.date
                do {
                    if isDateWeekend(date, with: calender) {
                        if let dayOfYear = calender.ordinality(of: .day, in: .year, for: commit.date) {
                            weekendCounter.insert(dayOfYear)
                        }
                    }
                }
                do {
                    let components = calender.dateComponents([.hour], from: date)
                    guard let hour = components.hour else {
                        continue
                    }
                    let object = CommitDateInDay.convertFrom(hour: hour)
                    counter[object, default: 0] += 1
                }
            }
        }
        averageCommitPerDay = Double(totalCounter) / 365 // no need to be that actuate
        averageCommitPerWeekday = Double(totalCounter) / 261 // google telling me 261 working days lol
        weekendCommitCount = weekendCounter.count
        var mostUsed = CommitDateInDay.midnight
        var mostUsedCount = -1
        for key in counter.keys {
            let count = counter[key, default: 0]
            if count > mostUsedCount {
                mostUsed = key
                mostUsedCount = count
            }
        }
        commitDateInDay = mostUsed
        commitDateInDayCount = mostUsedCount

        switch commitDateInDay {
        case .midnight:
            return .init(achievement: .init(
                name: NSLocalizedString("夜猫子", comment: ""),
                describe: NSLocalizedString("喜欢在午夜时分提交代码", comment: "")
            ))
        case .morning:
            return .init(achievement: .init(
                name: NSLocalizedString("早睡早起身体好", comment: ""),
                describe: NSLocalizedString("喜欢在早晨提交代码", comment: "")
            ))
        case .noon:
            return .init(achievement: .init(
                name: NSLocalizedString("干饭人!干饭魂!", comment: ""),
                describe: NSLocalizedString("喜欢在中午提交代码", comment: "")
            ))
        case .afternoon:
            return .init(achievement: .init(
                name: NSLocalizedString("星爸爸和气氛组的关怀", comment: ""),
                describe: NSLocalizedString("喜欢在下午茶时间提交代码", comment: "")
            ))
        case .dinner:
            return .init(achievement: .init(
                name: NSLocalizedString("晚饭的吃好", comment: ""),
                describe: NSLocalizedString("喜欢在晚饭时间提交代码", comment: "")
            ))
        case .night:
            return .init(achievement: .init(
                name: NSLocalizedString("睡前故事", comment: ""),
                describe: NSLocalizedString("喜欢在晚上提交代码", comment: "")
            ))
        }
    }

    func makeView() -> AnyView {
        AnyView(AssociatedView(
            commitDateInDay: commitDateInDay,
            commitDateInDayCount: commitDateInDayCount,
            averageCommitPerDay: averageCommitPerDay,
            averageCommitPerWeekday: averageCommitPerWeekday,
            weekendCommitCount: weekendCommitCount
        ))
    }

    func makeScreenShotView() -> AnyView {
        makeView()
    }

    struct AssociatedView: View {
        let commitDateInDay: CommitDateInDay
        let commitDateInDayCount: Int
        let averageCommitPerDay: Double
        let averageCommitPerWeekday: Double
        let weekendCommitCount: Int

        let preferredContextSize: CGFloat = 12
        let preferredContentHeight: CGFloat = 30

        var body: some View {
            Group {
                container
                    .padding(50)
            }
        }

        var container: some View {
            VStack(alignment: .leading, spacing: 0) {
                Group {
                    makeLarge(text: commitDateInDay.readableDescription())
                        .frame(height: preferredContentHeight)
                    Text("我最喜欢在 \(commitDateInDay.readableDescription()) 的时候提交代码,总共提交了 \(commitDateInDayCount) 次。")
                        .frame(height: preferredContentHeight)
                    Text("风雨兼程的 Coding 旅途,一天中我最忙碌的时段。")
                        .frame(height: preferredContentHeight)
                    Spacer()
                        .frame(height: 20)
                }
                Group {
                    Text("平均而言,我一天提交代码 \(makeBigNumber(averageCommitPerDay)) 次。")
                        .frame(height: preferredContentHeight)
                    Text("如果不计算周末的日子,则是 \(makeBigNumber(averageCommitPerWeekday)) 次。")
                        .frame(height: preferredContentHeight)
                    if averageCommitPerWeekday > 10 {
                        Text("我是卷王本王 🤪")
                            .frame(height: preferredContentHeight)
                    } else if averageCommitPerWeekday > 3 {
                        Text("辛苦啦 🥲")
                            .frame(height: preferredContentHeight)
                    } else {
                        Text("是的,我又在摸鱼 🥺")
                            .frame(height: preferredContentHeight)
                    }
                    Spacer()
                        .frame(height: 20)
                }

                Text("有 \(makeBigNumber(weekendCommitCount)) 个周末的日子,我在仓库留下了身影。")
                    .frame(height: preferredContentHeight)

                if weekendCommitCount > 0 {
                    if weekendCommitCount > 30 {
                        Text("修得的福报,是我一生最大的欢喜。")
                            .frame(height: preferredContentHeight)
                    } else if weekendCommitCount > 10 {
                        Text("可能敲代码,正是我的乐趣吧。")
                            .frame(height: preferredContentHeight)
                    }
                } else {
                    Text("这一年的周末,我都没有提交代码。")
                        .frame(height: preferredContentHeight)
                    Text("偷得浮生半日闲,可不能再修福报啦!")
                        .frame(height: preferredContentHeight)
                }

                Group {
                    Divider()
                        .hidden()
                }
            }
            .font(.system(size: preferredContextSize, weight: .semibold, design: .rounded))
        }

        func makeBigNumber(_ number: Int) -> Text {
            Text(" \(number) ")
                .font(.system(size: preferredContextSize * 2, weight: .semibold, design: .rounded))
                .foregroundColor(Color.blue)
        }

        func makeBigNumber(_ number: Double) -> Text {
            Text(" \(String(format: "%.4f", number)) ")
                .font(.system(size: preferredContextSize * 2, weight: .semibold, design: .rounded))
                .foregroundColor(Color.blue)
        }

        func makeLarge(text: String) -> Text {
            Text(text)
                .font(.system(size: preferredContextSize * 2, weight: .semibold, design: .rounded))
                .foregroundColor(.orange)
        }
    }

    func isDateWeekend(_ date: Date, with calendar: Calendar) -> Bool {
        var enCalendar = calendar
        enCalendar.locale = Locale(identifier: "en_US")
        let components = enCalendar.dateComponents([.weekday], from: date)
        guard let weekday = components.weekday else {
            assertionFailure("Failed to extract weekday from date")
            return false
        }
        return ["Saturday", "Sunday"].contains(enCalendar.weekdaySymbols[weekday - 1])
    }
}


================================================
FILE: MyYearWithGit/Data/ResultPackage/RS4.swift
================================================
//
//  RS4.swift
//  MyYearWithGit
//
//  Created by Lakr Aream on 2021/11/29.
//

import Foundation
import SwiftUI

class ResultSection4: ResultSection {
    var mostUsedWordInCode: String = ""
    var mostUsedWordInCodeCount: Int = 0
    var mostUsedWordInCommitLog: String = ""
    var mostUsedWordInCommitLogCount: Int = 0
    var otherUsedWordInCode: [String] = []
    var otherUsedWordInCommitLog: [String] = []

    func update(with scannerResult: ResultPackage.DataSource) -> ResultSectionUpdateRecipe? {
        mostUsedWordInCode = ""
        mostUsedWordInCodeCount = 0
        if let value = DicCounter.mostUsedKeyword(
            from: scannerResult.dictionaryIncrease
        ) {
            mostUsedWordInCode = value.0
            mostUsedWordInCodeCount = value.1
        }

        mostUsedWordInCommitLog = ""
        mostUsedWordInCommitLogCount = 0
        if let value = DicCounter.mostUsedKeyword(
            from: scannerResult.dictionaryCommit
        ) {
            mostUsedWordInCommitLog = value.0
            mostUsedWordInCommitLogCount = value.1
        }

        otherUsedWordInCode = DicCounter.mostUsedKeywords(from: scannerResult.dictionaryIncrease, count: 10)
        otherUsedWordInCommitLog = DicCounter.mostUsedKeywords(from: scannerResult.dictionaryCommit, count: 10)

        if dirtyWordList.contains(mostUsedWordInCode)
            || dirtyWordList.contains(mostUsedWordInCommitLog)
        {
            return .init(achievement: .init(
                name: NSLocalizedString("文明语言大师", comment: ""),
                describe: NSLocalizedString("在代码或者提交备注中使用的最多的词语是脏话", comment: "")
            ))
        }
        for item in otherUsedWordInCode + otherUsedWordInCommitLog where dirtyWordList.contains(item) {
            return .init(achievement: .init(
                name: NSLocalizedString("文明语言学者", comment: ""),
                describe: NSLocalizedString("在代码或者提交备注中使用了不少的脏话", comment: "")
            ))
        }
        return nil
    }

    func makeView() -> AnyView {
        AnyView(AssociatedView(
            mostUsedWordInCode: mostUsedWordInCode,
            mostUsedWordInCodeCount: mostUsedWordInCodeCount,
            mostUsedWordInCommitLog: mostUsedWordInCommitLog,
            mostUsedWordInCommitLogCount: mostUsedWordInCommitLogCount,
            otherUsedWordInCode: otherUsedWordInCode,
            otherUsedWordInCommitLog: otherUsedWordInCommitLog
        ))
    }

    func makeScreenShotView() -> AnyView {
        makeView()
    }

    struct AssociatedView: View {
        let mostUsedWordInCode: String
        let mostUsedWordInCodeCount: Int
        let mostUsedWordInCommitLog: String
        let mostUsedWordInCommitLogCount: Int

        let otherUsedWordInCode: [String]
        let otherUsedWordInCommitLog: [String]

        let preferredContextSize: CGFloat = 12
        let preferredContentHeight: CGFloat = 30

        var body: some View {
            Group {
                HStack {
                    container
                }
                .padding(50)
            }
        }

        var container: some View {
            VStack(alignment: .leading, spacing: 0) {
                Group {
                    if mostUsedWordInCodeCount > 0 {
                        makeLarge(text: mostUsedWordInCode)
                            .frame(height: preferredContentHeight)
                        Text("这是我在代码中最常写到的单词,他出现了 \(mostUsedWordInCodeCount) 次。")
                            .frame(height: preferredContentHeight)
                    }
                    if mostUsedWordInCommitLogCount > 0 {
                        makeLarge(text: mostUsedWordInCommitLog)
                            .frame(height: preferredContentHeight)
                        Text("这是我在代码提交记录中最常写到的单词,他出现了 \(mostUsedWordInCommitLogCount) 次。")
                            .frame(height: preferredContentHeight)
                    }
                    Spacer()
                        .frame(height: 20)
                }
                Group {
                    if otherUsedWordInCode.count > 0 {
                        Text("代码里,这些词经常出现")
                            .frame(height: preferredContentHeight)
                        Text(otherUsedWordInCode.joined(separator: " "))
                        Spacer()
                            .frame(height: 20)
                    }
                }
                Group {
                    if otherUsedWordInCommitLog.count > 0 {
                        Text("提交记录里,这些词经常出现")
                            .frame(height: preferredContentHeight)
                        Text(otherUsedWordInCommitLog.joined(separator: " "))
                        Spacer()
                            .frame(height: 20)
                    }
                }
                Group {
                    Text("我会写很多很多的单词,很多很多的句子。")
                        .frame(height: preferredContentHeight)
                }
                Group {
                    Divider()
                        .hidden()
                }
            }
            .font(.system(size: preferredContextSize, weight: .semibold, design: .rounded))
        }

        func makeBigNumber(_ number: Int) -> Text {
            Text(" \(number) ")
                .font(.system(size: preferredContextSize * 2, weight: .semibold, design: .rounded))
                .foregroundColor(Color.blue)
        }

        func makeLarge(text: String) -> Text {
            Text(text)
                .font(.system(size: preferredContextSize * 2, weight: .semibold, design: .rounded))
                .foregroundColor(.orange)
        }
    }
}

let dirtyWordList = [
    "2g1c",
    "2 girls 1 cup",
    "acrotomophilia",
    "alabama hot pocket",
    "alaskan pipeline",
    "anal",
    "anilingus",
    "anus",
    "apeshit",
    "arsehole",
    "ass",
    "asshole",
    "assmunch",
    "auto erotic",
    "autoerotic",
    "babeland",
    "baby batter",
    "baby juice",
    "ball gag",
    "ball gravy",
    "ball kicking",
    "ball licking",
    "ball sack",
    "ball sucking",
    "bangbros",
    "bangbus",
    "bareback",
    "barely legal",
    "barenaked",
    "bastard",
    "bastardo",
    "bastinado",
    "bbw",
    "bdsm",
    "beaner",
    "beaners",
    "beaver cleaver",
    "beaver lips",
    "beastiality",
    "bestiality",
    "big black",
    "big breasts",
    "big knockers",
    "big tits",
    "bimbos",
    "birdlock",
    "bitch",
    "bitches",
    "black cock",
    "blonde action",
    "blonde on blonde action",
    "blowjob",
    "blow job",
    "blow your load",
    "blue waffle",
    "blumpkin",
    "bollocks",
    "bondage",
    "boner",
    "boob",
    "boobs",
    "booty call",
    "brown showers",
    "brunette action",
    "bukkake",
    "bulldyke",
    "bullet vibe",
    "bullshit",
    "bung hole",
    "bunghole",
    "busty",
    "butt",
    "buttcheeks",
    "butthole",
    "camel toe",
    "camgirl",
    "camslut",
    "camwhore",
    "carpet muncher",
    "carpetmuncher",
    "chocolate rosebuds",
    "cialis",
    "circlejerk",
    "cleveland steamer",
    "clit",
    "clitoris",
    "clover clamps",
    "clusterfuck",
    "cock",
    "cocks",
    "coprolagnia",
    "coprophilia",
    "cornhole",
    "coon",
    "coons",
    "creampie",
    "cum",
    "cumming",
    "cumshot",
    "cumshots",
    "cunnilingus",
    "cunt",
    "darkie",
    "date rape",
    "daterape",
    "deep throat",
    "deepthroat",
    "dendrophilia",
    "dick",
    "dildo",
    "dingleberry",
    "dingleberries",
    "dirty pillows",
    "dirty sanchez",
    "doggie style",
    "doggiestyle",
    "doggy style",
    "doggystyle",
    "dog style",
    "dolcett",
    "domination",
    "dominatrix",
    "dommes",
    "donkey punch",
    "double dong",
    "double penetration",
    "dp action",
    "dry hump",
    "dvda",
    "eat my ass",
    "ecchi",
    "ejaculation",
    "erotic",
    "erotism",
    "escort",
    "eunuch",
    "fag",
    "faggot",
    "fecal",
    "felch",
    "fellatio",
    "feltch",
    "female squirting",
    "femdom",
    "figging",
    "fingerbang",
    "fingering",
    "fisting",
    "foot fetish",
    "footjob",
    "frotting",
    "fuck",
    "fuck buttons",
    "fuckin",
    "fucking",
    "fucktards",
    "fudge packer",
    "fudgepacker",
    "futanari",
    "gangbang",
    "gang bang",
    "gay sex",
    "genitals",
    "giant cock",
    "girl on",
    "girl on top",
    "girls gone wild",
    "goatcx",
    "goatse",
    "god damn",
    "gokkun",
    "golden shower",
    "goodpoop",
    "goo girl",
    "goregasm",
    "grope",
    "group sex",
    "g-spot",
    "guro",
    "hand job",
    "handjob",
    "hard core",
    "hardcore",
    "hentai",
    "homoerotic",
    "honkey",
    "hooker",
    "horny",
    "hot carl",
    "hot chick",
    "how to kill",
    "how to murder",
    "huge fat",
    "humping",
    "incest",
    "intercourse",
    "jack off",
    "jail bait",
    "jailbait",
    "jelly donut",
    "jerk off",
    "jigaboo",
    "jiggaboo",
    "jiggerboo",
    "jizz",
    "juggs",
    "kike",
    "kinbaku",
    "kinkster",
    "kinky",
    "knobbing",
    "leather restraint",
    "leather straight jacket",
    "lemon party",
    "livesex",
    "lolita",
    "lovemaking",
    "make me come",
    "male squirting",
    "masturbate",
    "masturbating",
    "masturbation",
    "menage a trois",
    "milf",
    "missionary position",
    "mong",
    "motherfucker",
    "mound of venus",
    "mr hands",
    "muff diver",
    "muffdiving",
    "nambla",
    "nawashi",
    "negro",
    "neonazi",
    "nigga",
    "nigger",
    "nig nog",
    "nimphomania",
    "nipple",
    "nipples",
    "nsfw",
    "nsfw images",
    "nude",
    "nudity",
    "nutten",
    "nympho",
    "nymphomania",
    "octopussy",
    "omorashi",
    "one cup two girls",
    "one guy one jar",
    "orgasm",
    "orgy",
    "paedophile",
    "paki",
    "panties",
    "panty",
    "pedobear",
    "pedophile",
    "pegging",
    "penis",
    "phone sex",
    "piece of shit",
    "pikey",
    "pissing",
    "piss pig",
    "pisspig",
    "playboy",
    "pleasure chest",
    "pole smoker",
    "ponyplay",
    "poof",
    "poon",
    "poontang",
    "punany",
    "poop chute",
    "poopchute",
    "porn",
    "porno",
    "pornography",
    "prince albert piercing",
    "pthc",
    "pubes",
    "pussy",
    "queaf",
    "queef",
    "quim",
    "raghead",
    "raging boner",
    "rape",
    "raping",
    "rapist",
    "rectum",
    "reverse cowgirl",
    "rimjob",
    "rimming",
    "rosy palm",
    "rosy palm and her 5 sisters",
    "rusty trombone",
    "sadism",
    "santorum",
    "scat",
    "schlong",
    "scissoring",
    "semen",
    "sex",
    "sexcam",
    "sexo",
    "sexy",
    "sexual",
    "sexually",
    "sexuality",
    "shaved beaver",
    "shaved pussy",
    "shemale",
    "shibari",
    "shit",
    "shitblimp",
    "shitty",
    "shota",
    "shrimping",
    "skeet",
    "slanteye",
    "slut",
    "s&m",
    "smut",
    "snatch",
    "snowballing",
    "sodomize",
    "sodomy",
    "spastic",
    "spic",
    "splooge",
    "splooge moose",
    "spooge",
    "spread legs",
    "spunk",
    "strap on",
    "strapon",
    "strappado",
    "strip club",
    "style doggy",
    "suck",
    "sucks",
    "suicide girls",
    "sultry women",
    "swastika",
    "swinger",
    "tainted love",
    "taste my",
    "tea bagging",
    "threesome",
    "throating",
    "thumbzilla",
    "tied up",
    "tight white",
    "tit",
    "tits",
    "titties",
    "titty",
    "tongue in a",
    "topless",
    "tosser",
    "towelhead",
    "tranny",
    "tribadism",
    "tub girl",
    "tubgirl",
    "tushy",
    "twat",
    "twink",
    "twinkie",
    "two girls one cup",
    "undressing",
    "upskirt",
    "urethra play",
    "urophilia",
    "vagina",
    "venus mound",
    "viagra",
    "vibrator",
    "violet wand",
    "vorarephilia",
    "voyeur",
    "voyeurweb",
    "voyuer",
    "vulva",
    "wank",
    "wetback",
    "wet dream",
    "white power",
    "whore",
    "worldsex",
    "wrapping men",
    "wrinkled starfish",
    "xx",
    "xxx",
    "yaoi",
    "yellow showers",
    "yiffy",
    "zoophilia",
    "🖕",
    "13.",
    "13点",
    "三级片",
    "下三烂",
    "下贱",
    "个老子的",
    "九游",
    "乳",
    "乳交",
    "乳头",
    "乳房",
    "乳波臀浪",
    "交配",
    "仆街",
    "他奶奶",
    "他奶奶的",
    "他奶娘的",
    "他妈",
    "他妈ㄉ王八蛋",
    "他妈地",
    "他妈的",
    "他娘",
    "他马的",
    "你个傻比",
    "你他马的",
    "你全家",
    "你奶奶的",
    "你她马的",
    "你妈",
    "你妈的",
    "你娘",
    "你娘卡好",
    "你娘咧",
    "你它妈的",
    "你它马的",
    "你是鸡",
    "你是鸭",
    "你马的",
    "做爱",
    "傻比",
    "傻逼",
    "册那",
    "军妓",
    "几八",
    "几叭",
    "几巴",
    "几芭",
    "刚度",
    "刚瘪三",
    "包皮",
    "十三点",
    "卖B",
    "卖比",
    "卖淫",
    "卵",
    "卵子",
    "双峰微颤",
    "口交",
    "口肯",
    "叫床",
    "吃屎",
    "后庭",
    "吹箫",
    "塞你公",
    "塞你娘",
    "塞你母",
    "塞你爸",
    "塞你老师",
    "塞你老母",
    "处女",
    "外阴",
    "大卵子",
    "大卵泡",
    "大鸡巴",
    "奶",
    "奶奶的熊",
    "奶子",
    "奸",
    "奸你",
    "她妈地",
    "她妈的",
    "她马的",
    "妈B",
    "妈个B",
    "妈个比",
    "妈个老比",
    "妈妈的",
    "妈比",
    "妈的",
    "妈的B",
    "妈逼",
    "妓",
    "妓女",
    "妓院",
    "妳她妈的",
    "妳妈的",
    "妳娘的",
    "妳老母的",
    "妳马的",
    "姘头",
    "姣西",
    "姦",
    "娘个比",
    "娘的",
    "婊子",
    "婊子养的",
    "嫖娼",
    "嫖客",
    "它妈地",
    "它妈的",
    "密洞",
    "射你",
    "射精",
    "小乳头",
    "小卵子",
    "小卵泡",
    "小瘪三",
    "小肉粒",
    "小骚比",
    "小骚货",
    "小鸡巴",
    "小鸡鸡",
    "屁眼",
    "屁股",
    "屄",
    "屌",
    "巨乳",
    "干x娘",
    "干七八",
    "干你",
    "干你妈",
    "干你娘",
    "干你老母",
    "干你良",
    "干妳妈",
    "干妳娘",
    "干妳老母",
    "干妳马",
    "干您娘",
    "干机掰",
    "干死CS",
    "干死GM",
    "干死你",
    "干死客服",
    "幹",
    "强奸",
    "强奸你",
    "性",
    "性交",
    "性器",
    "性无能",
    "性爱",
    "情色",
    "想上你",
    "懆您妈",
    "懆您娘",
    "懒8",
    "懒八",
    "懒叫",
    "懒教",
    "成人",
    "我操你祖宗十八代",
    "扒光",
    "打炮",
    "打飞机",
    "抽插",
    "招妓",
    "插你",
    "插死你",
    "撒尿",
    "操你",
    "操你全家",
    "操你奶奶",
    "操你妈",
    "操你娘",
    "操你祖宗",
    "操你老妈",
    "操你老母",
    "操妳",
    "操妳全家",
    "操妳妈",
    "操妳娘",
    "操妳祖宗",
    "操机掰",
    "操比",
    "操逼",
    "放荡",
    "日他娘",
    "日你",
    "日你妈",
    "日你老娘",
    "日你老母",
    "日批",
    "月经",
    "机八",
    "机巴",
    "机机歪歪",
    "杂种",
    "浪叫",
    "淫",
    "淫乱",
    "淫妇",
    "淫棍",
    "淫水",
    "淫秽",
    "淫荡",
    "淫西",
    "湿透的内裤",
    "激情",
    "灨你娘",
    "烂货",
    "烂逼",
    "爛",
    "狗屁",
    "狗日",
Download .txt
gitextract_qpqfygjk/

├── .gitignore
├── .gitmodules
├── .root
├── LICENSE
├── MyYearWithGit/
│   ├── App/
│   │   ├── App.swift
│   │   ├── Assets.xcassets/
│   │   │   ├── AccentColor.colorset/
│   │   │   │   └── Contents.json
│   │   │   ├── AppIcon.appiconset/
│   │   │   │   └── Contents.json
│   │   │   ├── Contents.json
│   │   │   ├── badge.imageset/
│   │   │   │   └── Contents.json
│   │   │   ├── bitbucket.imageset/
│   │   │   │   └── Contents.json
│   │   │   ├── git.imageset/
│   │   │   │   └── Contents.json
│   │   │   ├── github.imageset/
│   │   │   │   └── Contents.json
│   │   │   ├── gitlab.imageset/
│   │   │   │   └── Contents.json
│   │   │   ├── qrcode.imageset/
│   │   │   │   └── Contents.json
│   │   │   └── sfexp/
│   │   │       ├── Contents.json
│   │   │       ├── custom.aqi.high.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.aqi.low.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.aqi.medium.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.circle.fill.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.bolt.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.bolt.rain.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.drizzle.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.fog.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.hail.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.heavyrain.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.moon.bolt.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.moon.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.moon.rain.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.rain.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.sleet.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.snow.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.sun.bolt.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.sun.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.cloud.sun.rain.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.humidity.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.hurricane.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.moon.circle.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.moon.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.moon.stars.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.smoke.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.snowflake.circle.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.snowflake.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sparkles.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sun.and.horizon.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sun.dust.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sun.haze.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sun.max.circle.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sun.max.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sun.min.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sunrise.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.sunset.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.thermometer.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.thermometer.snowflake.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.thermometer.sun.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.tornado.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.tropicalstorm.imageset/
│   │   │       │   └── Contents.json
│   │   │       ├── custom.wind.imageset/
│   │   │       │   └── Contents.json
│   │   │       └── custom.wind.snow.imageset/
│   │   │           └── Contents.json
│   │   ├── Hooker.m
│   │   ├── InfoPlist.xcstrings
│   │   ├── Localizable.xcstrings
│   │   └── main.swift
│   ├── Data/
│   │   ├── Analyser/
│   │   │   ├── CommitFilter.swift
│   │   │   ├── DictionaryBuilder.swift
│   │   │   ├── GitDiff.swift
│   │   │   ├── GitLog.swift
│   │   │   ├── GitRepoResult.swift
│   │   │   └── RepoAnalyser.swift
│   │   ├── Api/
│   │   │   ├── ApiProtocol.swift
│   │   │   ├── BitbucketApi.swift
│   │   │   ├── GitHubApi.swift
│   │   │   └── GitLabApi.swift
│   │   ├── Generic/
│   │   │   ├── AuxiliaryExecute.swift
│   │   │   ├── Exts.swift
│   │   │   ├── SourceLanguage.swift
│   │   │   ├── SourcePackage.swift.swift
│   │   │   ├── SourceRegister.swift
│   │   │   ├── User.swift
│   │   │   └── UserDefault.swift.swift
│   │   └── ResultPackage/
│   │       ├── DicCounter.swift
│   │       ├── RS0.swift
│   │       ├── RS1.swift
│   │       ├── RS2.swift
│   │       ├── RS3.swift
│   │       ├── RS4.swift
│   │       ├── RS5.swift
│   │       ├── RS6.swift
│   │       ├── RS7.swift
│   │       ├── RS8.swift
│   │       ├── RS9.swift
│   │       ├── RSProtocol.swift.swift
│   │       └── ResultPackage.swift
│   ├── Entitlements.entitlements
│   ├── Info.plist
│   └── View/
│       ├── Configuration/
│       │   ├── BitbucketSheet.swift
│       │   ├── CommitFilterSheet.swift
│       │   ├── ConfigEmailSheet.swift
│       │   ├── GitHubRepoSheet.swift
│       │   ├── GitLabRepoSheet.swift
│       │   ├── LocalRepoSheet.swift
│       │   ├── MainSheet.swift
│       │   └── PickSourceSheet.swift
│       ├── Generic/
│       │   ├── AnalysisView.swift
│       │   ├── MainView.swift
│       │   ├── ResultView.swift
│       │   └── ThanksView.swift
│       ├── Helper/
│       │   ├── CodeTiles.swift
│       │   ├── SheetTemplate.swift
│       │   ├── TextIncrementEffectView.swift
│       │   ├── TextTypeEffectView.swift
│       │   └── sha256sum.swift
│       └── NavigatorView.swift
├── MyYearWithGit.xcodeproj/
│   └── project.pbxproj
├── MyYearWithGit.xcworkspace/
│   ├── contents.xcworkspacedata
│   └── xcshareddata/
│       ├── IDEWorkspaceChecks.plist
│       └── swiftpm/
│           └── Package.resolved
├── README.md
└── Resources/
    ├── MyYearWithGit.xd
    └── i18n/
        └── en/
            └── README.md
Condensed preview — 120 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (407K chars).
[
  {
    "path": ".gitignore",
    "chars": 1508,
    "preview": "!default.mode1v3\n!default.mode2v3\n!default.pbxuser\n!default.perspectivev3\n!default.xcworkspace\n*.dSYM\n*.dSYM.zip\n*.hmap\n"
  },
  {
    "path": ".gitmodules",
    "chars": 74,
    "preview": "[submodule \"Git/Core\"]\n\tpath = Git/Core\n\turl = https://github.com/git/git\n"
  },
  {
    "path": ".root",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "LICENSE",
    "chars": 1066,
    "preview": "MIT License\n\nCopyright (c) 2021 Lakr Aream\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "MyYearWithGit/App/App.swift",
    "chars": 3037,
    "preview": "//\n//  App.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/26.\n//\n\nimport AppKit\nimport SwiftUI\n\nlet pre"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/AccentColor.colorset/Contents.json",
    "chars": 123,
    "preview": "{\n  \"colors\" : [\n    {\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "chars": 1569,
    "preview": "{\n    \"images\": [\n        {\n            \"size\": \"16x16\",\n            \"idiom\": \"mac\",\n            \"filename\": \"icon-16.pn"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/Contents.json",
    "chars": 63,
    "preview": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/badge.imageset/Contents.json",
    "chars": 223,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"wall.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" :"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/bitbucket.imageset/Contents.json",
    "chars": 312,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"bitbucket_icon.svg\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/git.imageset/Contents.json",
    "chars": 222,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"git.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/github.imageset/Contents.json",
    "chars": 241,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"GitHub-Mark-120px-plus.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/gitlab.imageset/Contents.json",
    "chars": 225,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"gitlab.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\""
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/qrcode.imageset/Contents.json",
    "chars": 288,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"39__700a529aa6d6df65e62f2f7def773e06_e86fdd9ba31ec0fd57ed3c79bb536bdb.png\",\n "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/Contents.json",
    "chars": 63,
    "preview": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.aqi.high.imageset/Contents.json",
    "chars": 234,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.aqi.high.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n   "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.aqi.low.imageset/Contents.json",
    "chars": 233,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.aqi.low.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.aqi.medium.imageset/Contents.json",
    "chars": 236,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.aqi.medium.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.circle.fill.imageset/Contents.json",
    "chars": 237,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.circle.fill.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.bolt.imageset/Contents.json",
    "chars": 236,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.bolt.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.bolt.rain.imageset/Contents.json",
    "chars": 241,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.bolt.rain.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.drizzle.imageset/Contents.json",
    "chars": 239,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.drizzle.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.fog.imageset/Contents.json",
    "chars": 235,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.fog.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n  "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.hail.imageset/Contents.json",
    "chars": 236,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.hail.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.heavyrain.imageset/Contents.json",
    "chars": 241,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.heavyrain.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.imageset/Contents.json",
    "chars": 231,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"a"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.moon.bolt.imageset/Contents.json",
    "chars": 241,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.moon.bolt.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.moon.imageset/Contents.json",
    "chars": 236,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.moon.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.moon.rain.imageset/Contents.json",
    "chars": 241,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.moon.rain.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.rain.imageset/Contents.json",
    "chars": 236,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.rain.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.sleet.imageset/Contents.json",
    "chars": 237,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.sleet.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.snow.imageset/Contents.json",
    "chars": 236,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.snow.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.sun.bolt.imageset/Contents.json",
    "chars": 240,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.sun.bolt.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" :"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.sun.imageset/Contents.json",
    "chars": 235,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.sun.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n  "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.cloud.sun.rain.imageset/Contents.json",
    "chars": 240,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.cloud.sun.rain.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" :"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.humidity.imageset/Contents.json",
    "chars": 234,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.humidity.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n   "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.hurricane.imageset/Contents.json",
    "chars": 235,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.hurricane.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n  "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.moon.circle.imageset/Contents.json",
    "chars": 237,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.moon.circle.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.moon.imageset/Contents.json",
    "chars": 230,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.moon.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"au"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.moon.stars.imageset/Contents.json",
    "chars": 236,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.moon.stars.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.smoke.imageset/Contents.json",
    "chars": 231,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.smoke.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"a"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.snowflake.circle.imageset/Contents.json",
    "chars": 242,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.snowflake.circle.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\""
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.snowflake.imageset/Contents.json",
    "chars": 235,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.snowflake.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n  "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.sparkles.imageset/Contents.json",
    "chars": 234,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.sparkles.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n   "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.sun.and.horizon.imageset/Contents.json",
    "chars": 241,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.sun.and.horizon.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.sun.dust.imageset/Contents.json",
    "chars": 234,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.sun.dust.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n   "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.sun.haze.imageset/Contents.json",
    "chars": 234,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.sun.haze.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n   "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.sun.max.circle.imageset/Contents.json",
    "chars": 240,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.sun.max.circle.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" :"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.sun.max.imageset/Contents.json",
    "chars": 233,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.sun.max.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.sun.min.imageset/Contents.json",
    "chars": 233,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.sun.min.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.sunrise.imageset/Contents.json",
    "chars": 233,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.sunrise.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.sunset.imageset/Contents.json",
    "chars": 232,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.sunset.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \""
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.thermometer.imageset/Contents.json",
    "chars": 237,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.thermometer.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.thermometer.snowflake.imageset/Contents.json",
    "chars": 247,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.thermometer.snowflake.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \""
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.thermometer.sun.imageset/Contents.json",
    "chars": 241,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.thermometer.sun.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.tornado.imageset/Contents.json",
    "chars": 233,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.tornado.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.tropicalstorm.imageset/Contents.json",
    "chars": 239,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.tropicalstorm.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : "
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.wind.imageset/Contents.json",
    "chars": 230,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.wind.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"au"
  },
  {
    "path": "MyYearWithGit/App/Assets.xcassets/sfexp/custom.wind.snow.imageset/Contents.json",
    "chars": 235,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"custom.wind.snow.png\",\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n  "
  },
  {
    "path": "MyYearWithGit/App/Hooker.m",
    "chars": 2259,
    "preview": "//\n//  AskBeforeCloseMyWindow.swift\n//\n//\n//  Created by Lakr Aream on 2021/11/30.\n//\n\n#import <AppKit/AppKit.h>\n#import"
  },
  {
    "path": "MyYearWithGit/App/InfoPlist.xcstrings",
    "chars": 1762,
    "preview": "{\n  \"sourceLanguage\" : \"zh-Hans\",\n  \"strings\" : {\n    \"CFBundleDisplayName\" : {\n      \"comment\" : \"Bundle display name\","
  },
  {
    "path": "MyYearWithGit/App/Localizable.xcstrings",
    "chars": 49457,
    "preview": "{\n  \"sourceLanguage\" : \"zh-Hans\",\n  \"strings\" : {\n    \"\" : {\n      \"shouldTranslate\" : false\n    },\n    \" %@ \" : {\n     "
  },
  {
    "path": "MyYearWithGit/App/main.swift",
    "chars": 266,
    "preview": "//\n//  main.swift\n//  MyYearWithGit\n//\n//  Created by 秋星桥 on 2024/12/17.\n//\n\nimport Foundation\n\nlet requiredYear = 2025\n"
  },
  {
    "path": "MyYearWithGit/Data/Analyser/CommitFilter.swift",
    "chars": 4708,
    "preview": "//\n//  CommitFilter.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/12/1.\n//\n\nimport AppKit\nimport Foundati"
  },
  {
    "path": "MyYearWithGit/Data/Analyser/DictionaryBuilder.swift",
    "chars": 2883,
    "preview": "//\n//  DictionaryBuilder.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/29.\n//\n\nimport Foundation\n\nclas"
  },
  {
    "path": "MyYearWithGit/Data/Analyser/GitDiff.swift",
    "chars": 13257,
    "preview": "//\n//  GitDiff.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/28.\n//\n\nimport Foundation\n\nextension Repo"
  },
  {
    "path": "MyYearWithGit/Data/Analyser/GitLog.swift",
    "chars": 2833,
    "preview": "//\n//  GitLog.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/28.\n//\n\nimport Foundation\n\nprivate let jso"
  },
  {
    "path": "MyYearWithGit/Data/Analyser/GitRepoResult.swift",
    "chars": 444,
    "preview": "//\n//  GitRepoResult.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/28.\n//\n\nimport Foundation\n\nextensio"
  },
  {
    "path": "MyYearWithGit/Data/Analyser/RepoAnalyser.swift",
    "chars": 5655,
    "preview": "//\n//  RepoAnalyser.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/27.\n//\n\nimport Foundation\n\n// Sun Ap"
  },
  {
    "path": "MyYearWithGit/Data/Api/ApiProtocol.swift",
    "chars": 911,
    "preview": "//\n//  ApiProtocol.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/12/5.\n//\n\nimport Foundation\n\nprotocol Gi"
  },
  {
    "path": "MyYearWithGit/Data/Api/BitbucketApi.swift",
    "chars": 11384,
    "preview": "//\n//  BitbucketApi.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/12/3.\n//\n\nimport Foundation\n\nprivate le"
  },
  {
    "path": "MyYearWithGit/Data/Api/GitHubApi.swift",
    "chars": 3546,
    "preview": "//\n//  GitHubApi.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/12/5.\n//\n\nimport Foundation\nimport OctoKit"
  },
  {
    "path": "MyYearWithGit/Data/Api/GitLabApi.swift",
    "chars": 7310,
    "preview": "//\n//  GitLabApi.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/27.\n//\n\nimport Foundation\n\nclass GitLab"
  },
  {
    "path": "MyYearWithGit/Data/Generic/AuxiliaryExecute.swift",
    "chars": 1951,
    "preview": "//\n//  AuxiliaryExecute.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/27.\n//\n\nimport AuxiliaryExecute\n"
  },
  {
    "path": "MyYearWithGit/Data/Generic/Exts.swift",
    "chars": 2685,
    "preview": "//\n//  Exts.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/26.\n//\n\nimport Foundation\n\nprotocol HumanRea"
  },
  {
    "path": "MyYearWithGit/Data/Generic/SourceLanguage.swift",
    "chars": 2813,
    "preview": "//\n//  SourceLanguage.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/28.\n//\n\nimport Foundation\n\nenum So"
  },
  {
    "path": "MyYearWithGit/Data/Generic/SourcePackage.swift.swift",
    "chars": 1315,
    "preview": "//\n//  SourcePackage.swift.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/27.\n//\n\nimport Foundation\n\nex"
  },
  {
    "path": "MyYearWithGit/Data/Generic/SourceRegister.swift",
    "chars": 1639,
    "preview": "//\n//  SourceRegister.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/26.\n//\n\nimport Foundation\n\nenum So"
  },
  {
    "path": "MyYearWithGit/Data/Generic/User.swift",
    "chars": 1236,
    "preview": "//\n//  User.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/12/4.\n//\n\nimport Foundation\n\nprivate let userDe"
  },
  {
    "path": "MyYearWithGit/Data/Generic/UserDefault.swift.swift",
    "chars": 911,
    "preview": "//\n//  UserDefault.swift.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/12/4.\n//\n\nimport Foundation\n\n@prop"
  },
  {
    "path": "MyYearWithGit/Data/ResultPackage/DicCounter.swift",
    "chars": 1114,
    "preview": "//\n//  DicCounter.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/29.\n//\n\nimport Foundation\n\nenum DicCou"
  },
  {
    "path": "MyYearWithGit/Data/ResultPackage/RS0.swift",
    "chars": 4827,
    "preview": "//\n//  RS0.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/28.\n//\n\nimport Foundation\nimport SwiftUI\n\ncla"
  },
  {
    "path": "MyYearWithGit/Data/ResultPackage/RS1.swift",
    "chars": 8147,
    "preview": "//\n//  RS1.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/29.\n//\n\nimport Foundation\nimport SwiftUI\n\npri"
  },
  {
    "path": "MyYearWithGit/Data/ResultPackage/RS2.swift",
    "chars": 10059,
    "preview": "//\n//  RS2.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/29.\n//\n\nimport Foundation\nimport SwiftUI\n\ncla"
  },
  {
    "path": "MyYearWithGit/Data/ResultPackage/RS3.swift",
    "chars": 8136,
    "preview": "//\n//  RS3.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/29.\n//\n\nimport Foundation\nimport SwiftUI\n\npri"
  },
  {
    "path": "MyYearWithGit/Data/ResultPackage/RS4.swift",
    "chars": 15600,
    "preview": "//\n//  RS4.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/29.\n//\n\nimport Foundation\nimport SwiftUI\n\ncla"
  },
  {
    "path": "MyYearWithGit/Data/ResultPackage/RS5.swift",
    "chars": 3651,
    "preview": "//\n//  RS5.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/29.\n//\n\nimport Foundation\nimport SwiftUI\n\ncla"
  },
  {
    "path": "MyYearWithGit/Data/ResultPackage/RS6.swift",
    "chars": 8675,
    "preview": "//\n//  RS6.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/29.\n//\n\nimport Foundation\nimport SwiftUI\n\ncla"
  },
  {
    "path": "MyYearWithGit/Data/ResultPackage/RS7.swift",
    "chars": 3663,
    "preview": "//\n//  RS7.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/29.\n//\n\nimport Foundation\nimport SwiftUI\n\ncla"
  },
  {
    "path": "MyYearWithGit/Data/ResultPackage/RS8.swift",
    "chars": 1633,
    "preview": "//\n//  RS8.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/30.\n//\n\nimport Foundation\nimport SwiftUI\n\ncla"
  },
  {
    "path": "MyYearWithGit/Data/ResultPackage/RS9.swift",
    "chars": 12366,
    "preview": "//\n//  RS9.swift\n//  MyYearWithGit\n//\n//  Created by diablohl on 2025/1/5.\n//\n\nimport Foundation\nimport SwiftUI\n\nprivate"
  },
  {
    "path": "MyYearWithGit/Data/ResultPackage/RSProtocol.swift.swift",
    "chars": 2053,
    "preview": "//\n//  RSProtocol.swift.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/28.\n//\n\nimport SwiftUI\n\nextensio"
  },
  {
    "path": "MyYearWithGit/Data/ResultPackage/ResultPackage.swift",
    "chars": 1522,
    "preview": "//\n//  ResultPackage.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/27.\n//\n\nimport Foundation\n\nclass Re"
  },
  {
    "path": "MyYearWithGit/Entitlements.entitlements",
    "chars": 181,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "MyYearWithGit/Info.plist",
    "chars": 1501,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "MyYearWithGit/View/Configuration/BitbucketSheet.swift",
    "chars": 6598,
    "preview": "//\n//  BitbucketSheet.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/12/3.\n//\n\nimport SwiftUI\n\nstruct Bitb"
  },
  {
    "path": "MyYearWithGit/View/Configuration/CommitFilterSheet.swift",
    "chars": 2372,
    "preview": "//\n//  CommitFilterSheet.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/12/1.\n//\n\nimport SwiftUI\n\nstruct F"
  },
  {
    "path": "MyYearWithGit/View/Configuration/ConfigEmailSheet.swift",
    "chars": 2424,
    "preview": "//\n//  ConfigEmailSheet.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/27.\n//\n\nimport SwiftUI\n\nstruct C"
  },
  {
    "path": "MyYearWithGit/View/Configuration/GitHubRepoSheet.swift",
    "chars": 6134,
    "preview": "//\n//  GitHubRepoSheet.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/26.\n//\n\nimport SwiftUI\n\nimport Oc"
  },
  {
    "path": "MyYearWithGit/View/Configuration/GitLabRepoSheet.swift",
    "chars": 6706,
    "preview": "//\n//  GitLabRepoSheet.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/26.\n//\n\nimport SwiftUI\n\nstruct Gi"
  },
  {
    "path": "MyYearWithGit/View/Configuration/LocalRepoSheet.swift",
    "chars": 7395,
    "preview": "//\n//  LocalRepoSheet.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/26.\n//\n\nimport SwiftUI\n\nvar search"
  },
  {
    "path": "MyYearWithGit/View/Configuration/MainSheet.swift",
    "chars": 8594,
    "preview": "//\n//  MainSheet.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/26.\n//\n\nimport SwiftUI\n\nextension Notif"
  },
  {
    "path": "MyYearWithGit/View/Configuration/PickSourceSheet.swift",
    "chars": 1269,
    "preview": "//\n//  PickSourceSheet.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/26.\n//\n\nimport SwiftUI\n\nextension"
  },
  {
    "path": "MyYearWithGit/View/Generic/AnalysisView.swift",
    "chars": 10647,
    "preview": "//\n//  AnalysisView.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/27.\n//\n\nimport SwiftUI\n\n// After ana"
  },
  {
    "path": "MyYearWithGit/View/Generic/MainView.swift",
    "chars": 7071,
    "preview": "//\n//  MainView.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/26.\n//\n\nimport ColorfulX\nimport SwiftUI\n"
  },
  {
    "path": "MyYearWithGit/View/Generic/ResultView.swift",
    "chars": 14747,
    "preview": "//\n//  ResultView.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/27.\n//\n\nimport Quartz\nimport SwiftUI\n\n"
  },
  {
    "path": "MyYearWithGit/View/Generic/ThanksView.swift",
    "chars": 1456,
    "preview": "//\n//  ThanksView.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/29.\n//\n\nimport MarkdownUI\nimport Swift"
  },
  {
    "path": "MyYearWithGit/View/Helper/CodeTiles.swift",
    "chars": 2292,
    "preview": "//\n//  CodeTiles.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/28.\n//\n\nimport SwiftUI\n\nstruct CodeTile"
  },
  {
    "path": "MyYearWithGit/View/Helper/SheetTemplate.swift",
    "chars": 1594,
    "preview": "//\n//  SheetTemplate.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/26.\n//\n\nimport SwiftUI\n\nlet preferr"
  },
  {
    "path": "MyYearWithGit/View/Helper/TextIncrementEffectView.swift",
    "chars": 764,
    "preview": "//\n//  TextIncrementEffectView.swift\n//  MyYearWithGit\n//\n//  Created by Cyandev on 2021/11/28.\n//\n\nimport SwiftUI\n\nstru"
  },
  {
    "path": "MyYearWithGit/View/Helper/TextTypeEffectView.swift",
    "chars": 2503,
    "preview": "//\n//  TextTypeEffectView.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/26.\n//\n\nimport SwiftUI\n\nstruct"
  },
  {
    "path": "MyYearWithGit/View/Helper/sha256sum.swift",
    "chars": 555,
    "preview": "//\n//  sha256sum.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/30.\n//\n\nimport CommonCrypto\nimport Foun"
  },
  {
    "path": "MyYearWithGit/View/NavigatorView.swift",
    "chars": 3414,
    "preview": "//\n//  NavigatorView.swift\n//  MyYearWithGit\n//\n//  Created by Lakr Aream on 2021/11/27.\n//\n\nimport SwiftUI\n\nstruct Navi"
  },
  {
    "path": "MyYearWithGit.xcodeproj/project.pbxproj",
    "chars": 42605,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 55;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "MyYearWithGit.xcworkspace/contents.xcworkspacedata",
    "chars": 159,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:MyYearWithGit."
  },
  {
    "path": "MyYearWithGit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "chars": 238,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "MyYearWithGit.xcworkspace/xcshareddata/swiftpm/Package.resolved",
    "chars": 2859,
    "preview": "{\n  \"originHash\" : \"df25ac7eb41fe53aced11a9d0d1c121c77d4b5e5a38899baff74360177e957dc\",\n  \"pins\" : [\n    {\n      \"identit"
  },
  {
    "path": "README.md",
    "chars": 1318,
    "preview": "<div align=\"center\">\n\n# 我和我的代码,还有这一年。\n\n<p align=\"center\">\n  <a href=\"README.md\">简体中文</a> |\n  <a href=\"./Resources/i18n/e"
  },
  {
    "path": "Resources/i18n/en/README.md",
    "chars": 3112,
    "preview": "<div align=\"center\">\n\n# My Code & This Year\n\n<p align=\"center\">\n  <a href=\"../../README.md\">简体中文</a> |\n  <a href=\"README"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the Co2333/myyearwithgit GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 120 files (350.2 KB), approximately 94.1k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!