Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad7000fc33 | ||
|
|
08cf150bf8 | ||
|
|
7d03c26e9a | ||
|
|
21aeafd8dd | ||
|
|
ab704dc4be | ||
|
|
42c0a03ddc | ||
|
|
550529f1fa | ||
|
|
23fbc01a0e | ||
|
|
56546571b6 | ||
|
|
e5c634e672 | ||
|
|
7fdfe4a9ee | ||
|
|
3e95f77cc0 | ||
|
|
9b5e43eec5 | ||
|
|
ac3c3740c2 | ||
|
|
35a67ddf16 | ||
|
|
53815e0f28 | ||
|
|
7b7a73bd46 | ||
|
|
bf3fa6734e | ||
|
|
be06aef6d7 | ||
|
|
3e27abd1e8 | ||
|
|
0a6485e024 | ||
|
|
5b0df6bd4c | ||
|
|
a3f2a54f20 | ||
|
|
d1fd1fd9d0 | ||
|
|
cd5fb46963 | ||
|
|
09ebff06ee | ||
|
|
ac24d6d148 | ||
|
|
f481d22b75 | ||
|
|
149e3a5026 | ||
|
|
ef83525e9a | ||
|
|
56a042716e | ||
|
|
0fe722bfba | ||
|
|
3b53ce77bb | ||
|
|
b2f5c6c4d5 | ||
|
|
7c64864c2f | ||
|
|
9d0b947a48 | ||
|
|
9ed8a199b0 | ||
|
|
a0c9feefca | ||
|
|
1a2822d130 | ||
|
|
44007195b7 | ||
|
|
74b5a119d3 | ||
|
|
0539a3ad49 | ||
|
|
a06afd4bd2 | ||
|
|
1090acf3a5 | ||
|
|
b8ba0f0888 | ||
|
|
989b344b1d | ||
|
|
bf58335bbe | ||
|
|
5c4199ec74 | ||
|
|
7821d7c979 | ||
|
|
e2b47790a9 | ||
|
|
ff66a0664d | ||
|
|
6d42bef7ec | ||
|
|
cca3423a59 | ||
|
|
5e842d5850 | ||
|
|
0c724f3c7b | ||
|
|
55f3f59208 | ||
|
|
edc2f00603 | ||
|
|
bcb130e7eb | ||
|
|
d8de1e80b8 | ||
|
|
610378525a | ||
|
|
2f72c5d6ae | ||
|
|
a62949f0dc | ||
|
|
7ded01c277 | ||
|
|
a45361321d | ||
|
|
b7204f9694 | ||
|
|
b8a3b779e1 | ||
|
|
7906d630be | ||
|
|
3c04a4ce15 | ||
|
|
2f875b3bcb | ||
|
|
914f91f9f7 | ||
|
|
fcc6651b6a | ||
|
|
dda612c15e | ||
|
|
894a69d41f | ||
|
|
e2523f1d99 | ||
|
|
6fa35ae35c | ||
|
|
d0a2d31b5a | ||
|
|
43838e1ccc | ||
|
|
741e7902db | ||
|
|
6426d318fb | ||
|
|
8a98b4ee40 | ||
|
|
dcaac482de | ||
|
|
ee27df7680 | ||
|
|
e0ae29d64a | ||
|
|
db78e66451 | ||
|
|
b8ecd58005 | ||
|
|
2725834c4a | ||
|
|
42cb2d5d88 | ||
|
|
3994429b88 | ||
|
|
237bb1e0d9 | ||
|
|
911aad42cc | ||
|
|
36ded28ce4 | ||
|
|
9761bb91e9 | ||
|
|
435a310590 | ||
|
|
d377b3dbca | ||
|
|
850fe285b4 | ||
|
|
2adeb8dbcb | ||
|
|
fb5dfc4399 | ||
|
|
29e1cff8f1 | ||
|
|
2c3373ae16 | ||
|
|
c294ad0d4d | ||
|
|
ee436cc7cc | ||
|
|
168995493f | ||
|
|
e477f8b3da | ||
|
|
516329a408 | ||
|
|
938b7353ff | ||
|
|
a80721b2d3 | ||
|
|
4e065b9a80 | ||
|
|
aa8d7d02d1 | ||
|
|
05b36fc58f | ||
|
|
d6196ecad8 | ||
|
|
21a91421a6 | ||
|
|
272f51ad5b | ||
|
|
c352591d72 | ||
|
|
96caad46a5 | ||
|
|
309cae316b | ||
|
|
ffd0c75e8b | ||
|
|
fdf313472c | ||
|
|
011fdba7d3 | ||
|
|
e5e8521ae3 | ||
|
|
786e752417 | ||
|
|
d2220c68bd | ||
|
|
26d40e1149 | ||
|
|
15a55e6e07 | ||
|
|
32ab8d6573 | ||
|
|
ec55ae8b00 | ||
|
|
689adc0a30 | ||
|
|
fab9d7c0ab | ||
|
|
4aec2aa6da | ||
|
|
f46372b97c | ||
|
|
33c661505e | ||
|
|
91e16f7863 | ||
|
|
55e8c331a6 | ||
|
|
ae092cd1a7 | ||
|
|
122dc2ec0f | ||
|
|
c25b918a51 | ||
|
|
173bc97d0f | ||
|
|
84166ab954 | ||
|
|
a1cfd1de25 | ||
|
|
58fcae7af8 | ||
|
|
29f0a08391 | ||
|
|
2d683e7e46 | ||
|
|
247f6353b0 | ||
|
|
08e28fd0a5 | ||
|
|
cab591eb48 | ||
|
|
33e5acf0ea | ||
|
|
15554ef767 | ||
|
|
a9cb03c26f | ||
|
|
fb6110d0eb | ||
|
|
c3ace1faff | ||
|
|
c5286c3a6e | ||
|
|
1316eb2769 | ||
|
|
27909f1824 | ||
|
|
78c852514f | ||
|
|
985a681d72 | ||
|
|
3c79840a29 | ||
|
|
95ee614d9f | ||
|
|
591ce5274f | ||
|
|
3f18951368 | ||
|
|
be077f1a67 | ||
|
|
1a4b53917d | ||
|
|
726e13edcd | ||
|
|
4ebd990e30 | ||
|
|
4567550978 | ||
|
|
f489bd7d36 | ||
|
|
e93e42f952 | ||
|
|
250c9c4bce | ||
|
|
aa46a62457 | ||
|
|
f66c92aefb | ||
|
|
a696611615 | ||
|
|
5db53b5a9e | ||
|
|
e9e732756e | ||
|
|
ca96b85352 | ||
|
|
67f5098c95 | ||
|
|
f37652942d | ||
|
|
f67d182a92 | ||
|
|
b325cc75c0 | ||
|
|
6cc76903b0 | ||
|
|
b4bc0b006a | ||
|
|
b0ce899a71 | ||
|
|
bd162a9e08 | ||
|
|
8b7d69c0ff | ||
|
|
518f8b402e | ||
|
|
397457cacb | ||
|
|
eee0db133c | ||
|
|
dec05198c7 | ||
|
|
911c3c17c5 | ||
|
|
9d852eee9c | ||
|
|
17e1f1e4c7 | ||
|
|
c0ac29fdd8 | ||
|
|
9b3f93688e | ||
|
|
f4f7d9addc | ||
|
|
4e35f9f290 | ||
|
|
820b6ea3aa | ||
|
|
647f900b85 | ||
|
|
6c0f97ffe9 | ||
|
|
bc95b905af | ||
|
|
330ac54c6f | ||
|
|
54249d03dd | ||
|
|
d543393e3f | ||
|
|
ee010de36c | ||
|
|
3c7aaafa63 | ||
|
|
b62cec0cdc | ||
|
|
a474660498 | ||
|
|
6e2a5ff081 | ||
|
|
8dd63c722f | ||
|
|
e98dff325d | ||
|
|
8d93508062 | ||
|
|
fd0411b508 | ||
|
|
8564ed255a | ||
|
|
9d78700ab7 | ||
|
|
c72fedbb30 | ||
|
|
e637c61cc9 | ||
|
|
dae19ca067 | ||
|
|
9d6fc68642 | ||
|
|
2cd8b96d38 | ||
|
|
541337259d | ||
|
|
93defcd3a7 | ||
|
|
69edbbdf42 | ||
|
|
dcea005d8d | ||
|
|
cfd59d31a1 | ||
|
|
f42ffa61d1 | ||
|
|
0a2254702f | ||
|
|
d02327af2d | ||
|
|
c10ca2a77e | ||
|
|
2f8c01418d | ||
|
|
3a0c84a8f5 | ||
|
|
597b443796 | ||
|
|
0ea925289b | ||
|
|
f3b116e47c | ||
|
|
4c3ec7d067 | ||
|
|
941d8afb9a | ||
|
|
8e41662088 | ||
|
|
71bb2d889b | ||
|
|
c712473c7a | ||
|
|
121515cbc7 | ||
|
|
8b52dc8acb | ||
|
|
db5644e058 | ||
|
|
684cc666d3 | ||
|
|
dfff608ad1 | ||
|
|
f1c5ae73c2 | ||
|
|
d85ec7bcfb | ||
|
|
2855b1bb0b | ||
|
|
2a616e2518 | ||
|
|
d5d131185e | ||
|
|
0f2c0e794c | ||
|
|
d4e697c0de | ||
|
|
720dde1c06 | ||
|
|
1e017475ff | ||
|
|
95e51d1c27 | ||
|
|
d653a54fc3 | ||
|
|
c2ccccd093 | ||
|
|
837fa03f64 | ||
|
|
f027b4795f | ||
|
|
6ede54e3e0 | ||
|
|
922d259193 | ||
|
|
56075b5766 | ||
|
|
b0f02c6a36 | ||
|
|
de1326e118 | ||
|
|
53d1d1fded | ||
|
|
e17f427a5d | ||
|
|
df5af7d60c | ||
|
|
702cb0d140 | ||
|
|
9e415bff54 | ||
|
|
a696a0e0b2 | ||
|
|
52026701e4 | ||
|
|
7471488e33 | ||
|
|
0ef8a0b2d4 | ||
|
|
76a72a5ead | ||
|
|
3b0cba493b | ||
|
|
bc9f97f852 | ||
|
|
295eb2bd60 | ||
|
|
dfcf9de78e | ||
|
|
fc6d63603a | ||
|
|
9156ad915a | ||
|
|
a138a922ef | ||
|
|
b51ff6583d | ||
|
|
7207ad6da7 | ||
|
|
e3fafbc6ff | ||
|
|
be5eb26385 | ||
|
|
e9b529a644 | ||
|
|
250a1bcc81 | ||
|
|
96edb065d7 | ||
|
|
7e501a460a | ||
|
|
dd05ba239e | ||
|
|
b373fc465b | ||
|
|
f92f7ca803 | ||
|
|
51062a2499 | ||
|
|
48a3967b82 | ||
|
|
18ef16f6ee | ||
|
|
fda3ada055 | ||
|
|
db5500f130 | ||
|
|
42bbd0fe01 | ||
|
|
b257752812 | ||
|
|
54b7c8d697 | ||
|
|
bcafd0790f | ||
|
|
e07da9cad9 | ||
|
|
d3b5befe3e | ||
|
|
4481d94fa2 | ||
|
|
982a6dd5f2 | ||
|
|
898fc8c13c | ||
|
|
9ec2762bff | ||
|
|
6d9059ee86 | ||
|
|
ef6ab620fb | ||
|
|
ecf4cb15be | ||
|
|
c9d36b5bad | ||
|
|
9e932799ee | ||
|
|
6215b65ec9 | ||
|
|
9adf64c374 | ||
|
|
d32f9533e3 | ||
|
|
2a0a8585df | ||
|
|
87a2b219a5 | ||
|
|
c5e13ccc84 | ||
|
|
40c9a18be4 | ||
|
|
8a4aa7908f | ||
|
|
82879e39e7 | ||
|
|
60534bcfe3 | ||
|
|
41ddd7c1a6 | ||
|
|
5601a556c9 | ||
|
|
764e0f3f25 | ||
|
|
3619807cb9 | ||
|
|
d65f220530 | ||
|
|
903e758528 | ||
|
|
9b85f00564 | ||
|
|
cb191d60f3 | ||
|
|
ac70fcc5f9 | ||
|
|
68d24919b1 | ||
|
|
baa411d9c7 | ||
|
|
7e199f6815 | ||
|
|
9ca0649368 | ||
|
|
987b6b2f82 | ||
|
|
bf3a4dcc7a | ||
|
|
e4cfd85dc7 | ||
|
|
974b6a9ea2 | ||
|
|
71345465cf | ||
|
|
89c02c9a96 | ||
|
|
73382db4a2 | ||
|
|
9bafd037c3 | ||
|
|
57e3a369ae | ||
|
|
f0550d75b8 | ||
|
|
b694c837b4 | ||
|
|
a083b06de0 | ||
|
|
17e9599976 | ||
|
|
487b96d7d3 | ||
|
|
83b5319433 | ||
|
|
db305db392 | ||
|
|
dfd5f9dd94 | ||
|
|
8748d8b4e5 | ||
|
|
f97e9f9333 | ||
|
|
3c58c6bf5f | ||
|
|
a4899658df | ||
|
|
1053740723 | ||
|
|
b0adfb97ad | ||
|
|
d0d2314e9a | ||
|
|
22aafce24e | ||
|
|
c02dfafa2a | ||
|
|
f8b22dc1ed | ||
|
|
4a9b543a3a | ||
|
|
1332a73189 | ||
|
|
165a6695b9 | ||
|
|
b816745830 | ||
|
|
0b198b4031 | ||
|
|
ffdab44710 | ||
|
|
3e423a14f4 | ||
|
|
f56c65df79 | ||
|
|
c8eb0914b3 | ||
|
|
05851fb728 | ||
|
|
5c12810d23 | ||
|
|
e11392d0af | ||
|
|
e3f2da13f5 | ||
|
|
a94eeb023d | ||
|
|
82162b167b | ||
|
|
7100d251ec | ||
|
|
c4f98a10dc | ||
|
|
9585c92629 | ||
|
|
2594427e75 | ||
|
|
49178b50b0 | ||
|
|
353a7c9c2b | ||
|
|
a9614c15aa | ||
|
|
690e2f6e85 | ||
|
|
16b9122f9e | ||
|
|
4cfe16a708 | ||
|
|
3c4aaf5bba | ||
|
|
bc2fe382a9 | ||
|
|
a0fe1080f3 | ||
|
|
81eb07ee98 | ||
|
|
f7de2bb6d9 | ||
|
|
d430f835a4 | ||
|
|
c0f0ce7df2 | ||
|
|
d934fb41ab | ||
|
|
d0739ce0f1 | ||
|
|
545b5db143 | ||
|
|
649a5cb86a | ||
|
|
88c1595deb | ||
|
|
a8498bb7f6 | ||
|
|
d5fa496a20 | ||
|
|
9f86e8355d | ||
|
|
8f4784f86d | ||
|
|
696a489f43 | ||
|
|
67d436cfc5 | ||
|
|
a966de9f50 | ||
|
|
9b7e8250bc | ||
|
|
7723c0149d | ||
|
|
38c363162b | ||
|
|
4a46c46253 | ||
|
|
9d1349b5aa |
No files matched your search
@@ -1,2 +1,3 @@
|
||||
github: lwouis
|
||||
patreon: lwouis
|
||||
patreon: alt_tab_macos
|
||||
custom: ["paypal.com/donate/?hosted_button_id=ACYAC3UYCM7CN", "donate.stripe.com/4gw9D7bA3g3O0ikaEF"]
|
||||
@@ -0,0 +1,68 @@
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
APPCENTER_SECRET: ${{ secrets.APPCENTER_SECRET }}
|
||||
APPCENTER_TOKEN: ${{ secrets.APPCENTER_TOKEN }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_P12_CERTIFICATE: ${{ secrets.APPLE_P12_CERTIFICATE }}
|
||||
FEEDBACK_TOKEN: ${{ secrets.FEEDBACK_TOKEN }}
|
||||
NETLIFY_WEBHOOK: ${{ secrets.NETLIFY_WEBHOOK }}
|
||||
SPARKLE_ED_PRIVATE_KEY: ${{ secrets.SPARKLE_ED_PRIVATE_KEY }}
|
||||
GITHUB_EVENT_BEFORE: ${{ github.event.before }}
|
||||
GITHUB_EVENT_AFTER: ${{ github.event.after }}
|
||||
BUILD_DIR: ${{ github.workspace }}
|
||||
XCODE_BUILD_PATH: DerivedData/Build/Products/Release
|
||||
VERSION_FILE: VERSION.txt
|
||||
APP_NAME: AltTab
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-15 # all options: https://github.com/actions/runner-images/tree/main
|
||||
environment: production
|
||||
steps:
|
||||
# - env:
|
||||
# GITHUB_CONTEXT: ${{ toJSON(github) }}
|
||||
# run: echo "$GITHUB_CONTEXT"
|
||||
- id: pre-checkout
|
||||
env:
|
||||
COMMITS: ${{ toJson(github.event.commits) }}
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "push" ]]; then
|
||||
COUNT=$(( $(echo "$COMMITS" | jq length) + 5 ))
|
||||
else
|
||||
COUNT=1
|
||||
fi
|
||||
echo "fetch-depth=$COUNT" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: ${{ steps.pre-checkout.outputs.fetch-depth }}
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
cache: 'npm'
|
||||
- run: sudo xcode-select -s /Applications/Xcode_26.0.1.app/Contents/Developer
|
||||
- run: scripts/print_env.sh
|
||||
- run: npm ci
|
||||
- run: npx commitlint --from "$GITHUB_EVENT_BEFORE" --to "$GITHUB_EVENT_AFTER" --verbose
|
||||
- run: scripts/ensure_generated_files_are_up_to_date.sh
|
||||
- run: scripts/determine_next_version.sh
|
||||
- run: scripts/replace_environment_variables_in_app.sh
|
||||
- run: scripts/codesign/setup_ci_master.sh
|
||||
- run: scripts/run_tests.sh
|
||||
- run: scripts/build_app.sh
|
||||
- run: scripts/package_and_notarize_release.sh
|
||||
- run: scripts/upload_symbols_to_appcenter.sh
|
||||
- run: scripts/update_appcast.sh
|
||||
- run: scripts/update_readme_and_website.sh
|
||||
- run: npx semantic-release
|
||||
- id: set_tag_name
|
||||
run: echo "tag_name=v"$(cat $VERSION_FILE)"" >> "$GITHUB_OUTPUT"
|
||||
- uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
tag_name: ${{ steps.set_tag_name.outputs.tag_name }}
|
||||
files: ${{ env.XCODE_BUILD_PATH }}/*.zip
|
||||
- run: scripts/update_website.sh
|
||||
@@ -1,5 +1,7 @@
|
||||
/.idea/
|
||||
xcuserdata/
|
||||
/.vscode/
|
||||
/buildServer.json
|
||||
WorkspaceSettings.xcsettings
|
||||
IDEWorkspaceChecks.plist
|
||||
/node_modules/
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# We can find the rules here.
|
||||
# https://github.com/nicklockwood/SwiftFormat/blob/main/Rules.md
|
||||
# rules: https://github.com/nicklockwood/SwiftFormat/blob/main/Rules.md
|
||||
|
||||
--swiftversion 5.5
|
||||
|
||||
--maxwidth 120
|
||||
--swiftversion 5.8
|
||||
--maxwidth 110
|
||||
--nowrapoperators .,==,!=,<,>,>=,<=
|
||||
--wrapternary before-operators
|
||||
--disable andOperator
|
||||
--disable wrapConditionalBodies
|
||||
--disable wrapLoopBodies
|
||||
--disable wrapMultilineStatementBraces
|
||||
@@ -1,34 +0,0 @@
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
os: osx
|
||||
osx_image: xcode13.4
|
||||
language: node_js
|
||||
node_js:
|
||||
- 16
|
||||
addons:
|
||||
ssh_known_hosts: github.com
|
||||
homebrew:
|
||||
packages:
|
||||
- vitorgalvao/tiny-scripts/cask-repair
|
||||
update: true
|
||||
env:
|
||||
global:
|
||||
- IS_RELEASE=$(if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then echo true; fi)
|
||||
- XCODE_BUILD_PATH="DerivedData/Build/Products/Release"
|
||||
- VERSION_FILE="VERSION.txt"
|
||||
- APP_NAME="$(awk -F ' = ' '/PRODUCT_NAME/ { print $2; }' < config/base.xcconfig)"
|
||||
install: true # disable default install
|
||||
script: scripts/travis.sh
|
||||
before_deploy: if [[ $TRAVIS_TEST_RESULT == 1 ]]; then echo "build failed; exiting to prevent deploy phases"; sleep 2; exit 1; fi
|
||||
deploy:
|
||||
provider: releases
|
||||
token:
|
||||
secure: wZUHfOs+JQ0ikNMJ8BnM+8fuoQdhgOEQpNd01ueZxe760GAAjSbq1icME8qaYJJMk1G6n14jo9ecEhzxF0XV8hSdy4WtikK7l5SXiOx5Efuh/tNscmHggGk235eLwQD9pglePZsP3xJUB1BHEj260rypkjnSx5kVOfLUeB1ASeg4+KdxZd2vXjwel+YQf+dYbNUYtwoWqjiLbqT1ao+0q04MPgD2c9jb+HnsA94LUGb44lPXqfUJ+xG2LxBpcDW/q1JhFXL/AmJb0dOOEVzzrBqfWysPukgPMONexZse4c3BBqkMI52ZuF3OoEVAffofmuGKiR5OoyU/hW17xi9jGeb79r+Xt4RdaJAgwcn7/7GtemYKUJp8jhLGsy9XZJShENX7UHTkP3L4iyOrd2Wz+ctZWAebyNReLt985/xTaplpDiQrPcKAuQNBa4sgWk5rIsf7Z0tcBfZau/fQl9Q4100xTbwC+GeAbL0IyXG3kVzQGsGllXHr/2JM1sj7rmKA7lmDlp7xiOBCPscn2YCT87U+F6VbYoNvnxne0igQOUwrvX4qa4XlYrUXDeHcyKku0m8znY74nOu+m6LXkIt8r29pi6Xac0/ZGMwKZRUvKg/skamWPRoy9DAVd8TBQW1c91oYKmqDQRy0eWnD6X1djcKywJ7WlSQDejebJql0h+o=
|
||||
file_glob: true
|
||||
file: "$XCODE_BUILD_PATH/*.zip"
|
||||
skip_cleanup: true
|
||||
on:
|
||||
repo: lwouis/alt-tab-macos
|
||||
after_deploy: scripts/after_deploy.sh
|
||||
@@ -14,4 +14,4 @@ python_version = "3.6"
|
||||
|
||||
[scripts]
|
||||
font2png = "scripts/convert_font_to_png.sh"
|
||||
translate = "python scripts/translate_i18n_tools.py resources/l10n --retry_translate"
|
||||
translate = "python scripts/l10n/google_translate_all_terms_locally.py resources/l10n --retry_translate"
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "00c7c75d00988a027e56c90f3a0bbba05aec3b41b2f7fd9be24f3cb27bf15eaf"
|
||||
"sha256": "3646221352b85667ac21f1b528dc8b29f56ff1e24cb97e7eaba79b5040c78e21"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
"requires": {
|
||||
"python_version": "3.6"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
@@ -16,11 +18,11 @@
|
||||
"default": {
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8",
|
||||
"sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"
|
||||
"sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407",
|
||||
"sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2024.8.30"
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2025.8.3"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
@@ -68,11 +70,11 @@
|
||||
},
|
||||
"hstspreload": {
|
||||
"hashes": [
|
||||
"sha256:2ab4518495a132c4ae430c474afffd12938852c6eec68ce1368c8f7858dc3076",
|
||||
"sha256:9c1b2d0313899d3ff9dac03ab39d53fed95c32eef9862e7eabee8dc07dfd589c"
|
||||
"sha256:02bd5b0885b62f0d5239ca6c6876ffcad8d9c08dc97cee54292598141a16e9dc",
|
||||
"sha256:346552a807b3a1762376de8ecce097544e7fcd64fb64231b4652da52f86fa6f1"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2024.9.1"
|
||||
"version": "==2025.1.1"
|
||||
},
|
||||
"httpcore": {
|
||||
"hashes": [
|
||||
|
||||
@@ -1,11 +1,45 @@
|
||||
platform :osx, '10.12'
|
||||
# disable warnings coming from pods, which are always noise from our perspective
|
||||
inhibit_all_warnings!
|
||||
|
||||
def deployment_target_from_xcconfig()
|
||||
xcconfig_path = 'config/base.xcconfig'
|
||||
File.foreach(xcconfig_path) do |line|
|
||||
if line.start_with?('MACOSX_DEPLOYMENT_TARGET')
|
||||
target = line.split("=").last.strip
|
||||
puts "MACOSX_DEPLOYMENT_TARGET: #{target}"
|
||||
return target
|
||||
end
|
||||
end
|
||||
puts "\e[31mCouldn't read MACOSX_DEPLOYMENT_TARGET from #{xcconfig_path}\e[0m"
|
||||
exit 1
|
||||
end
|
||||
|
||||
deployment_target = deployment_target_from_xcconfig()
|
||||
|
||||
platform :osx, deployment_target
|
||||
|
||||
target 'alt-tab-macos' do
|
||||
use_frameworks!
|
||||
pod 'LetsMove', :git => 'https://github.com/lwouis/LetsMove.git', :commit => '7abf4daed1a25218f2b52f2dfd190aee5a50071c'
|
||||
pod 'Sparkle', :podspec => 'https://raw.githubusercontent.com/lwouis/Sparkle/fix-iframe-popup-1.24/Sparkle.podspec'
|
||||
pod 'ShortcutRecorder', :git => 'https://github.com/lwouis/ShortcutRecorder.git', :branch => 'alt-tab-current'
|
||||
pod 'SwiftyMarkdown', '1.1.0'
|
||||
pod 'AppCenter/Crashes', '4.3.0'
|
||||
pod 'SwiftyBeaver', '1.9.0'
|
||||
end
|
||||
|
||||
target 'unit-tests' do
|
||||
use_frameworks!
|
||||
pod 'ShortcutRecorder', :git => 'https://github.com/lwouis/ShortcutRecorder.git', :branch => 'alt-tab-current'
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
# disable code signing which is unnecessary for pods
|
||||
config.build_settings['CODE_SIGNING_REQUIRED'] = 'NO'
|
||||
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
|
||||
# set deployment_target for all pods, to avoid libarclite compiler error
|
||||
config.build_settings['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -6,7 +6,6 @@ PODS:
|
||||
- ShortcutRecorder (3.1)
|
||||
- Sparkle (1.24.0)
|
||||
- SwiftyBeaver (1.9.0)
|
||||
- SwiftyMarkdown (1.1.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- AppCenter/Crashes (= 4.3.0)
|
||||
@@ -14,13 +13,11 @@ DEPENDENCIES:
|
||||
- ShortcutRecorder (from `https://github.com/lwouis/ShortcutRecorder.git`, branch `alt-tab-current`)
|
||||
- Sparkle (from `https://raw.githubusercontent.com/lwouis/Sparkle/fix-iframe-popup-1.24/Sparkle.podspec`)
|
||||
- SwiftyBeaver (= 1.9.0)
|
||||
- SwiftyMarkdown (= 1.1.0)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- AppCenter
|
||||
- SwiftyBeaver
|
||||
- SwiftyMarkdown
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
LetsMove:
|
||||
@@ -37,7 +34,7 @@ CHECKOUT OPTIONS:
|
||||
:commit: 7abf4daed1a25218f2b52f2dfd190aee5a50071c
|
||||
:git: https://github.com/lwouis/LetsMove.git
|
||||
ShortcutRecorder:
|
||||
:commit: 5bb32febdab48038ce1762bf14f5ce8024b11fe7
|
||||
:commit: 594b360e07a8a368ffec2567f77e465477b9994f
|
||||
:git: https://github.com/lwouis/ShortcutRecorder.git
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
@@ -46,8 +43,7 @@ SPEC CHECKSUMS:
|
||||
ShortcutRecorder: fdf620aca34101b0cba3b10fca815e0459254189
|
||||
Sparkle: 1fa490bb4ab2a9b37cfb9ea4feec19dd33b81cd2
|
||||
SwiftyBeaver: d39e7c376bf15e9fffca8263b8fd1f42ea56aa2d
|
||||
SwiftyMarkdown: 033abc9dad9a37903f81aec5188cade436f40520
|
||||
|
||||
PODFILE CHECKSUM: 6e94a2963d935455790ee55be0ce938834d1bba5
|
||||
PODFILE CHECKSUM: c20cb0e8753361ba1c1daea73624f879862271ed
|
||||
|
||||
COCOAPODS: 1.9.1
|
||||
COCOAPODS: 1.16.2
|
||||
@@ -6,7 +6,6 @@ PODS:
|
||||
- ShortcutRecorder (3.1)
|
||||
- Sparkle (1.24.0)
|
||||
- SwiftyBeaver (1.9.0)
|
||||
- SwiftyMarkdown (1.1.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- AppCenter/Crashes (= 4.3.0)
|
||||
@@ -14,13 +13,11 @@ DEPENDENCIES:
|
||||
- ShortcutRecorder (from `https://github.com/lwouis/ShortcutRecorder.git`, branch `alt-tab-current`)
|
||||
- Sparkle (from `https://raw.githubusercontent.com/lwouis/Sparkle/fix-iframe-popup-1.24/Sparkle.podspec`)
|
||||
- SwiftyBeaver (= 1.9.0)
|
||||
- SwiftyMarkdown (= 1.1.0)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- AppCenter
|
||||
- SwiftyBeaver
|
||||
- SwiftyMarkdown
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
LetsMove:
|
||||
@@ -37,7 +34,7 @@ CHECKOUT OPTIONS:
|
||||
:commit: 7abf4daed1a25218f2b52f2dfd190aee5a50071c
|
||||
:git: https://github.com/lwouis/LetsMove.git
|
||||
ShortcutRecorder:
|
||||
:commit: 5bb32febdab48038ce1762bf14f5ce8024b11fe7
|
||||
:commit: 594b360e07a8a368ffec2567f77e465477b9994f
|
||||
:git: https://github.com/lwouis/ShortcutRecorder.git
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
@@ -46,8 +43,7 @@ SPEC CHECKSUMS:
|
||||
ShortcutRecorder: fdf620aca34101b0cba3b10fca815e0459254189
|
||||
Sparkle: 1fa490bb4ab2a9b37cfb9ea4feec19dd33b81cd2
|
||||
SwiftyBeaver: d39e7c376bf15e9fffca8263b8fd1f42ea56aa2d
|
||||
SwiftyMarkdown: 033abc9dad9a37903f81aec5188cade436f40520
|
||||
|
||||
PODFILE CHECKSUM: 6e94a2963d935455790ee55be0ce938834d1bba5
|
||||
PODFILE CHECKSUM: c20cb0e8753361ba1c1daea73624f879862271ed
|
||||
|
||||
COCOAPODS: 1.9.1
|
||||
COCOAPODS: 1.16.2
|
||||
@@ -442,8 +442,8 @@ NSString *const SRShortcutCharactersIgnoringModifiers = SRShortcutKeyCharactersI
|
||||
|
||||
- (UInt32)carbonKeyCode
|
||||
{
|
||||
if (self.keyCode == SRKeyCodeNone)
|
||||
os_trace_error("#Critical SRKeyCodeNone has no representation in Carbon");
|
||||
// if (self.keyCode == SRKeyCodeNone)
|
||||
// os_trace_error("#Critical SRKeyCodeNone has no representation in Carbon");
|
||||
|
||||
return self.keyCode;
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Simon Fairbairn
|
||||
|
||||
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.
|
||||
@@ -1,360 +0,0 @@
|
||||
# SwiftyMarkdown 1.0
|
||||
|
||||
SwiftyMarkdown converts Markdown files and strings into `NSAttributedString`s using sensible defaults and a Swift-style syntax. It uses dynamic type to set the font size correctly with whatever font you'd like to use.
|
||||
|
||||
- [What's New](#fully-rebuilt-for-2020)
|
||||
- [Installation](#installation)
|
||||
- [How to Use](#how-to-use-swiftymarkdown)
|
||||
- [Screenshot](#screenshot)
|
||||
- [Front Matter](#front-matter)
|
||||
- [Appendix](#appendix)
|
||||
|
||||
## Fully Rebuilt For 2020!
|
||||
|
||||
SwiftyMarkdown now features a more robust and reliable rules-based line processing and character tokenisation engine. It has added support for images stored in the bundle (``), codeblocks, blockquotes, and unordered lists!
|
||||
|
||||
Line-level attributes can now have a paragraph alignment applied to them (e.g. `h2.aligment = .center`), and links can be optionally underlined by setting `underlineLinks` to `true`.
|
||||
|
||||
It also uses the system color `.label` as the default font color on iOS 13 and above for Dark Mode support out of the box.
|
||||
|
||||
Support for all of Apple's platforms has been enabled.
|
||||
|
||||
## Installation
|
||||
|
||||
### CocoaPods:
|
||||
|
||||
`pod 'SwiftyMarkdown'`
|
||||
|
||||
### SPM:
|
||||
|
||||
In Xcode, `File -> Swift Packages -> Add Package Dependency` and add the GitHub URL.
|
||||
|
||||
## How To Use SwiftyMarkdown
|
||||
|
||||
Read Markdown from a text string...
|
||||
|
||||
```swift
|
||||
let md = SwiftyMarkdown(string: "# Heading\nMy *Markdown* string")
|
||||
md.attributedString()
|
||||
```
|
||||
|
||||
...or from a URL.
|
||||
|
||||
```swift
|
||||
if let url = Bundle.main.url(forResource: "file", withExtension: "md"), md = SwiftyMarkdown(url: url ) {
|
||||
md.attributedString()
|
||||
}
|
||||
```
|
||||
|
||||
If you want to use a different string once SwiftyMarkdown has been initialised, you can now do so like this:
|
||||
|
||||
```swift
|
||||
let md = SwiftyMarkdown(string: "# Heading\nMy *Markdown* string")
|
||||
md.attributedString(from: "A **SECOND** Markdown string. *Fancy!*")
|
||||
```
|
||||
|
||||
The attributed string can then be assigned to any label or text control that has support for attributed text.
|
||||
|
||||
```swift
|
||||
let md = SwiftyMarkdown(string: "# Heading\nMy *Markdown* string")
|
||||
let label = UILabel()
|
||||
label.attributedText = md.attributedString()
|
||||
```
|
||||
|
||||
## Supported Markdown Features
|
||||
|
||||
*italics* or _italics_
|
||||
**bold** or __bold__
|
||||
~~Linethrough~~Strikethroughs.
|
||||
`code`
|
||||
|
||||
# Header 1
|
||||
|
||||
or
|
||||
|
||||
Header 1
|
||||
====
|
||||
|
||||
## Header 2
|
||||
|
||||
or
|
||||
|
||||
Header 2
|
||||
---
|
||||
|
||||
### Header 3
|
||||
#### Header 4
|
||||
##### Header 5 #####
|
||||
###### Header 6 ######
|
||||
|
||||
Indented code blocks (spaces or tabs)
|
||||
|
||||
[Links](http://voyagetravelapps.com/)
|
||||

|
||||
|
||||
> Blockquotes
|
||||
|
||||
- Bulleted
|
||||
- Lists
|
||||
- Including indented lists
|
||||
- Up to three levels
|
||||
- Neat!
|
||||
|
||||
1. Ordered
|
||||
1. Lists
|
||||
1. Including indented lists
|
||||
- Up to three levels
|
||||
|
||||
|
||||
|
||||
Compound rules also work, for example:
|
||||
|
||||
It recognises **[Bold Links](http://voyagetravelapps.com/)**
|
||||
|
||||
Or [**Bold Links**](http://voyagetravelapps.com/)
|
||||
|
||||
Images will be inserted into the returned `NSAttributedString` as an `NSTextAttachment` (sadly, this will not work on watchOS as `NSTextAttachment` is not available).
|
||||
|
||||
## Customisation
|
||||
|
||||
Set the attributes of every paragraph and character style type using straightforward dot syntax:
|
||||
|
||||
```swift
|
||||
md.body.fontName = "AvenirNextCondensed-Medium"
|
||||
|
||||
md.h1.color = UIColor.redColor()
|
||||
md.h1.fontName = "AvenirNextCondensed-Bold"
|
||||
md.h1.fontSize = 16
|
||||
md.h1.alignmnent = .center
|
||||
|
||||
md.italic.color = UIColor.blueColor()
|
||||
|
||||
md.underlineLinks = true
|
||||
|
||||
md.bullet = "🍏"
|
||||
```
|
||||
|
||||
On iOS, Specified font sizes will be adjusted relative to the the user's dynamic type settings.
|
||||
|
||||
## Screenshot
|
||||
|
||||

|
||||
|
||||
There's an example project included in the repository. Open the `.xcworkspace` file to get started.
|
||||
|
||||
## Front Matter
|
||||
|
||||
SwiftyMarkdown recognises YAML front matter and will populate the `frontMatterAttributes` property with the key-value pairs that it fines.
|
||||
|
||||
## Appendix
|
||||
|
||||
### A) All Customisable Properties
|
||||
|
||||
```swift
|
||||
h1.fontName : String
|
||||
h1.fontSize : CGFloat
|
||||
h1.color : UI/NSColor
|
||||
h1.fontStyle : FontStyle
|
||||
h1.alignment : NSTextAlignment
|
||||
|
||||
h2.fontName : String
|
||||
h2.fontSize : CGFloat
|
||||
h2.color : UI/NSColor
|
||||
h2.fontStyle : FontStyle
|
||||
h2.alignment : NSTextAlignment
|
||||
|
||||
h3.fontName : String
|
||||
h3.fontSize : CGFloat
|
||||
h3.color : UI/NSColor
|
||||
h3.fontStyle : FontStyle
|
||||
h3.alignment : NSTextAlignment
|
||||
|
||||
h4.fontName : String
|
||||
h4.fontSize : CGFloat
|
||||
h4.color : UI/NSColor
|
||||
h4.fontStyle : FontStyle
|
||||
h4.alignment : NSTextAlignment
|
||||
|
||||
h5.fontName : String
|
||||
h5.fontSize : CGFloat
|
||||
h5.color : UI/NSColor
|
||||
h5.fontStyle : FontStyle
|
||||
h5.alignment : NSTextAlignment
|
||||
|
||||
h6.fontName : String
|
||||
h6.fontSize : CGFloat
|
||||
h6.color : UI/NSColor
|
||||
h6.fontStyle : FontStyle
|
||||
h6.alignment : NSTextAlignment
|
||||
|
||||
body.fontName : String
|
||||
body.fontSize : CGFloat
|
||||
body.color : UI/NSColor
|
||||
body.fontStyle : FontStyle
|
||||
body.alignment : NSTextAlignment
|
||||
|
||||
blockquotes.fontName : String
|
||||
blockquotes.fontSize : CGFloat
|
||||
blockquotes.color : UI/NSColor
|
||||
blockquotes.fontStyle : FontStyle
|
||||
blockquotes.alignment : NSTextAlignment
|
||||
|
||||
link.fontName : String
|
||||
link.fontSize : CGFloat
|
||||
link.color : UI/NSColor
|
||||
link.fontStyle : FontStyle
|
||||
|
||||
bold.fontName : String
|
||||
bold.fontSize : CGFloat
|
||||
bold.color : UI/NSColor
|
||||
bold.fontStyle : FontStyle
|
||||
|
||||
italic.fontName : String
|
||||
italic.fontSize : CGFloat
|
||||
italic.color : UI/NSColor
|
||||
italic.fontStyle : FontStyle
|
||||
|
||||
code.fontName : String
|
||||
code.fontSize : CGFloat
|
||||
code.color : UI/NSColor
|
||||
code.fontStyle : FontStyle
|
||||
|
||||
strikethrough.fontName : String
|
||||
strikethrough.fontSize : CGFloat
|
||||
strikethrough.color : UI/NSColor
|
||||
strikethrough.fontStyle : FontStyle
|
||||
|
||||
underlineLinks : Bool
|
||||
|
||||
bullet : String
|
||||
```
|
||||
|
||||
`FontStyle` is an enum with these cases: `normal`, `bold`, `italic`, and `bolditalic` to give you more precise control over how lines and character styles should look.
|
||||
|
||||
If you like a bit of chaos:
|
||||
|
||||
```swift
|
||||
md.bold.fontStyle = .italic
|
||||
md.italic.fontStyle = .bold
|
||||
```
|
||||
|
||||
### B) Advanced Customisation
|
||||
|
||||
SwiftyMarkdown uses a rules-based line processing and customisation engine that is no longer limited to Markdown. Rules are processed in order, from top to bottom. Line processing happens first, then character styles are applied based on the character rules.
|
||||
|
||||
For example, here's how a small subset of Markdown line tags are set up within SwiftyMarkdown:
|
||||
|
||||
```swift
|
||||
enum MarkdownLineStyle : LineStyling {
|
||||
case h1
|
||||
case h2
|
||||
case previousH1
|
||||
case codeblock
|
||||
case body
|
||||
|
||||
var shouldTokeniseLine: Bool {
|
||||
switch self {
|
||||
case .codeblock:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func styleIfFoundStyleAffectsPreviousLine() -> LineStyling? {
|
||||
switch self {
|
||||
case .previousH1:
|
||||
return MarkdownLineStyle.h1
|
||||
default :
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public var lineRules = [
|
||||
LineRule(token: " ",type : MarkdownLineStyle.codeblock, removeFrom: .leading),
|
||||
LineRule(token: "=",type : MarkdownLineStyle.previousH1, removeFrom: .entireLine, changeAppliesTo: .previous),
|
||||
LineRule(token: "## ",type : MarkdownLineStyle.h2, removeFrom: .both),
|
||||
LineRule(token: "# ",type : MarkdownLineStyle.h1, removeFrom: .both)
|
||||
]
|
||||
|
||||
let lineProcessor = SwiftyLineProcessor(rules: SwiftyMarkdown.lineRules, default: MarkdownLineStyle.body)
|
||||
```
|
||||
|
||||
Similarly, the character styles all follow rules:
|
||||
|
||||
```swift
|
||||
enum CharacterStyle : CharacterStyling {
|
||||
case link, bold, italic, code
|
||||
}
|
||||
|
||||
static public var characterRules = [
|
||||
CharacterRule(openTag: "[", intermediateTag: "](", closingTag: ")", escapeCharacter: "\\", styles: [1 : [CharacterStyle.link]], maxTags: 1),
|
||||
CharacterRule(openTag: "`", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.code]], maxTags: 1),
|
||||
CharacterRule(openTag: "*", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.italic], 2 : [CharacterStyle.bold], 3 : [CharacterStyle.bold, CharacterStyle.italic]], maxTags: 3),
|
||||
CharacterRule(openTag: "_", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.italic], 2 : [CharacterStyle.bold], 3 : [CharacterStyle.bold, CharacterStyle.italic]], maxTags: 3)
|
||||
]
|
||||
```
|
||||
|
||||
#### Rule Subsets
|
||||
|
||||
If you want to only support a small subset of Markdown, it's now easy to do.
|
||||
|
||||
This example would only process strings with `*` and `_` characters, ignoring links, images, code, and all line-level attributes (headings, blockquotes, etc.)
|
||||
```swift
|
||||
SwiftyMarkdown.lineRules = []
|
||||
|
||||
SwiftyMarkdown.characterRules = [
|
||||
CharacterRule(openTag: "*", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.italic], 2 : [CharacterStyle.bold], 3 : [CharacterStyle.bold, CharacterStyle.italic]], maxTags: 3),
|
||||
CharacterRule(openTag: "_", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.italic], 2 : [CharacterStyle.bold], 3 : [CharacterStyle.bold, CharacterStyle.italic]], maxTags: 3)
|
||||
]
|
||||
```
|
||||
|
||||
#### Custom Rules
|
||||
|
||||
If you wanted to create a rule that applied a style of `Elf` to a range of characters between "The elf will speak now: %Here is my elf speaking%", you could set things up like this:
|
||||
|
||||
```swift
|
||||
enum Characters : CharacterStyling {
|
||||
case elf
|
||||
|
||||
func isEqualTo( _ other : CharacterStyling) -> Bool {
|
||||
if let other = other as? Characters else {
|
||||
return false
|
||||
}
|
||||
return other == self
|
||||
}
|
||||
}
|
||||
|
||||
let characterRules = [
|
||||
CharacterRule(openTag: "%", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.elf]], maxTags: 1)
|
||||
]
|
||||
|
||||
let processor = SwiftyTokeniser( with : characterRules )
|
||||
let string = "The elf will speak now: %Here is my elf speaking%"
|
||||
let tokens = processor.process(string)
|
||||
```
|
||||
|
||||
The output is an array of tokens would be equivalent to:
|
||||
|
||||
```swift
|
||||
[
|
||||
Token(type: .string, inputString: "The elf will speak now: ", characterStyles: []),
|
||||
Token(type: .repeatingTag, inputString: "%", characterStyles: []),
|
||||
Token(type: .string, inputString: "Here is my elf speaking", characterStyles: [.elf]),
|
||||
Token(type: .repeatingTag, inputString: "%", characterStyles: [])
|
||||
]
|
||||
```
|
||||
|
||||
### C) SpriteKit Support
|
||||
|
||||
Did you know that `SKLabelNode` supports attributed text? I didn't.
|
||||
|
||||
```swift
|
||||
let smd = SwiftyMarkdown(string: "My Character's **Dialogue**")
|
||||
|
||||
let label = SKLabelNode()
|
||||
label.preferredMaxLayoutWidth = 500
|
||||
label.numberOfLines = 0
|
||||
label.attributedText = smd.attributedString()
|
||||
```
|
||||
@@ -1,44 +0,0 @@
|
||||
//
|
||||
// String+SwiftyMarkdown.swift
|
||||
// SwiftyMarkdown
|
||||
//
|
||||
// Created by Simon Fairbairn on 08/12/2019.
|
||||
// Copyright © 2019 Voyage Travel Apps. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Some helper functions based on this:
|
||||
/// https://stackoverflow.com/questions/32305891/index-of-a-substring-in-a-string-with-swift/32306142#32306142
|
||||
extension StringProtocol {
|
||||
func index<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> Index? {
|
||||
range(of: string, options: options)?.lowerBound
|
||||
}
|
||||
func endIndex<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> Index? {
|
||||
range(of: string, options: options)?.upperBound
|
||||
}
|
||||
func indices<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> [Index] {
|
||||
var indices: [Index] = []
|
||||
var startIndex = self.startIndex
|
||||
while startIndex < endIndex,
|
||||
let range = self[startIndex...]
|
||||
.range(of: string, options: options) {
|
||||
indices.append(range.lowerBound)
|
||||
startIndex = range.lowerBound < range.upperBound ? range.upperBound :
|
||||
index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
|
||||
}
|
||||
return indices
|
||||
}
|
||||
func ranges<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> [Range<String.Index>] {
|
||||
var result: [Range<Index>] = []
|
||||
var startIndex = self.startIndex
|
||||
while startIndex < endIndex,
|
||||
let range = self[startIndex...]
|
||||
.range(of: string, options: options) {
|
||||
result.append(range)
|
||||
startIndex = range.lowerBound < range.upperBound ? range.upperBound :
|
||||
index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -1,229 +0,0 @@
|
||||
//
|
||||
// SwiftyLineProcessor.swift
|
||||
// SwiftyMarkdown
|
||||
//
|
||||
// Created by Simon Fairbairn on 16/12/2019.
|
||||
// Copyright © 2019 Voyage Travel Apps. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol LineStyling {
|
||||
var shouldTokeniseLine : Bool { get }
|
||||
func styleIfFoundStyleAffectsPreviousLine() -> LineStyling?
|
||||
}
|
||||
|
||||
public struct SwiftyLine : CustomStringConvertible {
|
||||
public let line : String
|
||||
public let lineStyle : LineStyling
|
||||
public var description: String {
|
||||
return self.line
|
||||
}
|
||||
}
|
||||
|
||||
extension SwiftyLine : Equatable {
|
||||
public static func == ( _ lhs : SwiftyLine, _ rhs : SwiftyLine ) -> Bool {
|
||||
return lhs.line == rhs.line
|
||||
}
|
||||
}
|
||||
|
||||
public enum Remove {
|
||||
case leading
|
||||
case trailing
|
||||
case both
|
||||
case entireLine
|
||||
case none
|
||||
}
|
||||
|
||||
public enum ChangeApplication {
|
||||
case current
|
||||
case previous
|
||||
case untilClose
|
||||
}
|
||||
|
||||
public struct FrontMatterRule {
|
||||
let openTag : String
|
||||
let closeTag : String
|
||||
let keyValueSeparator : Character
|
||||
}
|
||||
|
||||
public struct LineRule {
|
||||
let token : String
|
||||
let removeFrom : Remove
|
||||
let type : LineStyling
|
||||
let shouldTrim : Bool
|
||||
let changeAppliesTo : ChangeApplication
|
||||
|
||||
public init(token : String, type : LineStyling, removeFrom : Remove = .leading, shouldTrim : Bool = true, changeAppliesTo : ChangeApplication = .current ) {
|
||||
self.token = token
|
||||
self.type = type
|
||||
self.removeFrom = removeFrom
|
||||
self.shouldTrim = shouldTrim
|
||||
self.changeAppliesTo = changeAppliesTo
|
||||
}
|
||||
}
|
||||
|
||||
public class SwiftyLineProcessor {
|
||||
|
||||
public var processEmptyStrings : LineStyling?
|
||||
public internal(set) var frontMatterAttributes : [String : String] = [:]
|
||||
|
||||
var closeToken : String? = nil
|
||||
let defaultType : LineStyling
|
||||
|
||||
let lineRules : [LineRule]
|
||||
let frontMatterRules : [FrontMatterRule]
|
||||
|
||||
public init( rules : [LineRule], defaultRule: LineStyling, frontMatterRules : [FrontMatterRule] = []) {
|
||||
self.lineRules = rules
|
||||
self.defaultType = defaultRule
|
||||
self.frontMatterRules = frontMatterRules
|
||||
}
|
||||
|
||||
func findLeadingLineElement( _ element : LineRule, in string : String ) -> String {
|
||||
var output = string
|
||||
if let range = output.index(output.startIndex, offsetBy: element.token.count, limitedBy: output.endIndex), output[output.startIndex..<range] == element.token {
|
||||
output.removeSubrange(output.startIndex..<range)
|
||||
return output
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func findTrailingLineElement( _ element : LineRule, in string : String ) -> String {
|
||||
var output = string
|
||||
let token = element.token.trimmingCharacters(in: .whitespaces)
|
||||
if let range = output.index(output.endIndex, offsetBy: -(token.count), limitedBy: output.startIndex), output[range..<output.endIndex] == token {
|
||||
output.removeSubrange(range..<output.endIndex)
|
||||
return output
|
||||
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func processLineLevelAttributes( _ text : String ) -> SwiftyLine? {
|
||||
if text.isEmpty, let style = processEmptyStrings {
|
||||
return SwiftyLine(line: "", lineStyle: style)
|
||||
}
|
||||
let previousLines = lineRules.filter({ $0.changeAppliesTo == .previous })
|
||||
|
||||
for element in lineRules {
|
||||
guard element.token.count > 0 else {
|
||||
continue
|
||||
}
|
||||
var output : String = (element.shouldTrim) ? text.trimmingCharacters(in: .whitespaces) : text
|
||||
let unprocessed = output
|
||||
|
||||
if let hasToken = self.closeToken, unprocessed != hasToken {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch element.removeFrom {
|
||||
case .leading:
|
||||
output = findLeadingLineElement(element, in: output)
|
||||
case .trailing:
|
||||
output = findTrailingLineElement(element, in: output)
|
||||
case .both:
|
||||
output = findLeadingLineElement(element, in: output)
|
||||
output = findTrailingLineElement(element, in: output)
|
||||
case .entireLine:
|
||||
let maybeOutput = output.replacingOccurrences(of: element.token, with: "")
|
||||
output = ( maybeOutput.isEmpty ) ? maybeOutput : output
|
||||
default:
|
||||
break
|
||||
}
|
||||
// Only if the output has changed in some way
|
||||
guard unprocessed != output else {
|
||||
continue
|
||||
}
|
||||
if element.changeAppliesTo == .untilClose {
|
||||
self.closeToken = (self.closeToken == nil) ? element.token : nil
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
output = (element.shouldTrim) ? output.trimmingCharacters(in: .whitespaces) : output
|
||||
return SwiftyLine(line: output, lineStyle: element.type)
|
||||
|
||||
}
|
||||
|
||||
for element in previousLines {
|
||||
let output = (element.shouldTrim) ? text.trimmingCharacters(in: .whitespaces) : text
|
||||
let charSet = CharacterSet(charactersIn: element.token )
|
||||
if output.unicodeScalars.allSatisfy({ charSet.contains($0) }) {
|
||||
return SwiftyLine(line: "", lineStyle: element.type)
|
||||
}
|
||||
}
|
||||
|
||||
return SwiftyLine(line: text.trimmingCharacters(in: .whitespaces), lineStyle: defaultType)
|
||||
}
|
||||
|
||||
func processFrontMatter( _ strings : [String] ) -> [String] {
|
||||
guard let firstString = strings.first?.trimmingCharacters(in: .whitespacesAndNewlines) else {
|
||||
return strings
|
||||
}
|
||||
var rulesToApply : FrontMatterRule? = nil
|
||||
for matter in self.frontMatterRules {
|
||||
if firstString == matter.openTag {
|
||||
rulesToApply = matter
|
||||
break
|
||||
}
|
||||
}
|
||||
guard let existentRules = rulesToApply else {
|
||||
return strings
|
||||
}
|
||||
var outputString = strings
|
||||
// Remove the first line, which is the front matter opening tag
|
||||
let _ = outputString.removeFirst()
|
||||
var closeFound = false
|
||||
while !closeFound {
|
||||
let nextString = outputString.removeFirst()
|
||||
if nextString == existentRules.closeTag {
|
||||
closeFound = true
|
||||
continue
|
||||
}
|
||||
var keyValue = nextString.components(separatedBy: "\(existentRules.keyValueSeparator)")
|
||||
if keyValue.count < 2 {
|
||||
continue
|
||||
}
|
||||
let key = keyValue.removeFirst()
|
||||
let value = keyValue.joined()
|
||||
self.frontMatterAttributes[key] = value
|
||||
}
|
||||
while outputString.first?.isEmpty ?? false {
|
||||
outputString.removeFirst()
|
||||
}
|
||||
return outputString
|
||||
}
|
||||
|
||||
public func process( _ string : String ) -> [SwiftyLine] {
|
||||
var foundAttributes : [SwiftyLine] = []
|
||||
|
||||
var lines = string.components(separatedBy: CharacterSet.newlines)
|
||||
lines = self.processFrontMatter(lines)
|
||||
|
||||
for heading in lines {
|
||||
|
||||
if processEmptyStrings == nil && heading.isEmpty {
|
||||
continue
|
||||
}
|
||||
|
||||
guard let input = processLineLevelAttributes(String(heading)) else {
|
||||
continue
|
||||
}
|
||||
|
||||
if let existentPrevious = input.lineStyle.styleIfFoundStyleAffectsPreviousLine(), foundAttributes.count > 0 {
|
||||
if let idx = foundAttributes.firstIndex(of: foundAttributes.last!) {
|
||||
let updatedPrevious = foundAttributes.last!
|
||||
foundAttributes[idx] = SwiftyLine(line: updatedPrevious.line, lineStyle: existentPrevious)
|
||||
}
|
||||
continue
|
||||
}
|
||||
foundAttributes.append(input)
|
||||
}
|
||||
return foundAttributes
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
//
|
||||
// SwiftyMarkdown+macOS.swift
|
||||
// SwiftyMarkdown
|
||||
//
|
||||
// Created by Simon Fairbairn on 17/12/2019.
|
||||
// Copyright © 2019 Voyage Travel Apps. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
#if !os(macOS)
|
||||
import UIKit
|
||||
|
||||
extension SwiftyMarkdown {
|
||||
|
||||
func font( for line : SwiftyLine, characterOverride : CharacterStyle? = nil ) -> UIFont {
|
||||
let textStyle : UIFont.TextStyle
|
||||
var fontName : String?
|
||||
var fontSize : CGFloat?
|
||||
|
||||
var globalBold = false
|
||||
var globalItalic = false
|
||||
|
||||
let style : FontProperties
|
||||
// What type are we and is there a font name set?
|
||||
switch line.lineStyle as! MarkdownLineStyle {
|
||||
case .h1:
|
||||
style = self.h1
|
||||
if #available(iOS 9, *) {
|
||||
textStyle = UIFont.TextStyle.title1
|
||||
} else {
|
||||
textStyle = UIFont.TextStyle.headline
|
||||
}
|
||||
case .h2:
|
||||
style = self.h2
|
||||
if #available(iOS 9, *) {
|
||||
textStyle = UIFont.TextStyle.title2
|
||||
} else {
|
||||
textStyle = UIFont.TextStyle.headline
|
||||
}
|
||||
case .h3:
|
||||
style = self.h3
|
||||
if #available(iOS 9, *) {
|
||||
textStyle = UIFont.TextStyle.title2
|
||||
} else {
|
||||
textStyle = UIFont.TextStyle.subheadline
|
||||
}
|
||||
case .h4:
|
||||
style = self.h4
|
||||
textStyle = UIFont.TextStyle.headline
|
||||
case .h5:
|
||||
style = self.h5
|
||||
textStyle = UIFont.TextStyle.subheadline
|
||||
case .h6:
|
||||
style = self.h6
|
||||
textStyle = UIFont.TextStyle.footnote
|
||||
case .codeblock:
|
||||
style = self.code
|
||||
textStyle = UIFont.TextStyle.body
|
||||
case .blockquote:
|
||||
style = self.blockquotes
|
||||
textStyle = UIFont.TextStyle.body
|
||||
default:
|
||||
style = self.body
|
||||
textStyle = UIFont.TextStyle.body
|
||||
}
|
||||
|
||||
fontName = style.fontName
|
||||
fontSize = style.fontSize
|
||||
switch style.fontStyle {
|
||||
case .bold:
|
||||
globalBold = true
|
||||
case .italic:
|
||||
globalItalic = true
|
||||
case .boldItalic:
|
||||
globalItalic = true
|
||||
globalBold = true
|
||||
case .normal:
|
||||
break
|
||||
}
|
||||
|
||||
if fontName == nil {
|
||||
fontName = body.fontName
|
||||
}
|
||||
|
||||
if let characterOverride = characterOverride {
|
||||
switch characterOverride {
|
||||
case .code:
|
||||
fontName = code.fontName ?? fontName
|
||||
fontSize = code.fontSize
|
||||
case .link:
|
||||
fontName = link.fontName ?? fontName
|
||||
fontSize = link.fontSize
|
||||
case .bold:
|
||||
fontName = bold.fontName ?? fontName
|
||||
fontSize = bold.fontSize
|
||||
globalBold = true
|
||||
case .italic:
|
||||
fontName = italic.fontName ?? fontName
|
||||
fontSize = italic.fontSize
|
||||
globalItalic = true
|
||||
case .strikethrough:
|
||||
fontName = strikethrough.fontName ?? fontName
|
||||
fontSize = strikethrough.fontSize
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
fontSize = fontSize == 0.0 ? nil : fontSize
|
||||
var font : UIFont
|
||||
if let existentFontName = fontName {
|
||||
font = UIFont.preferredFont(forTextStyle: textStyle)
|
||||
let finalSize : CGFloat
|
||||
if let existentFontSize = fontSize {
|
||||
finalSize = existentFontSize
|
||||
} else {
|
||||
let styleDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: textStyle)
|
||||
finalSize = styleDescriptor.fontAttributes[.size] as? CGFloat ?? CGFloat(14)
|
||||
}
|
||||
|
||||
if let customFont = UIFont(name: existentFontName, size: finalSize) {
|
||||
let fontMetrics = UIFontMetrics(forTextStyle: textStyle)
|
||||
font = fontMetrics.scaledFont(for: customFont)
|
||||
} else {
|
||||
font = UIFont.preferredFont(forTextStyle: textStyle)
|
||||
}
|
||||
} else {
|
||||
font = UIFont.preferredFont(forTextStyle: textStyle)
|
||||
}
|
||||
|
||||
if globalItalic, let italicDescriptor = font.fontDescriptor.withSymbolicTraits(.traitItalic) {
|
||||
font = UIFont(descriptor: italicDescriptor, size: 0)
|
||||
}
|
||||
if globalBold, let boldDescriptor = font.fontDescriptor.withSymbolicTraits(.traitBold) {
|
||||
font = UIFont(descriptor: boldDescriptor, size: 0)
|
||||
}
|
||||
|
||||
return font
|
||||
|
||||
}
|
||||
|
||||
func color( for line : SwiftyLine ) -> UIColor {
|
||||
// What type are we and is there a font name set?
|
||||
switch line.lineStyle as! MarkdownLineStyle {
|
||||
case .yaml:
|
||||
return body.color
|
||||
case .h1, .previousH1:
|
||||
return h1.color
|
||||
case .h2, .previousH2:
|
||||
return h2.color
|
||||
case .h3:
|
||||
return h3.color
|
||||
case .h4:
|
||||
return h4.color
|
||||
case .h5:
|
||||
return h5.color
|
||||
case .h6:
|
||||
return h6.color
|
||||
case .body:
|
||||
return body.color
|
||||
case .codeblock:
|
||||
return code.color
|
||||
case .blockquote:
|
||||
return blockquotes.color
|
||||
case .unorderedList, .unorderedListIndentFirstOrder, .unorderedListIndentSecondOrder, .orderedList, .orderedListIndentFirstOrder, .orderedListIndentSecondOrder:
|
||||
return body.color
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1,144 +0,0 @@
|
||||
//
|
||||
// SwiftyMarkdown+macOS.swift
|
||||
// SwiftyMarkdown
|
||||
//
|
||||
// Created by Simon Fairbairn on 17/12/2019.
|
||||
// Copyright © 2019 Voyage Travel Apps. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
#if os(macOS)
|
||||
import AppKit
|
||||
|
||||
extension SwiftyMarkdown {
|
||||
|
||||
func font( for line : SwiftyLine, characterOverride : CharacterStyle? = nil ) -> NSFont {
|
||||
var fontName : String?
|
||||
var fontSize : CGFloat?
|
||||
|
||||
var globalBold = false
|
||||
var globalItalic = false
|
||||
|
||||
let style : FontProperties
|
||||
// What type are we and is there a font name set?
|
||||
switch line.lineStyle as! MarkdownLineStyle {
|
||||
case .h1:
|
||||
style = self.h1
|
||||
case .h2:
|
||||
style = self.h2
|
||||
case .h3:
|
||||
style = self.h3
|
||||
case .h4:
|
||||
style = self.h4
|
||||
case .h5:
|
||||
style = self.h5
|
||||
case .h6:
|
||||
style = self.h6
|
||||
case .codeblock:
|
||||
style = self.code
|
||||
case .blockquote:
|
||||
style = self.blockquotes
|
||||
default:
|
||||
style = self.body
|
||||
}
|
||||
|
||||
fontName = style.fontName
|
||||
fontSize = style.fontSize
|
||||
switch style.fontStyle {
|
||||
case .bold:
|
||||
globalBold = true
|
||||
case .italic:
|
||||
globalItalic = true
|
||||
case .boldItalic:
|
||||
globalItalic = true
|
||||
globalBold = true
|
||||
case .normal:
|
||||
break
|
||||
}
|
||||
|
||||
if fontName == nil {
|
||||
fontName = body.fontName
|
||||
}
|
||||
|
||||
if let characterOverride = characterOverride {
|
||||
switch characterOverride {
|
||||
case .code:
|
||||
fontName = code.fontName ?? fontName
|
||||
fontSize = code.fontSize
|
||||
case .link:
|
||||
fontName = link.fontName ?? fontName
|
||||
fontSize = link.fontSize
|
||||
case .bold:
|
||||
fontName = bold.fontName ?? fontName
|
||||
fontSize = bold.fontSize
|
||||
globalBold = true
|
||||
case .italic:
|
||||
fontName = italic.fontName ?? fontName
|
||||
fontSize = italic.fontSize
|
||||
globalItalic = true
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
fontSize = fontSize == 0.0 ? nil : fontSize
|
||||
let finalSize : CGFloat
|
||||
if let existentFontSize = fontSize {
|
||||
finalSize = existentFontSize
|
||||
} else {
|
||||
finalSize = NSFont.systemFontSize
|
||||
}
|
||||
var font : NSFont
|
||||
if let existentFontName = fontName {
|
||||
if let customFont = NSFont(name: existentFontName, size: finalSize) {
|
||||
font = customFont
|
||||
} else {
|
||||
font = NSFont.systemFont(ofSize: finalSize)
|
||||
}
|
||||
} else {
|
||||
font = NSFont.systemFont(ofSize: finalSize)
|
||||
}
|
||||
|
||||
if globalItalic {
|
||||
let italicDescriptor = font.fontDescriptor.withSymbolicTraits(.italic)
|
||||
font = NSFont(descriptor: italicDescriptor, size: 0) ?? font
|
||||
}
|
||||
if globalBold {
|
||||
let boldDescriptor = font.fontDescriptor.withSymbolicTraits(.bold)
|
||||
font = NSFont(descriptor: boldDescriptor, size: 0) ?? font
|
||||
}
|
||||
|
||||
return font
|
||||
|
||||
}
|
||||
|
||||
func color( for line : SwiftyLine ) -> NSColor {
|
||||
// What type are we and is there a font name set?
|
||||
switch line.lineStyle as! MarkdownLineStyle {
|
||||
case .h1, .previousH1:
|
||||
return h1.color
|
||||
case .h2, .previousH2:
|
||||
return h2.color
|
||||
case .h3:
|
||||
return h3.color
|
||||
case .h4:
|
||||
return h4.color
|
||||
case .h5:
|
||||
return h5.color
|
||||
case .h6:
|
||||
return h6.color
|
||||
case .body:
|
||||
return body.color
|
||||
case .codeblock:
|
||||
return code.color
|
||||
case .blockquote:
|
||||
return blockquotes.color
|
||||
case .unorderedList, .unorderedListIndentFirstOrder, .unorderedListIndentSecondOrder, .orderedList, .orderedListIndentFirstOrder, .orderedListIndentSecondOrder:
|
||||
return body.color
|
||||
case .yaml:
|
||||
return body.color
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1,545 +0,0 @@
|
||||
//
|
||||
// SwiftyMarkdown.swift
|
||||
// SwiftyMarkdown
|
||||
//
|
||||
// Created by Simon Fairbairn on 05/03/2016.
|
||||
// Copyright © 2016 Voyage Travel Apps. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(macOS)
|
||||
import AppKit
|
||||
#else
|
||||
import UIKit
|
||||
#endif
|
||||
|
||||
enum CharacterStyle : CharacterStyling {
|
||||
case none
|
||||
case bold
|
||||
case italic
|
||||
case code
|
||||
case link
|
||||
case image
|
||||
case strikethrough
|
||||
|
||||
func isEqualTo(_ other: CharacterStyling) -> Bool {
|
||||
guard let other = other as? CharacterStyle else {
|
||||
return false
|
||||
}
|
||||
return other == self
|
||||
}
|
||||
}
|
||||
|
||||
enum MarkdownLineStyle : LineStyling {
|
||||
var shouldTokeniseLine: Bool {
|
||||
switch self {
|
||||
case .codeblock:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
case yaml
|
||||
case h1
|
||||
case h2
|
||||
case h3
|
||||
case h4
|
||||
case h5
|
||||
case h6
|
||||
case previousH1
|
||||
case previousH2
|
||||
case body
|
||||
case blockquote
|
||||
case codeblock
|
||||
case unorderedList
|
||||
case unorderedListIndentFirstOrder
|
||||
case unorderedListIndentSecondOrder
|
||||
case orderedList
|
||||
case orderedListIndentFirstOrder
|
||||
case orderedListIndentSecondOrder
|
||||
|
||||
|
||||
func styleIfFoundStyleAffectsPreviousLine() -> LineStyling? {
|
||||
switch self {
|
||||
case .previousH1:
|
||||
return MarkdownLineStyle.h1
|
||||
case .previousH2:
|
||||
return MarkdownLineStyle.h2
|
||||
default :
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc public enum FontStyle : Int {
|
||||
case normal
|
||||
case bold
|
||||
case italic
|
||||
case boldItalic
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
@objc public protocol FontProperties {
|
||||
var fontName : String? { get set }
|
||||
var color : NSColor { get set }
|
||||
var fontSize : CGFloat { get set }
|
||||
var fontStyle : FontStyle { get set }
|
||||
}
|
||||
#else
|
||||
@objc public protocol FontProperties {
|
||||
var fontName : String? { get set }
|
||||
var color : UIColor { get set }
|
||||
var fontSize : CGFloat { get set }
|
||||
var fontStyle : FontStyle { get set }
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@objc public protocol LineProperties {
|
||||
var alignment : NSTextAlignment { get set }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
A class defining the styles that can be applied to the parsed Markdown. The `fontName` property is optional, and if it's not set then the `fontName` property of the Body style will be applied.
|
||||
|
||||
If that is not set, then the system default will be used.
|
||||
*/
|
||||
@objc open class BasicStyles : NSObject, FontProperties {
|
||||
public var fontName : String?
|
||||
#if os(macOS)
|
||||
public var color = NSColor.black
|
||||
#else
|
||||
public var color = UIColor.black
|
||||
#endif
|
||||
public var fontSize : CGFloat = 0.0
|
||||
public var fontStyle : FontStyle = .normal
|
||||
}
|
||||
|
||||
@objc open class LineStyles : NSObject, FontProperties, LineProperties {
|
||||
public var fontName : String?
|
||||
#if os(macOS)
|
||||
public var color = NSColor.black
|
||||
#else
|
||||
public var color = UIColor.black
|
||||
#endif
|
||||
public var fontSize : CGFloat = 0.0
|
||||
public var fontStyle : FontStyle = .normal
|
||||
public var alignment: NSTextAlignment = .left
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// A class that takes a [Markdown](https://daringfireball.net/projects/markdown/) string or file and returns an NSAttributedString with the applied styles. Supports Dynamic Type.
|
||||
@objc open class SwiftyMarkdown: NSObject {
|
||||
static public var lineRules = [
|
||||
|
||||
LineRule(token: "=", type: MarkdownLineStyle.previousH1, removeFrom: .entireLine, changeAppliesTo: .previous),
|
||||
LineRule(token: "-", type: MarkdownLineStyle.previousH2, removeFrom: .entireLine, changeAppliesTo: .previous),
|
||||
LineRule(token: "\t\t- ", type: MarkdownLineStyle.unorderedListIndentSecondOrder, removeFrom: .leading, shouldTrim: false),
|
||||
LineRule(token: "\t- ", type: MarkdownLineStyle.unorderedListIndentFirstOrder, removeFrom: .leading, shouldTrim: false),
|
||||
LineRule(token: "- ",type : MarkdownLineStyle.unorderedList, removeFrom: .leading),
|
||||
LineRule(token: "\t\t* ", type: MarkdownLineStyle.unorderedListIndentSecondOrder, removeFrom: .leading, shouldTrim: false),
|
||||
LineRule(token: "\t* ", type: MarkdownLineStyle.unorderedListIndentFirstOrder, removeFrom: .leading, shouldTrim: false),
|
||||
LineRule(token: "\t\t1. ", type: MarkdownLineStyle.orderedListIndentSecondOrder, removeFrom: .leading, shouldTrim: false),
|
||||
LineRule(token: "\t1. ", type: MarkdownLineStyle.orderedListIndentFirstOrder, removeFrom: .leading, shouldTrim: false),
|
||||
LineRule(token: "1. ",type : MarkdownLineStyle.orderedList, removeFrom: .leading),
|
||||
LineRule(token: "* ",type : MarkdownLineStyle.unorderedList, removeFrom: .leading),
|
||||
LineRule(token: " ", type: MarkdownLineStyle.codeblock, removeFrom: .leading, shouldTrim: false),
|
||||
LineRule(token: "\t", type: MarkdownLineStyle.codeblock, removeFrom: .leading, shouldTrim: false),
|
||||
LineRule(token: ">",type : MarkdownLineStyle.blockquote, removeFrom: .leading),
|
||||
LineRule(token: "###### ",type : MarkdownLineStyle.h6, removeFrom: .both),
|
||||
LineRule(token: "##### ",type : MarkdownLineStyle.h5, removeFrom: .both),
|
||||
LineRule(token: "#### ",type : MarkdownLineStyle.h4, removeFrom: .both),
|
||||
LineRule(token: "### ",type : MarkdownLineStyle.h3, removeFrom: .both),
|
||||
LineRule(token: "## ",type : MarkdownLineStyle.h2, removeFrom: .both),
|
||||
LineRule(token: "# ",type : MarkdownLineStyle.h1, removeFrom: .both)
|
||||
]
|
||||
|
||||
static public var characterRules = [
|
||||
CharacterRule(openTag: "", escapeCharacter: "\\", styles: [1 : [CharacterStyle.image]], maxTags: 1),
|
||||
CharacterRule(openTag: "[", intermediateTag: "](", closingTag: ")", escapeCharacter: "\\", styles: [1 : [CharacterStyle.link]], maxTags: 1),
|
||||
CharacterRule(openTag: "`", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.code]], maxTags: 1, cancels: .allRemaining),
|
||||
CharacterRule(openTag: "~", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [2 : [CharacterStyle.strikethrough]], minTags: 2, maxTags: 2),
|
||||
CharacterRule(openTag: "*", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.italic], 2 : [CharacterStyle.bold], 3 : [CharacterStyle.bold, CharacterStyle.italic]], maxTags: 3),
|
||||
CharacterRule(openTag: "_", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.italic], 2 : [CharacterStyle.bold], 3 : [CharacterStyle.bold, CharacterStyle.italic]], maxTags: 3)
|
||||
]
|
||||
|
||||
static public var frontMatterRules = [
|
||||
FrontMatterRule(openTag: "---", closeTag: "---", keyValueSeparator: ":")
|
||||
]
|
||||
|
||||
let lineProcessor = SwiftyLineProcessor(rules: SwiftyMarkdown.lineRules, defaultRule: MarkdownLineStyle.body, frontMatterRules: SwiftyMarkdown.frontMatterRules)
|
||||
let tokeniser = SwiftyTokeniser(with: SwiftyMarkdown.characterRules)
|
||||
|
||||
/// The styles to apply to any H1 headers found in the Markdown
|
||||
open var h1 = LineStyles()
|
||||
|
||||
/// The styles to apply to any H2 headers found in the Markdown
|
||||
open var h2 = LineStyles()
|
||||
|
||||
/// The styles to apply to any H3 headers found in the Markdown
|
||||
open var h3 = LineStyles()
|
||||
|
||||
/// The styles to apply to any H4 headers found in the Markdown
|
||||
open var h4 = LineStyles()
|
||||
|
||||
/// The styles to apply to any H5 headers found in the Markdown
|
||||
open var h5 = LineStyles()
|
||||
|
||||
/// The styles to apply to any H6 headers found in the Markdown
|
||||
open var h6 = LineStyles()
|
||||
|
||||
/// The default body styles. These are the base styles and will be used for e.g. headers if no other styles override them.
|
||||
open var body = LineStyles()
|
||||
|
||||
/// The styles to apply to any blockquotes found in the Markdown
|
||||
open var blockquotes = LineStyles()
|
||||
|
||||
/// The styles to apply to any links found in the Markdown
|
||||
open var link = BasicStyles()
|
||||
|
||||
/// The styles to apply to any bold text found in the Markdown
|
||||
open var bold = BasicStyles()
|
||||
|
||||
/// The styles to apply to any italic text found in the Markdown
|
||||
open var italic = BasicStyles()
|
||||
|
||||
/// The styles to apply to any code blocks or inline code text found in the Markdown
|
||||
open var code = BasicStyles()
|
||||
|
||||
open var strikethrough = BasicStyles()
|
||||
|
||||
public var bullet : String = "・"
|
||||
|
||||
public var underlineLinks : Bool = false
|
||||
|
||||
public var frontMatterAttributes : [String : String] {
|
||||
get {
|
||||
return self.lineProcessor.frontMatterAttributes
|
||||
}
|
||||
}
|
||||
|
||||
var currentType : MarkdownLineStyle = .body
|
||||
|
||||
|
||||
var string : String
|
||||
|
||||
let tagList = "!\\_*`[]()"
|
||||
let validMarkdownTags = CharacterSet(charactersIn: "!\\_*`[]()")
|
||||
|
||||
var orderedListCount = 0
|
||||
var orderedListIndentFirstOrderCount = 0
|
||||
var orderedListIndentSecondOrderCount = 0
|
||||
|
||||
|
||||
/**
|
||||
|
||||
- parameter string: A string containing [Markdown](https://daringfireball.net/projects/markdown/) syntax to be converted to an NSAttributedString
|
||||
|
||||
- returns: An initialized SwiftyMarkdown object
|
||||
*/
|
||||
public init(string : String ) {
|
||||
self.string = string
|
||||
super.init()
|
||||
self.setup()
|
||||
}
|
||||
|
||||
/**
|
||||
A failable initializer that takes a URL and attempts to read it as a UTF-8 string
|
||||
|
||||
- parameter url: The location of the file to read
|
||||
|
||||
- returns: An initialized SwiftyMarkdown object, or nil if the string couldn't be read
|
||||
*/
|
||||
public init?(url : URL ) {
|
||||
|
||||
do {
|
||||
self.string = try NSString(contentsOf: url, encoding: String.Encoding.utf8.rawValue) as String
|
||||
|
||||
} catch {
|
||||
self.string = ""
|
||||
return nil
|
||||
}
|
||||
super.init()
|
||||
self.setup()
|
||||
}
|
||||
|
||||
func setup() {
|
||||
#if os(macOS)
|
||||
self.setFontColorForAllStyles(with: .labelColor)
|
||||
#elseif !os(watchOS)
|
||||
if #available(iOS 13.0, tvOS 13.0, *) {
|
||||
self.setFontColorForAllStyles(with: .label)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
Set font size for all styles
|
||||
|
||||
- parameter size: size of font
|
||||
*/
|
||||
open func setFontSizeForAllStyles(with size: CGFloat) {
|
||||
h1.fontSize = size
|
||||
h2.fontSize = size
|
||||
h3.fontSize = size
|
||||
h4.fontSize = size
|
||||
h5.fontSize = size
|
||||
h6.fontSize = size
|
||||
body.fontSize = size
|
||||
italic.fontSize = size
|
||||
bold.fontSize = size
|
||||
code.fontSize = size
|
||||
link.fontSize = size
|
||||
link.fontSize = size
|
||||
strikethrough.fontSize = size
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
open func setFontColorForAllStyles(with color: NSColor) {
|
||||
h1.color = color
|
||||
h2.color = color
|
||||
h3.color = color
|
||||
h4.color = color
|
||||
h5.color = color
|
||||
h6.color = color
|
||||
body.color = color
|
||||
italic.color = color
|
||||
bold.color = color
|
||||
code.color = color
|
||||
link.color = color
|
||||
blockquotes.color = color
|
||||
strikethrough.color = color
|
||||
}
|
||||
#else
|
||||
open func setFontColorForAllStyles(with color: UIColor) {
|
||||
h1.color = color
|
||||
h2.color = color
|
||||
h3.color = color
|
||||
h4.color = color
|
||||
h5.color = color
|
||||
h6.color = color
|
||||
body.color = color
|
||||
italic.color = color
|
||||
bold.color = color
|
||||
code.color = color
|
||||
link.color = color
|
||||
blockquotes.color = color
|
||||
strikethrough.color = color
|
||||
}
|
||||
#endif
|
||||
|
||||
open func setFontNameForAllStyles(with name: String) {
|
||||
h1.fontName = name
|
||||
h2.fontName = name
|
||||
h3.fontName = name
|
||||
h4.fontName = name
|
||||
h5.fontName = name
|
||||
h6.fontName = name
|
||||
body.fontName = name
|
||||
italic.fontName = name
|
||||
bold.fontName = name
|
||||
code.fontName = name
|
||||
link.fontName = name
|
||||
blockquotes.fontName = name
|
||||
strikethrough.fontName = name
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Generates an NSAttributedString from the string or URL passed at initialisation. Custom fonts or styles are applied to the appropriate elements when this method is called.
|
||||
|
||||
- returns: An NSAttributedString with the styles applied
|
||||
*/
|
||||
open func attributedString(from markdownString : String? = nil) -> NSAttributedString {
|
||||
if let existentMarkdownString = markdownString {
|
||||
self.string = existentMarkdownString
|
||||
}
|
||||
let attributedString = NSMutableAttributedString(string: "")
|
||||
self.lineProcessor.processEmptyStrings = MarkdownLineStyle.body
|
||||
let foundAttributes : [SwiftyLine] = lineProcessor.process(self.string)
|
||||
|
||||
for (idx, line) in foundAttributes.enumerated() {
|
||||
if idx > 0 {
|
||||
attributedString.append(NSAttributedString(string: "\n"))
|
||||
}
|
||||
let finalTokens = self.tokeniser.process(line.line)
|
||||
attributedString.append(attributedStringFor(tokens: finalTokens, in: line))
|
||||
|
||||
}
|
||||
return attributedString
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SwiftyMarkdown {
|
||||
|
||||
func attributedStringFor( tokens : [Token], in line : SwiftyLine ) -> NSAttributedString {
|
||||
|
||||
var finalTokens = tokens
|
||||
let finalAttributedString = NSMutableAttributedString()
|
||||
var attributes : [NSAttributedString.Key : AnyObject] = [:]
|
||||
|
||||
guard let markdownLineStyle = line.lineStyle as? MarkdownLineStyle else {
|
||||
preconditionFailure("The passed line style is not a valid Markdown Line Style")
|
||||
}
|
||||
|
||||
var listItem = self.bullet
|
||||
switch markdownLineStyle {
|
||||
case .orderedList:
|
||||
self.orderedListCount += 1
|
||||
self.orderedListIndentFirstOrderCount = 0
|
||||
self.orderedListIndentSecondOrderCount = 0
|
||||
listItem = "\(self.orderedListCount)."
|
||||
case .orderedListIndentFirstOrder, .unorderedListIndentFirstOrder:
|
||||
self.orderedListIndentFirstOrderCount += 1
|
||||
self.orderedListIndentSecondOrderCount = 0
|
||||
if markdownLineStyle == .orderedListIndentFirstOrder {
|
||||
listItem = "\(self.orderedListIndentFirstOrderCount)."
|
||||
}
|
||||
|
||||
case .orderedListIndentSecondOrder, .unorderedListIndentSecondOrder:
|
||||
self.orderedListIndentSecondOrderCount += 1
|
||||
if markdownLineStyle == .orderedListIndentSecondOrder {
|
||||
listItem = "\(self.orderedListIndentSecondOrderCount)."
|
||||
}
|
||||
|
||||
default:
|
||||
self.orderedListCount = 0
|
||||
self.orderedListIndentFirstOrderCount = 0
|
||||
self.orderedListIndentSecondOrderCount = 0
|
||||
}
|
||||
|
||||
let lineProperties : LineProperties
|
||||
switch markdownLineStyle {
|
||||
case .h1:
|
||||
lineProperties = self.h1
|
||||
case .h2:
|
||||
lineProperties = self.h2
|
||||
case .h3:
|
||||
lineProperties = self.h3
|
||||
case .h4:
|
||||
lineProperties = self.h4
|
||||
case .h5:
|
||||
lineProperties = self.h5
|
||||
case .h6:
|
||||
lineProperties = self.h6
|
||||
case .codeblock:
|
||||
lineProperties = body
|
||||
let paragraphStyle = NSMutableParagraphStyle()
|
||||
paragraphStyle.firstLineHeadIndent = 20.0
|
||||
attributes[.paragraphStyle] = paragraphStyle
|
||||
case .blockquote:
|
||||
lineProperties = self.blockquotes
|
||||
let paragraphStyle = NSMutableParagraphStyle()
|
||||
paragraphStyle.firstLineHeadIndent = 20.0
|
||||
paragraphStyle.headIndent = 20.0
|
||||
attributes[.paragraphStyle] = paragraphStyle
|
||||
case .unorderedList, .unorderedListIndentFirstOrder, .unorderedListIndentSecondOrder, .orderedList, .orderedListIndentFirstOrder, .orderedListIndentSecondOrder:
|
||||
|
||||
let interval : CGFloat = 30
|
||||
var addition = interval
|
||||
var indent = ""
|
||||
switch line.lineStyle as! MarkdownLineStyle {
|
||||
case .unorderedListIndentFirstOrder, .orderedListIndentFirstOrder:
|
||||
addition = interval * 2
|
||||
indent = "\t"
|
||||
case .unorderedListIndentSecondOrder, .orderedListIndentSecondOrder:
|
||||
addition = interval * 3
|
||||
indent = "\t\t"
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
lineProperties = body
|
||||
|
||||
let paragraphStyle = NSMutableParagraphStyle()
|
||||
paragraphStyle.tabStops = [NSTextTab(textAlignment: .left, location: interval, options: [:]), NSTextTab(textAlignment: .left, location: interval, options: [:])]
|
||||
paragraphStyle.defaultTabInterval = interval
|
||||
paragraphStyle.headIndent = addition
|
||||
|
||||
attributes[.paragraphStyle] = paragraphStyle
|
||||
finalTokens.insert(Token(type: .string, inputString: "\(indent)\(listItem)\t"), at: 0)
|
||||
|
||||
case .yaml:
|
||||
lineProperties = body
|
||||
case .previousH1:
|
||||
lineProperties = body
|
||||
case .previousH2:
|
||||
lineProperties = body
|
||||
case .body:
|
||||
lineProperties = body
|
||||
}
|
||||
|
||||
if lineProperties.alignment != .left {
|
||||
let paragraphStyle = NSMutableParagraphStyle()
|
||||
paragraphStyle.alignment = lineProperties.alignment
|
||||
attributes[.paragraphStyle] = paragraphStyle
|
||||
}
|
||||
|
||||
|
||||
for token in finalTokens {
|
||||
attributes[.font] = self.font(for: line)
|
||||
attributes[.link] = nil
|
||||
attributes[.strikethroughStyle] = nil
|
||||
attributes[.foregroundColor] = self.color(for: line)
|
||||
guard let styles = token.characterStyles as? [CharacterStyle] else {
|
||||
continue
|
||||
}
|
||||
if styles.contains(.italic) {
|
||||
attributes[.font] = self.font(for: line, characterOverride: .italic)
|
||||
attributes[.foregroundColor] = self.italic.color
|
||||
}
|
||||
if styles.contains(.bold) {
|
||||
attributes[.font] = self.font(for: line, characterOverride: .bold)
|
||||
attributes[.foregroundColor] = self.bold.color
|
||||
}
|
||||
|
||||
if styles.contains(.link), let url = token.metadataString {
|
||||
attributes[.foregroundColor] = self.link.color
|
||||
attributes[.font] = self.font(for: line, characterOverride: .link)
|
||||
attributes[.link] = url as AnyObject
|
||||
|
||||
if underlineLinks {
|
||||
attributes[.underlineStyle] = NSUnderlineStyle.single.rawValue as AnyObject
|
||||
}
|
||||
}
|
||||
|
||||
if styles.contains(.strikethrough) {
|
||||
attributes[.font] = self.font(for: line, characterOverride: .strikethrough)
|
||||
attributes[.strikethroughStyle] = NSUnderlineStyle.single.rawValue as AnyObject
|
||||
attributes[.foregroundColor] = self.strikethrough.color
|
||||
}
|
||||
|
||||
#if !os(watchOS)
|
||||
if styles.contains(.image), let imageName = token.metadataString {
|
||||
#if !os(macOS)
|
||||
let image1Attachment = NSTextAttachment()
|
||||
image1Attachment.image = UIImage(named: imageName)
|
||||
let str = NSAttributedString(attachment: image1Attachment)
|
||||
finalAttributedString.append(str)
|
||||
#elseif !os(watchOS)
|
||||
let image1Attachment = NSTextAttachment()
|
||||
image1Attachment.image = NSImage(named: imageName)
|
||||
let str = NSAttributedString(attachment: image1Attachment)
|
||||
finalAttributedString.append(str)
|
||||
#endif
|
||||
continue
|
||||
}
|
||||
#endif
|
||||
|
||||
if styles.contains(.code) {
|
||||
attributes[.foregroundColor] = self.code.color
|
||||
attributes[.font] = self.font(for: line, characterOverride: .code)
|
||||
} else {
|
||||
// Switch back to previous font
|
||||
}
|
||||
let str = NSAttributedString(string: token.outputString, attributes: attributes)
|
||||
finalAttributedString.append(str)
|
||||
}
|
||||
|
||||
return finalAttributedString
|
||||
}
|
||||
}
|
||||
@@ -1,821 +0,0 @@
|
||||
//
|
||||
// SwiftyTokeniser.swift
|
||||
// SwiftyMarkdown
|
||||
//
|
||||
// Created by Simon Fairbairn on 16/12/2019.
|
||||
// Copyright © 2019 Voyage Travel Apps. All rights reserved.
|
||||
//
|
||||
import Foundation
|
||||
import os.log
|
||||
|
||||
extension OSLog {
|
||||
private static var subsystem = "SwiftyTokeniser"
|
||||
static let tokenising = OSLog(subsystem: subsystem, category: "Tokenising")
|
||||
static let styling = OSLog(subsystem: subsystem, category: "Styling")
|
||||
}
|
||||
|
||||
// Tag definition
|
||||
public protocol CharacterStyling {
|
||||
func isEqualTo( _ other : CharacterStyling ) -> Bool
|
||||
}
|
||||
|
||||
public enum SpaceAllowed {
|
||||
case no
|
||||
case bothSides
|
||||
case oneSide
|
||||
case leadingSide
|
||||
case trailingSide
|
||||
}
|
||||
|
||||
public enum Cancel {
|
||||
case none
|
||||
case allRemaining
|
||||
case currentSet
|
||||
}
|
||||
|
||||
public struct CharacterRule : CustomStringConvertible {
|
||||
public let openTag : String
|
||||
public let intermediateTag : String?
|
||||
public let closingTag : String?
|
||||
public let escapeCharacter : Character?
|
||||
public let styles : [Int : [CharacterStyling]]
|
||||
public var minTags : Int = 1
|
||||
public var maxTags : Int = 1
|
||||
public var spacesAllowed : SpaceAllowed = .oneSide
|
||||
public var cancels : Cancel = .none
|
||||
|
||||
public var description: String {
|
||||
return "Character Rule with Open tag: \(self.openTag) and current styles : \(self.styles) "
|
||||
}
|
||||
|
||||
public init(openTag: String, intermediateTag: String? = nil, closingTag: String? = nil, escapeCharacter: Character? = nil, styles: [Int : [CharacterStyling]] = [:], minTags : Int = 1, maxTags : Int = 1, cancels : Cancel = .none) {
|
||||
self.openTag = openTag
|
||||
self.intermediateTag = intermediateTag
|
||||
self.closingTag = closingTag
|
||||
self.escapeCharacter = escapeCharacter
|
||||
self.styles = styles
|
||||
self.minTags = minTags
|
||||
self.maxTags = maxTags
|
||||
self.cancels = cancels
|
||||
}
|
||||
}
|
||||
|
||||
// Token definition
|
||||
public enum TokenType {
|
||||
case repeatingTag
|
||||
case openTag
|
||||
case intermediateTag
|
||||
case closeTag
|
||||
case string
|
||||
case escape
|
||||
case replacement
|
||||
}
|
||||
|
||||
|
||||
|
||||
public struct Token {
|
||||
public let id = UUID().uuidString
|
||||
public let type : TokenType
|
||||
public let inputString : String
|
||||
public fileprivate(set) var metadataString : String? = nil
|
||||
public fileprivate(set) var characterStyles : [CharacterStyling] = []
|
||||
public fileprivate(set) var count : Int = 0
|
||||
public fileprivate(set) var shouldSkip : Bool = false
|
||||
public fileprivate(set) var tokenIndex : Int = -1
|
||||
public fileprivate(set) var isProcessed : Bool = false
|
||||
public fileprivate(set) var isMetadata : Bool = false
|
||||
public var outputString : String {
|
||||
get {
|
||||
switch self.type {
|
||||
case .repeatingTag:
|
||||
if count <= 0 {
|
||||
return ""
|
||||
} else {
|
||||
let range = inputString.startIndex..<inputString.index(inputString.startIndex, offsetBy: self.count)
|
||||
return String(inputString[range])
|
||||
}
|
||||
case .openTag, .closeTag, .intermediateTag:
|
||||
return (self.isProcessed || self.isMetadata) ? "" : inputString
|
||||
case .escape, .string:
|
||||
return (self.isProcessed || self.isMetadata) ? "" : inputString
|
||||
case .replacement:
|
||||
return self.inputString
|
||||
}
|
||||
}
|
||||
}
|
||||
public init( type : TokenType, inputString : String, characterStyles : [CharacterStyling] = []) {
|
||||
self.type = type
|
||||
self.inputString = inputString
|
||||
self.characterStyles = characterStyles
|
||||
}
|
||||
|
||||
func newToken( fromSubstring string: String, isReplacement : Bool) -> Token {
|
||||
var newToken = Token(type: (isReplacement) ? .replacement : .string , inputString: string, characterStyles: self.characterStyles)
|
||||
newToken.metadataString = self.metadataString
|
||||
newToken.isMetadata = self.isMetadata
|
||||
newToken.isProcessed = self.isProcessed
|
||||
return newToken
|
||||
}
|
||||
}
|
||||
|
||||
extension Sequence where Iterator.Element == Token {
|
||||
var oslogDisplay: String {
|
||||
return "[\"\(self.map( { ($0.outputString.isEmpty) ? "\($0.type): \($0.inputString)" : $0.outputString }).joined(separator: "\", \""))\"]"
|
||||
}
|
||||
}
|
||||
|
||||
public class SwiftyTokeniser {
|
||||
let rules : [CharacterRule]
|
||||
var replacements : [String : [Token]] = [:]
|
||||
|
||||
var enableLog = (ProcessInfo.processInfo.environment["SwiftyTokeniserLogging"] != nil)
|
||||
|
||||
public init( with rules : [CharacterRule] ) {
|
||||
self.rules = rules
|
||||
}
|
||||
|
||||
|
||||
/// This goes through every CharacterRule in order and applies it to the input string, tokenising the string
|
||||
/// if there are any matches.
|
||||
///
|
||||
/// The for loop in the while loop (yeah, I know) is there to separate strings from within tags to
|
||||
/// those outside them.
|
||||
///
|
||||
/// e.g. "A string with a \[link\]\(url\) tag" would have the "link" text tokenised separately.
|
||||
///
|
||||
/// This is to prevent situations like **\[link**\](url) from returing a bold string.
|
||||
///
|
||||
/// - Parameter inputString: A string to have the CharacterRules in `self.rules` applied to
|
||||
public func process( _ inputString : String ) -> [Token] {
|
||||
guard rules.count > 0 else {
|
||||
return [Token(type: .string, inputString: inputString)]
|
||||
}
|
||||
|
||||
var currentTokens : [Token] = []
|
||||
var mutableRules = self.rules
|
||||
|
||||
|
||||
|
||||
while !mutableRules.isEmpty {
|
||||
let nextRule = mutableRules.removeFirst()
|
||||
|
||||
if enableLog {
|
||||
os_log("------------------------------", log: .tokenising, type: .info)
|
||||
os_log("RULE: %@", log: OSLog.tokenising, type:.info , nextRule.description)
|
||||
}
|
||||
|
||||
if currentTokens.isEmpty {
|
||||
// This means it's the first time through
|
||||
currentTokens = self.applyStyles(to: self.scan(inputString, with: nextRule), usingRule: nextRule)
|
||||
continue
|
||||
}
|
||||
|
||||
var outerStringTokens : [Token] = []
|
||||
var innerStringTokens : [Token] = []
|
||||
var isOuter = true
|
||||
for idx in 0..<currentTokens.count {
|
||||
let nextToken = currentTokens[idx]
|
||||
if nextToken.type == .openTag && nextToken.isProcessed {
|
||||
isOuter = false
|
||||
}
|
||||
if nextToken.type == .closeTag {
|
||||
let ref = UUID().uuidString
|
||||
outerStringTokens.append(Token(type: .replacement, inputString: ref))
|
||||
innerStringTokens.append(nextToken)
|
||||
self.replacements[ref] = self.handleReplacementTokens(innerStringTokens, with: nextRule)
|
||||
innerStringTokens.removeAll()
|
||||
isOuter = true
|
||||
continue
|
||||
}
|
||||
(isOuter) ? outerStringTokens.append(nextToken) : innerStringTokens.append(nextToken)
|
||||
}
|
||||
|
||||
currentTokens = self.handleReplacementTokens(outerStringTokens, with: nextRule)
|
||||
|
||||
var finalTokens : [Token] = []
|
||||
for token in currentTokens {
|
||||
guard token.type == .replacement else {
|
||||
finalTokens.append(token)
|
||||
continue
|
||||
}
|
||||
if let hasReplacement = self.replacements[token.inputString] {
|
||||
if enableLog {
|
||||
os_log("Found replacement for %@", log: .tokenising, type: .info, token.inputString)
|
||||
}
|
||||
|
||||
for var repToken in hasReplacement {
|
||||
guard repToken.type == .string else {
|
||||
finalTokens.append(repToken)
|
||||
continue
|
||||
}
|
||||
for style in token.characterStyles {
|
||||
if !repToken.characterStyles.contains(where: { $0.isEqualTo(style)}) {
|
||||
repToken.characterStyles.append(contentsOf: token.characterStyles)
|
||||
}
|
||||
}
|
||||
|
||||
finalTokens.append(repToken)
|
||||
}
|
||||
}
|
||||
}
|
||||
currentTokens = finalTokens
|
||||
|
||||
|
||||
// Each string could have additional tokens within it, so they have to be scanned as well with the current rule.
|
||||
// The one string token might then be exploded into multiple more tokens
|
||||
}
|
||||
|
||||
if enableLog {
|
||||
os_log("=====RULE PROCESSING COMPLETE=====", log: .tokenising, type: .info)
|
||||
os_log("==================================", log: .tokenising, type: .info)
|
||||
}
|
||||
|
||||
return currentTokens
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// In order to reinsert the original replacements into the new string token, the replacements
|
||||
/// need to be searched for in the incoming string one by one.
|
||||
///
|
||||
/// Using the `newToken(fromSubstring:isReplacement:)` function ensures that any metadata and character styles
|
||||
/// are passed over into the newly created tokens.
|
||||
///
|
||||
/// E.g. A string token that has an `outputString` of "This string AAAAA-BBBBB-CCCCC replacements", with
|
||||
/// a characterStyle of `bold` for the entire string, needs to be separated into the following tokens:
|
||||
///
|
||||
/// - `string`: "This string "
|
||||
/// - `replacement`: "AAAAA-BBBBB-CCCCC"
|
||||
/// - `string`: " replacements"
|
||||
///
|
||||
/// Each of these need to have a character style of `bold`.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - replacements: An array of `replacement` tokens
|
||||
/// - token: The new `string` token that may contain replacement IDs contained in the `replacements` array
|
||||
func reinsertReplacements(_ replacements : [Token], from stringToken : Token ) -> [Token] {
|
||||
guard !stringToken.outputString.isEmpty && !replacements.isEmpty else {
|
||||
return [stringToken]
|
||||
}
|
||||
var outputTokens : [Token] = []
|
||||
let scanner = Scanner(string: stringToken.outputString)
|
||||
scanner.charactersToBeSkipped = nil
|
||||
|
||||
// Remove any replacements that don't appear in the incoming string
|
||||
var repTokens = replacements.filter({ stringToken.outputString.contains($0.inputString) })
|
||||
|
||||
var testString = "\n"
|
||||
while !scanner.isAtEnd {
|
||||
var outputString : String = ""
|
||||
if repTokens.count > 0 {
|
||||
testString = repTokens.removeFirst().inputString
|
||||
}
|
||||
|
||||
if #available(iOS 13.0, OSX 10.15, watchOS 6.0, tvOS 13.0, *) {
|
||||
if let nextString = scanner.scanUpToString(testString) {
|
||||
outputString = nextString
|
||||
outputTokens.append(stringToken.newToken(fromSubstring: outputString, isReplacement: false))
|
||||
if let outputToken = scanner.scanString(testString) {
|
||||
outputTokens.append(stringToken.newToken(fromSubstring: outputToken, isReplacement: true))
|
||||
}
|
||||
} else if let outputToken = scanner.scanString(testString) {
|
||||
outputTokens.append(stringToken.newToken(fromSubstring: outputToken, isReplacement: true))
|
||||
}
|
||||
} else {
|
||||
var oldString : NSString? = nil
|
||||
var tokenString : NSString? = nil
|
||||
scanner.scanUpTo(testString, into: &oldString)
|
||||
if let nextString = oldString {
|
||||
outputString = nextString as String
|
||||
outputTokens.append(stringToken.newToken(fromSubstring: outputString, isReplacement: false))
|
||||
scanner.scanString(testString, into: &tokenString)
|
||||
if let outputToken = tokenString as String? {
|
||||
outputTokens.append(stringToken.newToken(fromSubstring: outputToken, isReplacement: true))
|
||||
}
|
||||
} else {
|
||||
scanner.scanString(testString, into: &tokenString)
|
||||
if let outputToken = tokenString as String? {
|
||||
outputTokens.append(stringToken.newToken(fromSubstring: outputToken, isReplacement: true))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return outputTokens
|
||||
}
|
||||
|
||||
|
||||
/// This function is necessary because a previously tokenised string might have
|
||||
///
|
||||
/// Consider a previously tokenised string, where AAAAA-BBBBB-CCCCC represents a replaced \[link\](url) instance.
|
||||
///
|
||||
/// The incoming tokens will look like this:
|
||||
///
|
||||
/// - `string`: "A \*\*Bold"
|
||||
/// - `replacement` : "AAAAA-BBBBB-CCCCC"
|
||||
/// - `string`: " with a trailing string**"
|
||||
///
|
||||
/// However, because the scanner can only tokenise individual strings, passing in the string values
|
||||
/// of these tokens individually and applying the styles will not correctly detect the starting and
|
||||
/// ending `repeatingTag` instances. (e.g. the scanner will see "A \*\*Bold", and then "AAAAA-BBBBB-CCCCC",
|
||||
/// and finally " with a trailing string\*\*")
|
||||
///
|
||||
/// The strings need to be combined, so that they form a single string:
|
||||
/// A \*\*Bold AAAAA-BBBBB-CCCCC with a trailing string\*\*.
|
||||
/// This string is then parsed and tokenised so that it looks like this:
|
||||
///
|
||||
/// - `string`: "A "
|
||||
/// - `repeatingTag`: "\*\*"
|
||||
/// - `string`: "Bold AAAAA-BBBBB-CCCCC with a trailing string"
|
||||
/// - `repeatingTag`: "\*\*"
|
||||
///
|
||||
/// Finally, the replacements from the original incoming token array are searched for and pulled out
|
||||
/// of this new string, so the final result looks like this:
|
||||
///
|
||||
/// - `string`: "A "
|
||||
/// - `repeatingTag`: "\*\*"
|
||||
/// - `string`: "Bold "
|
||||
/// - `replacement`: "AAAAA-BBBBB-CCCCC"
|
||||
/// - `string`: " with a trailing string"
|
||||
/// - `repeatingTag`: "\*\*"
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - tokens: The tokens to be combined, scanned, re-tokenised, and merged
|
||||
/// - rule: The character rule currently being applied
|
||||
func scanReplacementTokens( _ tokens : [Token], with rule : CharacterRule ) -> [Token] {
|
||||
guard tokens.count > 0 else {
|
||||
return []
|
||||
}
|
||||
|
||||
let combinedString = tokens.map({ $0.outputString }).joined()
|
||||
|
||||
let nextTokens = self.scan(combinedString, with: rule)
|
||||
var replacedTokens = self.applyStyles(to: nextTokens, usingRule: rule)
|
||||
|
||||
/// It's necessary here to check to see if the first token (which will always represent the styles
|
||||
/// to be applied from previous scans) has any existing metadata or character styles and apply them
|
||||
/// to *all* the string and replacement tokens found by the new scan.
|
||||
for idx in 0..<replacedTokens.count {
|
||||
guard replacedTokens[idx].type == .string || replacedTokens[idx].type == .replacement else {
|
||||
continue
|
||||
}
|
||||
if tokens.first!.metadataString != nil && replacedTokens[idx].metadataString == nil {
|
||||
replacedTokens[idx].metadataString = tokens.first!.metadataString
|
||||
}
|
||||
replacedTokens[idx].characterStyles.append(contentsOf: tokens.first!.characterStyles)
|
||||
}
|
||||
|
||||
// Swap the original replacement tokens back in
|
||||
let replacements = tokens.filter({ $0.type == .replacement })
|
||||
var outputTokens : [Token] = []
|
||||
for token in replacedTokens {
|
||||
guard token.type == .string else {
|
||||
outputTokens.append(token)
|
||||
continue
|
||||
}
|
||||
outputTokens.append(contentsOf: self.reinsertReplacements(replacements, from: token))
|
||||
}
|
||||
|
||||
return outputTokens
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// This function ensures that only concurrent `string` and `replacement` tokens are processed together.
|
||||
///
|
||||
/// i.e. If there is an existing `repeatingTag` token between two strings, then those strings will be
|
||||
/// processed individually. This prevents incorrect parsing of strings like "\*\*\_Should only be bold\*\*\_"
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - incomingTokens: A group of tokens whose string tokens and replacement tokens should be combined and re-tokenised
|
||||
/// - rule: The current rule being processed
|
||||
func handleReplacementTokens( _ incomingTokens : [Token], with rule : CharacterRule) -> [Token] {
|
||||
|
||||
// Only combine string and replacements that are next to each other.
|
||||
var newTokenSet : [Token] = []
|
||||
var currentTokenSet : [Token] = []
|
||||
for i in 0..<incomingTokens.count {
|
||||
guard incomingTokens[i].type == .string || incomingTokens[i].type == .replacement else {
|
||||
newTokenSet.append(contentsOf: self.scanReplacementTokens(currentTokenSet, with: rule))
|
||||
newTokenSet.append(incomingTokens[i])
|
||||
currentTokenSet.removeAll()
|
||||
continue
|
||||
}
|
||||
guard !incomingTokens[i].isProcessed && !incomingTokens[i].isMetadata && !incomingTokens[i].shouldSkip else {
|
||||
newTokenSet.append(contentsOf: self.scanReplacementTokens(currentTokenSet, with: rule))
|
||||
newTokenSet.append(incomingTokens[i])
|
||||
currentTokenSet.removeAll()
|
||||
continue
|
||||
}
|
||||
currentTokenSet.append(incomingTokens[i])
|
||||
}
|
||||
newTokenSet.append(contentsOf: self.scanReplacementTokens(currentTokenSet, with: rule))
|
||||
|
||||
return newTokenSet
|
||||
}
|
||||
|
||||
|
||||
func handleClosingTagFromOpenTag(withIndex index : Int, in tokens: inout [Token], following rule : CharacterRule ) {
|
||||
|
||||
guard rule.closingTag != nil else {
|
||||
return
|
||||
}
|
||||
guard let closeTokenIdx = tokens.firstIndex(where: { $0.type == .closeTag && !$0.isProcessed }) else {
|
||||
return
|
||||
}
|
||||
|
||||
var metadataIndex = index
|
||||
// If there's an intermediate tag, get the index of that
|
||||
if rule.intermediateTag != nil {
|
||||
guard let nextTokenIdx = tokens.firstIndex(where: { $0.type == .intermediateTag && !$0.isProcessed }) else {
|
||||
return
|
||||
}
|
||||
metadataIndex = nextTokenIdx
|
||||
let styles : [CharacterStyling] = rule.styles[1] ?? []
|
||||
for i in index..<nextTokenIdx {
|
||||
for style in styles {
|
||||
if !tokens[i].characterStyles.contains(where: { $0.isEqualTo(style )}) {
|
||||
tokens[i].characterStyles.append(style)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var metadataString : String = ""
|
||||
for i in metadataIndex..<closeTokenIdx {
|
||||
if tokens[i].type == .string {
|
||||
metadataString.append(tokens[i].outputString)
|
||||
tokens[i].isMetadata = true
|
||||
}
|
||||
}
|
||||
|
||||
for i in index..<metadataIndex {
|
||||
if tokens[i].type == .string {
|
||||
tokens[i].metadataString = metadataString
|
||||
}
|
||||
}
|
||||
|
||||
tokens[closeTokenIdx].isProcessed = true
|
||||
tokens[metadataIndex].isProcessed = true
|
||||
tokens[index].isProcessed = true
|
||||
}
|
||||
|
||||
|
||||
/// This is here to manage how opening tags are matched with closing tags when they're all the same
|
||||
/// character.
|
||||
///
|
||||
/// Of course, because Markdown is about as loose as a spec can be while still being considered any
|
||||
/// kind of spec, the number of times this character repeats causes different effects. Then there
|
||||
/// is the ill-defined way it should work if the number of opening and closing tags are different.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - index: The index of the current token in the loop
|
||||
/// - tokens: An inout variable of the loop tokens of interest
|
||||
/// - rule: The character rule being applied
|
||||
func handleClosingTagFromRepeatingTag(withIndex index : Int, in tokens: inout [Token], following rule : CharacterRule) {
|
||||
let theToken = tokens[index]
|
||||
|
||||
if enableLog {
|
||||
os_log("Found repeating tag with tag count: %i, tags: %@, current rule open tag: %@", log: .tokenising, type: .info, theToken.count, theToken.inputString, rule.openTag )
|
||||
}
|
||||
|
||||
guard theToken.count > 0 else {
|
||||
return
|
||||
}
|
||||
|
||||
let startIdx = index
|
||||
var endIdx : Int? = nil
|
||||
|
||||
let maxCount = (theToken.count > rule.maxTags) ? rule.maxTags : theToken.count
|
||||
// Try to find exact match first
|
||||
if let nextTokenIdx = tokens.firstIndex(where: { $0.inputString.first == theToken.inputString.first && $0.type == theToken.type && $0.count == theToken.count && $0.id != theToken.id && !$0.isProcessed }) {
|
||||
endIdx = nextTokenIdx
|
||||
}
|
||||
|
||||
if endIdx == nil, let nextTokenIdx = tokens.firstIndex(where: { $0.inputString.first == theToken.inputString.first && $0.type == theToken.type && $0.count >= 1 && $0.id != theToken.id && !$0.isProcessed }) {
|
||||
endIdx = nextTokenIdx
|
||||
}
|
||||
guard let existentEnd = endIdx else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let styles : [CharacterStyling] = rule.styles[maxCount] ?? []
|
||||
for i in startIdx..<existentEnd {
|
||||
for style in styles {
|
||||
if !tokens[i].characterStyles.contains(where: { $0.isEqualTo(style )}) {
|
||||
tokens[i].characterStyles.append(style)
|
||||
}
|
||||
}
|
||||
if rule.cancels == .allRemaining {
|
||||
tokens[i].shouldSkip = true
|
||||
}
|
||||
}
|
||||
|
||||
let maxEnd = (tokens[existentEnd].count > rule.maxTags) ? rule.maxTags : tokens[existentEnd].count
|
||||
tokens[index].count = theToken.count - maxEnd
|
||||
tokens[existentEnd].count = tokens[existentEnd].count - maxEnd
|
||||
if maxEnd < rule.maxTags {
|
||||
self.handleClosingTagFromRepeatingTag(withIndex: index, in: &tokens, following: rule)
|
||||
} else {
|
||||
tokens[existentEnd].isProcessed = true
|
||||
tokens[index].isProcessed = true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
func applyStyles( to tokens : [Token], usingRule rule : CharacterRule ) -> [Token] {
|
||||
var mutableTokens : [Token] = tokens
|
||||
|
||||
if enableLog {
|
||||
os_log("Applying styles to tokens: %@", log: .tokenising, type: .info, tokens.oslogDisplay )
|
||||
}
|
||||
for idx in 0..<mutableTokens.count {
|
||||
let token = mutableTokens[idx]
|
||||
switch token.type {
|
||||
case .escape:
|
||||
if enableLog {
|
||||
os_log("Found escape: %@", log: .tokenising, type: .info, token.inputString )
|
||||
}
|
||||
case .repeatingTag:
|
||||
self.handleClosingTagFromRepeatingTag(withIndex: idx, in: &mutableTokens, following: rule)
|
||||
case .openTag:
|
||||
let theToken = mutableTokens[idx]
|
||||
if enableLog {
|
||||
os_log("Found repeating tag with tags: %@, current rule open tag: %@", log: .tokenising, type: .info, theToken.inputString, rule.openTag )
|
||||
}
|
||||
|
||||
guard rule.closingTag != nil else {
|
||||
|
||||
// If there's an intermediate tag, get the index of that
|
||||
|
||||
// Get the index of the closing tag
|
||||
|
||||
continue
|
||||
}
|
||||
self.handleClosingTagFromOpenTag(withIndex: idx, in: &mutableTokens, following: rule)
|
||||
|
||||
|
||||
case .intermediateTag:
|
||||
let theToken = mutableTokens[idx]
|
||||
if enableLog {
|
||||
os_log("Found intermediate tag with tag count: %i, tags: %@", log: .tokenising, type: .info, theToken.count, theToken.inputString )
|
||||
}
|
||||
|
||||
case .closeTag:
|
||||
let theToken = mutableTokens[idx]
|
||||
if enableLog {
|
||||
os_log("Found close tag with tag count: %i, tags: %@", log: .tokenising, type: .info, theToken.count, theToken.inputString )
|
||||
}
|
||||
|
||||
case .string:
|
||||
let theToken = mutableTokens[idx]
|
||||
if enableLog {
|
||||
if theToken.isMetadata {
|
||||
os_log("Found Metadata: %@", log: .tokenising, type: .info, theToken.inputString )
|
||||
} else {
|
||||
os_log("Found String: %@", log: .tokenising, type: .info, theToken.inputString )
|
||||
}
|
||||
if let hasMetadata = theToken.metadataString {
|
||||
os_log("...with metadata: %@", log: .tokenising, type: .info, hasMetadata )
|
||||
}
|
||||
}
|
||||
|
||||
case .replacement:
|
||||
if enableLog {
|
||||
os_log("Found replacement with ID: %@", log: .tokenising, type: .info, mutableTokens[idx].inputString )
|
||||
}
|
||||
}
|
||||
}
|
||||
return mutableTokens
|
||||
}
|
||||
|
||||
|
||||
func scan( _ string : String, with rule : CharacterRule) -> [Token] {
|
||||
let scanner = Scanner(string: string)
|
||||
scanner.charactersToBeSkipped = nil
|
||||
var tokens : [Token] = []
|
||||
var set = CharacterSet(charactersIn: "\(rule.openTag)\(rule.intermediateTag ?? "")\(rule.closingTag ?? "")")
|
||||
if let existentEscape = rule.escapeCharacter {
|
||||
set.insert(charactersIn: String(existentEscape))
|
||||
}
|
||||
|
||||
var openTagFound = false
|
||||
var openingString = ""
|
||||
while !scanner.isAtEnd {
|
||||
|
||||
if #available(iOS 13.0, OSX 10.15, watchOS 6.0, tvOS 13.0, *) {
|
||||
if let start = scanner.scanUpToCharacters(from: set) {
|
||||
openingString.append(start)
|
||||
}
|
||||
} else {
|
||||
var string : NSString?
|
||||
scanner.scanUpToCharacters(from: set, into: &string)
|
||||
if let existentString = string as String? {
|
||||
openingString.append(existentString)
|
||||
}
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
|
||||
let lastChar : String?
|
||||
if #available(iOS 13.0, OSX 10.15, watchOS 6.0, tvOS 13.0, *) {
|
||||
lastChar = ( scanner.currentIndex > string.startIndex ) ? String(string[string.index(before: scanner.currentIndex)..<scanner.currentIndex]) : nil
|
||||
} else {
|
||||
if let scanLocation = string.index(string.startIndex, offsetBy: scanner.scanLocation, limitedBy: string.endIndex) {
|
||||
lastChar = ( scanLocation > string.startIndex ) ? String(string[string.index(before: scanLocation)..<scanLocation]) : nil
|
||||
} else {
|
||||
lastChar = nil
|
||||
}
|
||||
|
||||
}
|
||||
let maybeFoundChars : String?
|
||||
if #available(iOS 13.0, OSX 10.15, watchOS 6.0, tvOS 13.0, *) {
|
||||
maybeFoundChars = scanner.scanCharacters(from: set )
|
||||
} else {
|
||||
var string : NSString?
|
||||
scanner.scanCharacters(from: set, into: &string)
|
||||
maybeFoundChars = string as String?
|
||||
}
|
||||
|
||||
let nextChar : String?
|
||||
if #available(iOS 13.0, OSX 10.15, watchOS 6.0,tvOS 13.0, *) {
|
||||
nextChar = (scanner.currentIndex != string.endIndex) ? String(string[scanner.currentIndex]) : nil
|
||||
} else {
|
||||
if let scanLocation = string.index(string.startIndex, offsetBy: scanner.scanLocation, limitedBy: string.endIndex) {
|
||||
nextChar = (scanLocation != string.endIndex) ? String(string[scanLocation]) : nil
|
||||
} else {
|
||||
nextChar = nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
guard let foundChars = maybeFoundChars else {
|
||||
tokens.append(Token(type: .string, inputString: "\(openingString)"))
|
||||
openingString = ""
|
||||
continue
|
||||
}
|
||||
|
||||
if foundChars == rule.openTag && foundChars.count < rule.minTags {
|
||||
openingString.append(foundChars)
|
||||
continue
|
||||
}
|
||||
|
||||
if !validateSpacing(nextCharacter: nextChar, previousCharacter: lastChar, with: rule) {
|
||||
let escapeString = String("\(rule.escapeCharacter ?? Character(""))")
|
||||
var escaped = foundChars.replacingOccurrences(of: "\(escapeString)\(rule.openTag)", with: rule.openTag)
|
||||
if let hasIntermediateTag = rule.intermediateTag {
|
||||
escaped = foundChars.replacingOccurrences(of: "\(escapeString)\(hasIntermediateTag)", with: hasIntermediateTag)
|
||||
}
|
||||
if let existentClosingTag = rule.closingTag {
|
||||
escaped = foundChars.replacingOccurrences(of: "\(escapeString)\(existentClosingTag)", with: existentClosingTag)
|
||||
}
|
||||
|
||||
openingString.append(escaped)
|
||||
continue
|
||||
}
|
||||
|
||||
var cumulativeString = ""
|
||||
var openString = ""
|
||||
var intermediateString = ""
|
||||
var closedString = ""
|
||||
var maybeEscapeNext = false
|
||||
|
||||
|
||||
func addToken( for type : TokenType ) {
|
||||
var inputString : String
|
||||
switch type {
|
||||
case .openTag:
|
||||
inputString = openString
|
||||
case .intermediateTag:
|
||||
inputString = intermediateString
|
||||
case .closeTag:
|
||||
inputString = closedString
|
||||
default:
|
||||
inputString = ""
|
||||
}
|
||||
guard !inputString.isEmpty else {
|
||||
return
|
||||
}
|
||||
guard inputString.count >= rule.minTags else {
|
||||
return
|
||||
}
|
||||
|
||||
if !openingString.isEmpty {
|
||||
tokens.append(Token(type: .string, inputString: "\(openingString)"))
|
||||
openingString = ""
|
||||
}
|
||||
let actualType : TokenType = ( rule.intermediateTag == nil && rule.closingTag == nil ) ? .repeatingTag : type
|
||||
|
||||
var token = Token(type: actualType, inputString: inputString)
|
||||
if rule.closingTag == nil {
|
||||
token.count = inputString.count
|
||||
}
|
||||
|
||||
tokens.append(token)
|
||||
|
||||
switch type {
|
||||
case .openTag:
|
||||
openString = ""
|
||||
case .intermediateTag:
|
||||
intermediateString = ""
|
||||
case .closeTag:
|
||||
closedString = ""
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Here I am going through and adding the characters in the found set to a cumulative string.
|
||||
// If there is an escape character, then the loop stops and any open tags are tokenised.
|
||||
for char in foundChars {
|
||||
cumulativeString.append(char)
|
||||
if maybeEscapeNext {
|
||||
|
||||
var escaped = cumulativeString
|
||||
if String(char) == rule.openTag || String(char) == rule.intermediateTag || String(char) == rule.closingTag {
|
||||
escaped = String(cumulativeString.replacingOccurrences(of: String(rule.escapeCharacter ?? Character("")), with: ""))
|
||||
}
|
||||
|
||||
openingString.append(escaped)
|
||||
cumulativeString = ""
|
||||
maybeEscapeNext = false
|
||||
}
|
||||
if let existentEscape = rule.escapeCharacter {
|
||||
if cumulativeString == String(existentEscape) {
|
||||
maybeEscapeNext = true
|
||||
addToken(for: .openTag)
|
||||
addToken(for: .intermediateTag)
|
||||
addToken(for: .closeTag)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if cumulativeString == rule.openTag {
|
||||
openString.append(char)
|
||||
cumulativeString = ""
|
||||
openTagFound = true
|
||||
} else if cumulativeString == rule.intermediateTag, openTagFound {
|
||||
intermediateString.append(cumulativeString)
|
||||
cumulativeString = ""
|
||||
} else if cumulativeString == rule.closingTag, openTagFound {
|
||||
closedString.append(char)
|
||||
cumulativeString = ""
|
||||
openTagFound = false
|
||||
}
|
||||
}
|
||||
// If we're here, it means that an escape character was found but without a corresponding
|
||||
// tag, which means it might belong to a different rule.
|
||||
// It should be added to the next group of regular characters
|
||||
|
||||
addToken(for: .openTag)
|
||||
addToken(for: .intermediateTag)
|
||||
addToken(for: .closeTag)
|
||||
openingString.append( cumulativeString )
|
||||
}
|
||||
|
||||
if !openingString.isEmpty {
|
||||
tokens.append(Token(type: .string, inputString: "\(openingString)"))
|
||||
}
|
||||
|
||||
return tokens
|
||||
}
|
||||
|
||||
func validateSpacing( nextCharacter : String?, previousCharacter : String?, with rule : CharacterRule ) -> Bool {
|
||||
switch rule.spacesAllowed {
|
||||
case .leadingSide:
|
||||
guard nextCharacter != nil else {
|
||||
return true
|
||||
}
|
||||
if nextCharacter == " " {
|
||||
return false
|
||||
}
|
||||
case .trailingSide:
|
||||
guard previousCharacter != nil else {
|
||||
return true
|
||||
}
|
||||
if previousCharacter == " " {
|
||||
return false
|
||||
}
|
||||
case .no:
|
||||
switch (previousCharacter, nextCharacter) {
|
||||
case (nil, nil), ( " ", _ ), ( _, " " ):
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
|
||||
case .oneSide:
|
||||
switch (previousCharacter, nextCharacter) {
|
||||
case (nil, " " ), (" ", nil), (" ", " " ):
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
function on_error {
|
||||
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
|
||||
}
|
||||
trap 'on_error $LINENO' ERR
|
||||
|
||||
|
||||
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
|
||||
|
||||
|
||||
variant_for_slice()
|
||||
{
|
||||
case "$1" in
|
||||
"AppCenter.xcframework/ios-arm64_arm64e_armv7_armv7s")
|
||||
echo ""
|
||||
;;
|
||||
"AppCenter.xcframework/ios-arm64_i386_x86_64-simulator")
|
||||
echo "simulator"
|
||||
;;
|
||||
"AppCenter.xcframework/ios-arm64_x86_64-maccatalyst")
|
||||
echo "maccatalyst"
|
||||
;;
|
||||
"AppCenter.xcframework/macos-arm64_x86_64")
|
||||
echo ""
|
||||
;;
|
||||
"AppCenter.xcframework/tvos-arm64")
|
||||
echo ""
|
||||
;;
|
||||
"AppCenter.xcframework/tvos-arm64_x86_64-simulator")
|
||||
echo "simulator"
|
||||
;;
|
||||
"AppCenterCrashes.xcframework/ios-arm64_arm64e_armv7_armv7s")
|
||||
echo ""
|
||||
;;
|
||||
"AppCenterCrashes.xcframework/ios-arm64_i386_x86_64-simulator")
|
||||
echo "simulator"
|
||||
;;
|
||||
"AppCenterCrashes.xcframework/ios-arm64_x86_64-maccatalyst")
|
||||
echo "maccatalyst"
|
||||
;;
|
||||
"AppCenterCrashes.xcframework/macos-arm64_x86_64")
|
||||
echo ""
|
||||
;;
|
||||
"AppCenterCrashes.xcframework/tvos-arm64")
|
||||
echo ""
|
||||
;;
|
||||
"AppCenterCrashes.xcframework/tvos-arm64_x86_64-simulator")
|
||||
echo "simulator"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
archs_for_slice()
|
||||
{
|
||||
case "$1" in
|
||||
"AppCenter.xcframework/ios-arm64_arm64e_armv7_armv7s")
|
||||
echo "arm64 arm64e armv7 armv7s"
|
||||
;;
|
||||
"AppCenter.xcframework/ios-arm64_i386_x86_64-simulator")
|
||||
echo "arm64 i386 x86_64"
|
||||
;;
|
||||
"AppCenter.xcframework/ios-arm64_x86_64-maccatalyst")
|
||||
echo "arm64 x86_64"
|
||||
;;
|
||||
"AppCenter.xcframework/macos-arm64_x86_64")
|
||||
echo "arm64 x86_64"
|
||||
;;
|
||||
"AppCenter.xcframework/tvos-arm64")
|
||||
echo "arm64"
|
||||
;;
|
||||
"AppCenter.xcframework/tvos-arm64_x86_64-simulator")
|
||||
echo "arm64 x86_64"
|
||||
;;
|
||||
"AppCenterCrashes.xcframework/ios-arm64_arm64e_armv7_armv7s")
|
||||
echo "arm64 arm64e armv7 armv7s"
|
||||
;;
|
||||
"AppCenterCrashes.xcframework/ios-arm64_i386_x86_64-simulator")
|
||||
echo "arm64 i386 x86_64"
|
||||
;;
|
||||
"AppCenterCrashes.xcframework/ios-arm64_x86_64-maccatalyst")
|
||||
echo "arm64 x86_64"
|
||||
;;
|
||||
"AppCenterCrashes.xcframework/macos-arm64_x86_64")
|
||||
echo "arm64 x86_64"
|
||||
;;
|
||||
"AppCenterCrashes.xcframework/tvos-arm64")
|
||||
echo "arm64"
|
||||
;;
|
||||
"AppCenterCrashes.xcframework/tvos-arm64_x86_64-simulator")
|
||||
echo "arm64 x86_64"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
copy_dir()
|
||||
{
|
||||
local source="$1"
|
||||
local destination="$2"
|
||||
|
||||
# Use filter instead of exclude so missing patterns don't throw errors.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" \"${source}*\" \"${destination}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" "${source}"/* "${destination}"
|
||||
}
|
||||
|
||||
SELECT_SLICE_RETVAL=""
|
||||
|
||||
select_slice() {
|
||||
local xcframework_name="$1"
|
||||
xcframework_name="${xcframework_name##*/}"
|
||||
local paths=("${@:2}")
|
||||
# Locate the correct slice of the .xcframework for the current architectures
|
||||
local target_path=""
|
||||
|
||||
# Split archs on space so we can find a slice that has all the needed archs
|
||||
local target_archs=$(echo $ARCHS | tr " " "\n")
|
||||
|
||||
local target_variant=""
|
||||
if [[ "$PLATFORM_NAME" == *"simulator" ]]; then
|
||||
target_variant="simulator"
|
||||
fi
|
||||
if [[ ! -z ${EFFECTIVE_PLATFORM_NAME+x} && "$EFFECTIVE_PLATFORM_NAME" == *"maccatalyst" ]]; then
|
||||
target_variant="maccatalyst"
|
||||
fi
|
||||
for i in ${!paths[@]}; do
|
||||
local matched_all_archs="1"
|
||||
local slice_archs="$(archs_for_slice "${xcframework_name}/${paths[$i]}")"
|
||||
local slice_variant="$(variant_for_slice "${xcframework_name}/${paths[$i]}")"
|
||||
for target_arch in $target_archs; do
|
||||
if ! [[ "${slice_variant}" == "$target_variant" ]]; then
|
||||
matched_all_archs="0"
|
||||
break
|
||||
fi
|
||||
|
||||
if ! echo "${slice_archs}" | tr " " "\n" | grep -F -q -x "$target_arch"; then
|
||||
matched_all_archs="0"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$matched_all_archs" == "1" ]]; then
|
||||
# Found a matching slice
|
||||
echo "Selected xcframework slice ${paths[$i]}"
|
||||
SELECT_SLICE_RETVAL=${paths[$i]}
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
install_xcframework() {
|
||||
local basepath="$1"
|
||||
local name="$2"
|
||||
local package_type="$3"
|
||||
local paths=("${@:4}")
|
||||
|
||||
# Locate the correct slice of the .xcframework for the current architectures
|
||||
select_slice "${basepath}" "${paths[@]}"
|
||||
local target_path="$SELECT_SLICE_RETVAL"
|
||||
if [[ -z "$target_path" ]]; then
|
||||
echo "warning: [CP] $(basename ${basepath}): Unable to find matching slice in '${paths[@]}' for the current build architectures ($ARCHS) and platform (${EFFECTIVE_PLATFORM_NAME-${PLATFORM_NAME}})."
|
||||
return
|
||||
fi
|
||||
local source="$basepath/$target_path"
|
||||
|
||||
local destination="${PODS_XCFRAMEWORKS_BUILD_DIR}/${name}"
|
||||
|
||||
if [ ! -d "$destination" ]; then
|
||||
mkdir -p "$destination"
|
||||
fi
|
||||
|
||||
copy_dir "$source/" "$destination"
|
||||
echo "Copied $source to $destination"
|
||||
}
|
||||
|
||||
install_xcframework "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework" "AppCenter/Core" "framework" "macos-arm64_x86_64"
|
||||
install_xcframework "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple/AppCenterCrashes.xcframework" "AppCenter/Crashes" "framework" "macos-arm64_x86_64"
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CODE_SIGN_IDENTITY =
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/AppCenter
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple" "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/macos-arm64_x86_64" "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple/AppCenterCrashes.xcframework/macos-arm64_x86_64"
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Core" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Crashes"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3" -l"z" -framework "AppKit" -framework "Foundation" -framework "SystemConfiguration"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/AppCenter
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -1,12 +1,15 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CODE_SIGN_IDENTITY =
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/AppCenter
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple" "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/macos-arm64_x86_64" "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple/AppCenterCrashes.xcframework/macos-arm64_x86_64"
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Core" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Crashes"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3" -l"z" -framework "AppKit" -framework "Foundation" -framework "SystemConfiguration"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/AppCenter
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CODE_SIGN_IDENTITY =
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/LetsMove
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/LetsMove
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -1,10 +1,13 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CODE_SIGN_IDENTITY =
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/LetsMove
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/LetsMove
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
||||
@@ -459,29 +459,4 @@ 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.
|
||||
|
||||
|
||||
## SwiftyMarkdown
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Simon Fairbairn
|
||||
|
||||
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.
|
||||
|
||||
Generated by CocoaPods - https://cocoapods.org
|
||||
@@ -495,37 +495,6 @@ SOFTWARE.
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Simon Fairbairn
|
||||
|
||||
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.
|
||||
</string>
|
||||
<key>License</key>
|
||||
<string>MIT</string>
|
||||
<key>Title</key>
|
||||
<string>SwiftyMarkdown</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Generated by CocoaPods - https://cocoapods.org</string>
|
||||
|
||||
@@ -18,10 +18,9 @@ echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
|
||||
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
|
||||
SWIFT_STDLIB_PATH="${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
|
||||
BCSYMBOLMAP_DIR="BCSymbolMaps"
|
||||
|
||||
# Used as a return value for each invocation of `strip_invalid_archs` function.
|
||||
STRIP_BINARY_RETVAL=0
|
||||
|
||||
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||
@@ -42,7 +41,17 @@ install_framework()
|
||||
|
||||
if [ -L "${source}" ]; then
|
||||
echo "Symlinked..."
|
||||
source="$(readlink "${source}")"
|
||||
source="$(readlink -f "${source}")"
|
||||
fi
|
||||
|
||||
if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
|
||||
# Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
|
||||
find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
|
||||
echo "Installing $f"
|
||||
install_bcsymbolmap "$f" "$destination"
|
||||
rm "$f"
|
||||
done
|
||||
rmdir "${source}/${BCSYMBOLMAP_DIR}"
|
||||
fi
|
||||
|
||||
# Use filter instead of exclude so missing patterns don't throw errors.
|
||||
@@ -80,7 +89,6 @@ install_framework()
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# Copies and strips a vendored dSYM
|
||||
install_dsym() {
|
||||
local source="$1"
|
||||
@@ -95,22 +103,55 @@ install_dsym() {
|
||||
binary_name="$(ls "$source/Contents/Resources/DWARF")"
|
||||
binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
|
||||
|
||||
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
||||
# Strip invalid architectures from the dSYM.
|
||||
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
|
||||
strip_invalid_archs "$binary" "$warn_missing_arch"
|
||||
fi
|
||||
|
||||
if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
|
||||
if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
|
||||
# Move the stripped file into its final destination.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
|
||||
else
|
||||
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
|
||||
mkdir -p "${DWARF_DSYM_FOLDER_PATH}"
|
||||
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Used as a return value for each invocation of `strip_invalid_archs` function.
|
||||
STRIP_BINARY_RETVAL=0
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
warn_missing_arch=${2:-true}
|
||||
# Get architectures for current target binary
|
||||
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
|
||||
# Intersect them with the architectures we are building for
|
||||
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
|
||||
# If there are no archs supported by this binary then warn the user
|
||||
if [[ -z "$intersected_archs" ]]; then
|
||||
if [[ "$warn_missing_arch" == "true" ]]; then
|
||||
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=1
|
||||
return
|
||||
fi
|
||||
stripped=""
|
||||
for arch in $binary_archs; do
|
||||
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary"
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=0
|
||||
}
|
||||
|
||||
# Copies the bcsymbolmap files of a vendored framework
|
||||
install_bcsymbolmap() {
|
||||
local bcsymbolmap_path="$1"
|
||||
@@ -134,83 +175,17 @@ code_sign_if_enabled() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
warn_missing_arch=${2:-true}
|
||||
# Get architectures for current target binary
|
||||
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
|
||||
# Intersect them with the architectures we are building for
|
||||
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
|
||||
# If there are no archs supported by this binary then warn the user
|
||||
if [[ -z "$intersected_archs" ]]; then
|
||||
if [[ "$warn_missing_arch" == "true" ]]; then
|
||||
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=0
|
||||
return
|
||||
fi
|
||||
stripped=""
|
||||
for arch in $binary_archs; do
|
||||
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary"
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=1
|
||||
}
|
||||
|
||||
install_artifact() {
|
||||
artifact="$1"
|
||||
base="$(basename "$artifact")"
|
||||
case $base in
|
||||
*.framework)
|
||||
install_framework "$artifact"
|
||||
;;
|
||||
*.dSYM)
|
||||
# Suppress arch warnings since XCFrameworks will include many dSYM files
|
||||
install_dsym "$artifact" "false"
|
||||
;;
|
||||
*.bcsymbolmap)
|
||||
install_bcsymbolmap "$artifact"
|
||||
;;
|
||||
*)
|
||||
echo "error: Unrecognized artifact "$artifact""
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
copy_artifacts() {
|
||||
file_list="$1"
|
||||
while read artifact; do
|
||||
install_artifact "$artifact"
|
||||
done <$file_list
|
||||
}
|
||||
|
||||
ARTIFACT_LIST_FILE="${BUILT_PRODUCTS_DIR}/cocoapods-artifacts-${CONFIGURATION}.txt"
|
||||
if [ -r "${ARTIFACT_LIST_FILE}" ]; then
|
||||
copy_artifacts "${ARTIFACT_LIST_FILE}"
|
||||
fi
|
||||
|
||||
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/LetsMove/LetsMove.framework"
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/ShortcutRecorder/ShortcutRecorder.framework"
|
||||
install_framework "${PODS_ROOT}/Sparkle/Sparkle.framework"
|
||||
install_dsym "${PODS_ROOT}/Sparkle/Sparkle.framework.dSYM"
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/SwiftyBeaver/SwiftyBeaver.framework"
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/SwiftyMarkdown/SwiftyMarkdown.framework"
|
||||
fi
|
||||
if [[ "$CONFIGURATION" == "Release" ]]; then
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/LetsMove/LetsMove.framework"
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/ShortcutRecorder/ShortcutRecorder.framework"
|
||||
install_framework "${PODS_ROOT}/Sparkle/Sparkle.framework"
|
||||
install_dsym "${PODS_ROOT}/Sparkle/Sparkle.framework.dSYM"
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/SwiftyBeaver/SwiftyBeaver.framework"
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/SwiftyMarkdown/SwiftyMarkdown.framework"
|
||||
fi
|
||||
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
|
||||
wait
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LetsMove" "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMarkdown" "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple" "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/macos-arm64_x86_64" "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple/AppCenterCrashes.xcframework/macos-arm64_x86_64" "${PODS_ROOT}/Sparkle"
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LetsMove" "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver" "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple" "${PODS_ROOT}/Sparkle" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Core" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Crashes"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LetsMove/LetsMove.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder/ShortcutRecorder.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMarkdown/SwiftyMarkdown.framework/Headers"
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' @loader_path/../Frameworks
|
||||
OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3" -l"z" -framework "AppCenter" -framework "AppCenterCrashes" -framework "AppKit" -framework "Carbon" -framework "Cocoa" -framework "Foundation" -framework "LetsMove" -framework "ShortcutRecorder" -framework "Sparkle" -framework "SwiftyBeaver" -framework "SwiftyMarkdown" -framework "SystemConfiguration"
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LetsMove/LetsMove.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder/ShortcutRecorder.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers"
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/../Frameworks' '@loader_path/Frameworks' "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" @loader_path/../Frameworks
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||
OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/LetsMove/LetsMove.framework/Headers" -isystem "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder/ShortcutRecorder.framework/Headers" -isystem "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers" -iframework "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple" -iframework "${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Core" -iframework "${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Crashes" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/LetsMove" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder" -iframework "${PODS_ROOT}/Sparkle" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver"
|
||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"sqlite3" -l"z" -framework "AppCenter" -framework "AppCenterCrashes" -framework "AppKit" -framework "Carbon" -framework "Cocoa" -framework "Foundation" -framework "LetsMove" -framework "ShortcutRecorder" -framework "Sparkle" -framework "SwiftyBeaver" -framework "SystemConfiguration"
|
||||
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AppCenter" "-F${PODS_CONFIGURATION_BUILD_DIR}/LetsMove" "-F${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder" "-F${PODS_CONFIGURATION_BUILD_DIR}/Sparkle" "-F${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -1,12 +1,17 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LetsMove" "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMarkdown" "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple" "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/macos-arm64_x86_64" "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple/AppCenterCrashes.xcframework/macos-arm64_x86_64" "${PODS_ROOT}/Sparkle"
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LetsMove" "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver" "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple" "${PODS_ROOT}/Sparkle" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Core" "${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Crashes"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LetsMove/LetsMove.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder/ShortcutRecorder.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMarkdown/SwiftyMarkdown.framework/Headers"
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' @loader_path/../Frameworks
|
||||
OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3" -l"z" -framework "AppCenter" -framework "AppCenterCrashes" -framework "AppKit" -framework "Carbon" -framework "Cocoa" -framework "Foundation" -framework "LetsMove" -framework "ShortcutRecorder" -framework "Sparkle" -framework "SwiftyBeaver" -framework "SwiftyMarkdown" -framework "SystemConfiguration"
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LetsMove/LetsMove.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder/ShortcutRecorder.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers"
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/../Frameworks' '@loader_path/Frameworks' "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" @loader_path/../Frameworks
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||
OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/LetsMove/LetsMove.framework/Headers" -isystem "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder/ShortcutRecorder.framework/Headers" -isystem "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver/SwiftyBeaver.framework/Headers" -iframework "${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple" -iframework "${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Core" -iframework "${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Crashes" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/LetsMove" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder" -iframework "${PODS_ROOT}/Sparkle" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver"
|
||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"sqlite3" -l"z" -framework "AppCenter" -framework "AppCenterCrashes" -framework "AppKit" -framework "Carbon" -framework "Cocoa" -framework "Foundation" -framework "LetsMove" -framework "ShortcutRecorder" -framework "Sparkle" -framework "SwiftyBeaver" -framework "SystemConfiguration"
|
||||
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AppCenter" "-F${PODS_CONFIGURATION_BUILD_DIR}/LetsMove" "-F${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder" "-F${PODS_CONFIGURATION_BUILD_DIR}/Sparkle" "-F${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
@@ -0,0 +1,344 @@
|
||||
# Acknowledgements
|
||||
This application makes use of the following third party libraries:
|
||||
|
||||
## ShortcutRecorder
|
||||
|
||||
Creative Commons Attribution 4.0 International Public License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution 4.0 International Public License ("Public License"). To the
|
||||
extent this Public License may be interpreted as a contract, You are
|
||||
granted the Licensed Rights in consideration of Your acceptance of
|
||||
these terms and conditions, and the Licensor grants You such rights in
|
||||
consideration of benefits the Licensor receives from making the
|
||||
Licensed Material available under these terms and conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
d. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
e. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
f. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
g. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
h. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
i. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
j. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
k. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
4. If You Share Adapted Material You produce, the Adapter's
|
||||
License You apply must not prevent recipients of the Adapted
|
||||
Material from complying with this Public License.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material; and
|
||||
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public
|
||||
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||
its public licenses to material it publishes and in those instances
|
||||
will be considered the “Licensor.” The text of the Creative Commons
|
||||
public licenses is dedicated to the public domain under the CC0 Public
|
||||
Domain Dedication. Except for the limited purpose of indicating that
|
||||
material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the
|
||||
public licenses.
|
||||
|
||||
Generated by CocoaPods - https://cocoapods.org
|
||||
@@ -0,0 +1,376 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreferenceSpecifiers</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>This application makes use of the following third party libraries:</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Creative Commons Attribution 4.0 International Public License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution 4.0 International Public License ("Public License"). To the
|
||||
extent this Public License may be interpreted as a contract, You are
|
||||
granted the Licensed Rights in consideration of Your acceptance of
|
||||
these terms and conditions, and the Licensor grants You such rights in
|
||||
consideration of benefits the Licensor receives from making the
|
||||
Licensed Material available under these terms and conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
d. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
e. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
f. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
g. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
h. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
i. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
j. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
k. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
4. If You Share Adapted Material You produce, the Adapter's
|
||||
License You apply must not prevent recipients of the Adapted
|
||||
Material from complying with this Public License.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material; and
|
||||
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public
|
||||
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||
its public licenses to material it publishes and in those instances
|
||||
will be considered the “Licensor.” The text of the Creative Commons
|
||||
public licenses is dedicated to the public domain under the CC0 Public
|
||||
Domain Dedication. Except for the limited purpose of indicating that
|
||||
material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the
|
||||
public licenses.
|
||||
</string>
|
||||
<key>License</key>
|
||||
<string>CC BY 4.0</string>
|
||||
<key>Title</key>
|
||||
<string>ShortcutRecorder</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Generated by CocoaPods - https://cocoapods.org</string>
|
||||
<key>Title</key>
|
||||
<string></string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>StringsTable</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,5 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_Pods_unit_tests : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_Pods_unit_tests
|
||||
@end
|
||||
@@ -0,0 +1,186 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
function on_error {
|
||||
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
|
||||
}
|
||||
trap 'on_error $LINENO' ERR
|
||||
|
||||
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
|
||||
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
|
||||
# frameworks to, so exit 0 (signalling the script phase was successful).
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
|
||||
SWIFT_STDLIB_PATH="${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
|
||||
BCSYMBOLMAP_DIR="BCSymbolMaps"
|
||||
|
||||
|
||||
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
|
||||
|
||||
# Copies and strips a vendored framework
|
||||
install_framework()
|
||||
{
|
||||
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$1"
|
||||
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
|
||||
elif [ -r "$1" ]; then
|
||||
local source="$1"
|
||||
fi
|
||||
|
||||
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
if [ -L "${source}" ]; then
|
||||
echo "Symlinked..."
|
||||
source="$(readlink -f "${source}")"
|
||||
fi
|
||||
|
||||
if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
|
||||
# Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
|
||||
find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
|
||||
echo "Installing $f"
|
||||
install_bcsymbolmap "$f" "$destination"
|
||||
rm "$f"
|
||||
done
|
||||
rmdir "${source}/${BCSYMBOLMAP_DIR}"
|
||||
fi
|
||||
|
||||
# Use filter instead of exclude so missing patterns don't throw errors.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .framework "$1")"
|
||||
binary="${destination}/${basename}.framework/${basename}"
|
||||
|
||||
if ! [ -r "$binary" ]; then
|
||||
binary="${destination}/${basename}"
|
||||
elif [ -L "${binary}" ]; then
|
||||
echo "Destination binary is symlinked..."
|
||||
dirname="$(dirname "${binary}")"
|
||||
binary="${dirname}/$(readlink "${binary}")"
|
||||
fi
|
||||
|
||||
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
||||
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
|
||||
strip_invalid_archs "$binary"
|
||||
fi
|
||||
|
||||
# Resign the code if required by the build settings to avoid unstable apps
|
||||
code_sign_if_enabled "${destination}/$(basename "$1")"
|
||||
|
||||
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
|
||||
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
|
||||
local swift_runtime_libs
|
||||
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
|
||||
for lib in $swift_runtime_libs; do
|
||||
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
|
||||
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
|
||||
code_sign_if_enabled "${destination}/${lib}"
|
||||
done
|
||||
fi
|
||||
}
|
||||
# Copies and strips a vendored dSYM
|
||||
install_dsym() {
|
||||
local source="$1"
|
||||
warn_missing_arch=${2:-true}
|
||||
if [ -r "$source" ]; then
|
||||
# Copy the dSYM into the targets temp dir.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .dSYM "$source")"
|
||||
binary_name="$(ls "$source/Contents/Resources/DWARF")"
|
||||
binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
|
||||
|
||||
# Strip invalid architectures from the dSYM.
|
||||
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
|
||||
strip_invalid_archs "$binary" "$warn_missing_arch"
|
||||
fi
|
||||
if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
|
||||
# Move the stripped file into its final destination.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
|
||||
else
|
||||
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
|
||||
mkdir -p "${DWARF_DSYM_FOLDER_PATH}"
|
||||
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Used as a return value for each invocation of `strip_invalid_archs` function.
|
||||
STRIP_BINARY_RETVAL=0
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
warn_missing_arch=${2:-true}
|
||||
# Get architectures for current target binary
|
||||
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
|
||||
# Intersect them with the architectures we are building for
|
||||
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
|
||||
# If there are no archs supported by this binary then warn the user
|
||||
if [[ -z "$intersected_archs" ]]; then
|
||||
if [[ "$warn_missing_arch" == "true" ]]; then
|
||||
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=1
|
||||
return
|
||||
fi
|
||||
stripped=""
|
||||
for arch in $binary_archs; do
|
||||
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary"
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=0
|
||||
}
|
||||
|
||||
# Copies the bcsymbolmap files of a vendored framework
|
||||
install_bcsymbolmap() {
|
||||
local bcsymbolmap_path="$1"
|
||||
local destination="${BUILT_PRODUCTS_DIR}"
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
|
||||
}
|
||||
|
||||
# Signs a framework with the provided identity
|
||||
code_sign_if_enabled() {
|
||||
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
|
||||
# Use the current code_sign_identity
|
||||
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
|
||||
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
|
||||
|
||||
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
|
||||
code_sign_cmd="$code_sign_cmd &"
|
||||
fi
|
||||
echo "$code_sign_cmd"
|
||||
eval "$code_sign_cmd"
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/ShortcutRecorder/ShortcutRecorder.framework"
|
||||
fi
|
||||
if [[ "$CONFIGURATION" == "Release" ]]; then
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/ShortcutRecorder/ShortcutRecorder.framework"
|
||||
fi
|
||||
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
|
||||
wait
|
||||
fi
|
||||
@@ -11,6 +11,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
FOUNDATION_EXPORT double SwiftyMarkdownVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char SwiftyMarkdownVersionString[];
|
||||
FOUNDATION_EXPORT double Pods_unit_testsVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char Pods_unit_testsVersionString[];
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder/ShortcutRecorder.framework/Headers"
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/../Frameworks'
|
||||
OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder/ShortcutRecorder.framework/Headers" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder"
|
||||
OTHER_LDFLAGS = $(inherited) -framework "Carbon" -framework "Cocoa" -framework "ShortcutRecorder"
|
||||
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -0,0 +1,6 @@
|
||||
framework module Pods_unit_tests {
|
||||
umbrella header "Pods-unit-tests-umbrella.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder/ShortcutRecorder.framework/Headers"
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/../Frameworks'
|
||||
OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder/ShortcutRecorder.framework/Headers" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder"
|
||||
OTHER_LDFLAGS = $(inherited) -framework "Carbon" -framework "Cocoa" -framework "ShortcutRecorder"
|
||||
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CODE_SIGN_IDENTITY =
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
OTHER_LDFLAGS = $(inherited) -framework "Carbon" -framework "Cocoa"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/ShortcutRecorder
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -1,11 +1,14 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CODE_SIGN_IDENTITY =
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/ShortcutRecorder
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
OTHER_LDFLAGS = $(inherited) -framework "Carbon" -framework "Cocoa"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/ShortcutRecorder
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
function on_error {
|
||||
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
|
||||
}
|
||||
trap 'on_error $LINENO' ERR
|
||||
|
||||
# Used as a return value for each invocation of `strip_invalid_archs` function.
|
||||
STRIP_BINARY_RETVAL=0
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
warn_missing_arch=${2:-true}
|
||||
# Get architectures for current target binary
|
||||
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
|
||||
# Intersect them with the architectures we are building for
|
||||
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
|
||||
# If there are no archs supported by this binary then warn the user
|
||||
if [[ -z "$intersected_archs" ]]; then
|
||||
if [[ "$warn_missing_arch" == "true" ]]; then
|
||||
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=1
|
||||
return
|
||||
fi
|
||||
stripped=""
|
||||
for arch in $binary_archs; do
|
||||
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary"
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=0
|
||||
}
|
||||
|
||||
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
|
||||
|
||||
# Copies and strips a vendored dSYM
|
||||
install_dsym() {
|
||||
local source="$1"
|
||||
warn_missing_arch=${2:-true}
|
||||
if [ -r "$source" ]; then
|
||||
# Copy the dSYM into the targets temp dir.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .dSYM "$source")"
|
||||
binary_name="$(ls "$source/Contents/Resources/DWARF")"
|
||||
binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
|
||||
|
||||
# Strip invalid architectures from the dSYM.
|
||||
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
|
||||
strip_invalid_archs "$binary" "$warn_missing_arch"
|
||||
fi
|
||||
if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
|
||||
# Move the stripped file into its final destination.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
|
||||
else
|
||||
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
|
||||
mkdir -p "${DWARF_DSYM_FOLDER_PATH}"
|
||||
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Copies the bcsymbolmap files of a vendored framework
|
||||
install_bcsymbolmap() {
|
||||
local bcsymbolmap_path="$1"
|
||||
local destination="${BUILT_PRODUCTS_DIR}"
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
|
||||
}
|
||||
|
||||
install_dsym "${PODS_ROOT}/Sparkle/Sparkle.framework.dSYM"
|
||||
@@ -1,3 +1,4 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CODE_SIGN_IDENTITY =
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Sparkle
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Sparkle"
|
||||
@@ -5,8 +6,10 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) @loader_path/../Frameworks
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/Sparkle
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -1,3 +1,4 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CODE_SIGN_IDENTITY =
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Sparkle
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Sparkle"
|
||||
@@ -5,8 +6,10 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) @loader_path/../Frameworks
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/Sparkle
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CODE_SIGN_IDENTITY =
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -suppress-warnings
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftyBeaver
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -1,11 +1,15 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CODE_SIGN_IDENTITY =
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyBeaver
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -suppress-warnings
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftyBeaver
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -1,5 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_SwiftyMarkdown : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_SwiftyMarkdown
|
||||
@end
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#else
|
||||
#ifndef FOUNDATION_EXPORT
|
||||
#if defined(__cplusplus)
|
||||
#define FOUNDATION_EXPORT extern "C"
|
||||
#else
|
||||
#define FOUNDATION_EXPORT extern
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
CODE_SIGN_IDENTITY =
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMarkdown
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftyMarkdown
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -1,6 +0,0 @@
|
||||
framework module SwiftyMarkdown {
|
||||
umbrella header "SwiftyMarkdown-umbrella.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
CODE_SIGN_IDENTITY =
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMarkdown
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftyMarkdown
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -1,7 +1,19 @@
|
||||
<div align = center>
|
||||
|
||||
# AltTab
|
||||
|
||||
[](docs/public/demo/frontpage.jpg)
|
||||
|
||||
**AltTab** brings the power of Windows alt-tab to macOS
|
||||
|
||||
[Find out more on the official website](https://alt-tab-macos.netlify.app/)
|
||||
[Official website](https://alt-tab-macos.netlify.app/)<br/><sub>14K stars</sub> | [Download](https://github.com/lwouis/alt-tab-macos/releases/download/v8.3.3/AltTab-8.3.3.zip)<br/><sub>6.6M downloads</sub>
|
||||
-|-
|
||||
|
||||
<div align="right">
|
||||
<p>Project supported by</p>
|
||||
<a href="https://jb.gg/OpenSource">
|
||||
<img src="docs/public/demo/jetbrains.svg" alt="Jetbrains" width="149" height="32">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1130"
|
||||
LastUpgradeVersion = "1620"
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -37,7 +37,7 @@
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugDocumentVersioning = "NO"
|
||||
debugServiceExtension = "internal"
|
||||
enableGPUValidationMode = "1"
|
||||
allowLocationSimulation = "YES">
|
||||
@@ -51,6 +51,12 @@
|
||||
ReferencedContainer = "container:alt-tab-macos.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<CommandLineArguments>
|
||||
<CommandLineArgument
|
||||
argument = "--logs=info"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
</CommandLineArguments>
|
||||
<LocationScenarioReference
|
||||
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
|
||||
referenceType = "1">
|
||||
@@ -62,6 +68,16 @@
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D04BA5E73DAF232ADE11C97A"
|
||||
BuildableName = "AltTab.app"
|
||||
BlueprintName = "alt-tab-macos"
|
||||
ReferencedContainer = "container:alt-tab-macos.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1620"
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "BF0C873EC188A7EBBCF4310D"
|
||||
BuildableName = "unit-tests.xctest"
|
||||
BlueprintName = "unit-tests"
|
||||
ReferencedContainer = "container:alt-tab-macos.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "NO">
|
||||
<EnvironmentVariables>
|
||||
<EnvironmentVariable
|
||||
key = ""
|
||||
value = ""
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO"
|
||||
parallelizable = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "BF0C873EC188A7EBBCF4310D"
|
||||
BuildableName = "unit-tests.xctest"
|
||||
BlueprintName = "unit-tests"
|
||||
ReferencedContainer = "container:alt-tab-macos.xcodeproj">
|
||||
</BuildableReference>
|
||||
<LocationScenarioReference
|
||||
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
|
||||
referenceType = "1">
|
||||
</LocationScenarioReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<LocationScenarioReference
|
||||
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
|
||||
referenceType = "1">
|
||||
</LocationScenarioReference>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -4,6 +4,762 @@
|
||||
<title>alt-tab-macos</title>
|
||||
<language>en</language>
|
||||
|
||||
<item>
|
||||
<title>Version 8.3.3</title>
|
||||
<pubDate>Sun, 25 Jan 2026 21:23:56 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v8.3.3/AltTab-8.3.3.zip"
|
||||
sparkle:version="8.3.3"
|
||||
sparkle:shortVersionString="8.3.3"
|
||||
sparkle:edSignature="56edeQ0CPAyClzRH9vK+xnwn79CvRH8w4tEsVMRNT8Qjja8cv/Q9aYqkPXRFaXR74wY9ogFqzPFK+NZoVf8gAg==" length="12107335"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 8.3.2</title>
|
||||
<pubDate>Thu, 22 Jan 2026 23:33:49 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v8.3.2/AltTab-8.3.2.zip"
|
||||
sparkle:version="8.3.2"
|
||||
sparkle:shortVersionString="8.3.2"
|
||||
sparkle:edSignature="ojwCSKUiwD/Xk4DL/1bFn8TEJahuvjfGJ5aALCUx/DDvwUl8313ECXaNTHKZ58W/RA1QYrk8jjv3kLl4JqiYCQ==" length="12103858"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 8.3.1</title>
|
||||
<pubDate>Thu, 22 Jan 2026 21:47:18 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v8.3.1/AltTab-8.3.1.zip"
|
||||
sparkle:version="8.3.1"
|
||||
sparkle:shortVersionString="8.3.1"
|
||||
sparkle:edSignature="4Usbj7WgaPmzkW9vj4rOAQLxcXymN8sOrQnJJgvh9xahyFi3EBS1R/jrA/FQx6R9YFbebzMkZMVnyhrdVg7/Bw==" length="12102360"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 8.3.0</title>
|
||||
<pubDate>Tue, 20 Jan 2026 17:58:52 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v8.3.0/AltTab-8.3.0.zip"
|
||||
sparkle:version="8.3.0"
|
||||
sparkle:shortVersionString="8.3.0"
|
||||
sparkle:edSignature="1fb/o7iUv3OCQxm+BLlq7mZGXhwCv4/xDmR6RmPLfJ47S4Cy8ui32VQEnePfA7JtHP6z/ZLGVvC3aETKbG/QCA==" length="12095858"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 8.2.0</title>
|
||||
<pubDate>Thu, 15 Jan 2026 18:01:36 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v8.2.0/AltTab-8.2.0.zip"
|
||||
sparkle:version="8.2.0"
|
||||
sparkle:shortVersionString="8.2.0"
|
||||
sparkle:edSignature="k3DXj6SOQDYxMFOqVzwWC4pwJOdEd2/GOe8wzOi6z4ITkKIviEGm3o+5w0e6ECR3Gd4eAC0+N5NzItupXClIDg==" length="12102733"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 8.1.0</title>
|
||||
<pubDate>Wed, 14 Jan 2026 23:19:00 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v8.1.0/AltTab-8.1.0.zip"
|
||||
sparkle:version="8.1.0"
|
||||
sparkle:shortVersionString="8.1.0"
|
||||
sparkle:edSignature="PeL1FVtC8wV+tB4hl8mSKn96EYCls/c+iyb1bYGDm8EcJl/acFtTyMaAMq8LzIOtLv3Q6C4aNPqyXWTSIGRyDg==" length="12103907"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 8.0.0</title>
|
||||
<pubDate>Tue, 06 Jan 2026 18:36:14 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v8.0.0/AltTab-8.0.0.zip"
|
||||
sparkle:version="8.0.0"
|
||||
sparkle:shortVersionString="8.0.0"
|
||||
sparkle:edSignature="d4RDsNE+p13oq+BWEsuylv1T1wsIR36e72uTT4ge4ynaNX4pD9jUY1QQCUNe1HK3Dg78vl8gvjQHcriZFaGjBQ==" length="12095023"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.39.0</title>
|
||||
<pubDate>Sat, 03 Jan 2026 18:22:52 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.39.0/AltTab-7.39.0.zip"
|
||||
sparkle:version="7.39.0"
|
||||
sparkle:shortVersionString="7.39.0"
|
||||
sparkle:edSignature="Cq61dj1IouJja0FIWp1F6HFBXYg4Efsij0Xq75G5iFY/o6j02mGOtnIFFx0bWuLjt5I9PzsD7dN9izsoi72gAw==" length="12054195"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.38.1</title>
|
||||
<pubDate>Sat, 13 Dec 2025 19:15:05 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.38.1/AltTab-7.38.1.zip"
|
||||
sparkle:version="7.38.1"
|
||||
sparkle:shortVersionString="7.38.1"
|
||||
sparkle:edSignature="U2y/vJ0QU4BOlfO8XYFQuNWnKaPgLsSfHmptf31MgJInApaUu3OWTi1LSJVyxrLYYHy/bTroxNUy1JMO3y7QBA==" length="12055563"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.38.0</title>
|
||||
<pubDate>Sun, 07 Dec 2025 11:40:11 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.38.0/AltTab-7.38.0.zip"
|
||||
sparkle:version="7.38.0"
|
||||
sparkle:shortVersionString="7.38.0"
|
||||
sparkle:edSignature="434T6MFU7nzI9df8UoMKhuS6K1VIXpLzLebIrYlRJoyI3oHe+9t+2+JnDKL4+yCPv8ROmkNflum0dFd31mshDg==" length="12055145"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.37.0</title>
|
||||
<pubDate>Fri, 28 Nov 2025 23:07:24 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.37.0/AltTab-7.37.0.zip"
|
||||
sparkle:version="7.37.0"
|
||||
sparkle:shortVersionString="7.37.0"
|
||||
sparkle:edSignature="hlFs3CoK+I4wE2JWVpLVMSleEv41TIuoJkIBDw5khS1bf+RF02Ox6XUF6a9f8GZOuIKxDhT8xEwwmR3gdsqYBQ==" length="11982409"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.36.0</title>
|
||||
<pubDate>Tue, 25 Nov 2025 08:56:19 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.36.0/AltTab-7.36.0.zip"
|
||||
sparkle:version="7.36.0"
|
||||
sparkle:shortVersionString="7.36.0"
|
||||
sparkle:edSignature="E1DX+8VVWQm8yz7eoAAf7EeCiRwk/1sou5DwLhgPAGN047tSY0Ue4Naa4ksGqL/wm+2THrZtE34WvMuyjQgtDQ==" length="11976119"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.35.0</title>
|
||||
<pubDate>Mon, 24 Nov 2025 22:30:26 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.35.0/AltTab-7.35.0.zip"
|
||||
sparkle:version="7.35.0"
|
||||
sparkle:shortVersionString="7.35.0"
|
||||
sparkle:edSignature="XB9XpgmAfpOcwTzvMMQ20C/puBCOM60o5sOrazrvoJzFxhN7tOFPkMabTD3fgksb36mi0bUB4u77VUw4maqMAw==" length="11976052"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.34.0</title>
|
||||
<pubDate>Thu, 20 Nov 2025 23:27:29 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.34.0/AltTab-7.34.0.zip"
|
||||
sparkle:version="7.34.0"
|
||||
sparkle:shortVersionString="7.34.0"
|
||||
sparkle:edSignature="3oF5l++qYAolRZesZe4zJPqW6fQF6Ey1LKYOY3eneesGBVsFllWjQTnDwpJ5m//ECu7NA4fqibQP5KzstPAqAw==" length="11973772"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.33.0</title>
|
||||
<pubDate>Sun, 16 Nov 2025 17:57:15 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.33.0/AltTab-7.33.0.zip"
|
||||
sparkle:version="7.33.0"
|
||||
sparkle:shortVersionString="7.33.0"
|
||||
sparkle:edSignature="19AxsBTeotGHqI+AWpkTapwWeDwc/S6xaIkknBjMNqEsKvezlCX5CLQBPr6uC5ozPzlYUK9Lv0Y6wdP870HEAQ==" length="11995420"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.32.0</title>
|
||||
<pubDate>Mon, 10 Nov 2025 19:56:35 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.32.0/AltTab-7.32.0.zip"
|
||||
sparkle:version="7.32.0"
|
||||
sparkle:shortVersionString="7.32.0"
|
||||
sparkle:edSignature="GjhqV7w7fdj9RycWPS1AmsK05DwIu7TAAW1qTHsye3QYO7gy0KLW6D67dx4AwJSrZyhX7xIA1XIVtoZNge0ICQ==" length="11986568"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.31.0</title>
|
||||
<pubDate>Sun, 26 Oct 2025 16:45:12 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.31.0/AltTab-7.31.0.zip"
|
||||
sparkle:version="7.31.0"
|
||||
sparkle:shortVersionString="7.31.0"
|
||||
sparkle:edSignature="oB5HVUPVAsXqPmFPMSKOEgvSAUIb3bPx0O3bCsxhAIyaDB65khFrG5GbjeOHfxzJUSEaKi0Mqnjv8Zra7fA+DA==" length="11969676"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.30.0</title>
|
||||
<pubDate>Tue, 23 Sep 2025 22:05:12 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.30.0/AltTab-7.30.0.zip"
|
||||
sparkle:version="7.30.0"
|
||||
sparkle:shortVersionString="7.30.0"
|
||||
sparkle:edSignature="6KhCnriRms8qeHxh4k0Pk4p0w4aJyPcfCOG9KRSUwA1DrGYTs7Acr26zbc1qJyr5dcoPm5cMuKgbqrQLv+3HAA==" length="12145187"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.29.0</title>
|
||||
<pubDate>Sat, 20 Sep 2025 13:15:19 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.29.0/AltTab-7.29.0.zip"
|
||||
sparkle:version="7.29.0"
|
||||
sparkle:shortVersionString="7.29.0"
|
||||
sparkle:edSignature="wbKh9oVfM0z9m0+WQ5O03ZKoGbthPXTPkYi4/JdRxTLZ2nEtNYiNYOqqBv7EHUQvUjEAQDsGMKSfDQ9HGE52Bw==" length="12146186"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.28.0</title>
|
||||
<pubDate>Mon, 15 Sep 2025 20:18:19 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.28.0/AltTab-7.28.0.zip"
|
||||
sparkle:version="7.28.0"
|
||||
sparkle:shortVersionString="7.28.0"
|
||||
sparkle:edSignature="ey5vKahrE3K1JxAhFqG3VpBFLKZE1Fc5sTMAupn8N/yxYFlTI9NvnkDYogWr7WK8dqyqIqdv6KzfhHlqUzRaAw==" length="12143852"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.27.0</title>
|
||||
<pubDate>Tue, 12 Aug 2025 20:02:48 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.27.0/AltTab-7.27.0.zip"
|
||||
sparkle:version="7.27.0"
|
||||
sparkle:shortVersionString="7.27.0"
|
||||
sparkle:edSignature="HsWTurDRRgJtSXzbkuNFSJQvaDVOV+toiG28vkeHezZwqrV8pY3ysBUwQHju2YpvjSZ0Up9AvReFlb8pCdI4Cw==" length="12102965"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.26.0</title>
|
||||
<pubDate>Thu, 31 Jul 2025 17:55:14 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.26.0/AltTab-7.26.0.zip"
|
||||
sparkle:version="7.26.0"
|
||||
sparkle:shortVersionString="7.26.0"
|
||||
sparkle:edSignature="TRUr+e8GhQvKR8QZUNU3ovE1tJp3u7ZvEDiYyqWR77BGiiWCjYWWUsSua5fi3nSdxbDmn8C585z/CUn+UdwKDg==" length="12103981"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.25.0</title>
|
||||
<pubDate>Sat, 14 Jun 2025 12:29:16 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.25.0/AltTab-7.25.0.zip"
|
||||
sparkle:version="7.25.0"
|
||||
sparkle:shortVersionString="7.25.0"
|
||||
sparkle:edSignature="zVmu83QeFQxeMZ9Hmu5vNekfH9eCBjlA57a86i8PWqF2MhRLYdiyff7+8GXScV8BlPL9OXRhWu+Jsccm7DGnCQ==" length="12186853"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.24.0</title>
|
||||
<pubDate>Mon, 05 May 2025 10:07:18 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.24.0/AltTab-7.24.0.zip"
|
||||
sparkle:version="7.24.0"
|
||||
sparkle:shortVersionString="7.24.0"
|
||||
sparkle:edSignature="JxlIuuTXU/fB+BEN8ocloYWHHl6HNsQ4h6N53XpsiCvHySn5zANTOQh1fcTKpBCRffT4krnNjZnmN/7GVGV4CQ==" length="12164288"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.23.0</title>
|
||||
<pubDate>Tue, 01 Apr 2025 21:38:22 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.23.0/AltTab-7.23.0.zip"
|
||||
sparkle:version="7.23.0"
|
||||
sparkle:shortVersionString="7.23.0"
|
||||
sparkle:edSignature="nZ8zV82o2r1GWHBm2giFxIuy5w9JTyk679exNA6BguFIY2nkNb6L0O88RH7uNwHsGHNi6aFWmQZZsdsoa10pDg==" length="12163382"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.22.0</title>
|
||||
<pubDate>Sun, 30 Mar 2025 00:58:16 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.22.0/AltTab-7.22.0.zip"
|
||||
sparkle:version="7.22.0"
|
||||
sparkle:shortVersionString="7.22.0"
|
||||
sparkle:edSignature="fAiZFmWoT/ztme+hksTS4yz6hwrqzI1ENoHNxIlkbpSbPZay9hY43G7TPCK27BOl3IjNWa69lYv6joeQF9XWAA==" length="12162891"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.21.1</title>
|
||||
<pubDate>Sat, 22 Feb 2025 09:54:40 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.21.1/AltTab-7.21.1.zip"
|
||||
sparkle:version="7.21.1"
|
||||
sparkle:shortVersionString="7.21.1"
|
||||
sparkle:edSignature="UEqTVG5Fzcv9w02PhssjZXX0VpWTqanAyZjhaQDQxakVLPdPTu+jpqXXpEBghEW3Nh8YpSvHY2lyftbgheMNBg==" length="12162502"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.21.0</title>
|
||||
<pubDate>Fri, 21 Feb 2025 21:33:30 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.21.0/AltTab-7.21.0.zip"
|
||||
sparkle:version="7.21.0"
|
||||
sparkle:shortVersionString="7.21.0"
|
||||
sparkle:edSignature="dfPd4U2SuNa1Uilb2GVrT8AQjFG9TyKJMUoZYIPSWwrk00x21BWT7nGSuyzCNX7Cp6PHL+eKCPwqqAUdJ0GACw==" length="12162404"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.20.1</title>
|
||||
<pubDate>Thu, 20 Feb 2025 07:11:47 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.20.1/AltTab-7.20.1.zip"
|
||||
sparkle:version="7.20.1"
|
||||
sparkle:shortVersionString="7.20.1"
|
||||
sparkle:edSignature="GwLmwzRnOV+J5iEgUR1bcbno4de+pUvm88Idic1XQnS0Ip4SgSSDBUdYnom+dYw1+DYj/f8k304avXpQIKWcAw==" length="12156264"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.20.0</title>
|
||||
<pubDate>Wed, 19 Feb 2025 17:48:04 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.20.0/AltTab-7.20.0.zip"
|
||||
sparkle:version="7.20.0"
|
||||
sparkle:shortVersionString="7.20.0"
|
||||
sparkle:edSignature="9013fqFT5XMbV2o8rYEXpH+9YT2RWwPxv/dVhviIvEd7YqWYncWClFOfKSF6+VouHh07zEfsG3ABxOaDnt9yDQ==" length="12153372"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.19.1</title>
|
||||
<pubDate>Tue, 14 Jan 2025 21:43:35 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.19.1/AltTab-7.19.1.zip"
|
||||
sparkle:version="7.19.1"
|
||||
sparkle:shortVersionString="7.19.1"
|
||||
sparkle:edSignature="9YlS2uLqpeMMwn9RmQnWOUPA0rgTWkeHuFxmDb7J3yQjgfvJaRokU/xKAXzmImtlmJbPyR+9CY0WR894RcPwCg==" length="12138856"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.19.0</title>
|
||||
<pubDate>Tue, 14 Jan 2025 17:36:58 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.19.0/AltTab-7.19.0.zip"
|
||||
sparkle:version="7.19.0"
|
||||
sparkle:shortVersionString="7.19.0"
|
||||
sparkle:edSignature="MUe0qIFuaoT8TgiFXTEqTibw9LjyWQzJRu5eLAvtkSyqVq6Cve+TZJlbXZRf1f5FvJH4686aFoj5aTcVXTg1BQ==" length="12141162"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.18.1</title>
|
||||
<pubDate>Sun, 12 Jan 2025 21:32:56 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.18.1/AltTab-7.18.1.zip"
|
||||
sparkle:version="7.18.1"
|
||||
sparkle:shortVersionString="7.18.1"
|
||||
sparkle:edSignature="Uqk4OcpGZOs0w19yUVnIu0laU4TO88b2yXWVaBTcNv2JnAjzWJ14YU0yt0hKvvDpc4tYzJC9mK5+4Pkk672UDQ==" length="12139298"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.18.0</title>
|
||||
<pubDate>Tue, 07 Jan 2025 00:20:42 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.18.0/AltTab-7.18.0.zip"
|
||||
sparkle:version="7.18.0"
|
||||
sparkle:shortVersionString="7.18.0"
|
||||
sparkle:edSignature="oLLPFUpBFVGf5/3lSmOv82+QYWAGdMrj2g6/RTnX7l3gHzX6seewAgCmNYPXIIQC/BwKmUVot7sDL7HleNn1Ag==" length="12137782"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.17.0</title>
|
||||
<pubDate>Sun, 05 Jan 2025 18:28:41 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.17.0/AltTab-7.17.0.zip"
|
||||
sparkle:version="7.17.0"
|
||||
sparkle:shortVersionString="7.17.0"
|
||||
sparkle:edSignature="59aUXQn630CpP1He4qRtQsrnOSodWdfcsrhej324myFYUeIPnfnp7biwv8vkMV8m6PJx546KSe/iLtX08E4aBQ==" length="12138297"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.16.0</title>
|
||||
<pubDate>Sat, 04 Jan 2025 01:31:25 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.16.0/AltTab-7.16.0.zip"
|
||||
sparkle:version="7.16.0"
|
||||
sparkle:shortVersionString="7.16.0"
|
||||
sparkle:edSignature="7Jsnp1f6p+DSyonDKYdp5VQk7Vlto6ft40SiZBNyiRKqAAf5RNKWCVp84P0QQjIH05DXRQczYcN3LdeiECRwAw==" length="12110300"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.15.0</title>
|
||||
<pubDate>Thu, 02 Jan 2025 18:33:13 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.15.0/AltTab-7.15.0.zip"
|
||||
sparkle:version="7.15.0"
|
||||
sparkle:shortVersionString="7.15.0"
|
||||
sparkle:edSignature="Xy+k6PjRmJVtsoikBI4qP3DPzmqOW5E5mtLOIIKG9dBSk02d4m+xg0idhBVt+T70z7X6qyRXHV6VyZ8drC63DQ==" length="12100003"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.14.1</title>
|
||||
<pubDate>Sat, 28 Dec 2024 18:25:55 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.14.1/AltTab-7.14.1.zip"
|
||||
sparkle:version="7.14.1"
|
||||
sparkle:shortVersionString="7.14.1"
|
||||
sparkle:edSignature="tgixbmM1Fu8iDGd3saBJr/9bontPn8gLY5IfTvuffHa7BbWGpvsW5bd8wwiJ3NPhu+U5vv1U1zpGB44OQYNYCg==" length="12092272"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.14.0</title>
|
||||
<pubDate>Thu, 26 Dec 2024 23:41:11 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.14.0/AltTab-7.14.0.zip"
|
||||
sparkle:version="7.14.0"
|
||||
sparkle:shortVersionString="7.14.0"
|
||||
sparkle:edSignature="SD1YUCytnXNlKC6JUK/y8pS9JelriXGKRgqXl7DOBQ6Twd6qhnFv6GMk//Cs99j6u0tofgzfP9c+Y2eRuaUrAQ==" length="12093683"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.13.1</title>
|
||||
<pubDate>Tue, 24 Dec 2024 09:01:53 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.13.1/AltTab-7.13.1.zip"
|
||||
sparkle:version="7.13.1"
|
||||
sparkle:shortVersionString="7.13.1"
|
||||
sparkle:edSignature="+tsgUEklyfLHIA/eeLE0AciHB8lb9PQp6PIuWUpEIfTA8yCBZ0kuvkdXiMpLGgFvJ5bhTLZuCuKO1GqiD4fBDA==" length="12079557"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.13.0</title>
|
||||
<pubDate>Tue, 24 Dec 2024 01:55:31 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.13.0/AltTab-7.13.0.zip"
|
||||
sparkle:version="7.13.0"
|
||||
sparkle:shortVersionString="7.13.0"
|
||||
sparkle:edSignature="fiMWHtfHP7EIvpwxKp9aQF1yDQ1JpwmGs6pXhB+/FGkfDlscawBwT9F7MSMvufeg0vpw8yVNTkC7pYQqv9MGAw==" length="12126150"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.12.0</title>
|
||||
<pubDate>Wed, 11 Dec 2024 20:58:56 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.12.0/AltTab-7.12.0.zip"
|
||||
sparkle:version="7.12.0"
|
||||
sparkle:shortVersionString="7.12.0"
|
||||
sparkle:edSignature="mYrYwigM3UaCOfZcQXk6MYVsqofKUXsr9AjBl5QHQVFJKS/EP8qPKiezcL3GaJ+4fK8LCk8mD5LdWforVtBKAg==" length="12150844"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.11.0</title>
|
||||
<pubDate>Mon, 09 Dec 2024 23:06:13 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.11.0/AltTab-7.11.0.zip"
|
||||
sparkle:version="7.11.0"
|
||||
sparkle:shortVersionString="7.11.0"
|
||||
sparkle:edSignature="Re4huA4wp46GMiz3SHGlT3EJuDZf6wD/7z3RmH+nnR3HO9u9efI4TJajvS3ii1XIyOYV4eJ9xPQcvEY0+UyxBw==" length="12380040"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.10.0</title>
|
||||
<pubDate>Sun, 08 Dec 2024 11:36:39 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.10.0/AltTab-7.10.0.zip"
|
||||
sparkle:version="7.10.0"
|
||||
sparkle:shortVersionString="7.10.0"
|
||||
sparkle:edSignature="gdYgXVU7thyfcnZnwWOifgjcl6b53rCEatHJAoCLq+piPET51DKcgkISjyITfv8I9jv25C8Nv1Rpp6LWMtylDA==" length="12352003"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.9.0</title>
|
||||
<pubDate>Sat, 07 Dec 2024 17:17:46 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.9.0/AltTab-7.9.0.zip"
|
||||
sparkle:version="7.9.0"
|
||||
sparkle:shortVersionString="7.9.0"
|
||||
sparkle:edSignature="NxJ+HI2NXMtYV0tzUW8Bo2oe9wlC+8GA5xBxJ07LMVhqZunAPd/ttweXL2Ta/IHNLPIP97lhozteuHNRj1iXDA==" length="12351354"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.8.0</title>
|
||||
<pubDate>Fri, 06 Dec 2024 16:44:34 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.8.0/AltTab-7.8.0.zip"
|
||||
sparkle:version="7.8.0"
|
||||
sparkle:shortVersionString="7.8.0"
|
||||
sparkle:edSignature="nKxDI2dJryWHHpTMFMMi5w3L3KSGGJKBz1AIrOOUB0IHv6YVr6tR4P9LOhQEeyHd4ciDoXrG50VU1K1WipNkDA==" length="12347668"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.7.0</title>
|
||||
<pubDate>Tue, 03 Dec 2024 23:26:56 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.7.0/AltTab-7.7.0.zip"
|
||||
sparkle:version="7.7.0"
|
||||
sparkle:shortVersionString="7.7.0"
|
||||
sparkle:edSignature="ZE+SO2mqNir8X3Pr78Lddx6UvLbiPKjX5IzSM1ITYEHf6cTeCng/Trfyo1+KJ88BxjR21JI21JQjHTvzDNo3Dw==" length="12357485"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.6.0</title>
|
||||
<pubDate>Sun, 01 Dec 2024 21:24:26 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.6.0/AltTab-7.6.0.zip"
|
||||
sparkle:version="7.6.0"
|
||||
sparkle:shortVersionString="7.6.0"
|
||||
sparkle:edSignature="Hl+KgePFoGrahMpI6Q0M9jrJeXh4qn7ChWz5J3TcgkMzazGhRSA6JYaXvSaHCRE5iMfeyVmlwA7kNMH3+g1cCA==" length="12376002"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.5.0</title>
|
||||
<pubDate>Wed, 27 Nov 2024 09:55:37 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.5.0/AltTab-7.5.0.zip"
|
||||
sparkle:version="7.5.0"
|
||||
sparkle:shortVersionString="7.5.0"
|
||||
sparkle:edSignature="w3wJtC8B4NHuoniSZNqlz5m/Me698GyOR6hYU/UNlzXqCj9rfsh+PAF47PlLliX3fI/dCi5EMFqa0S8TrZZiAA==" length="12335380"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.4.0</title>
|
||||
<pubDate>Sat, 16 Nov 2024 15:47:33 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.4.0/AltTab-7.4.0.zip"
|
||||
sparkle:version="7.4.0"
|
||||
sparkle:shortVersionString="7.4.0"
|
||||
sparkle:edSignature="DRiH4Nx9MoqQOmL0Ow/aPacNDR7Av94hiSPbMRlZUCVSDfDVA6lXIfUO54/pbY5Me5ZoiGK9Yy5iyKGFmNOfDw==" length="12324503"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.3.0</title>
|
||||
<pubDate>Sun, 10 Nov 2024 18:02:28 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.3.0/AltTab-7.3.0.zip"
|
||||
sparkle:version="7.3.0"
|
||||
sparkle:shortVersionString="7.3.0"
|
||||
sparkle:edSignature="GWMrm8hFMm9Qb2wwxe5xRrMqNYvVJj30q4cJ/5+75U7mG8yzwEZtoOqc7uPP+cIbbraqG8fkApwOiTWK5MuNCA==" length="12323536"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.2.0</title>
|
||||
<pubDate>Mon, 04 Nov 2024 22:54:42 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.2.0/AltTab-7.2.0.zip"
|
||||
sparkle:version="7.2.0"
|
||||
sparkle:shortVersionString="7.2.0"
|
||||
sparkle:edSignature="U8AGYMeIV29JN7si+OM/yxMzii5vI0debFImN0rdnOVFusNEyN2Uh96zvGVt4aHguPcyoeZep/1KeeCT5J/EAg==" length="12310766"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.1.1</title>
|
||||
<pubDate>Sun, 03 Nov 2024 00:28:20 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.1.1/AltTab-7.1.1.zip"
|
||||
sparkle:version="7.1.1"
|
||||
sparkle:shortVersionString="7.1.1"
|
||||
sparkle:edSignature="YuKAiP2T6nZa39kIDVHrPPTAXbIGO8sr08hRf/bDf4Z5/AvMxrU/IAYXkdah0UlcQPfeV1uY+vCH+OwgpPxgBQ==" length="12291608"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.1.0</title>
|
||||
<pubDate>Sat, 02 Nov 2024 21:32:24 +0000</pubDate>
|
||||
<sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion>
|
||||
<sparkle:releaseNotesLink>https://alt-tab-macos.netlify.app/changelog-bare</sparkle:releaseNotesLink>
|
||||
<enclosure
|
||||
url="https://github.com/lwouis/alt-tab-macos/releases/download/v7.1.0/AltTab-7.1.0.zip"
|
||||
sparkle:version="7.1.0"
|
||||
sparkle:shortVersionString="7.1.0"
|
||||
sparkle:edSignature="1tj7Jsrl5kkjHwlSvgP9xvHfXyG5bgpoI37GrvvsgKv65HKyB5GqlmOu99zlki46SDrvplxQsb+GTb0RV/umBg==" length="12311574"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Version 7.0.2</title>
|
||||
<pubDate>Sat, 12 Oct 2024 11:09:58 +0000</pubDate>
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
PRODUCT_NAME = AltTab
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lwouis.alt-tab-macos
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.12
|
||||
SWIFT_VERSION = 5.8
|
||||
SWIFT_VERSION = 5.8 // xcode 14.2 translates this to 5.0; xcode 16.2 as 5.8
|
||||
SWIFT_TREAT_WARNINGS_AS_ERRORS = YES
|
||||
INFOPLIST_FILE = Info.plist
|
||||
CODE_SIGN_ENTITLEMENTS = alt_tab_macos.entitlements
|
||||
FRAMEWORK_SEARCH_PATHS[config=*] = $(inherited) /System/Library/PrivateFrameworks // for SkyLight.framework
|
||||
@@ -13,4 +14,6 @@ INFOPLIST_OUTPUT_FORMAT = binary
|
||||
PLIST_FILE_OUTPUT_FORMAT = binary
|
||||
COCOAPODS_PARALLEL_CODE_SIGN = YES // codesign pods faster
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES
|
||||
SWIFT_OBJC_BRIDGING_HEADER = alt-tab-macos-Bridging-Header.h
|
||||
SWIFT_OBJC_BRIDGING_HEADER = alt-tab-macos-Bridging-Header.h
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES
|
||||
DEAD_CODE_STRIPPING = YES
|
||||
@@ -7,3 +7,4 @@ CODE_SIGN_IDENTITY = Local Self-Signed
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG // for macro `#if DEBUG`
|
||||
OTHER_SWIFT_FLAGS = -driver-time-compilation -Xfrontend -warn-long-function-bodies=250 -Xfrontend -warn-long-expression-type-checking=250 // find slow compilation areas
|
||||
OTHER_CODE_SIGN_FLAGS = --timestamp=none
|
||||
SWIFT_COMPILATION_MODE = incremental
|
||||
@@ -6,3 +6,5 @@
|
||||
CODE_SIGN_IDENTITY = Developer ID Application: Louis Pontoise (QXD7GW8FHY)
|
||||
CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO // for notarization
|
||||
OTHER_CODE_SIGN_FLAGS = --timestamp --deep --options runtime // for notarization
|
||||
SWIFT_COMPILATION_MODE = wholemodule
|
||||
SWIFT_OPTIMIZATION_LEVEL = -O
|
||||
@@ -0,0 +1,12 @@
|
||||
// docs: https://help.apple.com/xcode/mac/11.4/#/itcaec37c2a6
|
||||
|
||||
SWIFT_VERSION = 5.8
|
||||
SWIFT_TREAT_WARNINGS_AS_ERRORS = YES
|
||||
CODE_SIGNING_REQUIRED = NO // no need for codesign
|
||||
CODE_SIGNING_ALLOWED = NO // no need for codesign
|
||||
ONLY_ACTIVE_ARCH = YES // only need to run on the host machine
|
||||
ENABLE_BITCODE = NO
|
||||
GCC_GENERATE_TEST_COVERAGE_FILES = NO
|
||||
GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = NO
|
||||
TEST_ATTACHMENT_LOGGING = NO
|
||||
DEAD_CODE_STRIPPING = YES
|
||||
@@ -0,0 +1,8 @@
|
||||
// docs: https://help.apple.com/xcode/mac/11.4/#/itcaec37c2a6
|
||||
|
||||
#include "Pods/Target Support Files/Pods-unit-tests/Pods-unit-tests.debug.xcconfig"
|
||||
#include "test-base.xcconfig"
|
||||
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG // for macro `#if DEBUG`
|
||||
OTHER_SWIFT_FLAGS = -driver-time-compilation -Xfrontend -warn-long-function-bodies=250 -Xfrontend -warn-long-expression-type-checking=250 // find slow compilation areas
|
||||
SWIFT_COMPILATION_MODE = incremental
|
||||
@@ -0,0 +1,7 @@
|
||||
// docs: https://help.apple.com/xcode/mac/11.4/#/itcaec37c2a6
|
||||
|
||||
#include "Pods/Target Support Files/Pods-unit-tests/Pods-unit-tests.release.xcconfig"
|
||||
#include "test-base.xcconfig"
|
||||
|
||||
DEBUG_INFORMATION_FORMAT = none // we don't need dSYM files
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO // we don't need dSYM files
|
||||
@@ -1,4 +1,4 @@
|
||||
# Acknowledgments
|
||||
## Acknowledgments
|
||||
|
||||
These third-party libraries are used:
|
||||
|
||||
@@ -8,9 +8,6 @@ These third-party libraries are used:
|
||||
**Sparkle**
|
||||
[Website](https://github.com/sparkle-project/Sparkle) - [License](https://github.com/sparkle-project/Sparkle/blob/master/LICENSE)
|
||||
|
||||
**SwiftyMarkdown**
|
||||
[Website](https://github.com/SimonFairbairn/SwiftyMarkdown) - [MIT License](https://github.com/SimonFairbairn/SwiftyMarkdown/blob/master/LICENSE)
|
||||
|
||||
**LetsMove**
|
||||
[Website](https://github.com/potionfactory/LetsMove) - [Public domain](https://github.com/potionfactory/LetsMove#license)
|
||||
|
||||
|
||||
@@ -1,42 +1,5 @@
|
||||
---
|
||||
layout: bare
|
||||
layout: changelog-bare
|
||||
---
|
||||
|
||||
{% include_relative Changelog.md %}
|
||||
|
||||
<style>#google_translate_element,.skiptranslate{display:none;}body{top:0!important;}</style>
|
||||
<div id="google_translate_element"></div>
|
||||
<script>
|
||||
function getUserLanguage() {
|
||||
if (navigator.languages && navigator.languages.length > 0) {
|
||||
// Chinese is the only exception where google translate needs the full code
|
||||
// see https://sites.google.com/site/opti365/translate_codes
|
||||
const l = navigator.languages[0]
|
||||
if (l.length > 2 && l !== "zh-CN" && l !== "zh-TW") {
|
||||
return l.slice(0, 2)
|
||||
}
|
||||
return l
|
||||
}
|
||||
return "en"
|
||||
}
|
||||
|
||||
function googleTranslateElementInit() {
|
||||
new google.translate.TranslateElement({
|
||||
pageLanguage: 'en',
|
||||
includedLanguages: getUserLanguage(),
|
||||
autoDisplay: false
|
||||
}, 'google_translate_element')
|
||||
setTimeout(() => {
|
||||
var a = document.querySelector("#google_translate_element select")
|
||||
a.selectedIndex = 1
|
||||
a.dispatchEvent(new Event('change'))
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
const userLanguage = getUserLanguage()
|
||||
if (userLanguage !== "en") {
|
||||
let script = document.createElement("script")
|
||||
script.src = "https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"
|
||||
document.head.appendChild(script)
|
||||
}
|
||||
</script>
|
||||
@@ -1,4 +1,698 @@
|
||||
# Release notes
|
||||
## [8.3.3](https://github.com/lwouis/alt-tab-macos/compare/v8.3.2...v8.3.3) (2026-01-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* app icons could sometimes be invisible (closes [#5226](https://github.com/lwouis/alt-tab-macos/issues/5226)) ([23fbc01](https://github.com/lwouis/alt-tab-macos/commit/23fbc01))
|
||||
* improve trackpad gesture detection (closes [#5203](https://github.com/lwouis/alt-tab-macos/issues/5203)) ([9b5e43e](https://github.com/lwouis/alt-tab-macos/commit/9b5e43e))
|
||||
* switcher could sometimes show with no window pre-selected ([3e95f77](https://github.com/lwouis/alt-tab-macos/commit/3e95f77))
|
||||
* title could be off-center in app-icons appearance (closes [#5235](https://github.com/lwouis/alt-tab-macos/issues/5235)) ([7fdfe4a](https://github.com/lwouis/alt-tab-macos/commit/7fdfe4a))
|
||||
|
||||
## [8.3.2](https://github.com/lwouis/alt-tab-macos/compare/v8.3.1...v8.3.2) (2026-01-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* blacklisting fullscreen windows was not working (closes [#5228](https://github.com/lwouis/alt-tab-macos/issues/5228)) ([53815e0](https://github.com/lwouis/alt-tab-macos/commit/53815e0))
|
||||
|
||||
## [8.3.1](https://github.com/lwouis/alt-tab-macos/compare/v8.3.0...v8.3.1) (2026-01-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* chrome apps windows would not show in the switcher (closes [#5227](https://github.com/lwouis/alt-tab-macos/issues/5227)) ([bf3fa67](https://github.com/lwouis/alt-tab-macos/commit/bf3fa67))
|
||||
|
||||
# [8.3.0](https://github.com/lwouis/alt-tab-macos/compare/v8.2.0...v8.3.0) (2026-01-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* position of windowless indicator in thumbnails appearance ([d1fd1fd](https://github.com/lwouis/alt-tab-macos/commit/d1fd1fd))
|
||||
* small memory leak when opening the switcher (closes [#4255](https://github.com/lwouis/alt-tab-macos/issues/4255)) ([0a6485e](https://github.com/lwouis/alt-tab-macos/commit/0a6485e))
|
||||
* windows would sometimes not update their order (closes [#5207](https://github.com/lwouis/alt-tab-macos/issues/5207)) ([a3f2a54](https://github.com/lwouis/alt-tab-macos/commit/a3f2a54))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* increase apparition delay granularity (closes [#5210](https://github.com/lwouis/alt-tab-macos/issues/5210)) ([5b0df6b](https://github.com/lwouis/alt-tab-macos/commit/5b0df6b))
|
||||
|
||||
# [8.2.0](https://github.com/lwouis/alt-tab-macos/compare/v8.1.0...v8.2.0) (2026-01-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* thumbnails could sometimes be stretched (closes [#5204](https://github.com/lwouis/alt-tab-macos/issues/5204)) ([ac24d6d](https://github.com/lwouis/alt-tab-macos/commit/ac24d6d))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* stop checking screen-recording permission after launch ([#5202](https://github.com/lwouis/alt-tab-macos/issues/5202)) ([f481d22](https://github.com/lwouis/alt-tab-macos/commit/f481d22))
|
||||
|
||||
# [8.1.0](https://github.com/lwouis/alt-tab-macos/compare/v8.0.0...v8.1.0) (2026-01-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow f-keys as shortcuts-when-active (closes [#5166](https://github.com/lwouis/alt-tab-macos/issues/5166)) ([a0c9fee](https://github.com/lwouis/alt-tab-macos/commit/a0c9fee))
|
||||
* avoid unintentional trackpad trigger (closes [#4278](https://github.com/lwouis/alt-tab-macos/issues/4278)) ([0539a3a](https://github.com/lwouis/alt-tab-macos/commit/0539a3a))
|
||||
* better handle palm/fingers resting on the trackpad (closes [#5191](https://github.com/lwouis/alt-tab-macos/issues/5191)) ([9ed8a19](https://github.com/lwouis/alt-tab-macos/commit/9ed8a19))
|
||||
* mitigate macos 15 bugs with screencapture-kit (closes [#5190](https://github.com/lwouis/alt-tab-macos/issues/5190)) ([b2f5c6c](https://github.com/lwouis/alt-tab-macos/commit/b2f5c6c))
|
||||
* mouse hover detection for hidden/windowless apps ([7c64864](https://github.com/lwouis/alt-tab-macos/commit/7c64864))
|
||||
* thumbnails could sometimes be the wrong size ([9d0b947](https://github.com/lwouis/alt-tab-macos/commit/9d0b947))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add belarusian localization ([0fe722b](https://github.com/lwouis/alt-tab-macos/commit/0fe722b))
|
||||
* improve accidental cursor movement ([74b5a11](https://github.com/lwouis/alt-tab-macos/commit/74b5a11)), closes [/github.com/lwouis/alt-tab-macos/issues/4278#issuecomment-3733280737](https://github.com//github.com/lwouis/alt-tab-macos/issues/4278/issues/issuecomment-3733280737)
|
||||
* improve pl localization ([3b53ce7](https://github.com/lwouis/alt-tab-macos/commit/3b53ce7))
|
||||
* show outline of windows hidden for privacy reasons (closes [#5172](https://github.com/lwouis/alt-tab-macos/issues/5172)) ([1090acf](https://github.com/lwouis/alt-tab-macos/commit/1090acf))
|
||||
|
||||
# [8.0.0](https://github.com/lwouis/alt-tab-macos/compare/v7.39.0...v8.0.0) (2026-01-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* avoid macos bug where many permission dialogs pop (closes [#5106](https://github.com/lwouis/alt-tab-macos/issues/5106)) ([5c4199e](https://github.com/lwouis/alt-tab-macos/commit/5c4199e))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve memory image of showing app icons (closes [#5144](https://github.com/lwouis/alt-tab-macos/issues/5144)) ([bf58335](https://github.com/lwouis/alt-tab-macos/commit/bf58335))
|
||||
* improve ta localization ([989b344](https://github.com/lwouis/alt-tab-macos/commit/989b344))
|
||||
* improve thumbnails with screen-capture kit ([7821d7c](https://github.com/lwouis/alt-tab-macos/commit/7821d7c)), closes [#4255](https://github.com/lwouis/alt-tab-macos/issues/4255) [#3652](https://github.com/lwouis/alt-tab-macos/issues/3652)
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* debounce screen/space events to minimize work ([e2b4779](https://github.com/lwouis/alt-tab-macos/commit/e2b4779))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Better thumbnails with ScreenCaptureKit for users on macOS >= 14
|
||||
|
||||
# [7.39.0](https://github.com/lwouis/alt-tab-macos/compare/v7.38.1...v7.39.0) (2026-01-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* avoid showing closed windows (closes [#3589](https://github.com/lwouis/alt-tab-macos/issues/3589)) ([894a69d](https://github.com/lwouis/alt-tab-macos/commit/894a69d)), closes [#4924](https://github.com/lwouis/alt-tab-macos/issues/4924)
|
||||
* permission checks might freeze or restart the app (closes [#5112](https://github.com/lwouis/alt-tab-macos/issues/5112)) ([7906d63](https://github.com/lwouis/alt-tab-macos/commit/7906d63))
|
||||
* permission window could steal focus (see [#3577](https://github.com/lwouis/alt-tab-macos/issues/3577)) ([2f875b3](https://github.com/lwouis/alt-tab-macos/commit/2f875b3))
|
||||
* permissions window could look wrong in some languages like chinese ([914f91f](https://github.com/lwouis/alt-tab-macos/commit/914f91f)), closes [/github.com/lwouis/alt-tab-macos/issues/5112#issuecomment-3692769341](https://github.com//github.com/lwouis/alt-tab-macos/issues/5112/issues/issuecomment-3692769341)
|
||||
* preview could sometimes be incorrectly positioned ([edc2f00](https://github.com/lwouis/alt-tab-macos/commit/edc2f00))
|
||||
* show some hovering windows (e.g. zoom.app) (closes [#5140](https://github.com/lwouis/alt-tab-macos/issues/5140)) ([fcc6651](https://github.com/lwouis/alt-tab-macos/commit/fcc6651))
|
||||
* thumbnails could sometimes have the wrong size ([55f3f59](https://github.com/lwouis/alt-tab-macos/commit/55f3f59))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* avoid occasional delays in showing the switcher (closes [#5109](https://github.com/lwouis/alt-tab-macos/issues/5109)) ([3c04a4c](https://github.com/lwouis/alt-tab-macos/commit/3c04a4c))
|
||||
* improve nb/tr localizations ([5e842d5](https://github.com/lwouis/alt-tab-macos/commit/5e842d5))
|
||||
* remove shadow around app icon appearance ([dda612c](https://github.com/lwouis/alt-tab-macos/commit/dda612c))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* do login item and plist updates later to accelerate launch ([2f72c5d](https://github.com/lwouis/alt-tab-macos/commit/2f72c5d))
|
||||
* don't compute diffs of running-apps; directly get new/old ([7ded01c](https://github.com/lwouis/alt-tab-macos/commit/7ded01c))
|
||||
* improve mouse hover algo and core-animation side ([6103785](https://github.com/lwouis/alt-tab-macos/commit/6103785))
|
||||
|
||||
## [7.38.1](https://github.com/lwouis/alt-tab-macos/compare/v7.38.0...v7.38.1) (2025-12-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* could sometimes freeze on the permission window ([43838e1](https://github.com/lwouis/alt-tab-macos/commit/43838e1)), closes [#5112](https://github.com/lwouis/alt-tab-macos/issues/5112)
|
||||
* prevent crash when sending a debug profile ([741e790](https://github.com/lwouis/alt-tab-macos/commit/741e790))
|
||||
|
||||
# [7.38.0](https://github.com/lwouis/alt-tab-macos/compare/v7.37.0...v7.38.0) (2025-12-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* could sometimes freeze upon launch (closes [#5079](https://github.com/lwouis/alt-tab-macos/issues/5079)) ([ee27df7](https://github.com/lwouis/alt-tab-macos/commit/ee27df7))
|
||||
* sending feedback with a debug-profile could sometimes crash ([e0ae29d](https://github.com/lwouis/alt-tab-macos/commit/e0ae29d))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve ca/es/ga/pt/pt-br/uk localizations ([8a98b4e](https://github.com/lwouis/alt-tab-macos/commit/8a98b4e))
|
||||
* prevent mouse-hover when using trackpad swipes (closes [#5071](https://github.com/lwouis/alt-tab-macos/issues/5071)) ([b8ecd58](https://github.com/lwouis/alt-tab-macos/commit/b8ecd58))
|
||||
|
||||
# [7.37.0](https://github.com/lwouis/alt-tab-macos/compare/v7.36.0...v7.37.0) (2025-11-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* better crop app icons on macos < 26 (closes [#5080](https://github.com/lwouis/alt-tab-macos/issues/5080)) ([237bb1e](https://github.com/lwouis/alt-tab-macos/commit/237bb1e))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve portuguese localization ([3994429](https://github.com/lwouis/alt-tab-macos/commit/3994429))
|
||||
* warn tahoe users of shortcut conflict with macos game-overlay ([911aad4](https://github.com/lwouis/alt-tab-macos/commit/911aad4)), closes [#5018](https://github.com/lwouis/alt-tab-macos/issues/5018)
|
||||
|
||||
# [7.36.0](https://github.com/lwouis/alt-tab-macos/compare/v7.35.0...v7.36.0) (2025-11-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* switcher could become broken after changing appearance ([d377b3d](https://github.com/lwouis/alt-tab-macos/commit/d377b3d)), closes [#5061](https://github.com/lwouis/alt-tab-macos/issues/5061)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve portuguese localization ([435a310](https://github.com/lwouis/alt-tab-macos/commit/435a310))
|
||||
|
||||
# [7.35.0](https://github.com/lwouis/alt-tab-macos/compare/v7.34.0...v7.35.0) (2025-11-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* app would sometimes crash on macos monterey (closes [#5051](https://github.com/lwouis/alt-tab-macos/issues/5051)) ([29e1cff](https://github.com/lwouis/alt-tab-macos/commit/29e1cff))
|
||||
* better gesture recognition (closes [#5039](https://github.com/lwouis/alt-tab-macos/issues/5039)) ([1689954](https://github.com/lwouis/alt-tab-macos/commit/1689954))
|
||||
* closing fullscreen window would glitch it (closes [#5029](https://github.com/lwouis/alt-tab-macos/issues/5029)) ([ee436cc](https://github.com/lwouis/alt-tab-macos/commit/ee436cc))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add trackpad haptic feedback for better navigation (closes [#4763](https://github.com/lwouis/alt-tab-macos/issues/4763)) ([fb5dfc4](https://github.com/lwouis/alt-tab-macos/commit/fb5dfc4))
|
||||
* better icon for feedback form (closes [#5013](https://github.com/lwouis/alt-tab-macos/issues/5013)) ([2c3373a](https://github.com/lwouis/alt-tab-macos/commit/2c3373a))
|
||||
* improve portuguese localization ([c294ad0](https://github.com/lwouis/alt-tab-macos/commit/c294ad0))
|
||||
|
||||
# [7.34.0](https://github.com/lwouis/alt-tab-macos/compare/v7.33.0...v7.34.0) (2025-11-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* reduce memory footprint after running for a while (closes [#4255](https://github.com/lwouis/alt-tab-macos/issues/4255)) ([938b735](https://github.com/lwouis/alt-tab-macos/commit/938b735))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve localizations ([516329a](https://github.com/lwouis/alt-tab-macos/commit/516329a))
|
||||
* improve responsiveness in showing switcher (closes [#4959](https://github.com/lwouis/alt-tab-macos/issues/4959)) ([a80721b](https://github.com/lwouis/alt-tab-macos/commit/a80721b))
|
||||
|
||||
# [7.33.0](https://github.com/lwouis/alt-tab-macos/compare/v7.32.0...v7.33.0) (2025-11-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* app icon was too small in titles-appearance large-size ([ffd0c75](https://github.com/lwouis/alt-tab-macos/commit/ffd0c75))
|
||||
* take into account accent-color immediatly (closes [#4984](https://github.com/lwouis/alt-tab-macos/issues/4984)) ([011fdba](https://github.com/lwouis/alt-tab-macos/commit/011fdba))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve dealing with reserved/conflicting shortcuts ([fdf3134](https://github.com/lwouis/alt-tab-macos/commit/fdf3134)), closes [#3190](https://github.com/lwouis/alt-tab-macos/issues/3190) [#3288](https://github.com/lwouis/alt-tab-macos/issues/3288) [#1835](https://github.com/lwouis/alt-tab-macos/issues/1835) [#3826](https://github.com/lwouis/alt-tab-macos/issues/3826)
|
||||
* improve nl/pl/uk localizations ([96caad4](https://github.com/lwouis/alt-tab-macos/commit/96caad4))
|
||||
* improve trackpad multi-fingers swiping (closes [#4765](https://github.com/lwouis/alt-tab-macos/issues/4765)) ([d6196ec](https://github.com/lwouis/alt-tab-macos/commit/d6196ec))
|
||||
* improve ux for titles-appearance (closes [#4975](https://github.com/lwouis/alt-tab-macos/issues/4975)) ([c352591](https://github.com/lwouis/alt-tab-macos/commit/c352591))
|
||||
* macos tahoe improvements: menubar menu, feedback form, wording ([309cae3](https://github.com/lwouis/alt-tab-macos/commit/309cae3)), closes [#4986](https://github.com/lwouis/alt-tab-macos/issues/4986)
|
||||
|
||||
# [7.32.0](https://github.com/lwouis/alt-tab-macos/compare/v7.31.0...v7.32.0) (2025-11-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* alt-tab could crash if asked to close one of its own window ([f46372b](https://github.com/lwouis/alt-tab-macos/commit/f46372b))
|
||||
* could sometimes crash when navigating up or down (closes [#4110](https://github.com/lwouis/alt-tab-macos/issues/4110)) ([d2220c6](https://github.com/lwouis/alt-tab-macos/commit/d2220c6))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve pl/zh-hk localizations ([786e752](https://github.com/lwouis/alt-tab-macos/commit/786e752))
|
||||
* improve responsiveness of showing the switcher ([689adc0](https://github.com/lwouis/alt-tab-macos/commit/689adc0))
|
||||
* new look for tahoe and liquid glass (closes [#4658](https://github.com/lwouis/alt-tab-macos/issues/4658)) ([fab9d7c](https://github.com/lwouis/alt-tab-macos/commit/fab9d7c))
|
||||
* titles appearance now resizes for better readability ([26d40e1](https://github.com/lwouis/alt-tab-macos/commit/26d40e1)), closes [#3882](https://github.com/lwouis/alt-tab-macos/issues/3882)
|
||||
* update visuals for macos tahoe and liquid glass ([33c6615](https://github.com/lwouis/alt-tab-macos/commit/33c6615))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* improve rendering performance by doing less work ([ec55ae8](https://github.com/lwouis/alt-tab-macos/commit/ec55ae8))
|
||||
|
||||
# [7.31.0](https://github.com/lwouis/alt-tab-macos/compare/v7.30.0...v7.31.0) (2025-10-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* cmd+q would quit alt-tab instead of the selected app (closes [#4867](https://github.com/lwouis/alt-tab-macos/issues/4867)) ([247f635](https://github.com/lwouis/alt-tab-macos/commit/247f635)), closes [#4891](https://github.com/lwouis/alt-tab-macos/issues/4891)
|
||||
* title was truncated in app-icons appearance (closes [#4860](https://github.com/lwouis/alt-tab-macos/issues/4860)) ([a1cfd1d](https://github.com/lwouis/alt-tab-macos/commit/a1cfd1d))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve ar/de/fr/kn/ru/zh-tw localizations ([173bc97](https://github.com/lwouis/alt-tab-macos/commit/173bc97))
|
||||
* improve windows detection ([cab591e](https://github.com/lwouis/alt-tab-macos/commit/cab591e))
|
||||
* new cli command to focus a window using focus order (closes [#4610](https://github.com/lwouis/alt-tab-macos/issues/4610)) ([84166ab](https://github.com/lwouis/alt-tab-macos/commit/84166ab))
|
||||
* save resources trying to detect certain windows ([33e5acf](https://github.com/lwouis/alt-tab-macos/commit/33e5acf))
|
||||
|
||||
# [7.30.0](https://github.com/lwouis/alt-tab-macos/compare/v7.29.0...v7.30.0) (2025-09-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* bring back pre-v7.28 performance (closes [#4805](https://github.com/lwouis/alt-tab-macos/issues/4805)) ([fb6110d](https://github.com/lwouis/alt-tab-macos/commit/fb6110d))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve nb/nl/zh-tw localizations ([a9cb03c](https://github.com/lwouis/alt-tab-macos/commit/a9cb03c))
|
||||
|
||||
# [7.29.0](https://github.com/lwouis/alt-tab-macos/compare/v7.28.0...v7.29.0) (2025-09-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* windows order was not updating correctly (closes [#4754](https://github.com/lwouis/alt-tab-macos/issues/4754)) ([1316eb2](https://github.com/lwouis/alt-tab-macos/commit/1316eb2))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve fr/ja languages ([c5286c3](https://github.com/lwouis/alt-tab-macos/commit/c5286c3))
|
||||
|
||||
# [7.28.0](https://github.com/lwouis/alt-tab-macos/compare/v7.27.0...v7.28.0) (2025-09-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* focusing windows could fail after focusing a frozen app ([#4520](https://github.com/lwouis/alt-tab-macos/issues/4520)) ([591ce52](https://github.com/lwouis/alt-tab-macos/commit/591ce52))
|
||||
* improve detection of windows (closes [#4405](https://github.com/lwouis/alt-tab-macos/issues/4405)) ([3c79840](https://github.com/lwouis/alt-tab-macos/commit/3c79840))
|
||||
* keyboard selection now works with dragging + mouse hover ([be077f1](https://github.com/lwouis/alt-tab-macos/commit/be077f1)), closes [#4711](https://github.com/lwouis/alt-tab-macos/issues/4711)
|
||||
* remove high-volume unactionable logs (closes [#4697](https://github.com/lwouis/alt-tab-macos/issues/4697)) ([e93e42f](https://github.com/lwouis/alt-tab-macos/commit/e93e42f))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add gujarati localization ([4ebd990](https://github.com/lwouis/alt-tab-macos/commit/4ebd990))
|
||||
* add hong-kong cantonese + improve other languages ([78c8525](https://github.com/lwouis/alt-tab-macos/commit/78c8525))
|
||||
* add preference to show only non-active apps (closes [#4691](https://github.com/lwouis/alt-tab-macos/issues/4691)) ([4567550](https://github.com/lwouis/alt-tab-macos/commit/4567550))
|
||||
* improve norwegian localization ([726e13e](https://github.com/lwouis/alt-tab-macos/commit/726e13e))
|
||||
* more fine-grained cursor-follows-focus preference (closes [#4734](https://github.com/lwouis/alt-tab-macos/issues/4734)) ([985a681](https://github.com/lwouis/alt-tab-macos/commit/985a681))
|
||||
|
||||
# [7.27.0](https://github.com/lwouis/alt-tab-macos/compare/v7.26.0...v7.27.0) (2025-08-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* restore default command+tab if shortcut is unbound (closes [#4642](https://github.com/lwouis/alt-tab-macos/issues/4642)) ([f66c92a](https://github.com/lwouis/alt-tab-macos/commit/f66c92a))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve cs/th localizations ([aa46a62](https://github.com/lwouis/alt-tab-macos/commit/aa46a62))
|
||||
* windowless apps can now be shown in focus-order (closes [#4653](https://github.com/lwouis/alt-tab-macos/issues/4653)) ([5db53b5](https://github.com/lwouis/alt-tab-macos/commit/5db53b5))
|
||||
|
||||
# [7.26.0](https://github.com/lwouis/alt-tab-macos/compare/v7.25.0...v7.26.0) (2025-07-31)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* ignore autodesk fusion internal panels (closes [#4578](https://github.com/lwouis/alt-tab-macos/issues/4578)) ([f67d182](https://github.com/lwouis/alt-tab-macos/commit/f67d182))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve da/fi/ga localizations ([f376529](https://github.com/lwouis/alt-tab-macos/commit/f376529))
|
||||
* improve preference to show-apps-with-open-window (closes [#4485](https://github.com/lwouis/alt-tab-macos/issues/4485)) ([67f5098](https://github.com/lwouis/alt-tab-macos/commit/67f5098))
|
||||
|
||||
# [7.25.0](https://github.com/lwouis/alt-tab-macos/compare/v7.24.0...v7.25.0) (2025-06-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* icons on thumbnails could sometimes be incorrect ([b4bc0b0](https://github.com/lwouis/alt-tab-macos/commit/b4bc0b0))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* new cli commands: --show, --detailed-list (closes [#4489](https://github.com/lwouis/alt-tab-macos/issues/4489)) ([b0ce899](https://github.com/lwouis/alt-tab-macos/commit/b0ce899))
|
||||
|
||||
# [7.24.0](https://github.com/lwouis/alt-tab-macos/compare/v7.23.0...v7.24.0) (2025-05-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* clicking to focus windows/apps is now easier (closes [#4407](https://github.com/lwouis/alt-tab-macos/issues/4407)) ([397457c](https://github.com/lwouis/alt-tab-macos/commit/397457c))
|
||||
* improve ca/pt/ro localizations ([8b7d69c](https://github.com/lwouis/alt-tab-macos/commit/8b7d69c))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* avoid updating preview if not necessary ([518f8b4](https://github.com/lwouis/alt-tab-macos/commit/518f8b4))
|
||||
|
||||
# [7.23.0](https://github.com/lwouis/alt-tab-macos/compare/v7.22.0...v7.23.0) (2025-04-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* avoid crashing on uncommon keys in shortcuts (closes [#4379](https://github.com/lwouis/alt-tab-macos/issues/4379)) ([9d852ee](https://github.com/lwouis/alt-tab-macos/commit/9d852ee))
|
||||
* window name would sometimes be empty (closes [#4350](https://github.com/lwouis/alt-tab-macos/issues/4350)) ([911c3c1](https://github.com/lwouis/alt-tab-macos/commit/911c3c1))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve hindi localization ([dec0519](https://github.com/lwouis/alt-tab-macos/commit/dec0519))
|
||||
|
||||
# [7.22.0](https://github.com/lwouis/alt-tab-macos/compare/v7.21.1...v7.22.0) (2025-03-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* language switcher picked up as window ([f4f7d9a](https://github.com/lwouis/alt-tab-macos/commit/f4f7d9a))
|
||||
* prevent rare crash ([4e35f9f](https://github.com/lwouis/alt-tab-macos/commit/4e35f9f))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* update ca/de/fr/ko/ru/tw localizations ([9b3f936](https://github.com/lwouis/alt-tab-macos/commit/9b3f936))
|
||||
|
||||
## [7.21.1](https://github.com/lwouis/alt-tab-macos/compare/v7.21.0...v7.21.1) (2025-02-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* update how feedback messages are sent ([647f900](https://github.com/lwouis/alt-tab-macos/commit/647f900))
|
||||
|
||||
# [7.21.0](https://github.com/lwouis/alt-tab-macos/compare/v7.20.1...v7.21.0) (2025-02-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* app would sometimes crash (closes [#4244](https://github.com/lwouis/alt-tab-macos/issues/4244)) ([d543393](https://github.com/lwouis/alt-tab-macos/commit/d543393))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add lithuanian localization ([bc95b90](https://github.com/lwouis/alt-tab-macos/commit/bc95b90))
|
||||
* improve chinese localization ([330ac54](https://github.com/lwouis/alt-tab-macos/commit/330ac54))
|
||||
|
||||
## [7.20.1](https://github.com/lwouis/alt-tab-macos/compare/v7.20.0...v7.20.1) (2025-02-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* may crash when changing space or screen ([b62cec0](https://github.com/lwouis/alt-tab-macos/commit/b62cec0))
|
||||
|
||||
# [7.20.0](https://github.com/lwouis/alt-tab-macos/compare/v7.19.1...v7.20.0) (2025-02-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* better detect windows from other spaces (closes [#1324](https://github.com/lwouis/alt-tab-macos/issues/1324)) ([2cd8b96](https://github.com/lwouis/alt-tab-macos/commit/2cd8b96))
|
||||
* colored circles would go away on ui refresh (closes [#4151](https://github.com/lwouis/alt-tab-macos/issues/4151)) ([dcea005](https://github.com/lwouis/alt-tab-macos/commit/dcea005))
|
||||
* stage manager no longer skews the thumbnails (closes [#1731](https://github.com/lwouis/alt-tab-macos/issues/1731)) ([93defcd](https://github.com/lwouis/alt-tab-macos/commit/93defcd))
|
||||
* window might be noted to be on the wrong space ([5413372](https://github.com/lwouis/alt-tab-macos/commit/5413372))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add javanese localization ([8564ed2](https://github.com/lwouis/alt-tab-macos/commit/8564ed2))
|
||||
* improve performance and lower resources consumption ([9d78700](https://github.com/lwouis/alt-tab-macos/commit/9d78700))
|
||||
* improve thumbnails quality and performance (closes [#4183](https://github.com/lwouis/alt-tab-macos/issues/4183)) ([9d6fc68](https://github.com/lwouis/alt-tab-macos/commit/9d6fc68))
|
||||
* improve window focusing action ([8dd63c7](https://github.com/lwouis/alt-tab-macos/commit/8dd63c7))
|
||||
* update fr, kn, pt-br, uk localizations ([fd0411b](https://github.com/lwouis/alt-tab-macos/commit/fd0411b))
|
||||
|
||||
## [7.19.1](https://github.com/lwouis/alt-tab-macos/compare/v7.19.0...v7.19.1) (2025-01-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* a few labels were not displaying (closes [#4127](https://github.com/lwouis/alt-tab-macos/issues/4127)) ([0a22547](https://github.com/lwouis/alt-tab-macos/commit/0a22547))
|
||||
|
||||
# [7.19.0](https://github.com/lwouis/alt-tab-macos/compare/v7.18.1...v7.19.0) (2025-01-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add preference to toggle animation of preview (closes [#4118](https://github.com/lwouis/alt-tab-macos/issues/4118)) ([c10ca2a](https://github.com/lwouis/alt-tab-macos/commit/c10ca2a))
|
||||
* middle-click will now close windows and quit applications ([2f8c014](https://github.com/lwouis/alt-tab-macos/commit/2f8c014))
|
||||
|
||||
## [7.18.1](https://github.com/lwouis/alt-tab-macos/compare/v7.18.0...v7.18.1) (2025-01-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* don't check screen-recording permission if unnecessary ([f3b116e](https://github.com/lwouis/alt-tab-macos/commit/f3b116e)), closes [#4113](https://github.com/lwouis/alt-tab-macos/issues/4113)
|
||||
* show shadows around thumbnails (closes [#4068](https://github.com/lwouis/alt-tab-macos/issues/4068)) ([597b443](https://github.com/lwouis/alt-tab-macos/commit/597b443))
|
||||
|
||||
# [7.18.0](https://github.com/lwouis/alt-tab-macos/compare/v7.17.0...v7.18.0) (2025-01-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* various issues with the app freezing or being slowly ([121515c](https://github.com/lwouis/alt-tab-macos/commit/121515c))
|
||||
* window order on first display was wrong ([db5644e](https://github.com/lwouis/alt-tab-macos/commit/db5644e))
|
||||
* window preview was not showing in titles style ([684cc66](https://github.com/lwouis/alt-tab-macos/commit/684cc66))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve polish localization ([c712473](https://github.com/lwouis/alt-tab-macos/commit/c712473))
|
||||
|
||||
# [7.17.0](https://github.com/lwouis/alt-tab-macos/compare/v7.16.0...v7.17.0) (2025-01-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* app icons could sometimes be at the wrong size ([d5d1311](https://github.com/lwouis/alt-tab-macos/commit/d5d1311))
|
||||
* more robust screen-recording permission detection ([d85ec7b](https://github.com/lwouis/alt-tab-macos/commit/d85ec7b))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* handle cli commands: --list and --focus=window_id ([0f2c0e7](https://github.com/lwouis/alt-tab-macos/commit/0f2c0e7))
|
||||
|
||||
# [7.16.0](https://github.com/lwouis/alt-tab-macos/compare/v7.15.0...v7.16.0) (2025-01-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* app badges could be incorrectly positioned on the very first launch ([c2ccccd](https://github.com/lwouis/alt-tab-macos/commit/c2ccccd))
|
||||
* app-icons wouldn't show when permissions were skipped ([837fa03](https://github.com/lwouis/alt-tab-macos/commit/837fa03))
|
||||
* screen recording warnings shouldn't appear with skipped permissions ([f027b47](https://github.com/lwouis/alt-tab-macos/commit/f027b47))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve performance by caching preferences better ([d653a54](https://github.com/lwouis/alt-tab-macos/commit/d653a54))
|
||||
|
||||
# [7.15.0](https://github.com/lwouis/alt-tab-macos/compare/v7.14.1...v7.15.0) (2025-01-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* better position preview for fullscreen windows (closes [#4051](https://github.com/lwouis/alt-tab-macos/issues/4051)) ([3b0cba4](https://github.com/lwouis/alt-tab-macos/commit/3b0cba4))
|
||||
* layout was sometimes broken in app-icons style (closes [#4036](https://github.com/lwouis/alt-tab-macos/issues/4036)) ([be5eb26](https://github.com/lwouis/alt-tab-macos/commit/be5eb26))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve chinese-taiwanese localization ([dfcf9de](https://github.com/lwouis/alt-tab-macos/commit/dfcf9de))
|
||||
* improve performance and order accuracy at launch ([fc6d636](https://github.com/lwouis/alt-tab-macos/commit/fc6d636))
|
||||
* improve quality of thumbnails and performance ([a138a92](https://github.com/lwouis/alt-tab-macos/commit/a138a92))
|
||||
* reduce space between app icon and window title ([295eb2b](https://github.com/lwouis/alt-tab-macos/commit/295eb2b))
|
||||
* switcher displays faster; other performance improvements ([b51ff65](https://github.com/lwouis/alt-tab-macos/commit/b51ff65))
|
||||
|
||||
## [7.14.1](https://github.com/lwouis/alt-tab-macos/compare/v7.14.0...v7.14.1) (2024-12-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* improve label display in app-icons style ([7e501a4](https://github.com/lwouis/alt-tab-macos/commit/7e501a4))
|
||||
* title would sometimes not show when mouse hovering ([dd05ba2](https://github.com/lwouis/alt-tab-macos/commit/dd05ba2))
|
||||
|
||||
# [7.14.0](https://github.com/lwouis/alt-tab-macos/compare/v7.13.1...v7.14.0) (2024-12-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* improve acknowledgments tab (closes [#4025](https://github.com/lwouis/alt-tab-macos/issues/4025)) ([db5500f](https://github.com/lwouis/alt-tab-macos/commit/db5500f))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* clear feedback form after submission (closes [#4026](https://github.com/lwouis/alt-tab-macos/issues/4026)) ([42bbd0f](https://github.com/lwouis/alt-tab-macos/commit/42bbd0f))
|
||||
* improve chinese, irish, italian localizations ([18ef16f](https://github.com/lwouis/alt-tab-macos/commit/18ef16f))
|
||||
* swipes can now be horizontal or vertical (closes [#4020](https://github.com/lwouis/alt-tab-macos/issues/4020)) ([fda3ada](https://github.com/lwouis/alt-tab-macos/commit/fda3ada))
|
||||
|
||||
## [7.13.1](https://github.com/lwouis/alt-tab-macos/compare/v7.13.0...v7.13.1) (2024-12-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* acknowledgments tab was hard to read in dark mode (closes [#4019](https://github.com/lwouis/alt-tab-macos/issues/4019)) ([4481d94](https://github.com/lwouis/alt-tab-macos/commit/4481d94))
|
||||
* app crash from v7.13.0 (closes [#4016](https://github.com/lwouis/alt-tab-macos/issues/4016)) ([d3b5bef](https://github.com/lwouis/alt-tab-macos/commit/d3b5bef))
|
||||
|
||||
# [7.13.0](https://github.com/lwouis/alt-tab-macos/compare/v7.12.0...v7.13.0) (2024-12-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* enabling previews with multiple screens could lead to flickering ([87a2b21](https://github.com/lwouis/alt-tab-macos/commit/87a2b21))
|
||||
* prevent initial window lastFocusOrder overlaps ([d32f953](https://github.com/lwouis/alt-tab-macos/commit/d32f953))
|
||||
* previews on multiple screens could get misplaced ([2a0a858](https://github.com/lwouis/alt-tab-macos/commit/2a0a858))
|
||||
* titles could sometimes be covered when in small size ([c5e13cc](https://github.com/lwouis/alt-tab-macos/commit/c5e13cc))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add fade-in for window previews (closes [#2456](https://github.com/lwouis/alt-tab-macos/issues/2456)) ([40c9a18](https://github.com/lwouis/alt-tab-macos/commit/40c9a18))
|
||||
* allow vertical swipes as trigger (closes [#4012](https://github.com/lwouis/alt-tab-macos/issues/4012)) ([9adf64c](https://github.com/lwouis/alt-tab-macos/commit/9adf64c))
|
||||
* improve localizations ([6d9059e](https://github.com/lwouis/alt-tab-macos/commit/6d9059e))
|
||||
* reduce disk size of localizations ([9ec2762](https://github.com/lwouis/alt-tab-macos/commit/9ec2762))
|
||||
* swiping won't wrap-around to other rows (closes [#3983](https://github.com/lwouis/alt-tab-macos/issues/3983)) ([6215b65](https://github.com/lwouis/alt-tab-macos/commit/6215b65))
|
||||
|
||||
# [7.12.0](https://github.com/lwouis/alt-tab-macos/compare/v7.11.0...v7.12.0) (2024-12-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* switcher could appear collapsed in titles style (closes [#3744](https://github.com/lwouis/alt-tab-macos/issues/3744)) ([60534bc](https://github.com/lwouis/alt-tab-macos/commit/60534bc))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* acknowledgments tab was slow to display (closes [#3957](https://github.com/lwouis/alt-tab-macos/issues/3957)) ([41ddd7c](https://github.com/lwouis/alt-tab-macos/commit/41ddd7c))
|
||||
|
||||
# [7.11.0](https://github.com/lwouis/alt-tab-macos/compare/v7.10.0...v7.11.0) (2024-12-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* always show a window in show:apps mode (closes [#3950](https://github.com/lwouis/alt-tab-macos/issues/3950)) ([ac70fcc](https://github.com/lwouis/alt-tab-macos/commit/ac70fcc))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* decrease shortcuts from 5 to 3 ([d65f220](https://github.com/lwouis/alt-tab-macos/commit/d65f220))
|
||||
* improve chinese localization ([764e0f3](https://github.com/lwouis/alt-tab-macos/commit/764e0f3))
|
||||
* improve focus in show:apps mode (closes [#3951](https://github.com/lwouis/alt-tab-macos/issues/3951)) ([cb191d6](https://github.com/lwouis/alt-tab-macos/commit/cb191d6))
|
||||
* support 3 or 4 finger swipes to use the app (closes [#730](https://github.com/lwouis/alt-tab-macos/issues/730)) ([903e758](https://github.com/lwouis/alt-tab-macos/commit/903e758))
|
||||
* switcher will now show in "show desktop" mode (closes [#783](https://github.com/lwouis/alt-tab-macos/issues/783)) ([9b85f00](https://github.com/lwouis/alt-tab-macos/commit/9b85f00))
|
||||
|
||||
# [7.10.0](https://github.com/lwouis/alt-tab-macos/compare/v7.9.0...v7.10.0) (2024-12-08)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve catalan localization ([7e199f6](https://github.com/lwouis/alt-tab-macos/commit/7e199f6))
|
||||
* make it more clear how to hide the menubar icon (closes [#503](https://github.com/lwouis/alt-tab-macos/issues/503)) ([9ca0649](https://github.com/lwouis/alt-tab-macos/commit/9ca0649))
|
||||
|
||||
# [7.9.0](https://github.com/lwouis/alt-tab-macos/compare/v7.8.0...v7.9.0) (2024-12-07)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve catalan and taiwanese localizations ([bf3a4dc](https://github.com/lwouis/alt-tab-macos/commit/bf3a4dc))
|
||||
* try to avoid launching multiple instances at login (closes [#1840](https://github.com/lwouis/alt-tab-macos/issues/1840)) ([e4cfd85](https://github.com/lwouis/alt-tab-macos/commit/e4cfd85))
|
||||
|
||||
# [7.8.0](https://github.com/lwouis/alt-tab-macos/compare/v7.7.0...v7.8.0) (2024-12-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* bring back the cursor follow focus feature ([#3882](https://github.com/lwouis/alt-tab-macos/issues/3882)) ([73382db](https://github.com/lwouis/alt-tab-macos/commit/73382db))
|
||||
* improve display of very small windows (closes [#3902](https://github.com/lwouis/alt-tab-macos/issues/3902)) ([9bafd03](https://github.com/lwouis/alt-tab-macos/commit/9bafd03))
|
||||
* improve irish localization ([89c02c9](https://github.com/lwouis/alt-tab-macos/commit/89c02c9))
|
||||
* switcher will show faster (closes [#3845](https://github.com/lwouis/alt-tab-macos/issues/3845)) ([b694c83](https://github.com/lwouis/alt-tab-macos/commit/b694c83))
|
||||
|
||||
# [7.7.0](https://github.com/lwouis/alt-tab-macos/compare/v7.6.0...v7.7.0) (2024-12-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* [after release: do nothing] was broken in v7.6.0 (closes [#3929](https://github.com/lwouis/alt-tab-macos/issues/3929)) ([83b5319](https://github.com/lwouis/alt-tab-macos/commit/83b5319))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve chinese localization ([17e9599](https://github.com/lwouis/alt-tab-macos/commit/17e9599))
|
||||
* improve tooltips in preferences ([f97e9f9](https://github.com/lwouis/alt-tab-macos/commit/f97e9f9))
|
||||
|
||||
# [7.6.0](https://github.com/lwouis/alt-tab-macos/compare/v7.5.0...v7.6.0) (2024-12-01)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* better display on some external monitors (closes [#3866](https://github.com/lwouis/alt-tab-macos/issues/3866)) ([165a669](https://github.com/lwouis/alt-tab-macos/commit/165a669))
|
||||
* improve keyboard handling when macos is overwhelmed ([4a9b543](https://github.com/lwouis/alt-tab-macos/commit/4a9b543))
|
||||
* improve korean localization ([22aafce](https://github.com/lwouis/alt-tab-macos/commit/22aafce))
|
||||
|
||||
# [7.5.0](https://github.com/lwouis/alt-tab-macos/compare/v7.4.0...v7.5.0) (2024-11-27)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* improve da, hu, tr localizations ([ffdab44](https://github.com/lwouis/alt-tab-macos/commit/ffdab44))
|
||||
* in-app feedback form now requires a title ([05851fb](https://github.com/lwouis/alt-tab-macos/commit/05851fb))
|
||||
* update switcher max-width to 90% of screen, like windows 11 ([a94eeb0](https://github.com/lwouis/alt-tab-macos/commit/a94eeb0))
|
||||
|
||||
# [7.4.0](https://github.com/lwouis/alt-tab-macos/compare/v7.3.0...v7.4.0) (2024-11-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* permission callout could show even with permission granted ([9585c92](https://github.com/lwouis/alt-tab-macos/commit/9585c92)), closes [#3801](https://github.com/lwouis/alt-tab-macos/issues/3801)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* better switcher max-width at various monitor sizes ([49178b5](https://github.com/lwouis/alt-tab-macos/commit/49178b5))
|
||||
* improve ar, de, el, hu, it, ko, pt localizations ([c4f98a1](https://github.com/lwouis/alt-tab-macos/commit/c4f98a1))
|
||||
|
||||
# [7.3.0](https://github.com/lwouis/alt-tab-macos/compare/v7.2.0...v7.3.0) (2024-11-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* better handle screen or space changes (closes [#1254](https://github.com/lwouis/alt-tab-macos/issues/1254), closes [#2983](https://github.com/lwouis/alt-tab-macos/issues/2983)) ([3c4aaf5](https://github.com/lwouis/alt-tab-macos/commit/3c4aaf5))
|
||||
* potential issues with key repeats due to concurrency ([4cfe16a](https://github.com/lwouis/alt-tab-macos/commit/4cfe16a))
|
||||
* switcher would not close, or cycle on its own (closes [#3117](https://github.com/lwouis/alt-tab-macos/issues/3117)) ([d430f83](https://github.com/lwouis/alt-tab-macos/commit/d430f83))
|
||||
* works without screen-recording permissions (closes [#3819](https://github.com/lwouis/alt-tab-macos/issues/3819)) ([f7de2bb](https://github.com/lwouis/alt-tab-macos/commit/f7de2bb))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* can pass the --logs= flags at launch to show logs ([81eb07e](https://github.com/lwouis/alt-tab-macos/commit/81eb07e))
|
||||
* improve el, fi, hi, it, pl, pt localizations ([a9614c1](https://github.com/lwouis/alt-tab-macos/commit/a9614c1))
|
||||
|
||||
# [7.2.0](https://github.com/lwouis/alt-tab-macos/compare/v7.1.1...v7.2.0) (2024-11-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* hide space labels when showing same-space windows ([88c1595](https://github.com/lwouis/alt-tab-macos/commit/88c1595)), closes [#3766](https://github.com/lwouis/alt-tab-macos/issues/3766)
|
||||
* improve switcher layout and presentation ([545b5db](https://github.com/lwouis/alt-tab-macos/commit/545b5db))
|
||||
|
||||
## [7.1.1](https://github.com/lwouis/alt-tab-macos/compare/v7.1.0...v7.1.1) (2024-11-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* blacklist could prevent app launch in v7.1.0 ([8f4784f](https://github.com/lwouis/alt-tab-macos/commit/8f4784f))
|
||||
|
||||
# [7.1.0](https://github.com/lwouis/alt-tab-macos/compare/v7.0.2...v7.1.0) (2024-11-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fixed the rounded corners when the mouse moves over the table ([dd379c4](https://github.com/lwouis/alt-tab-macos/commit/dd379c4))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add irish localization ([19f59b2](https://github.com/lwouis/alt-tab-macos/commit/19f59b2))
|
||||
* add language preference ([f33418e](https://github.com/lwouis/alt-tab-macos/commit/f33418e))
|
||||
* allow to run the app without screen-recording permissions ([129d061](https://github.com/lwouis/alt-tab-macos/commit/129d061)), closes [#1082](https://github.com/lwouis/alt-tab-macos/issues/1082)
|
||||
* hide space labels when showing same-space windows (closes [#3766](https://github.com/lwouis/alt-tab-macos/issues/3766)) ([ad64ced](https://github.com/lwouis/alt-tab-macos/commit/ad64ced))
|
||||
* i18n ([d77fa67](https://github.com/lwouis/alt-tab-macos/commit/d77fa67))
|
||||
* improve appearance at the different sizes ([2c857a6](https://github.com/lwouis/alt-tab-macos/commit/2c857a6))
|
||||
* improve display of wide/tall thumbnails (closes [#3791](https://github.com/lwouis/alt-tab-macos/issues/3791)) ([45bbc93](https://github.com/lwouis/alt-tab-macos/commit/45bbc93))
|
||||
* improve localizations ([9d1349b](https://github.com/lwouis/alt-tab-macos/commit/9d1349b))
|
||||
|
||||
## [7.0.2](https://github.com/lwouis/alt-tab-macos/compare/v7.0.1...v7.0.2) (2024-10-12)
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# Contributing
|
||||
|
||||
There are many ways to contribute:
|
||||
|
||||
* Come discuss with us on the [Discord server](https://discord.gg/CVEPeDufJa).
|
||||
* [Suggest an enhancement or discuss an issue on github](https://github.com/lwouis/alt-tab-macos/issues), or use the feedback form in the app.
|
||||
* [Localize the app in your language](https://poeditor.com/join/project/8AOEZ0eAZE)
|
||||
|
||||
@@ -10,18 +7,14 @@ There are many ways to contribute:
|
||||
|
||||
This document gives a technical overview of the project, for newcomers who want to contribute.
|
||||
|
||||
## Building the project locally
|
||||
## Building the project
|
||||
|
||||
This project has minimal dependency on Xcode-only features (e.g. InterfaceBuilder, Playgrounds). You can build it by doing:
|
||||
|
||||
* `scripts/codesign/setup_local.sh` to generate a local self-signed certificate, to avoid having to re-check the `System Preferences > Security & Privacy` permissions on every build
|
||||
* Either open `alt-tab-macos.xcworkspace` with XCode, or use the cli: `xcodebuild -workspace alt-tab-macos.xcworkspace -scheme Debug` to build the .app with the `Debug` build configuration
|
||||
|
||||
## Raising a pull-request
|
||||
|
||||
If you want to contribute a PR, please run `npm install` once. It will add the pre-commit hook to ensure that your commits follow the convention and will pass the PR.
|
||||
|
||||
## Mac development ecosystem
|
||||
## Mac development
|
||||
|
||||
Mac development ecosystem is pretty terrible in general. They keep piling on the tech stacks on top of each other, so you have C APIs, ObjC APIs, Swift APIs, Interface builder, Playgrounds, Swift UI, Mac Catalyst. All these are bridging with each other with a bunch of macros, SDKs glue, compiler flags, compatibility mode, XCode legacy build system, etc. For alt-tab, we are on Swift 5.0. Note that swift just recently started being stable, but overall any change of version breaks a lot of stuff. Swift itself is the mainstream language with the worst governance I’ve seen in modern times.
|
||||
|
||||
@@ -31,9 +24,9 @@ Documentation is abysmal. Very simple things are not documented at all, and good
|
||||
|
||||
Dependencies were historically never handled by Apple. The community came up with [Cocoapods](https://cocoapods.org/) which is the de-facto dependency manager for Apple ecosystem projects these days, even though Apple is now trying to push their own.
|
||||
|
||||
OS APIs are quite limited for the kind of low-level, system-wide app AltTab is. This means often we just don’t have an API to do something. For instance, there is no API to ask the OS “how many Spaces does the user have?” or “Can you focus the window on Space 2?”. There are however, retro-engineered private APIs which you can call. These are not documented at all, not guaranteed to be there in future macOS releases, and prevent us from releasing AltTab on the Mac AppStore. We have tried my best to [document](https://github.com/lwouis/alt-tab-macos/blob/master/src/api-wrappers/PrivateApis.swift) the ones we are using, as well as ones we investigated in the past.
|
||||
OS APIs are quite limited for the kind of low-level, system-wide app AltTab is. This means often we just don’t have an API to do something. For instance, there is no API to ask the OS “how many Spaces does the user have?” or “Can you focus the window on Space 2?”. There are however, retro-engineered private APIs which you can call. These are not documented at all, not guaranteed to be there in future macOS releases, and prevent us from releasing AltTab on the Mac AppStore. We have tried our best to [document the ones we are using](https://github.com/lwouis/alt-tab-macos/blob/master/src/api-wrappers/private-apis/README.md), as well as [the ones we investigated](https://github.com/lwouis/alt-tab-macos/blob/master/src/experimentations/PrivateApis.swift) in the past.
|
||||
|
||||
## This project specifically
|
||||
## Project architecture
|
||||
|
||||
To mitigate the issues listed above, we took some measures.
|
||||
|
||||
|
||||
@@ -1,229 +1,7 @@
|
||||
# Contributors
|
||||
## [Developed the app](https://github.com/lwouis/alt-tab-macos/graphs/contributors)
|
||||
|
||||
They helped [develop the app](https://github.com/lwouis/alt-tab-macos/graphs/contributors):
|
||||
[adamnemecek](https://github.com/adamnemecek), [AfzalivE](https://github.com/AfzalivE), [akx](https://github.com/akx), [Allsochen](https://github.com/Allsochen), [ayroblu](https://github.com/ayroblu), [britalmeida](https://github.com/britalmeida), [Calinou](https://github.com/Calinou), [damonpam](https://github.com/damonpam), [decodism](https://github.com/decodism), [delaneyb](https://github.com/delaneyb), [gingerr](https://github.com/gingerr), [GrzegorzKazana](https://github.com/GrzegorzKazana), [hughlilly](https://github.com/hughlilly), [karbassi](https://github.com/karbassi), [L1cardo](https://github.com/L1cardo), [lwouis](https://github.com/lwouis), [metacodes](https://github.com/metacodes), [mnin](https://github.com/mnin), [MrPaschenko](https://github.com/MrPaschenko), [nella17](https://github.com/nella17), [notlmn](https://github.com/notlmn), [phungtuanhoang1996](https://github.com/phungtuanhoang1996), [rbnis](https://github.com/rbnis), [Rjevski](https://github.com/Rjevski), [ShlomoCode](https://github.com/ShlomoCode), [skolj](https://github.com/skolj), [stopdesign](https://github.com/stopdesign), [xanathar](https://github.com/xanathar), [zacharee](https://github.com/zacharee)
|
||||
|
||||
* [adamnemecek](https://github.com/adamnemecek)
|
||||
* [AfzalivE](https://github.com/AfzalivE)
|
||||
* [akx](https://github.com/akx)
|
||||
* [Allsochen](https://github.com/Allsochen)
|
||||
* [ayroblu](https://github.com/ayroblu)
|
||||
* [Calinou](https://github.com/Calinou)
|
||||
* [damonpam](https://github.com/damonpam)
|
||||
* [decodism](https://github.com/decodism)
|
||||
* [gcbw](https://github.com/gcbw)
|
||||
* [gingerr](https://github.com/gingerr)
|
||||
* [GrzegorzKazana](https://github.com/GrzegorzKazana)
|
||||
* [hughlilly](https://github.com/hughlilly)
|
||||
* [karbassi](https://github.com/karbassi)
|
||||
* [L1cardo](https://github.com/L1cardo)
|
||||
* [lwouis](https://github.com/lwouis)
|
||||
* [metacodes](https://github.com/metacodes)
|
||||
* [mnin](https://github.com/mnin)
|
||||
* [MrPaschenko](https://github.com/MrPaschenko)
|
||||
* [nella17](https://github.com/nella17)
|
||||
* [notlmn](https://github.com/notlmn)
|
||||
* [phungtuanhoang1996](https://github.com/phungtuanhoang1996)
|
||||
* [rbnis](https://github.com/rbnis)
|
||||
* [Rjevski](https://github.com/Rjevski)
|
||||
* [samdenty](https://github.com/samdenty)
|
||||
* [ShlomoCode](https://github.com/ShlomoCode)
|
||||
* [skolj](https://github.com/skolj)
|
||||
* [xanathar](https://github.com/xanathar)
|
||||
* [xconverge](https://github.com/xconverge)
|
||||
* [zacharee](https://github.com/zacharee)
|
||||
## [Localized the app](https://poeditor.com/join/project/8AOEZ0eAZE)
|
||||
|
||||
They helped [localize the app](https://poeditor.com/join/project/8AOEZ0eAZE):
|
||||
|
||||
* 73
|
||||
* Aamirsuleman
|
||||
* Aarni Koskela
|
||||
* Abdulelah
|
||||
* Abdur-Rahman Bilal
|
||||
* Aden Aziz
|
||||
* Admin
|
||||
* Aindriú Mac Giolla Eoin
|
||||
* Ajaykumarmkaju
|
||||
* Albert Abdilim
|
||||
* Alex
|
||||
* Alexander Kilian
|
||||
* Ali Gokmen
|
||||
* Ali. tas103
|
||||
* Allen Guan
|
||||
* Alonso Chen
|
||||
* Ameng
|
||||
* Anders
|
||||
* Andrew Vader
|
||||
* antoon334
|
||||
* Anurag Roy
|
||||
* anushree b
|
||||
* Arman
|
||||
* Artem Stankov
|
||||
* Arthur
|
||||
* Ash
|
||||
* blanorama
|
||||
* bluefirex
|
||||
* bovirus
|
||||
* BV Joshi
|
||||
* caduellery
|
||||
* Caner İlhan
|
||||
* catcore
|
||||
* Christian Keilmann
|
||||
* Chun Fei Lung
|
||||
* codecantata
|
||||
* Cong Tri
|
||||
* Dan
|
||||
* Dan84
|
||||
* Darius Rosendahl
|
||||
* Darko
|
||||
* David R
|
||||
* Didier Deschrijver
|
||||
* Dzhuneyt
|
||||
* EDUARDO
|
||||
* edu_sombra
|
||||
* Eliezer Shpigelman
|
||||
* Eric WANTZ
|
||||
* Ersagun Kuruca
|
||||
* EUKA
|
||||
* Eukarya
|
||||
* Eyelly wu
|
||||
* Filipe
|
||||
* Frangarciasalomon
|
||||
* Frank
|
||||
* Friendship1
|
||||
* Fukuda
|
||||
* Gezimos
|
||||
* Giacomo Volpi
|
||||
* Giang
|
||||
* Github
|
||||
* Gkostov
|
||||
* Grzegorz Kazana
|
||||
* Guillaume
|
||||
* Gumpanath Puttarassu
|
||||
* hann-solo
|
||||
* Haoshuai Xu
|
||||
* Hjörtur Hjartarson
|
||||
* Hokuto Kato
|
||||
* Huandngoc
|
||||
* Huynh Sang
|
||||
* Ialiendeg
|
||||
* Ida Bomholt Dyrholm Jacobsen
|
||||
* Igor Aradski
|
||||
* Indexerrowaty
|
||||
* isametry
|
||||
* Ismatulla
|
||||
* Isthereanybody
|
||||
* Jaeyong Sung
|
||||
* Jakob
|
||||
* Jakob Licina
|
||||
* Jakub Bartušek
|
||||
* jiho4
|
||||
* Jisan
|
||||
* Joao Vitor Casarin
|
||||
* Jord Nijhuis
|
||||
* Jules Beckers
|
||||
* Julian Nowaczyk
|
||||
* Julio
|
||||
* Kagurazaka Tsuki
|
||||
* kal
|
||||
* kant
|
||||
* kazuki sakamoto
|
||||
* Kevinsevinche
|
||||
* Kinyagulovrr
|
||||
* Klara
|
||||
* Kristófer Fannar Björnsson
|
||||
* Kushnee5
|
||||
* Kuuchi
|
||||
* L
|
||||
* Lakshman Kolappan
|
||||
* Lasse Mattila
|
||||
* Lcwhhh
|
||||
* Lester
|
||||
* Loïc
|
||||
* Loic. peron
|
||||
* LostInCompilation
|
||||
* Lumaxis
|
||||
* lwouis
|
||||
* Maplevantablack
|
||||
* Marc Pla
|
||||
* Marcus Billman
|
||||
* Marekscholle
|
||||
* Marko McLion
|
||||
* Martin Mitka
|
||||
* Martin. mitka
|
||||
* Masayoshi Motojima
|
||||
* Masih
|
||||
* Matheus
|
||||
* Max
|
||||
* Maximilian Falk
|
||||
* MaximilianFreitag
|
||||
* Mehmet Ali Ertorer
|
||||
* Meriç Bağlayan
|
||||
* Michael
|
||||
* Milos M
|
||||
* Mohammad Al Zouabi
|
||||
* Mr. axel. bock
|
||||
* MuDraconis
|
||||
* Muzhenstudent
|
||||
* Mwolfinspace
|
||||
* Nathancodes
|
||||
* Nikola Rajić
|
||||
* Nils Fahldieck
|
||||
* Nilton Souza
|
||||
* Nmolham
|
||||
* Nuriddin Islamov
|
||||
* Ori
|
||||
* Paulius
|
||||
* Pehovorka
|
||||
* Peterkim0620
|
||||
* Petr Kolář
|
||||
* Piotr Budny
|
||||
* ponchik
|
||||
* Quentin. douarre
|
||||
* Raphaël
|
||||
* Rasmus
|
||||
* Raymonf
|
||||
* raz
|
||||
* Razvan
|
||||
* rbnis
|
||||
* rei fujise
|
||||
* Roccobot
|
||||
* Rodrigo Schneider
|
||||
* Ron Nuss
|
||||
* sawtooth
|
||||
* Selcuk Dursun
|
||||
* Sergey
|
||||
* Seyedparsa Mirtaheri
|
||||
* Shameem Reza
|
||||
* SheNeVmerla
|
||||
* Shivam Bansal
|
||||
* shlomo
|
||||
* Sippawit Thammawiset
|
||||
* Sjur Moshagen
|
||||
* Sjur.n. moshagen
|
||||
* Stan Smits
|
||||
* Stefan
|
||||
* Svetoslav Stefanov
|
||||
* Thomas Wölk
|
||||
* Thorsten
|
||||
* Tomoa Nozawa
|
||||
* Umutakkaya1996
|
||||
* Vadym
|
||||
* Vijayant Saini
|
||||
* Vincent Orback
|
||||
* Vlad
|
||||
* Webmaster
|
||||
* Wesley Matos
|
||||
* Whatsmine-HaoshuaiXu
|
||||
* Wilhelm Wolfgang Gärtner
|
||||
* Wowpapa3232
|
||||
* wtwt0119!!
|
||||
* Yongsung Yoon
|
||||
* Yorben
|
||||
* Yossi Zahn
|
||||
* ysaito
|
||||
* Yukai
|
||||
* yumechan
|
||||
* Yusuf Caliskan
|
||||
* 橙梓
|
||||
* Ивайло
|
||||
* Андрій Кирбаба
|
||||
73, A, a774 nn, Aamirsuleman, Aarni Koskela, Abdulelah, Abdur-Rahman Bilal, Aden Aziz, Admin, Aindriú Mac Giolla Eoin, Ajaykumarmkaju, Aku, Albert Abdilim, Aleksander Bang-Larsen, Alex, Alexander Kilian, Alexey Eremeev, Ali, Ali Gokmen, Ali. tas103, Allen Guan, Alonso Chen, Ameng, Anders, Andreas Wagner, Andrej Koman, Andrew Vader, antoon334, Anurag Roy, anushree b, Arman, Artem Stankov, Arthur, Ash, blanorama, bluefirex, BO the Man, bovirus, Bufo, BV Joshi, caduellery, Caner İlhan, catcore, changanmoon, Christian Keilmann, Chun Fei Lung, codecantata, codingalone, Cong Tri, Dan, Dan84, Darius Rosendahl, Darko, David R, Denis, Dékány Martin, dibas-np, Didier Deschrijver, Dzhuneyt, edu_sombra, EDUARDO, Eimantas, Eliezer Shpigelman, Emir H. KAYNAK, EP45, Eric WANTZ, Ersagun Kuruca, EUKA, Eukarya, Eyelly wu, fil, Filipe, Frangarciasalomon, Frank, Friendship1, Fukuda, Ganesh Sawant, Gezimos, Giacomo Volpi, Giang, Github, Gkostov, Grzegorz Kazana, Guillaume, Gumpanath Puttarassu, hann-solo, Haoshuai Xu, Hao豪, Heramb Lonkar, Hjörtur Hjartarson, Hokuto Kato, Huandngoc, Huynh Sang, Ialiendeg, Ida Bomholt Dyrholm Jacobsen, Igor Aradski, igorpocta, Indexerrowaty, Inês Almeida, isametry, Ismatulla, Isthereanybody, Jaeyong Sung, Jakob, Jakob Licina, Jakub Bartušek, Jesus Angel Villafuerte, jiho4, Jisan, Joao Vitor Casarin, Jord Nijhuis, Jui Yuan Liu, Jules Beckers, Julian Nowaczyk, Julio, justcontributor, Kagurazaka Tsuki, kal, kant, Kawarimidoll+git, kazuki sakamoto, Kevinsevinche, KillianG, Kinyagulovrr, Klara, Kostiantyn Ko, Kristófer Fannar Björnsson, Kushnee5, Kuuchi, Lakshman Kolappan, Lars, Lasse Mattila, Lcwhhh, Leo, Lester, Logan Boissy, Loic. peron, Loïc, LostInCompilation, Lumaxis, lwouis, M, Malo, Maplevantablack, Marc Pla, Marcus Billman, Marekscholle, Marko McLion, Martin Mitka, Martin. mitka, Masayoshi Motojima, Masih, Matheus, Max, Maximilian Falk, MaximilianFreitag, Mehmet Ali Ertorer, Meriç Bağlayan, Michael, Milos M, Mohammad Al Zouabi, mohma, Mohsin Rahman, Mr. axel. bock, mrtbts, MuDraconis, Muzhenstudent, Mwolfinspace, Nathancodes, NIKHIL S, Nikola Rajić, Nils Fahldieck, Nilton Souza, Nmolham, Nuriddin Islamov, Ori, Paul Pichaureau, Paul Przybyszewski, Paul. pichaureau, Pehovorka, Pendolino, Petar Shomov, Peterkim0620, Petr Kolář, Petter Johan Olsen, Piotr Budny, Quentin. douarre, Rajesh Kaswala, rajuneon, Rami Elsawy, Raphaël, Rasmus, Raymonf, raz, Razvan, rbnis, rei fujise, Roccobot, Roccobot, Rodrigo Schneider, Ron Nuss, rPaasch, Ryan Nardi, sa-ha, Sai Khant Zay Lynn Yaung, Sami Suleiman, Samimkel00, Saransh, sawtooth, Sebastian, Selcuk Dursun, Sergey, Serhii Alekseev, Seyedparsa Mirtaheri, Shameem Reza, SheNeVmerla, Shivam Bansal, shlomo, Sippawit Thammawiset, Sjur Moshagen, Sjur.n. moshagen, Stan Smits, star-affinity, Stefan, Stefan Lange, Svetoslav Stefanov, Tamilselvan0x0, Thebennue, Thomas Wölk, Thorsten, Thorsten, Tomoa Nozawa, Trevor, Tsilimpotis Dimitrios, Umutakkaya1996, Vadym, Vijayant Saini, Vincent Orback, Vlad, Webmaster, Wesley Matos, Whatsmine-HaoshuaiXu, White Vogel, Wilhelm Wolfgang Gärtner, Yongsung Yoon, Yorben, Yossi Zahn, ysaito, Yukai, yumechan, Yusuf Caliskan, Zamaialexander, Zuhaib Syed, Τσιλιμπότης Δημ., Андрій Кирбаба, Ивайло, Пустой, 林清, 橙梓
|
||||
@@ -0,0 +1,36 @@
|
||||
## Can it show, or hide, this window?
|
||||
|
||||
It's sometimes hard to say that some dialog, HUD, UI element, is a window or not. Not everyone will agree that a particular window is a window. AltTab does its best to decide what a window is, and show it to the user.
|
||||
|
||||
Some apps are not native macOS apps, or poorly programmed. Such apps will use "windows" to code things like menus, and play tricks like hidding a window instead of closing it. Notorious examples: Electron apps (e.g. Slack, Discord, etc) and apps using cross-platform SDKs (e.g. Adobe apps, Steam, IntelliJ, etc).
|
||||
|
||||
If a window is showing, and you think it shouldn't, please contact the app maker so they can fix their product.
|
||||
|
||||
## Can it show individual browser tabs?
|
||||
|
||||
Browser windows are not standard windows or tabs. They are custom UI painted by each browser, in their own unique way. There is no macOS API to screenshot a browser tab. Some browser may not even render a tab that's not active, so there are no pixels to screenshot.
|
||||
|
||||
Browser may offer custom integration to know about tabs, screenshot, active them. However, each browser is unique, and it would require to write these integrations for each one, as well as to maintain them. Browsers evolve fast, so maintaining multiple fast-changing integrations is not attainable.
|
||||
|
||||
## Can we add window-management features?
|
||||
|
||||
AltTab is not intended to be a window manager. It will not add features such as: resizing windows, organizing them into tiles, Dock enhancements.
|
||||
|
||||
[Other apps](http://localhost:4000/#alternatives) offer such experiences.
|
||||
|
||||
AltTab aims at being the best at the Windows-style alt+tab experience.
|
||||
|
||||
## Can it be on the App Store?
|
||||
|
||||
AltTab uses **many** private APIs. This prevents us from publishing on the App Store. It's a shame. Many more casual users would benefit from it. However, without these private APIs, the user experience would be crippled. We use private APIs for refined details, but also for basic functionality.
|
||||
|
||||
## Where are settings stored?
|
||||
|
||||
The app uses the standard macOS API to store settings. You can interact with them from the Terminal, using the `defaults` command:
|
||||
* List current settings: `defaults read com.lwouis.alt-tab-macos.plist`
|
||||
* Update a setting: `defaults write com.lwouis.alt-tab-macos.plist AppleAccentColor -int 4`
|
||||
* Export settings to a file: `defaults export com.lwouis.alt-tab-macos.plist /tmp/my-export.plist`
|
||||
|
||||
## Can I share an idea or report a bug?
|
||||
|
||||
Please open an issue on [GitHub](https://github.com/lwouis/alt-tab-macos/issues)
|
||||
@@ -1,133 +1,126 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (6.1.7.10)
|
||||
activesupport (6.0.2.2)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
zeitwerk (~> 2.3)
|
||||
addressable (2.8.7)
|
||||
public_suffix (>= 2.0.2, < 7.0)
|
||||
base64 (0.2.0)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
zeitwerk (~> 2.2)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.12.2)
|
||||
coffee-script-source (1.11.1)
|
||||
colorator (1.1.0)
|
||||
commonmarker (0.23.10)
|
||||
concurrent-ruby (1.3.4)
|
||||
dnsruby (1.72.2)
|
||||
simpleidn (~> 0.2.1)
|
||||
em-websocket (0.5.3)
|
||||
commonmarker (0.17.13)
|
||||
ruby-enum (~> 0.5)
|
||||
concurrent-ruby (1.1.6)
|
||||
dnsruby (1.61.3)
|
||||
addressable (~> 2.5)
|
||||
em-websocket (0.5.1)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
http_parser.rb (~> 0.6.0)
|
||||
ethon (0.12.0)
|
||||
ffi (>= 1.3.0)
|
||||
eventmachine (1.2.7)
|
||||
execjs (2.10.0)
|
||||
faraday (2.8.1)
|
||||
base64
|
||||
faraday-net_http (>= 2.0, < 3.1)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-net_http (3.0.2)
|
||||
ffi (1.17.0)
|
||||
execjs (2.7.0)
|
||||
faraday (1.0.1)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.12.2)
|
||||
forwardable-extended (2.6.0)
|
||||
gemoji (4.1.0)
|
||||
github-pages (231)
|
||||
github-pages-health-check (= 1.18.2)
|
||||
jekyll (= 3.9.5)
|
||||
jekyll-avatar (= 0.8.0)
|
||||
jekyll-coffeescript (= 1.2.2)
|
||||
jekyll-commonmark-ghpages (= 0.4.0)
|
||||
jekyll-default-layout (= 0.1.5)
|
||||
jekyll-feed (= 0.17.0)
|
||||
gemoji (3.0.1)
|
||||
github-pages (204)
|
||||
github-pages-health-check (= 1.16.1)
|
||||
jekyll (= 3.8.5)
|
||||
jekyll-avatar (= 0.7.0)
|
||||
jekyll-coffeescript (= 1.1.1)
|
||||
jekyll-commonmark-ghpages (= 0.1.6)
|
||||
jekyll-default-layout (= 0.1.4)
|
||||
jekyll-feed (= 0.13.0)
|
||||
jekyll-gist (= 1.5.0)
|
||||
jekyll-github-metadata (= 2.16.1)
|
||||
jekyll-include-cache (= 0.2.1)
|
||||
jekyll-mentions (= 1.6.0)
|
||||
jekyll-github-metadata (= 2.13.0)
|
||||
jekyll-mentions (= 1.5.1)
|
||||
jekyll-optional-front-matter (= 0.3.2)
|
||||
jekyll-paginate (= 1.1.0)
|
||||
jekyll-readme-index (= 0.3.0)
|
||||
jekyll-redirect-from (= 0.16.0)
|
||||
jekyll-redirect-from (= 0.15.0)
|
||||
jekyll-relative-links (= 0.6.1)
|
||||
jekyll-remote-theme (= 0.4.3)
|
||||
jekyll-remote-theme (= 0.4.1)
|
||||
jekyll-sass-converter (= 1.5.2)
|
||||
jekyll-seo-tag (= 2.8.0)
|
||||
jekyll-seo-tag (= 2.6.1)
|
||||
jekyll-sitemap (= 1.4.0)
|
||||
jekyll-swiss (= 1.0.0)
|
||||
jekyll-theme-architect (= 0.2.0)
|
||||
jekyll-theme-cayman (= 0.2.0)
|
||||
jekyll-theme-dinky (= 0.2.0)
|
||||
jekyll-theme-hacker (= 0.2.0)
|
||||
jekyll-theme-leap-day (= 0.2.0)
|
||||
jekyll-theme-merlot (= 0.2.0)
|
||||
jekyll-theme-midnight (= 0.2.0)
|
||||
jekyll-theme-minimal (= 0.2.0)
|
||||
jekyll-theme-modernist (= 0.2.0)
|
||||
jekyll-theme-primer (= 0.6.0)
|
||||
jekyll-theme-slate (= 0.2.0)
|
||||
jekyll-theme-tactile (= 0.2.0)
|
||||
jekyll-theme-time-machine (= 0.2.0)
|
||||
jekyll-theme-architect (= 0.1.1)
|
||||
jekyll-theme-cayman (= 0.1.1)
|
||||
jekyll-theme-dinky (= 0.1.1)
|
||||
jekyll-theme-hacker (= 0.1.1)
|
||||
jekyll-theme-leap-day (= 0.1.1)
|
||||
jekyll-theme-merlot (= 0.1.1)
|
||||
jekyll-theme-midnight (= 0.1.1)
|
||||
jekyll-theme-minimal (= 0.1.1)
|
||||
jekyll-theme-modernist (= 0.1.1)
|
||||
jekyll-theme-primer (= 0.5.4)
|
||||
jekyll-theme-slate (= 0.1.1)
|
||||
jekyll-theme-tactile (= 0.1.1)
|
||||
jekyll-theme-time-machine (= 0.1.1)
|
||||
jekyll-titles-from-headings (= 0.5.3)
|
||||
jemoji (= 0.13.0)
|
||||
kramdown (= 2.4.0)
|
||||
kramdown-parser-gfm (= 1.1.0)
|
||||
liquid (= 4.0.4)
|
||||
jemoji (= 0.11.1)
|
||||
kramdown (= 1.17.0)
|
||||
liquid (= 4.0.3)
|
||||
mercenary (~> 0.3)
|
||||
minima (= 2.5.1)
|
||||
nokogiri (>= 1.13.6, < 2.0)
|
||||
rouge (= 3.30.0)
|
||||
nokogiri (>= 1.10.4, < 2.0)
|
||||
rouge (= 3.13.0)
|
||||
terminal-table (~> 1.4)
|
||||
github-pages-health-check (1.18.2)
|
||||
github-pages-health-check (1.16.1)
|
||||
addressable (~> 2.3)
|
||||
dnsruby (~> 1.60)
|
||||
octokit (>= 4, < 8)
|
||||
public_suffix (>= 3.0, < 6.0)
|
||||
octokit (~> 4.0)
|
||||
public_suffix (~> 3.0)
|
||||
typhoeus (~> 1.3)
|
||||
html-pipeline (2.14.3)
|
||||
html-pipeline (2.12.3)
|
||||
activesupport (>= 2)
|
||||
nokogiri (>= 1.4)
|
||||
http_parser.rb (0.8.0)
|
||||
i18n (1.14.6)
|
||||
http_parser.rb (0.6.0)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jekyll (3.9.5)
|
||||
jekyll (3.8.5)
|
||||
addressable (~> 2.4)
|
||||
colorator (~> 1.0)
|
||||
em-websocket (~> 0.5)
|
||||
i18n (>= 0.7, < 2)
|
||||
i18n (~> 0.7)
|
||||
jekyll-sass-converter (~> 1.0)
|
||||
jekyll-watch (~> 2.0)
|
||||
kramdown (>= 1.17, < 3)
|
||||
kramdown (~> 1.14)
|
||||
liquid (~> 4.0)
|
||||
mercenary (~> 0.3.3)
|
||||
pathutil (~> 0.9)
|
||||
rouge (>= 1.7, < 4)
|
||||
safe_yaml (~> 1.0)
|
||||
jekyll-avatar (0.8.0)
|
||||
jekyll-avatar (0.7.0)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-coffeescript (1.2.2)
|
||||
jekyll-coffeescript (1.1.1)
|
||||
coffee-script (~> 2.2)
|
||||
coffee-script-source (~> 1.12)
|
||||
jekyll-commonmark (1.4.0)
|
||||
commonmarker (~> 0.22)
|
||||
jekyll-commonmark-ghpages (0.4.0)
|
||||
commonmarker (~> 0.23.7)
|
||||
jekyll (~> 3.9.0)
|
||||
jekyll-commonmark (~> 1.4.0)
|
||||
rouge (>= 2.0, < 5.0)
|
||||
jekyll-default-layout (0.1.5)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-feed (0.17.0)
|
||||
coffee-script-source (~> 1.11.1)
|
||||
jekyll-commonmark (1.3.1)
|
||||
commonmarker (~> 0.14)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-commonmark-ghpages (0.1.6)
|
||||
commonmarker (~> 0.17.6)
|
||||
jekyll-commonmark (~> 1.2)
|
||||
rouge (>= 2.0, < 4.0)
|
||||
jekyll-default-layout (0.1.4)
|
||||
jekyll (~> 3.0)
|
||||
jekyll-feed (0.13.0)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-gist (1.5.0)
|
||||
octokit (~> 4.2)
|
||||
jekyll-github-metadata (2.16.1)
|
||||
jekyll-github-metadata (2.13.0)
|
||||
jekyll (>= 3.4, < 5.0)
|
||||
octokit (>= 4, < 7, != 4.4.0)
|
||||
jekyll-include-cache (0.2.1)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-mentions (1.6.0)
|
||||
octokit (~> 4.0, != 4.4.0)
|
||||
jekyll-mentions (1.5.1)
|
||||
html-pipeline (~> 2.3)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-optional-front-matter (0.3.2)
|
||||
@@ -135,120 +128,115 @@ GEM
|
||||
jekyll-paginate (1.1.0)
|
||||
jekyll-readme-index (0.3.0)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-redirect-from (0.16.0)
|
||||
jekyll-redirect-from (0.15.0)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-relative-links (0.6.1)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-remote-theme (0.4.3)
|
||||
jekyll-remote-theme (0.4.1)
|
||||
addressable (~> 2.0)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
|
||||
rubyzip (>= 1.3.0, < 3.0)
|
||||
rubyzip (>= 1.3.0)
|
||||
jekyll-sass-converter (1.5.2)
|
||||
sass (~> 3.4)
|
||||
jekyll-seo-tag (2.8.0)
|
||||
jekyll (>= 3.8, < 5.0)
|
||||
jekyll-seo-tag (2.6.1)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-sitemap (1.4.0)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-swiss (1.0.0)
|
||||
jekyll-theme-architect (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-theme-architect (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-cayman (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-theme-cayman (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-dinky (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-theme-dinky (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-hacker (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-theme-hacker (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-leap-day (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-theme-leap-day (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-merlot (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-theme-merlot (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-midnight (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-theme-midnight (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-minimal (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-theme-minimal (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-modernist (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-theme-modernist (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-primer (0.6.0)
|
||||
jekyll-theme-primer (0.5.4)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-github-metadata (~> 2.9)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-slate (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-theme-slate (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-tactile (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-theme-tactile (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-time-machine (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-theme-time-machine (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-titles-from-headings (0.5.3)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-watch (2.2.1)
|
||||
listen (~> 3.0)
|
||||
jemoji (0.13.0)
|
||||
gemoji (>= 3, < 5)
|
||||
jemoji (0.11.1)
|
||||
gemoji (~> 3.0)
|
||||
html-pipeline (~> 2.2)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
kramdown (2.4.0)
|
||||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
liquid (4.0.4)
|
||||
listen (3.9.0)
|
||||
kramdown (1.17.0)
|
||||
liquid (4.0.3)
|
||||
listen (3.2.1)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
mercenary (0.3.6)
|
||||
mini_portile2 (2.8.7)
|
||||
mini_portile2 (2.4.0)
|
||||
minima (2.5.1)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
jekyll-feed (~> 0.9)
|
||||
jekyll-seo-tag (~> 2.1)
|
||||
minitest (5.25.1)
|
||||
nokogiri (1.13.10)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
octokit (4.25.1)
|
||||
faraday (>= 1, < 3)
|
||||
sawyer (~> 0.9)
|
||||
minitest (5.14.0)
|
||||
multipart-post (2.1.1)
|
||||
nokogiri (1.10.9)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
octokit (4.18.0)
|
||||
faraday (>= 0.9)
|
||||
sawyer (~> 0.8.0, >= 0.5.3)
|
||||
pathutil (0.16.2)
|
||||
forwardable-extended (~> 2.6)
|
||||
public_suffix (5.1.1)
|
||||
racc (1.8.1)
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.11.1)
|
||||
public_suffix (3.1.1)
|
||||
rb-fsevent (0.10.3)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rexml (3.3.9)
|
||||
rouge (3.30.0)
|
||||
ruby2_keywords (0.0.5)
|
||||
rubyzip (2.3.2)
|
||||
rouge (3.13.0)
|
||||
ruby-enum (0.8.0)
|
||||
i18n
|
||||
rubyzip (2.3.0)
|
||||
safe_yaml (1.0.5)
|
||||
sass (3.7.4)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
sawyer (0.9.2)
|
||||
sawyer (0.8.2)
|
||||
addressable (>= 2.3.5)
|
||||
faraday (>= 0.17.3, < 3)
|
||||
simpleidn (0.2.3)
|
||||
faraday (> 0.8, < 2.0)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
typhoeus (1.4.1)
|
||||
thread_safe (0.3.6)
|
||||
typhoeus (1.3.1)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
unicode-display_width (1.8.0)
|
||||
zeitwerk (2.6.18)
|
||||
tzinfo (1.2.7)
|
||||
thread_safe (~> 0.1)
|
||||
unicode-display_width (1.7.0)
|
||||
zeitwerk (2.3.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
@@ -2,13 +2,18 @@
|
||||
permalink: /
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
[<img src="public/demo/frontpage.jpg" alt="Screenshot showing AltTab" width="1920" height="1080" style="width:100%; height:auto;" />](public/demo/frontpage.jpg)
|
||||
[<img src="public/demo/frontpage.jpg" alt="Screenshot showing AltTab" width="1920" height="1080" style="width:100%; height:auto;" class="can-extend" />](public/demo/frontpage.jpg)
|
||||
|
||||
Alternative Styles
|
||||
|
||||
| [<img loading="lazy" src="public/demo/app-icons-style.jpg" alt="Screenshot: App Icons Style" width="513" height="241" style="width:100%; height:auto;" />](public/demo/app-icons-style.jpg) | [<img loading="lazy" src="public/demo/titles-style.jpg" alt="Screenshot: Titles Style" width="766" height="248" style="width:100%; height:auto;" />](public/demo/titles-style.jpg) |
|
||||
<div class="can-extend" style="display:flex; align-items:center; gap:10px;">
|
||||
<a href="public/demo/app-icons-style.jpg">
|
||||
<img loading="lazy" src="public/demo/app-icons-style.jpg" alt="Screenshot: App Icons Style" width="513" height="241" style="width:100%; height:auto;" />
|
||||
</a>
|
||||
<a href="public/demo/titles-style.jpg">
|
||||
<img loading="lazy" src="public/demo/titles-style.jpg" alt="Screenshot: Titles Style" width="766" height="248" style="width:100%; height:auto;" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -33,22 +38,42 @@ Alternative Styles
|
||||
|
||||
## Localization
|
||||
|
||||
AltTab is available in many languages: Bahasa Indonesia, Català, Dansk, Deutsch, Eesti keel, English, Español, Français, Gaeilge, Galego, Hrvatski, Italiano, Kurdî, Limba română, Lëtzebuergesch, Magyar, Nederlands, Norsk Bokmål, Norsk Nynorsk, Oʻzbekcha, Polski, Português, Português (Brasil), Shqip, Slovenčina, Slovenščina, Suomi, Svenska, Tiếng Việt, Türkçe, Íslenska, Čeština, Ελληνικά, Български, Русский, Српски / Srpski, Українська, עִבְרִית, العربية, فارسی, हिन्दी, বাংলা, தமிழ், ಕನ್ನಡ, മലയാളം, ภาษาไทย, 日本語, 简体中文, 繁體中文, 한국어
|
||||
AltTab is available in many languages: Bahasa Indonesia, Basa Jawa, Català, Čeština, Dansk, Deutsch, Eesti keel, English, Español, Français, Gaeilge, Galego, Hrvatski, Íslenska, Italiano, Kurdî, Lietuvių, Lëtzebuergesch, Magyar, Nederlands, Norsk Bokmål, Norsk Nynorsk, Oʻzbekcha, Polski, Português, Português (Brasil), Română, Shqip, Slovenčina, Slovenščina, Suomi, Svenska, Tiếng Việt, Türkçe, Беларуская мова, Български, Русский, Српски, Українська, Ελληνικά, עִבְרִית, العربية, فارسی, हिन्दी, বাংলা, ગુજરાતી, தமிழ், ಕನ್ನಡ, മലയാളം, ภาษาไทย, 日本語, 简体中文, 繁體中文, 繁體中文 (香港), 한국어
|
||||
|
||||
[Contribute your own language easily!](https://poeditor.com/join/project/8AOEZ0eAZE)
|
||||
|
||||
## Privacy and respecting the user
|
||||
## Privacy
|
||||
|
||||
* AltTab doesn’t upload or download any data without the user explicitly asking for it (e.g. asking to update the app, sending a crash report, etc)
|
||||
* AltTab uses as few resources as possible: CPU, memory, disk, etc. The app footprint is small (e.g. small disk size, minimal CPU use in the background, etc)
|
||||
AltTab doesn’t communicate to any server for so-called telemetry. AltTab will only use the network if it's absolutely required (e.g. checking for updates).
|
||||
|
||||
## Performance
|
||||
|
||||
AltTab has been designed to take as few resources as possible on the user computer. The app itself is kept as small as possible. CPU usage is kept to a minimum, especially while in the background. The goal is to respect the user and try to have no negative impact on their experience.
|
||||
|
||||
## Configuration
|
||||
|
||||
Change the shortcut keys, switch to a Windows theme and more, using the Preferences window:
|
||||
Change the shortcut keys, switch to a Windows theme and more, using the Settings window:
|
||||
|
||||
| [<img loading="lazy" src="public/demo/preferences-general.jpg" alt="Screenshot: General preferences" width="672" height="354" style="width:100%; height:auto;" />](public/demo/preferences-general.jpg) | [<img loading="lazy" src="public/demo/preferences-controls.jpg" alt="Screenshot: Controls preferences" width="677" height="688" style="width:100%; height:auto;" />](public/demo/preferences-controls.jpg) |
|
||||
| [<img loading="lazy" src="public/demo/preferences-appearance.jpg" alt="Screenshot: Appearance preferences" width="672" height="735" style="width:100%; height:auto;" />](public/demo/preferences-appearance.jpg) | [<img loading="lazy" src="public/demo/preferences-appearance-details.jpg" alt="Screenshot: Appearance preferences (details)" width="672" height="934" style="width:100%; height:auto;" />](public/demo/preferences-appearance-details.jpg) |
|
||||
| [<img loading="lazy" src="public/demo/preferences-blacklist.jpg" alt="Screenshot: Blacklist preferences" width="672" height="655" style="width:100%; height:auto;" />](public/demo/preferences-blacklist.jpg) | [<img loading="lazy" src="public/demo/preferences-policies.jpg" alt="Screenshot: Policies preferences" width="672" height="353" style="width:100%; height:auto;" />](public/demo/preferences-policies.jpg) |
|
||||
<div class="can-extend" style="display:flex; align-items:center; flex-wrap: wrap;">
|
||||
<a href="public/demo/preferences-general.jpg"><img loading="lazy" src="public/demo/preferences-general.jpg" alt="Screenshot: General preferences" width="672" height="354" style="width:100%; height:auto; max-width:330px;" /></a>
|
||||
<a href="public/demo/preferences-controls.jpg"><img loading="lazy" src="public/demo/preferences-controls.jpg" alt="Screenshot: Controls preferences" width="677" height="688" style="width:100%; height:auto; max-width:330px;" /></a>
|
||||
<a href="public/demo/preferences-appearance.jpg"><img loading="lazy" src="public/demo/preferences-appearance.jpg" alt="Screenshot: Appearance preferences" width="672" height="735" style="width:100%; height:auto; max-width:330px;" /></a>
|
||||
<a href="public/demo/preferences-appearance-details.jpg"><img loading="lazy" src="public/demo/preferences-appearance-details.jpg" alt="Screenshot: Appearance preferences (details)" width="672" height="934" style="width:100%; height:auto; max-width:330px;" /></a>
|
||||
<a href="public/demo/preferences-blacklist.jpg"><img loading="lazy" src="public/demo/preferences-blacklist.jpg" alt="Screenshot: Blacklist preferences" width="672" height="655" style="width:100%; height:auto; max-width:330px;" /></a>
|
||||
<a href="public/demo/preferences-policies.jpg"><img loading="lazy" src="public/demo/preferences-policies.jpg" alt="Screenshot: Policies preferences" width="672" height="353" style="width:100%; height:auto; max-width:330px;" /></a>
|
||||
</div>
|
||||
|
||||
## CLI usage
|
||||
|
||||
You can run CLI commands directly on the executable inside the .app bundle (e.g. `/Applications/AltTab.app/Contents/MacOS/AltTab`)
|
||||
|
||||
* `AltTab --list` will return the list of windows (ID and title) in JSON
|
||||
* `AltTab --detailed-list` will return the list of windows (lots of info) in JSON
|
||||
* `AltTab --show=shortcut_index` will show AltTab UI, as if the corresponding shortcut was pressed
|
||||
* `AltTab --focus=window_id` will focus the window with the specified ID (get it from --list)
|
||||
* `AltTab --focusUsingLastFocusOrder=focus_order` will focus the window with the specified focus-order (get it from --detailed-list)
|
||||
|
||||
For this to work, you need AltTab.app to be running, to keep track of the state of windows, and execute the commands
|
||||
|
||||
## Alternatives
|
||||
|
||||
@@ -65,7 +90,7 @@ Before building my own app, I looked around at similar apps. However, none was c
|
||||
| Built-in `⌘ command` + `⇥ tab` | Only shows apps, not windows (note: can press down to see window of selected app) |
|
||||
| Built-in `⌘ command` + `` ` `` | Cycles through tabs and windows, but only of the same app. Only cycling, no direct access |
|
||||
|
||||
There are also related apps which don’t really overlap in functionality, but target similar needs: [Swish](https://highlyopinionated.co/swish/), [Hookshot](https://hookshot.app/), [Magnet](https://magnet.crowdcafe.com/), [Spectacle](https://www.spectacleapp.com/), [Rectangle](https://github.com/rxhanson/Rectangle), [yabai](https://github.com/koekeishiya/yabai), [LayAuto](https://layautoapp.com/), [OptimalLayout](http://most-advantageous.com/optimal-layout/), [BetterTouchTool](https://folivora.ai/), [BetterSnapTool](https://folivora.ai/bettersnaptool), [Moom](https://manytricks.com/moom/), [uBar](https://brawersoftware.com/products/ubar).
|
||||
There are also related apps which don’t really overlap in functionality, but target similar needs: [Swish](https://highlyopinionated.co/swish/), [Hookshot](https://hookshot.app/), [Magnet](https://magnet.crowdcafe.com/), [Spectacle](https://www.spectacleapp.com/), [Rectangle](https://github.com/rxhanson/Rectangle), [yabai](https://github.com/koekeishiya/yabai), [LayAuto](https://layautoapp.com/), [BetterTouchTool](https://folivora.ai/), [BetterSnapTool](https://folivora.ai/bettersnaptool), [Moom](https://manytricks.com/moom/), [uBar](https://brawersoftware.com/products/ubar).
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -1,6 +1,28 @@
|
||||
# Support this project
|
||||
<h1 style="text-align:center">Support this project ❤️</h1>
|
||||
|
||||
There are 2 ways to support this project:
|
||||
|
||||
* [Patreon](https://www.patreon.com/lwouis/membership)
|
||||
* [GitHub Sponsors](https://github.com/sponsors/lwouis)
|
||||
<div class="support-buttons">
|
||||
<div class="support-button-wrapper">
|
||||
<a href="https://www.paypal.com/donate/?hosted_button_id=ACYAC3UYCM7CN" target="_blank" class="support-button">
|
||||
<img src="public/support/logo-paypal.png" class="paypal" alt="PayPal">
|
||||
</a>
|
||||
<img src="public/support/mascot-cat.png" class="mascot cat" alt="">
|
||||
</div>
|
||||
<div class="support-button-wrapper">
|
||||
<a href="https://github.com/sponsors/lwouis" target="_blank" class="support-button">
|
||||
<img src="public/support/logo-github-sponsors.png" class="github-sponsors" alt="GitHub Sponsors">
|
||||
</a>
|
||||
<img src="public/support/mascot-dog.png" class="mascot dog" alt="">
|
||||
</div>
|
||||
<div class="support-button-wrapper">
|
||||
<a href="https://www.patreon.com/alt_tab_macos" target="_blank" class="support-button">
|
||||
<img src="public/support/logo-patreon.svg" class="patreon" alt="Patreon">
|
||||
</a>
|
||||
<img src="public/support/mascot-squirrel.png" class="mascot squirrel" alt="">
|
||||
</div>
|
||||
<div class="support-button-wrapper">
|
||||
<a href="https://donate.stripe.com/4gw9D7bA3g3O0ikaEF" target="_blank" class="support-button">
|
||||
<img src="public/support/logo-stripe.svg" class="stripe" alt="Stripe">
|
||||
</a>
|
||||
<img src="public/support/mascot-rabbit.png" class="mascot rabbit" alt="">
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,221 +1,569 @@
|
||||
$width: 700px;
|
||||
|
||||
html, body {
|
||||
width: 100%;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
//margin: 0;
|
||||
//padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
html, body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
line-height: 1.6;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;
|
||||
//background-color: #a9e7da;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
header {
|
||||
width: 100%;
|
||||
:root {
|
||||
--sidebar-bg: #f1f7ff;
|
||||
--content-bg: #ffffff;
|
||||
--item-bg: #cfe0ff;
|
||||
--subitem-bg: #b9d0ff;
|
||||
--border: #c0d3ff;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0366d6;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
code, pre, tt {
|
||||
padding: .2em .4em;
|
||||
margin: 0;
|
||||
font-size: 85%;
|
||||
background-color: rgba(27, 31, 35, .05);
|
||||
border-radius: 3px;
|
||||
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 0.2em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.1em;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
|
||||
thead {
|
||||
text-align: left;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
thead {
|
||||
border-bottom: 7px solid #fff;
|
||||
}
|
||||
|
||||
tr {
|
||||
border-bottom: 7px solid #fff;
|
||||
border-top: 7px solid #fff;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
tr:first-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
tr:last-child {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
td, th {
|
||||
border-left: 5px solid #fff;
|
||||
border-right: 5px solid #fff;
|
||||
}
|
||||
|
||||
td:first-child, th:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
td:last-child, th:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
|
||||
li + li {
|
||||
margin-top: .25em;
|
||||
}
|
||||
|
||||
/* ---------- Root ---------- */
|
||||
.layout {
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 20px 0 5px 10px;
|
||||
line-height: 1;
|
||||
/* ---------- Desktop layout ---------- */
|
||||
.app {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background-color: #dccb921c;
|
||||
}
|
||||
|
||||
/* ---------- Sidebar ---------- */
|
||||
.sidebar {
|
||||
flex-shrink: 0;
|
||||
width: 262px;
|
||||
background: var(--sidebar-bg);
|
||||
//border-right: 2px solid var(--border);
|
||||
box-shadow: rgb(216, 231, 251) 0px 2px 4px 1px;
|
||||
overflow-y: auto;
|
||||
padding: 16px;
|
||||
|
||||
#turbolinks-header {
|
||||
|
||||
#logo {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a.button.rainbow {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
z-index: 0;
|
||||
background: linear-gradient(60deg, #f79533, #f37055, #ef4e7b, #a166ab, #5073b8, #1098ad, #07b39b, #6fba82);
|
||||
background-size: 300% 300%;
|
||||
animation: animatedgradient 5s linear infinite;
|
||||
color: #fff;
|
||||
font-size: 120%;
|
||||
padding: 0.4em 0.9em;
|
||||
border-radius: 3em;
|
||||
margin-right: 0;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: -1px;
|
||||
border-radius: inherit;
|
||||
z-index: -1;
|
||||
background: linear-gradient(60deg, #f79533, #f37055, #ef4e7b, #a166ab, #5073b8, #1098ad, #07b39b, #6fba82);
|
||||
background-size: 300% 300%;
|
||||
animation: animatedgradient 5s linear infinite;
|
||||
filter: blur(8px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:hover::before {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
&:active::before {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
padding-bottom: 5px;
|
||||
line-height: 1;
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#title-and-subtitle {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
#download-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 25px;
|
||||
|
||||
div {
|
||||
font-size: 0.7em;
|
||||
margin-top: 5px;
|
||||
color: #646464;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animatedgradient {
|
||||
0% {
|
||||
background-position: 0% 0%;
|
||||
}
|
||||
25% {
|
||||
background-position: 50% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 10%;
|
||||
}
|
||||
75% {
|
||||
background-position: 50% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 0%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 0 10px;
|
||||
color: #666;
|
||||
}
|
||||
/* ---------- Menu ---------- */
|
||||
.menu,
|
||||
.menu ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
margin-bottom: 8px;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
& > div {
|
||||
display: flex;
|
||||
margin-top: 5px;
|
||||
color: #468ed8;
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
position: sticky;
|
||||
z-index: 1000000;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
//max-width: $width;
|
||||
//background-color: rgba(255, 255, 255, 1);
|
||||
//background-color: #dff8ff;
|
||||
background-color: #f1f7ff;
|
||||
.menu-item > input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.menu-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
//background-color: rgba(255, 255, 255, 0.9);
|
||||
//backdrop-filter: blur(10px);
|
||||
gap: 6px;
|
||||
//background: var(--item-bg);
|
||||
padding: 6px 0;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
padding: 5px 10px;
|
||||
border-radius: 15px;
|
||||
color: #468ed8;
|
||||
|
||||
span {
|
||||
padding-bottom: 1px;
|
||||
border-bottom: #468ed8 solid 1px;
|
||||
}
|
||||
|
||||
&:hover, &.active {
|
||||
text-decoration: none;
|
||||
background-color: #d5e6ff;
|
||||
//color: #222;
|
||||
//box-shadow: #222 0px 1px;
|
||||
|
||||
span {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a.rainbow {
|
||||
background: linear-gradient(60deg, #f79533, #f37055, #ef4e7b, #a166ab, #5073b8, #1098ad, #07b39b, #6fba82);
|
||||
animation: animatedgradient 5s linear alternate infinite;
|
||||
background-size: 300% 300%;
|
||||
text-decoration: none;
|
||||
margin-right: 10px;
|
||||
color: #fff;
|
||||
//box-shadow: #222 0px 1px;
|
||||
|
||||
&:hover {
|
||||
//color: #000;
|
||||
animation-play-state: paused;
|
||||
}
|
||||
}
|
||||
&.active, &:hover {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
//color: #0052a7;
|
||||
}
|
||||
|
||||
@keyframes animatedgradient {
|
||||
0% {
|
||||
background-position: 0% 0%;
|
||||
}
|
||||
25% {
|
||||
background-position: 50% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 10%;
|
||||
}
|
||||
75% {
|
||||
background-position: 50% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 0%;
|
||||
&.support {
|
||||
color: #c10029;
|
||||
}
|
||||
}
|
||||
|
||||
ul.submenu {
|
||||
padding-left: 28px;
|
||||
border-left: 1px solid var(--border);
|
||||
margin-left: 1px;
|
||||
font-size: 15px;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
|
||||
a.active, a:hover {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
//color: #0052a7;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- Content ---------- */
|
||||
.content {
|
||||
max-width: 1048px;
|
||||
flex-shrink: 1;
|
||||
flex-grow: 1;
|
||||
background: var(--content-bg);
|
||||
overflow-y: auto;
|
||||
padding: 24px;
|
||||
|
||||
& > div {
|
||||
max-width: 700px;
|
||||
|
||||
.can-extend {
|
||||
width: calc(100vw - 310px) !important;
|
||||
max-width: 1000px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
max-width: $width;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
word-break: break-word;
|
||||
/* ---------- Mobile ---------- */
|
||||
#menu-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
img {
|
||||
.hamburger-bar {
|
||||
display: none;
|
||||
height: 60px;
|
||||
background: var(--sidebar-bg);
|
||||
//border-bottom: 2px solid var(--border);
|
||||
box-shadow: rgb(216, 231, 251) 0px 2px 4px 1px;
|
||||
padding: 8px;
|
||||
align-items: center;
|
||||
|
||||
#mobile-logo {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& > span:last-child {
|
||||
margin-top: 4px;
|
||||
font-size: 13px;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hamburger-label {
|
||||
background: var(--item-bg);
|
||||
padding: 10px 15px;
|
||||
border-radius: 15px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* ---------- Mobile behavior ---------- */
|
||||
@media (max-width: 800px) {
|
||||
#turbolinks-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hamburger-bar {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.app {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 55px;
|
||||
//left: 0;
|
||||
right: 0;
|
||||
//bottom: 0;
|
||||
width: auto;
|
||||
transform: translateY(-100%);
|
||||
transition: transform 0.2s ease;
|
||||
z-index: 10;
|
||||
padding: 14px 24px 0 14px;
|
||||
}
|
||||
|
||||
/* FIX: checkbox now controls sidebar */
|
||||
#menu-toggle:checked ~ .app .sidebar {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.content {
|
||||
padding-top: 24px;
|
||||
|
||||
& > div {
|
||||
max-width: unset;
|
||||
|
||||
.can-extend {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Toggle text */
|
||||
.close {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#menu-toggle:checked + .hamburger-bar .open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#menu-toggle:checked + .hamburger-bar .close {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
pointer-events: none; /* closed = not clickable */
|
||||
}
|
||||
|
||||
#menu-toggle:checked ~ .app .sidebar {
|
||||
transform: translateY(0);
|
||||
pointer-events: auto; /* open = clickable */
|
||||
}
|
||||
|
||||
.hamburger-bar {
|
||||
position: relative;
|
||||
z-index: 20; /* always above sidebar */
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- Support Page ------------- */
|
||||
.support-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
column-gap: 40px;
|
||||
row-gap: 55px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 70px;
|
||||
|
||||
/* Wrapper: each button keeps its mascot */
|
||||
.support-button-wrapper {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: 120px; /* ensures space for mascot below */
|
||||
}
|
||||
|
||||
/* Button shape + style */
|
||||
.support-button {
|
||||
width: 130px;
|
||||
height: 50px;
|
||||
border-radius: 22px;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
background: linear-gradient(145deg, #ffffff, #dce8ff);
|
||||
box-shadow:
|
||||
4px 4px 10px rgba(0,0,0,0.15),
|
||||
-4px -4px 10px rgba(255,255,255,0.7);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Shine streak */
|
||||
.support-button::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -150%;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
120deg,
|
||||
rgba(255,255,255,0) 0%,
|
||||
rgba(255,255,255,0.55) 50%,
|
||||
rgba(255,255,255,0) 100%
|
||||
);
|
||||
transform: skewX(-20deg);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.support-button:hover::before {
|
||||
animation: shine-sweep 0.8s forwards;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@keyframes shine-sweep {
|
||||
0% { left: -150%; }
|
||||
100% { left: 200%; }
|
||||
}
|
||||
|
||||
/* Button image */
|
||||
.support-button img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
object-position: center;
|
||||
}
|
||||
|
||||
code, pre, tt {
|
||||
padding: .2em .4em;
|
||||
/* Hover lift */
|
||||
.support-button:hover {
|
||||
transform: scale(1.08);
|
||||
box-shadow:
|
||||
6px 6px 15px rgba(0,0,0,0.18),
|
||||
-6px -6px 15px rgba(255,255,255,0.8);
|
||||
}
|
||||
|
||||
/* Mascots */
|
||||
.mascot {
|
||||
position: absolute;
|
||||
width: 60px;
|
||||
bottom: -20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(0);
|
||||
transition: transform 0.3s;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.rabbit { width: 50px } /* long ears '^^ /*
|
||||
|
||||
/* Hover reactions */
|
||||
.support-button-wrapper:hover .cat { transform: translateX(-50%) translateY(-20px) rotate(-15deg); }
|
||||
.support-button-wrapper:hover .dog { transform: translateX(-50%) translateY(-20px) scaleX(-1); }
|
||||
.support-button-wrapper:hover .squirrel { transform: translateX(-50%) translateY(-20px) rotate(15deg); }
|
||||
.support-button-wrapper:hover .rabbit { transform: translateX(-50%) translateY(-20px) rotate(-10deg); }
|
||||
|
||||
.support-button img.paypal { width: 60%; margin-top: 6px; }
|
||||
.support-button img.github-sponsors { width: 110%; margin-top: 6px; }
|
||||
.support-button img.stripe { width: 51%; margin-top: 4px; }
|
||||
}
|
||||
|
||||
#changelog {
|
||||
margin-top: -20px;
|
||||
padding: 15px;
|
||||
|
||||
#support-link {
|
||||
margin: 0;
|
||||
font-size: 85%;
|
||||
background-color: rgba(27, 31, 35, .05);
|
||||
border-radius: 3px;
|
||||
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
|
||||
white-space: normal;
|
||||
position: fixed;
|
||||
top: 15px;
|
||||
right: 10px;
|
||||
border-radius: 0.5em;
|
||||
padding: 0.15em 0.9em;
|
||||
font-size: 13px;
|
||||
background: #ffdbd5;
|
||||
/*background: #f91675;*/
|
||||
color: #950020;
|
||||
/*color: white;*/
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.3em;
|
||||
h1, h2 {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 20px;
|
||||
background-color: #f1f7ff;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.1em;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
|
||||
thead {
|
||||
text-align: left;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
thead {
|
||||
border-bottom: 7px solid #fff;
|
||||
}
|
||||
|
||||
tr {
|
||||
border-bottom: 7px solid #fff;
|
||||
border-top: 7px solid #fff;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
tr:first-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
tr:last-child {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
td, th {
|
||||
border-left: 5px solid #fff;
|
||||
border-right: 5px solid #fff;
|
||||
}
|
||||
|
||||
td:first-child, th:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
td:last-child, th:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
|
||||
li + li {
|
||||
margin-top: .25em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0366d6;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
ul {
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
function slugify(text) {
|
||||
return text.toLowerCase().trim().replace(/[^\w\s-]/g, '').replace(/\s+/g, '-');
|
||||
}
|
||||
|
||||
function buildTOC() {
|
||||
const urlParts = window.location.pathname.split('/');
|
||||
const currentPage = urlParts[urlParts.length - 1] || ""; // fallback
|
||||
const tocContainer = currentPage === "" ? document.querySelector('.submenu') : document.querySelector(`.submenu.${currentPage}`);
|
||||
if (!tocContainer) return;
|
||||
tocContainer.innerHTML = ''; // clear old TOC
|
||||
const headings = document.querySelectorAll('.content h1, .content h2');
|
||||
if (!headings.length || headings.length === 1) {
|
||||
tocContainer.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
const usedIds = new Set();
|
||||
headings.forEach((heading) => {
|
||||
let id = heading.id;
|
||||
if (!id) {
|
||||
id = slugify(heading.textContent);
|
||||
let uniqueId = id;
|
||||
let i = 1;
|
||||
while (usedIds.has(uniqueId) || document.getElementById(uniqueId)) {
|
||||
uniqueId = `${id}-${i++}`;
|
||||
}
|
||||
id = uniqueId;
|
||||
heading.id = id;
|
||||
}
|
||||
usedIds.add(id);
|
||||
const li = document.createElement('li');
|
||||
li.className = `toc-${heading.tagName.toLowerCase()}`;
|
||||
const a = document.createElement('a');
|
||||
a.href = `#${id}`;
|
||||
a.textContent = heading.textContent;
|
||||
a.setAttribute('data-turbolinks', 'false');
|
||||
li.appendChild(a);
|
||||
tocContainer.appendChild(li);
|
||||
});
|
||||
|
||||
const hash = window.location.hash;
|
||||
if (!hash) return;
|
||||
// remove existing .active, if exists
|
||||
const existingLink = document.querySelector(`.submenu a.active`);
|
||||
if (existingLink) {
|
||||
existingLink.classList.remove('active');
|
||||
}
|
||||
// add new .active, if exists
|
||||
const link = document.querySelector(`a[href="${hash}"]`);
|
||||
if (link) {
|
||||
link.classList.add('active');
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('turbolinks:load', buildTOC);
|
||||
window.addEventListener('hashchange', buildTOC);
|
||||
@@ -0,0 +1,2 @@
|
||||
(function(){var t=this;(function(){(function(){this.Turbolinks={supported:function(){return null!=window.history.pushState&&null!=window.requestAnimationFrame&&null!=window.addEventListener}(),visit:function(t,r){return e.controller.visit(t,r)},clearCache:function(){return e.controller.clearCache()},setProgressBarDelay:function(t){return e.controller.setProgressBarDelay(t)}}}).call(this)}).call(t);var e=t.Turbolinks;(function(){(function(){var t,r,n,o=[].slice;e.copyObject=function(t){var e,r,n;r={};for(e in t)n=t[e],r[e]=n;return r},e.closest=function(e,r){return t.call(e,r)},t=function(){var t,e;return t=document.documentElement,null!=(e=t.closest)?e:function(t){var e;for(e=this;e;){if(e.nodeType===Node.ELEMENT_NODE&&r.call(e,t))return e;e=e.parentNode}}}(),e.defer=function(t){return setTimeout(t,1)},e.throttle=function(t){var e;return e=null,function(){var r;return r=1<=arguments.length?o.call(arguments,0):[],null!=e?e:e=requestAnimationFrame(function(n){return function(){return e=null,t.apply(n,r)}}(this))}},e.dispatch=function(t,e){var r,o,i,s,a,u;return a=null!=e?e:{},u=a.target,r=a.cancelable,o=a.data,i=document.createEvent("Events"),i.initEvent(t,!0,r===!0),i.data=null!=o?o:{},i.cancelable&&!n&&(s=i.preventDefault,i.preventDefault=function(){return this.defaultPrevented||Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}}),s.call(this)}),(null!=u?u:document).dispatchEvent(i),i},n=function(){var t;return t=document.createEvent("Events"),t.initEvent("test",!0,!0),t.preventDefault(),t.defaultPrevented}(),e.match=function(t,e){return r.call(t,e)},r=function(){var t,e,r,n;return t=document.documentElement,null!=(e=null!=(r=null!=(n=t.matchesSelector)?n:t.webkitMatchesSelector)?r:t.msMatchesSelector)?e:t.mozMatchesSelector}(),e.uuid=function(){var t,e,r;for(r="",t=e=1;36>=e;t=++e)r+=9===t||14===t||19===t||24===t?"-":15===t?"4":20===t?(Math.floor(4*Math.random())+8).toString(16):Math.floor(15*Math.random()).toString(16);return r}}).call(this),function(){e.Location=function(){function t(t){var e,r;null==t&&(t=""),r=document.createElement("a"),r.href=t.toString(),this.absoluteURL=r.href,e=r.hash.length,2>e?this.requestURL=this.absoluteURL:(this.requestURL=this.absoluteURL.slice(0,-e),this.anchor=r.hash.slice(1))}var e,r,n,o;return t.wrap=function(t){return t instanceof this?t:new this(t)},t.prototype.getOrigin=function(){return this.absoluteURL.split("/",3).join("/")},t.prototype.getPath=function(){var t,e;return null!=(t=null!=(e=this.requestURL.match(/\/\/[^\/]*(\/[^?;]*)/))?e[1]:void 0)?t:"/"},t.prototype.getPathComponents=function(){return this.getPath().split("/").slice(1)},t.prototype.getLastPathComponent=function(){return this.getPathComponents().slice(-1)[0]},t.prototype.getExtension=function(){var t,e;return null!=(t=null!=(e=this.getLastPathComponent().match(/\.[^.]*$/))?e[0]:void 0)?t:""},t.prototype.isHTML=function(){return this.getExtension().match(/^(?:|\.(?:htm|html|xhtml))$/)},t.prototype.isPrefixedBy=function(t){var e;return e=r(t),this.isEqualTo(t)||o(this.absoluteURL,e)},t.prototype.isEqualTo=function(t){return this.absoluteURL===(null!=t?t.absoluteURL:void 0)},t.prototype.toCacheKey=function(){return this.requestURL},t.prototype.toJSON=function(){return this.absoluteURL},t.prototype.toString=function(){return this.absoluteURL},t.prototype.valueOf=function(){return this.absoluteURL},r=function(t){return e(t.getOrigin()+t.getPath())},e=function(t){return n(t,"/")?t:t+"/"},o=function(t,e){return t.slice(0,e.length)===e},n=function(t,e){return t.slice(-e.length)===e},t}()}.call(this),function(){var t=function(t,e){return function(){return t.apply(e,arguments)}};e.HttpRequest=function(){function r(r,n,o){this.delegate=r,this.requestCanceled=t(this.requestCanceled,this),this.requestTimedOut=t(this.requestTimedOut,this),this.requestFailed=t(this.requestFailed,this),this.requestLoaded=t(this.requestLoaded,this),this.requestProgressed=t(this.requestProgressed,this),this.url=e.Location.wrap(n).requestURL,this.referrer=e.Location.wrap(o).absoluteURL,this.createXHR()}return r.NETWORK_FAILURE=0,r.TIMEOUT_FAILURE=-1,r.timeout=60,r.prototype.send=function(){var t;return this.xhr&&!this.sent?(this.notifyApplicationBeforeRequestStart(),this.setProgress(0),this.xhr.send(),this.sent=!0,"function"==typeof(t=this.delegate).requestStarted?t.requestStarted():void 0):void 0},r.prototype.cancel=function(){return this.xhr&&this.sent?this.xhr.abort():void 0},r.prototype.requestProgressed=function(t){return t.lengthComputable?this.setProgress(t.loaded/t.total):void 0},r.prototype.requestLoaded=function(){return this.endRequest(function(t){return function(){var e;return 200<=(e=t.xhr.status)&&300>e?t.delegate.requestCompletedWithResponse(t.xhr.responseText,t.xhr.getResponseHeader("Turbolinks-Location")):(t.failed=!0,t.delegate.requestFailedWithStatusCode(t.xhr.status,t.xhr.responseText))}}(this))},r.prototype.requestFailed=function(){return this.endRequest(function(t){return function(){return t.Line truncated
|
||||
},r.prototype.cacheSnapshot=function(){var t,r;return this.shouldCacheSnapshot()?(this.notifyApplicationBeforeCachingSnapshot(),r=this.view.getSnapshot(),t=this.lastRenderedLocation,e.defer(function(e){return function(){return e.cache.put(t,r.clone())}}(this))):void 0},r.prototype.scrollToAnchor=function(t){var e;return(e=this.view.getElementForAnchor(t))?this.scrollToElement(e):this.scrollToPosition({x:0,y:0})},r.prototype.scrollToElement=function(t){return this.scrollManager.scrollToElement(t)},r.prototype.scrollToPosition=function(t){return this.scrollManager.scrollToPosition(t)},r.prototype.scrollPositionChanged=function(t){var e;return e=this.getCurrentRestorationData(),e.scrollPosition=t},r.prototype.render=function(t,e){return this.view.render(t,e)},r.prototype.viewInvalidated=function(){return this.adapter.pageInvalidated()},r.prototype.viewWillRender=function(t){return this.notifyApplicationBeforeRender(t)},r.prototype.viewRendered=function(){return this.lastRenderedLocation=this.currentVisit.location,this.notifyApplicationAfterRender()},r.prototype.pageLoaded=function(){return this.lastRenderedLocation=this.location,this.notifyApplicationAfterPageLoad()},r.prototype.clickCaptured=function(){return removeEventListener("click",this.clickBubbled,!1),addEventListener("click",this.clickBubbled,!1)},r.prototype.clickBubbled=function(t){var e,r,n;return this.enabled&&this.clickEventIsSignificant(t)&&(r=this.getVisitableLinkForNode(t.target))&&(n=this.getVisitableLocationForLink(r))&&this.applicationAllowsFollowingLinkToLocation(r,n)?(t.preventDefault(),e=this.getActionForLink(r),this.visit(n,{action:e})):void 0},r.prototype.applicationAllowsFollowingLinkToLocation=function(t,e){var r;return r=this.notifyApplicationAfterClickingLinkToLocation(t,e),!r.defaultPrevented},r.prototype.applicationAllowsVisitingLocation=function(t){var e;return e=this.notifyApplicationBeforeVisitingLocation(t),!e.defaultPrevented},r.prototype.notifyApplicationAfterClickingLinkToLocation=function(t,r){return e.dispatch("turbolinks:click",{target:t,data:{url:r.absoluteURL},cancelable:!0})},r.prototype.notifyApplicationBeforeVisitingLocation=function(t){return e.dispatch("turbolinks:before-visit",{data:{url:t.absoluteURL},cancelable:!0})},r.prototype.notifyApplicationAfterVisitingLocation=function(t){return e.dispatch("turbolinks:visit",{data:{url:t.absoluteURL}})},r.prototype.notifyApplicationBeforeCachingSnapshot=function(){return e.dispatch("turbolinks:before-cache")},r.prototype.notifyApplicationBeforeRender=function(t){return e.dispatch("turbolinks:before-render",{data:{newBody:t}})},r.prototype.notifyApplicationAfterRender=function(){return e.dispatch("turbolinks:render")},r.prototype.notifyApplicationAfterPageLoad=function(t){return null==t&&(t={}),e.dispatch("turbolinks:load",{data:{url:this.location.absoluteURL,timing:t}})},r.prototype.startVisit=function(t,e,r){var n;return null!=(n=this.currentVisit)&&n.cancel(),this.currentVisit=this.createVisit(t,e,r),this.currentVisit.start(),this.notifyApplicationAfterVisitingLocation(t)},r.prototype.createVisit=function(t,r,n){var o,i,s,a,u;return i=null!=n?n:{},a=i.restorationIdentifier,s=i.restorationData,o=i.historyChanged,u=new e.Visit(this,t,r),u.restorationIdentifier=null!=a?a:e.uuid(),u.restorationData=e.copyObject(s),u.historyChanged=o,u.referrer=this.location,u},r.prototype.visitCompleted=function(t){return this.notifyApplicationAfterPageLoad(t.getTimingMetrics())},r.prototype.clickEventIsSignificant=function(t){return!(t.defaultPrevented||t.target.isContentEditable||t.which>1||t.altKey||t.ctrlKey||t.metaKey||t.shiftKey)},r.prototype.getVisitableLinkForNode=function(t){return this.nodeIsVisitable(t)?e.closest(t,"a[href]:not([target]):not([download])"):void 0},r.prototype.getVisitableLocationForLink=function(t){var r;return r=new e.Location(t.getAttribute("href")),this.locationIsVisitable(r)?r:void 0},r.prototype.getActionForLink=function(t){var e;return null!=(e=t.getAttribute("data-turbolinks-action"))?e:"advance"},r.prototype.nodeIsVisitable=function(t){var r;return(r=e.closest(t,"[data-turbolinks]"))?"false"!==r.getAttribute("data-turbolinks"):!0},r.prototype.locationIsVisitable=function(t){return t.isPrefixedBy(this.view.getRootLocation())&&t.isHTML()},r.prototype.getCurrentRestorationData=function(){return this.getRestorationDataForIdentifier(this.restorationIdentifier)},r.prototype.getRestorationDataForIdentifier=function(t){var e;return null!=(e=this.restorationData)[t]?e[t]:e[t]={}},r}()}.call(this),function(){!function(){var t,e;if((t=e=document.currentScript)&&!e.hasAttribute("data-turbolinks-suppress-warning"))for(;t=t.parentNode;)if(t===document.body)return console.warn("You are loading Turbolinks from a <script> element inside the <body> element. This is probably not what you meant to do!\n\nLoad your application\u2019s JavaScript bundle inside the <head> element instead. <script> elements in <body> are evaluated with each page change.\n\nFor more information,Line truncated
|
||||
@@ -16,9 +16,10 @@
|
||||
|
||||
<body>
|
||||
|
||||
<section class="page">
|
||||
<div id="changelog">
|
||||
<a id="support-link" href="https://alt-tab-macos.netlify.app/support">Support this project ❤️</a>
|
||||
{{ content }}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,22 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-us">
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>
|
||||
{% if page.title == "Introduction" %} {{ site.title }} - {{ site.description }}
|
||||
{% else %} {{ site.title }} - {{ page.title }} {% endif %}
|
||||
</title>
|
||||
|
||||
<style type="text/css">
|
||||
{% capture main %}
|
||||
{% include main.scss %}
|
||||
{% endcapture %}
|
||||
{{ main | scssify }}
|
||||
</style>
|
||||
<meta name="description" content="Windows alt-tab on macOS">
|
||||
|
||||
<!-- Generated with https://realfavicongenerator.net/ -->
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ site.baseurl }}public/apple-touch-icon.png">
|
||||
@@ -27,38 +16,95 @@
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<script>
|
||||
(function(){var t=this;(function(){(function(){this.Turbolinks={supported:function(){return null!=window.history.pushState&&null!=window.requestAnimationFrame&&null!=window.addEventListener}(),visit:function(t,r){return e.controller.visit(t,r)},clearCache:function(){return e.controller.clearCache()},setProgressBarDelay:function(t){return e.controller.setProgressBarDelay(t)}}}).call(this)}).call(t);var e=t.Turbolinks;(function(){(function(){var t,r,n,o=[].slice;e.copyObject=function(t){var e,r,n;r={};for(e in t)n=t[e],r[e]=n;return r},e.closest=function(e,r){return t.call(e,r)},t=function(){var t,e;return t=document.documentElement,null!=(e=t.closest)?e:function(t){var e;for(e=this;e;){if(e.nodeType===Node.ELEMENT_NODE&&r.call(e,t))return e;e=e.parentNode}}}(),e.defer=function(t){return setTimeout(t,1)},e.throttle=function(t){var e;return e=null,function(){var r;return r=1<=arguments.length?o.call(arguments,0):[],null!=e?e:e=requestAnimationFrame(function(n){return function(){return e=null,t.apply(n,r)}}(this))}},e.dispatch=function(t,e){var r,o,i,s,a,u;return a=null!=e?e:{},u=a.target,r=a.cancelable,o=a.data,i=document.createEvent("Events"),i.initEvent(t,!0,r===!0),i.data=null!=o?o:{},i.cancelable&&!n&&(s=i.preventDefault,i.preventDefault=function(){return this.defaultPrevented||Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}}),s.call(this)}),(null!=u?u:document).dispatchEvent(i),i},n=function(){var t;return t=document.createEvent("Events"),t.initEvent("test",!0,!0),t.preventDefault(),t.defaultPrevented}(),e.match=function(t,e){return r.call(t,e)},r=function(){var t,e,r,n;return t=document.documentElement,null!=(e=null!=(r=null!=(n=t.matchesSelector)?n:t.webkitMatchesSelector)?r:t.msMatchesSelector)?e:t.mozMatchesSelector}(),e.uuid=function(){var t,e,r;for(r="",t=e=1;36>=e;t=++e)r+=9===t||14===t||19===t||24===t?"-":15===t?"4":20===t?(Math.floor(4*Math.random())+8).toString(16):Math.floor(15*Math.random()).toString(16);return r}}).call(this),function(){e.Location=function(){function t(t){var e,r;null==t&&(t=""),r=document.createElement("a"),r.href=t.toString(),this.absoluteURL=r.href,e=r.hash.length,2>e?this.requestURL=this.absoluteURL:(this.requestURL=this.absoluteURL.slice(0,-e),this.anchor=r.hash.slice(1))}var e,r,n,o;return t.wrap=function(t){return t instanceof this?t:new this(t)},t.prototype.getOrigin=function(){return this.absoluteURL.split("/",3).join("/")},t.prototype.getPath=function(){var t,e;return null!=(t=null!=(e=this.requestURL.match(/\/\/[^\/]*(\/[^?;]*)/))?e[1]:void 0)?t:"/"},t.prototype.getPathComponents=function(){return this.getPath().split("/").slice(1)},t.prototype.getLastPathComponent=function(){return this.getPathComponents().slice(-1)[0]},t.prototype.getExtension=function(){var t,e;return null!=(t=null!=(e=this.getLastPathComponent().match(/\.[^.]*$/))?e[0]:void 0)?t:""},t.prototype.isHTML=function(){return this.getExtension().match(/^(?:|\.(?:htm|html|xhtml))$/)},t.prototype.isPrefixedBy=function(t){var e;return e=r(t),this.isEqualTo(t)||o(this.absoluteURL,e)},t.prototype.isEqualTo=function(t){return this.absoluteURL===(null!=t?t.absoluteURL:void 0)},t.prototype.toCacheKey=function(){return this.requestURL},t.prototype.toJSON=function(){return this.absoluteURL},t.prototype.toString=function(){return this.absoluteURL},t.prototype.valueOf=function(){return this.absoluteURL},r=function(t){return e(t.getOrigin()+t.getPath())},e=function(t){return n(t,"/")?t:t+"/"},o=function(t,e){return t.slice(0,e.length)===e},n=function(t,e){return t.slice(-e.length)===e},t}()}.call(this),function(){var t=function(t,e){return function(){return t.apply(e,arguments)}};e.HttpRequest=function(){function r(r,n,o){this.delegate=r,this.requestCanceled=t(this.requestCanceled,this),this.requestTimedOut=t(this.requestTimedOut,this),this.requestFailed=t(this.requestFailed,this),this.requestLoaded=t(this.requestLoaded,this),this.requestProgressed=t(this.requestProgressed,this),this.url=e.Location.wrap(n).requestURL,this.referrer=e.Location.wrap(o).absoluteURL,this.createXHR()}return r.NETWORK_FAILURE=0,r.TIMEOUT_FAILURE=-1,r.timeout=60,r.prototype.send=function(){var t;return this.xhr&&!this.sent?(this.notifyApplicationBeforeRequestStart(),this.setProgress(0),this.xhr.send(),this.sent=!0,"function"==typeof(t=this.delegate).requestStarted?t.requestStarted():void 0):void 0},r.prototype.cancel=function(){return this.xhr&&this.sent?this.xhr.abort():void 0},r.prototype.requestProgressed=function(t){return t.lengthComputable?this.setProgress(t.loaded/t.total):void 0},r.prototype.requestLoaded=function(){return this.endRequest(function(t){return function(){var e;return 200<=(e=t.xhr.status)&&300>e?t.delegate.requestCompletedWithResponse(t.xhr.responseText,t.xhr.getResponseHeader("Turbolinks-Location")):(t.failed=!0,t.delegate.requestFailedWithStatusCode(t.xhr.status,t.xhr.responseText))}}(this))},r.prototype.requestFailed=function(){return this.endRequest(function(t){return function(){rLine truncated
|
||||
},r.prototype.cacheSnapshot=function(){var t,r;return this.shouldCacheSnapshot()?(this.notifyApplicationBeforeCachingSnapshot(),r=this.view.getSnapshot(),t=this.lastRenderedLocation,e.defer(function(e){return function(){return e.cache.put(t,r.clone())}}(this))):void 0},r.prototype.scrollToAnchor=function(t){var e;return(e=this.view.getElementForAnchor(t))?this.scrollToElement(e):this.scrollToPosition({x:0,y:0})},r.prototype.scrollToElement=function(t){return this.scrollManager.scrollToElement(t)},r.prototype.scrollToPosition=function(t){return this.scrollManager.scrollToPosition(t)},r.prototype.scrollPositionChanged=function(t){var e;return e=this.getCurrentRestorationData(),e.scrollPosition=t},r.prototype.render=function(t,e){return this.view.render(t,e)},r.prototype.viewInvalidated=function(){return this.adapter.pageInvalidated()},r.prototype.viewWillRender=function(t){return this.notifyApplicationBeforeRender(t)},r.prototype.viewRendered=function(){return this.lastRenderedLocation=this.currentVisit.location,this.notifyApplicationAfterRender()},r.prototype.pageLoaded=function(){return this.lastRenderedLocation=this.location,this.notifyApplicationAfterPageLoad()},r.prototype.clickCaptured=function(){return removeEventListener("click",this.clickBubbled,!1),addEventListener("click",this.clickBubbled,!1)},r.prototype.clickBubbled=function(t){var e,r,n;return this.enabled&&this.clickEventIsSignificant(t)&&(r=this.getVisitableLinkForNode(t.target))&&(n=this.getVisitableLocationForLink(r))&&this.applicationAllowsFollowingLinkToLocation(r,n)?(t.preventDefault(),e=this.getActionForLink(r),this.visit(n,{action:e})):void 0},r.prototype.applicationAllowsFollowingLinkToLocation=function(t,e){var r;return r=this.notifyApplicationAfterClickingLinkToLocation(t,e),!r.defaultPrevented},r.prototype.applicationAllowsVisitingLocation=function(t){var e;return e=this.notifyApplicationBeforeVisitingLocation(t),!e.defaultPrevented},r.prototype.notifyApplicationAfterClickingLinkToLocation=function(t,r){return e.dispatch("turbolinks:click",{target:t,data:{url:r.absoluteURL},cancelable:!0})},r.prototype.notifyApplicationBeforeVisitingLocation=function(t){return e.dispatch("turbolinks:before-visit",{data:{url:t.absoluteURL},cancelable:!0})},r.prototype.notifyApplicationAfterVisitingLocation=function(t){return e.dispatch("turbolinks:visit",{data:{url:t.absoluteURL}})},r.prototype.notifyApplicationBeforeCachingSnapshot=function(){return e.dispatch("turbolinks:before-cache")},r.prototype.notifyApplicationBeforeRender=function(t){return e.dispatch("turbolinks:before-render",{data:{newBody:t}})},r.prototype.notifyApplicationAfterRender=function(){return e.dispatch("turbolinks:render")},r.prototype.notifyApplicationAfterPageLoad=function(t){return null==t&&(t={}),e.dispatch("turbolinks:load",{data:{url:this.location.absoluteURL,timing:t}})},r.prototype.startVisit=function(t,e,r){var n;return null!=(n=this.currentVisit)&&n.cancel(),this.currentVisit=this.createVisit(t,e,r),this.currentVisit.start(),this.notifyApplicationAfterVisitingLocation(t)},r.prototype.createVisit=function(t,r,n){var o,i,s,a,u;return i=null!=n?n:{},a=i.restorationIdentifier,s=i.restorationData,o=i.historyChanged,u=new e.Visit(this,t,r),u.restorationIdentifier=null!=a?a:e.uuid(),u.restorationData=e.copyObject(s),u.historyChanged=o,u.referrer=this.location,u},r.prototype.visitCompleted=function(t){return this.notifyApplicationAfterPageLoad(t.getTimingMetrics())},r.prototype.clickEventIsSignificant=function(t){return!(t.defaultPrevented||t.target.isContentEditable||t.which>1||t.altKey||t.ctrlKey||t.metaKey||t.shiftKey)},r.prototype.getVisitableLinkForNode=function(t){return this.nodeIsVisitable(t)?e.closest(t,"a[href]:not([target]):not([download])"):void 0},r.prototype.getVisitableLocationForLink=function(t){var r;return r=new e.Location(t.getAttribute("href")),this.locationIsVisitable(r)?r:void 0},r.prototype.getActionForLink=function(t){var e;return null!=(e=t.getAttribute("data-turbolinks-action"))?e:"advance"},r.prototype.nodeIsVisitable=function(t){var r;return(r=e.closest(t,"[data-turbolinks]"))?"false"!==r.getAttribute("data-turbolinks"):!0},r.prototype.locationIsVisitable=function(t){return t.isPrefixedBy(this.view.getRootLocation())&&t.isHTML()},r.prototype.getCurrentRestorationData=function(){return this.getRestorationDataForIdentifier(this.restorationIdentifier)},r.prototype.getRestorationDataForIdentifier=function(t){var e;return null!=(e=this.restorationData)[t]?e[t]:e[t]={}},r}()}.call(this),function(){!function(){var t,e;if((t=e=document.currentScript)&&!e.hasAttribute("data-turbolinks-suppress-warning"))for(;t=t.parentNode;)if(t===document.body)return console.warn("You are loading Turbolinks from a <script> element inside the <body> element. This is probably not what you meant to do!\n\nLoad your application\u2019s JavaScript bundle inside the <head> element instead. <script> elements in <body> are evaluated with each page change.\n\nFor more infoLine truncated
|
||||
</script>
|
||||
<title>
|
||||
{% if page.name == "Introduction.md" %} {{ site.title }} - {{ site.description }}
|
||||
{% else %} {{ site.title }} - {{ page.name | remove: ".md" }} {% endif %}
|
||||
</title>
|
||||
|
||||
<style type="text/css">
|
||||
{% capture main %}
|
||||
{% include main.scss %}
|
||||
{% endcapture %}
|
||||
{{ main | scssify }}
|
||||
</style>
|
||||
|
||||
<script>{% include turbolinks.js %}</script>
|
||||
<script>{% include table-of-contents.js %}</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<div>
|
||||
<a href="{{ site.baseurl }}"><img src="{{ site.baseurl }}public/android-chrome-256x256.png" width="100" height="100"/></a>
|
||||
<div>
|
||||
<h1><a href="{{ site.baseurl }}">{{ site.title }}</a></h1>
|
||||
<p>{{ site.github.project_tagline }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a class="rainbow" href="{{ site.github.latest_release.assets[0].browser_download_url }}">Download</a></li>
|
||||
<li><a class="{% if page.name == 'Introduction.md' %}active{% endif %}" href="{{ site.baseurl }}"><span>Introduction</span></a></li>
|
||||
<li><a class="{% if page.name == 'Changelog.md' %}active{% endif %}" href="{{ site.baseurl }}changelog"><span>Release notes</span></a></li>
|
||||
<li><a class="{% if page.name == 'Contributing.md' %}active{% endif %}" href="{{ site.baseurl }}contributing"><span>Contributing</span></a></li>
|
||||
<li><a class="{% if page.name == 'Thanks.md' %}active{% endif %}" href="{{ site.baseurl }}thanks"><span>Thanks</span></a></li>
|
||||
<li><a href="{{ site.github.repository_url }}"><span>GitHub</span></a></li>
|
||||
<li><a class="{% if page.name == 'Support.md' %}active{% endif %}" href="{{ site.baseurl }}support"><span>Support this project ❤️</span></a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="layout">
|
||||
<input type="checkbox" id="menu-toggle" />
|
||||
|
||||
<section class="page">
|
||||
{{ content }}
|
||||
</section>
|
||||
<div class="hamburger-bar" style="line-height: 1">
|
||||
<div id="mobile-logo">
|
||||
<a href="{{ site.baseurl }}" aria-label="Homepage"><img src="{{ site.baseurl }}public/android-chrome-256x256.png" width="42" height="42" alt="AltTab logo" /></a>
|
||||
<div>
|
||||
<span><a href="{{ site.baseurl }}">{{ site.title }}</a></span>
|
||||
<span>{{ site.github.project_tagline }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<label for="menu-toggle" class="hamburger-label">
|
||||
<span class="open">Menu</span>
|
||||
<span class="close">Close</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="app">
|
||||
<aside class="sidebar">
|
||||
<div id="turbolinks-header" data-turbolinks-permanent>
|
||||
<div id="logo">
|
||||
<a href="{{ site.baseurl }}" aria-label="Homepage"><img src="{{ site.baseurl }}public/android-chrome-256x256.png" width="100" height="100" alt="AltTab logo" style="display:block" /></a>
|
||||
<div id="title-and-subtitle">
|
||||
<h1><a href="{{ site.baseurl }}">{{ site.title }}</a></h1>
|
||||
<p>{{ site.github.project_tagline }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="download-section">
|
||||
<a class="button rainbow" href="{{ site.github.latest_release.assets[0].browser_download_url }}">Download</a>
|
||||
<div id="downloads">6.6M downloads</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="menu">
|
||||
<li class="menu-item">
|
||||
<a class="menu-label button {% if page.name == 'Introduction.md' %}active{% endif %}" href="{{ site.baseurl }}"><span>Introduction</span></a>
|
||||
<ul class="submenu"></ul>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a class="menu-label button {% if page.name == 'FAQ.md' %}active{% endif %}" href="{{ site.baseurl }}faq"><span>FAQ</span></a>
|
||||
<ul class="submenu faq"></ul>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a class="menu-label button {% if page.name == 'Changelog.md' %}active{% endif %}" href="{{ site.baseurl }}changelog"><span>Release notes</span></a>
|
||||
<ul class="submenu changelog"></ul>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a class="menu-label button {% if page.name == 'Contributing.md' %}active{% endif %}" href="{{ site.baseurl }}contributing"><span>Contributing</span></a>
|
||||
<ul class="submenu contributing"></ul>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a class="menu-label button {% if page.name == 'Thanks.md' %}active{% endif %}" href="{{ site.baseurl }}thanks"><span>Thanks</span></a>
|
||||
<ul class="submenu thanks"></ul>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a class="menu-label button external" href="{{ site.github.repository_url }}"><span style="display:flex; gap:3px;">GitHub <img src="data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMiIgdmlld0JveD0iMCAwIDEyIDEyIj4KCTx0aXRsZT4KCQlleHRlcm5hbCBsaW5rCgk8L3RpdGxlPgoJPHBhdGggZmlsbD0iIzM2YyIgZD0iTTYgMWg1djVMOC44NiAzLjg1IDQuNyA4IDQgNy4zbDQuMTUtNC4xNnpNMiAzaDJ2MUgydjZoNlY4aDF2MmExIDEgMCAwIDEtMSAxSDJhMSAxIDAgMCAxLTEtMVY0YTEgMSAwIDAgMSAxLTEiLz4KPC9zdmc+Cg==" /></span></a>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a class="menu-label button support {% if page.name == 'Support.md' %}active{% endif %}" href="{{ site.baseurl }}support"><span>Support this project ❤️</span></a>
|
||||
<ul class="submenu support"></ul>
|
||||
</li>
|
||||
</ul>
|
||||
</aside>
|
||||
|
||||
<main class="content">
|
||||
<div{% if page.name == 'Changelog.md' %} id="changelog"{% endif %}>
|
||||
{{ content }}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="298" height="64" fill="none" viewBox="0 0 298 64">
|
||||
<defs>
|
||||
<linearGradient id="a" x1=".850001" x2="62.62" y1="62.72" y2="1.81" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF9419"/>
|
||||
<stop offset=".43" stop-color="#FF021D"/>
|
||||
<stop offset=".99" stop-color="#E600FF"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path fill="#000" d="M86.4844 40.5858c0 .8464-.1792 1.5933-.5377 2.2505-.3585.6573-.8564 1.1651-1.5137 1.5236-.6572.3585-1.3941.5378-2.2406.5378H78v6.1044h5.0787c1.912 0 3.6248-.4282 5.1484-1.2846 1.5236-.8564 2.7186-2.0415 3.585-3.5452.8663-1.5037 1.3045-3.1966 1.3045-5.0886V21.0178h-6.6322v19.568Zm17.8556-1.8224h13.891v-5.6065H104.34v-6.3633h15.355v-5.7758H97.8766v29.9743h22.2464v-5.7757H104.34v-6.453Zm17.865-11.8005h8.882v24.0193h6.633V26.9629h8.842v-5.9451h-24.367v5.9551l.01-.01Zm47.022 9.0022c-.517-.2788-1.085-.4879-1.673-.6472.449-.1295.877-.2888 1.275-.488 1.096-.5676 1.962-1.3643 2.579-2.39.618-1.0257.936-2.2007.936-3.5351 0-1.5237-.418-2.8879-1.244-4.0929-.827-1.195-1.992-2.131-3.486-2.8082-1.494-.6672-3.206-1.0058-5.118-1.0058h-13.315v29.9743h13.574c2.011 0 3.804-.3485 5.387-1.0556 1.573-.707 2.798-1.6829 3.675-2.9476.866-1.2547 1.304-2.6887 1.304-4.302 0-1.4837-.338-2.8082-1.026-3.9833-.687-1.175-1.633-2.0812-2.858-2.7285l-.01.0099Zm-13.603-9.9184h5.886c.816 0 1.533.1494 2.161.4382.627.2888 1.115.707 1.464 1.2547.348.5378.527 1.1751.527 1.9021 0 .7269-.179 1.414-.527 1.9817-.349.5676-.837.9958-1.464 1.3045-.628.3087-1.345.4581-2.161.4581h-5.886v-7.3492.0099Zm10.138 18.134c-.378.5676-.916 1.0058-1.603 1.3145-.697.3087-1.484.4581-2.39.4581h-6.145v-7.6878h6.145c.886 0 1.673.1693 2.37.4979.687.3286 1.235.7867 1.613 1.3842.378.5975.578 1.2747.578 2.0414 0 .7668-.19 1.4241-.568 1.9917Zm29.596-5.3077c1.663-.7967 2.947-1.922 3.864-3.3659.916-1.444 1.374-3.117 1.374-5.0289 0-1.912-.448-3.5253-1.344-4.9592-.897-1.434-2.171-2.5394-3.814-3.3261-1.644-.7867-3.546-1.1751-5.717-1.1751h-13.124v29.9743h6.642V40.0779h4.322l6.084 10.9142h7.578l-6.851-11.7208c.339-.1195.677-.249.996-.3983h-.01Zm-2.151-6.1244c-.369.6274-.896 1.1154-1.583 1.444-.688.3386-1.494.5079-2.42.5079h-5.975v-8.2953h5.975c.926 0 1.732.1693 2.42.4979.687.3287 1.214.8166 1.583 1.434.368.6174.558 1.3544.558 2.1908 0 .8365-.19 1.5734-.558 2.2008v.0199Zm20.594-11.7308-10.706 29.9743h6.742l2.121-6.6122h11.114l2.27 6.6122h6.612L220.99 21.0178h-7.189Zm-.339 18.3431 3.445-10.5756.409-1.922.408 1.922 3.685 10.5756h-7.947Zm20.693 11.6312h6.851V21.0178h-6.851v29.9743Zm31.02-9.6993-12.896-20.275h-6.463v29.9743h6.055V30.7172l12.826 20.2749h6.533V21.0178h-6.055v20.275Zm31.528-3.3559c-.647-1.2448-1.564-2.2904-2.729-3.1369-1.165-.8464-2.509-1.4041-4.023-1.6929l-5.098-1.0456c-.797-.1892-1.434-.5178-1.902-.9958-.469-.478-.708-1.0755-.708-1.7825 0-.6473.17-1.205.518-1.683.339-.478.827-.8464 1.444-1.1153.618-.2689 1.335-.3983 2.151-.3983.817 0 1.554.1394 2.181.4182.627.2788 1.115.6672 1.464 1.1751s.528 1.0755.528 1.7228h6.642c-.04-1.7427-.528-3.2863-1.444-4.6207-.916-1.3443-2.201-2.3899-3.834-3.1468-1.633-.7568-3.505-1.1352-5.597-1.1352-2.091 0-3.943.3884-5.566 1.1751-1.623.7867-2.898 1.8721-3.804 3.2663-.906 1.3941-1.364 2.9775-1.364 4.76 0 1.444.288 2.7485.876 3.9036.587 1.1652 1.414 2.1311 2.479 2.8979 1.076.7668 2.311 1.3045 3.725 1.6033l5.397 1.1153c.886.2091 1.584.5975 2.101 1.1551.518.5577.767 1.2448.767 2.0813 0 .6672-.189 1.2747-.567 1.8025-.379.5277-.907.936-1.584 1.2248-.677.2888-1.474.4282-2.39.4282-.916 0-1.782-.1593-2.529-.478-.747-.3186-1.325-.7767-1.733-1.3742-.418-.5875-.617-1.2747-.617-2.0414h-6.642c.029 1.8721.527 3.5152 1.513 4.9492.976 1.424 2.32 2.5394 4.033 3.336 1.713.7967 3.675 1.195 5.886 1.195 2.21 0 4.202-.4083 5.915-1.2249 1.723-.8165 3.057-1.9418 4.023-3.3758.966-1.434 1.444-3.0572 1.444-4.8696 0-1.4838-.329-2.848-.976-4.1028l.02.01Z"/>
|
||||
<path fill="url(#a)" d="M20.34 3.66 3.66 20.34C1.32 22.68 0 25.86 0 29.18V59c0 2.76 2.24 5 5 5h29.82c3.32 0 6.49-1.32 8.84-3.66l16.68-16.68c2.34-2.34 3.66-5.52 3.66-8.84V5c0-2.76-2.24-5-5-5H29.18c-3.32 0-6.49 1.32-8.84 3.66Z"/>
|
||||
<path fill="#000" d="M48 16H8v40h40V16Z"/>
|
||||
<path fill="#fff" d="M30 47H13v4h17v-4Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 749.3 227.1" xmlns="http://www.w3.org/2000/svg"><path d="m222.8 85.4c0-3.4 2.5-5.6 6.4-5.6h18.6c16.9 0 28.3 9.3 28.3 22.9s-11.3 23.3-28.3 23.3h-2.6c-6.5 0-9.8 3.4-9.8 8.8v15.2c0 4.3-2.5 7-6.3 7s-6.3-2.7-6.3-7zm12.6 19.3c0 6.8 3.5 10.1 10.1 10.1h1.6c9.3 0 16.1-3.8 16.1-12.1s-6.8-12.1-16.1-12.1h-1.6c-6.6 0-10.1 3.2-10.1 10.1v4.1zm40.7 46.4c0 3.6 2.5 5.9 6.3 5.9s4.8-1.6 6.1-5l2.3-6.1c1.8-4.9 5.1-7.1 8.6-7.1h20.5c3.6 0 6.8 2.3 8.6 7.1l2.3 6.1c1.3 3.4 3.6 5 6.1 5 3.8 0 6.3-2.4 6.3-5.9s-.2-2.2-.6-3.4l-24.5-63.8c-1.5-3.9-5-5.8-8.3-5.8s-6.8 1.9-8.3 5.8l-24.5 63.8c-.4 1.2-.6 2.4-.6 3.4zm23.9-29c0-1.2.3-2.3.9-3.9l4.6-12.9c.9-2.5 2.4-3.7 4.1-3.7s3.2 1.2 4.1 3.7l4.6 12.9c.5 1.6.9 2.7.9 3.9 0 3.2-1.8 5.5-6.7 5.5h-5.8c-4.9 0-6.7-2.3-6.7-5.5zm39-36.5c0-3.5 2.5-5.8 6.5-5.8h49.7c4 0 6.5 2.4 6.5 5.8s-2.5 5.8-6.5 5.8h-8.3c-6.6 0-10.2 3.4-10.2 11v47.4c0 4.4-2.5 7.1-6.4 7.1s-6.4-2.7-6.4-7.1v-47.4c0-7.7-3.6-11-10.2-11h-8.3c-4 0-6.5-2.4-6.5-5.8zm74.4 64.4c0 4.3 2.5 7 6.3 7s6.3-2.7 6.3-7v-17.2c0-4.9 2.8-6.9 6.3-6.9h.9c2.3 0 4.5 1.4 5.9 3.5l16.4 24.1c1.5 2.3 3.5 3.6 5.9 3.6s5.8-2.7 5.8-5.9-.4-2.7-1.4-4.1l-10.9-15.3c-1.3-1.8-1.8-3.4-1.8-4.6 0-2.7 2.4-4.6 5.2-6.7 5.1-3.8 10.6-8.8 10.6-18.3s-10.4-22.3-27.5-22.3h-21.7c-3.9 0-6.3 2.3-6.3 5.6v64.6zm12.5-46.3v-3.2c0-7 3.7-9.9 9.3-9.9h5.4c9.3 0 15.2 3.5 15.2 11.5s-6.3 11.7-15.6 11.7h-5.1c-5.6 0-9.3-2.9-9.3-9.9zm58.9 46.1v-64.4c0-3.4 2.4-5.6 6.3-5.6h40.9c3.9 0 6.3 2.3 6.3 5.6s-2.4 5.6-6.3 5.6h-25.8c-5.1 0-8.8 3-8.8 8.8v2.4c0 5.7 3.7 8.8 8.8 8.8h20c3.9 0 6.3 2.3 6.3 5.6s-2.4 5.6-6.3 5.6h-19.2c-5.1 0-9.5 3.1-9.5 9.5v3c0 6.4 4.4 9.5 9.5 9.5h25.1c3.9 0 6.3 2.3 6.3 5.6s-2.4 5.6-6.3 5.6h-40.9c-3.9 0-6.3-2.3-6.3-5.6zm60.9-32.2c0-23.3 17.5-39.4 38-39.4s38 16.1 38 39.4-17.5 39.4-38 39.4-38-16.1-38-39.4zm14.2 0c0 16.4 9.7 26.9 23.8 26.9s23.8-10.5 23.8-26.9-9.7-26.9-23.8-26.9-23.8 10.4-23.8 26.9zm76.9 32.4c0 4.3 2.5 7 6.3 7s6.3-2.7 6.3-7v-33.1c0-4 2.4-5.9 4.9-5.9s3.6 1.1 4.8 3l20.8 34.7c2.8 4.8 5.4 8.3 10.7 8.3s8.8-3.7 8.8-9.6v-62.2c0-4.3-2.5-7-6.3-7s-6.3 2.7-6.3 7v33.1c0 4-2.4 5.9-4.9 5.9s-3.6-1.1-4.8-3l-20.8-34.7c-2.8-4.8-5.4-8.3-10.7-8.3s-8.8 3.7-8.8 9.6z"/><path d="m169.2 87.5c0-16.7-13-30.3-28.2-35.2-18.9-6.1-43.8-5.2-61.9 3.3-21.9 10.3-28.7 32.9-29 55.5-.2 18.5 1.6 67.4 29.2 67.7 20.5.3 23.5-26.1 33-38.8 6.7-9 15.4-11.6 26.1-14.2 18.4-4.5 30.9-19 30.8-38.2z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1 @@
|
||||
<svg fill="none" height="151" viewBox="0 0 360 151" width="360" xmlns="http://www.w3.org/2000/svg"><g fill="#061b31"><g clip-rule="evenodd" fill-rule="evenodd"><path d="m360 78.2001c0-25.6-12.4-45.8-36.1-45.8-23.8 0-38.2 20.2-38.2 45.6 0 30.0999 17 45.2999 41.4 45.2999 11.9 0 20.9-2.7 27.7-6.5v-19.9999c-6.8 3.3999-14.6 5.4999-24.5 5.4999-9.7 0-18.3-3.3998-19.4-15.1998h48.9c0-1.3.2-6.5.2-8.9001zm-49.4-9.5c0-11.2999 6.9-16 13.2-16 6.1 0 12.6 4.7001 12.6 16z"/><path d="m247.1 32.4001c-9.8 0-16.1 4.6-19.6 7.8l-1.3-6.2h-22v116.5999l25-5.3.1-28.3c3.6 2.6 8.9 6.3 17.7 6.3 17.9 0 34.2-14.4 34.2-46.0999-.1-29-16.6-44.8-34.1-44.8zm-6 68.8999c-5.9 0-9.4-2.0999-11.8-4.6998l-.1-37.1001c2.6-2.9 6.2-4.8999 11.9-4.8999 9.1 0 15.4 10.1999 15.4 23.2999 0 13.4-6.2 23.3999-15.4 23.3999z"/><path d="m169.8 26.5 25.1-5.4v-20.299951l-25.1 5.300001z"/></g><path d="m194.9 34.1001h-25.1v87.4999h25.1z"/><path clip-rule="evenodd" d="m142.9 41.5001-1.6-7.4h-21.6v87.4999h25v-59.2999c5.9-7.7 15.9-6.3 19-5.2v-23c-3.2-1.2-14.9-3.4-20.8 7.4z" fill-rule="evenodd"/><path clip-rule="evenodd" d="m92.8999 12.4001-24.4 5.2-.1 80.1c0 14.7999 11.1 25.6999 25.9 25.6999 8.2001 0 14.2001-1.5 17.5001-3.3v-20.2999c-3.2 1.2999-19.0001 5.8999-19.0001-8.9v-35.5h19.0001v-21.2999h-19.0001z" fill-rule="evenodd"/><path clip-rule="evenodd" d="m25.3 59.5001c0-3.9 3.2-5.3999 8.5-5.3999 7.6 0 17.2 2.2999 24.8 6.3999v-23.5c-8.3-3.3-16.5-4.6-24.8-4.6-20.3 0-33.8 10.6-33.8 28.3 0 27.6 38 23.2 38 35.1 0 4.5999-4 6.0999-9.6 6.0999-8.3 0-18.9-3.3998-27.3-7.9998v23.7998c9.3 4 18.7 5.7 27.3 5.7 20.8 0 35.1-10.3 35.1-28.1999-.1-29.8-38.2-24.5-38.2-35.7z" fill-rule="evenodd"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 17 KiB |
@@ -7,12 +7,15 @@
|
||||
"": {
|
||||
"name": "alt-tab-macos",
|
||||
"version": "1.0.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "^22.10.2",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^8.1.0",
|
||||
"@commitlint/config-conventional": "^8.1.0",
|
||||
"@commitlint/travis-cli": "^8.1.0",
|
||||
"@semantic-release/changelog": "^3.0.4",
|
||||
"@semantic-release/git": "^7.0.16",
|
||||
"fontkit": "^1.8.0",
|
||||
@@ -21,6 +24,9 @@
|
||||
"lint-staged": "^13.0.0",
|
||||
"marked": "^0.8.0",
|
||||
"semantic-release": "^15.13.24"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
@@ -222,6 +228,13 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/resolve-extends/node_modules/@types/node": {
|
||||
"version": "12.20.55",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz",
|
||||
"integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@commitlint/rules": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-8.1.0.tgz",
|
||||
@@ -325,21 +338,16 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@commitlint/travis-cli": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@commitlint/travis-cli/-/travis-cli-8.1.0.tgz",
|
||||
"integrity": "sha512-HSeinF08sstSTXDIPvTx5evAd4U49NLF1n0eAXu9rzyHA+ELc6gVSiW3HnIdNx83WkTV+nuQIPQGXqXYx9vleA==",
|
||||
"dev": true,
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@commitlint/cli": "^8.1.0",
|
||||
"babel-runtime": "6.26.0",
|
||||
"execa": "0.9.0"
|
||||
},
|
||||
"bin": {
|
||||
"commitlint-travis": "lib/cli.js"
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui": {
|
||||
@@ -445,6 +453,31 @@
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@marionebl/sander": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@marionebl/sander/-/sander-0.6.1.tgz",
|
||||
@@ -1157,6 +1190,30 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsconfig/node10": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
||||
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node12": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node14": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node16": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/events": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
|
||||
@@ -1181,10 +1238,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "12.7.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.2.tgz",
|
||||
"integrity": "sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg==",
|
||||
"dev": true
|
||||
"version": "22.10.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz",
|
||||
"integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/normalize-package-data": {
|
||||
"version": "2.4.0",
|
||||
@@ -1216,6 +1276,30 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-walk": {
|
||||
"version": "8.3.4",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
||||
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"acorn": "^8.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-walk/node_modules/acorn": {
|
||||
"version": "8.14.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
||||
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
|
||||
@@ -1287,6 +1371,12 @@
|
||||
"integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
@@ -2064,16 +2154,11 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
|
||||
"integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^4.0.1",
|
||||
"shebang-command": "^1.2.0",
|
||||
"which": "^1.2.9"
|
||||
}
|
||||
"node_modules/create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/currently-unhandled": {
|
||||
"version": "0.4.1",
|
||||
@@ -2222,6 +2307,15 @@
|
||||
"integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/dir-glob": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||
@@ -2511,24 +2605,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/execa": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-0.9.0.tgz",
|
||||
"integrity": "sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cross-spawn": "^5.0.1",
|
||||
"get-stream": "^3.0.0",
|
||||
"is-stream": "^1.1.0",
|
||||
"npm-run-path": "^2.0.0",
|
||||
"p-finally": "^1.0.0",
|
||||
"signal-exit": "^3.0.0",
|
||||
"strip-eof": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/falafel": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/falafel/-/falafel-2.2.4.tgz",
|
||||
@@ -2805,15 +2881,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/get-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/git-log-parser": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz",
|
||||
@@ -4302,16 +4369,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
|
||||
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"pseudomap": "^1.0.2",
|
||||
"yallist": "^2.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/macos-release": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz",
|
||||
@@ -4330,6 +4387,12 @@
|
||||
"vlq": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/map-obj": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz",
|
||||
@@ -9681,12 +9744,6 @@
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/pseudomap": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
||||
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/pump": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
@@ -10929,6 +10986,61 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node": {
|
||||
"version": "10.9.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
"@tsconfig/node12": "^1.0.7",
|
||||
"@tsconfig/node14": "^1.0.0",
|
||||
"@tsconfig/node16": "^1.0.2",
|
||||
"acorn": "^8.4.1",
|
||||
"acorn-walk": "^8.1.1",
|
||||
"arg": "^4.1.0",
|
||||
"create-require": "^1.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"v8-compile-cache-lib": "^3.0.1",
|
||||
"yn": "3.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"ts-node": "dist/bin.js",
|
||||
"ts-node-cwd": "dist/bin-cwd.js",
|
||||
"ts-node-esm": "dist/bin-esm.js",
|
||||
"ts-node-script": "dist/bin-script.js",
|
||||
"ts-node-transpile-only": "dist/bin-transpile.js",
|
||||
"ts-script": "dist/bin-script-deprecated.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/core": ">=1.2.50",
|
||||
"@swc/wasm": ">=1.2.50",
|
||||
"@types/node": "*",
|
||||
"typescript": ">=2.7"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@swc/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@swc/wasm": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node/node_modules/acorn": {
|
||||
"version": "8.14.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
||||
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
|
||||
@@ -10956,6 +11068,19 @@
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
|
||||
"integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/uglify-js": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz",
|
||||
@@ -10973,6 +11098,12 @@
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/unicode-properties": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.3.1.tgz",
|
||||
@@ -11039,6 +11170,12 @@
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||
@@ -11303,12 +11440,6 @@
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
||||
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz",
|
||||
@@ -11423,6 +11554,15 @@
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,14 +22,21 @@
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^8.1.0",
|
||||
"@commitlint/config-conventional": "^8.1.0",
|
||||
"@commitlint/travis-cli": "^8.1.0",
|
||||
"@semantic-release/changelog": "^3.0.4",
|
||||
"@semantic-release/git": "^7.0.16",
|
||||
"fontkit": "^1.8.0",
|
||||
"glob": "^10.0.0",
|
||||
"husky": "^3.0.4",
|
||||
"lint-staged": "^13.0.0",
|
||||
"marked": "^0.8.0",
|
||||
"semantic-release": "^15.13.24",
|
||||
"glob": "^10.0.0"
|
||||
"semantic-release": "^15.13.24"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "^22.10.2",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.7.2"
|
||||
}
|
||||
}
|
||||
@@ -15,13 +15,14 @@ module.exports = {
|
||||
}],
|
||||
'@semantic-release/release-notes-generator',
|
||||
['@semantic-release/changelog', {
|
||||
'changelogTitle': '# Release notes',
|
||||
'changelogFile': 'docs/Changelog.md',
|
||||
}],
|
||||
['@semantic-release/git', {
|
||||
'assets': [
|
||||
'docs/Changelog.md',
|
||||
'appcast.xml'
|
||||
'appcast.xml',
|
||||
'README.md',
|
||||
'docs/_layouts/default.html'
|
||||
],
|
||||
}],
|
||||
],
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24412" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24412"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication"/>
|
||||
@@ -11,17 +11,10 @@
|
||||
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
||||
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||
<items>
|
||||
<menuItem title="NewApplication" id="1Xt-HY-uBw">
|
||||
<menuItem title="AltTab" id="1Xt-HY-uBw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="NewApplication" systemMenu="apple" id="uQy-DD-JDr">
|
||||
<menu key="submenu" title="AltTab" systemMenu="apple" id="uQy-DD-JDr">
|
||||
<items>
|
||||
<menuItem title="About NewApplication" id="5kV-Vb-QxS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
|
||||
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
|
||||
<menuItem title="Services" id="NMo-om-nkz">
|
||||
@@ -29,17 +22,6 @@
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
|
||||
<menuItem title="Hide NewApplication" keyEquivalent="h" id="Olw-nP-bQN">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="PnN-Uc-m68"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="Kd2-mp-pUS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
@@ -47,7 +29,7 @@
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
|
||||
<menuItem title="Quit NewApplication" keyEquivalent="q" id="4sb-4s-VLi">
|
||||
<menuItem title="Quit AltTab" keyEquivalent="q" id="4sb-4s-VLi">
|
||||
<connections>
|
||||
<action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
|
||||
</connections>
|
||||
@@ -59,50 +41,11 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="File" id="bib-Uj-vzu">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
|
||||
<connections>
|
||||
<action selector="newDocument:" target="-1" id="4Si-XN-c54"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
|
||||
<connections>
|
||||
<action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open Recent" id="tXI-mr-wws">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="vNY-rz-j42">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="clearRecentDocuments:" target="-1" id="Daa-9d-B3U"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
|
||||
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
|
||||
<connections>
|
||||
<action selector="performClose:" target="-1" id="HmO-Ls-i7Q"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
|
||||
<connections>
|
||||
<action selector="saveDocument:" target="-1" id="teZ-XB-qJY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
|
||||
<connections>
|
||||
<action selector="saveDocumentAs:" target="-1" id="mDf-zr-I0C"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Revert to Saved" keyEquivalent="r" id="KaW-ft-85H">
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
|
||||
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
@@ -599,38 +542,6 @@
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="View" id="H8h-7b-M4v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="View" id="HyV-fh-RgO">
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="-1" id="BXY-wc-z0C"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="pQI-g3-MTW"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="hB3-LF-h0Y"/>
|
||||
<menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleSidebar:" target="-1" id="iwa-gc-5KM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleFullScreen:" target="-1" id="dU3-MA-1Rq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="aUF-d1-5bR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
||||
@@ -660,7 +571,7 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
|
||||
<items>
|
||||
<menuItem title="NewApplication Help" keyEquivalent="?" id="FKE-Sm-Kum">
|
||||
<menuItem title="AltTab Help" keyEquivalent="?" id="FKE-Sm-Kum">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="y7X-2Q-9no"/>
|
||||
</connections>
|
||||
@@ -669,7 +580,7 @@
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
<point key="canvasLocation" x="139" y="154"/>
|
||||
</menu>
|
||||
<customObject id="ULp-HF-g0s" customClass="SUUpdater"/>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,22 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_i)">
|
||||
<path d="M4 3.45H18C18.856 3.45 19.55 4.14396 19.55 5V17C19.55 17.856 18.856 18.55 18 18.55H4C3.14396 18.55 2.45 17.856 2.45 17V5C2.45 4.14396 3.14396 3.45 4 3.45Z" stroke="black" stroke-width="0.9"/>
|
||||
</g>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.16239 12.1506C9.16239 11.7772 8.76803 11.5355 8.43537 11.7051L4.66767 13.625C4.30369 13.8105 4.30369 14.3306 4.66767 14.516L8.43537 16.436C8.76803 16.6055 9.16239 16.3639 9.16239 15.9905L9.16239 15.4506C9.16239 15.1744 9.38625 14.9506 9.66239 14.9506H11.7031C11.9793 14.9506 12.2031 14.7267 12.2031 14.4506V13.6906C12.2031 13.4144 11.9793 13.1906 11.7031 13.1906H9.66239C9.38624 13.1906 9.16239 12.9667 9.16239 12.6906L9.16239 12.1506Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.8405 12.6406C12.8405 13.0139 13.2349 13.2556 13.5676 13.0861L17.3353 11.1661C17.6992 10.9806 17.6992 10.4606 17.3353 10.2751L13.5676 8.35513C13.2349 8.18561 12.8405 8.42726 12.8405 8.80062L12.8405 9.34055C12.8405 9.61669 12.6167 9.84055 12.3405 9.84055H10.2998C10.0237 9.84055 9.7998 10.0644 9.7998 10.3405V11.1005C9.7998 11.3767 10.0237 11.6005 10.2998 11.6005H12.3405C12.6167 11.6005 12.8405 11.8244 12.8405 12.1005L12.8405 12.6406Z" fill="black"/>
|
||||
<circle cx="5.3" cy="6.3" r="0.8" fill="black"/>
|
||||
<circle cx="7.92402" cy="6.3" r="0.8" fill="black"/>
|
||||
<circle cx="10.5754" cy="6.3" r="0.8" fill="black"/>
|
||||
<defs>
|
||||
<filter id="filter0_i" x="2" y="3" width="18" height="16.3718" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.371818"/>
|
||||
<feGaussianBlur stdDeviation="0.185909"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.2 0"/>
|
||||
<feBlend mode="normal" in2="shape" result="effect1_innerShadow"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 456 B |
@@ -1,12 +1,11 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<mask id="path-1-inside-1" fill="white">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3C2.89543 3 2 3.89543 2 5V17C2 18.1046 2.89543 19 4 19H18C19.1046 19 20 18.1046 20 17V5C20 3.89543 19.1046 3 18 3H4ZM6.1 6.3C6.1 6.74183 5.74183 7.1 5.3 7.1C4.85817 7.1 4.5 6.74183 4.5 6.3C4.5 5.85817 4.85817 5.5 5.3 5.5C5.74183 5.5 6.1 5.85817 6.1 6.3ZM13.5672 13.0861C13.2345 13.2556 12.8402 13.014 12.8402 12.6406V12.1006C12.8402 11.8244 12.6163 11.6006 12.3402 11.6006H10.2995C10.0233 11.6006 9.79945 11.3767 9.79945 11.1006V10.3406C9.79945 10.0644 10.0233 9.84058 10.2995 9.84058H12.3402C12.6163 9.84058 12.8402 9.61672 12.8402 9.34058V8.80065C12.8402 8.42728 13.2345 8.18563 13.5672 8.35515L17.3349 10.2751C17.6989 10.4606 17.6989 10.9806 17.3349 11.1661L13.5672 13.0861ZM8.43521 11.7051C8.76787 11.5356 9.16223 11.7772 9.16223 12.1506V12.6906C9.16223 12.9667 9.38609 13.1906 9.66223 13.1906H11.703C11.9791 13.1906 12.203 13.4145 12.203 13.6906V14.4506C12.203 14.7267 11.9791 14.9506 11.703 14.9506H9.66223C9.38609 14.9506 9.16223 15.1745 9.16223 15.4506V15.9905C9.16223 16.3639 8.76787 16.6055 8.43521 16.436L4.66751 14.516C4.30354 14.3306 4.30354 13.8105 4.66751 13.6251L8.43521 11.7051ZM7.92441 7.1C8.36624 7.1 8.72441 6.74183 8.72441 6.3C8.72441 5.85817 8.36624 5.5 7.92441 5.5C7.48259 5.5 7.12441 5.85817 7.12441 6.3C7.12441 6.74183 7.48259 7.1 7.92441 7.1ZM11.3752 6.3C11.3752 6.74183 11.017 7.1 10.5752 7.1C10.1334 7.1 9.7752 6.74183 9.7752 6.3C9.7752 5.85817 10.1334 5.5 10.5752 5.5C11.017 5.5 11.3752 5.85817 11.3752 6.3Z"/>
|
||||
</mask>
|
||||
<g filter="url(#filter0_i)">
|
||||
<path d="M4 3.45H18C18.856 3.45 19.55 4.14396 19.55 5V17C19.55 17.856 18.856 18.55 18 18.55H4C3.14396 18.55 2.45 17.856 2.45 17V5C2.45 4.14396 3.14396 3.45 4 3.45Z" stroke="black" stroke-width="0.9"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3C2.89543 3 2 3.89543 2 5V17C2 18.1046 2.89543 19 4 19H18C19.1046 19 20 18.1046 20 17V5C20 3.89543 19.1046 3 18 3H4ZM6.1 6.3C6.1 6.74183 5.74183 7.1 5.3 7.1C4.85817 7.1 4.5 6.74183 4.5 6.3C4.5 5.85817 4.85817 5.5 5.3 5.5C5.74183 5.5 6.1 5.85817 6.1 6.3ZM13.5672 13.0861C13.2345 13.2556 12.8402 13.014 12.8402 12.6406V12.1006C12.8402 11.8244 12.6163 11.6006 12.3402 11.6006H10.2995C10.0233 11.6006 9.79945 11.3767 9.79945 11.1006V10.3406C9.79945 10.0644 10.0233 9.84058 10.2995 9.84058H12.3402C12.6163 9.84058 12.8402 9.61672 12.8402 9.34058V8.80065C12.8402 8.42728 13.2345 8.18563 13.5672 8.35515L17.3349 10.2751C17.6989 10.4606 17.6989 10.9806 17.3349 11.1661L13.5672 13.0861ZM8.43521 11.7051C8.76787 11.5356 9.16223 11.7772 9.16223 12.1506V12.6906C9.16223 12.9667 9.38609 13.1906 9.66223 13.1906H11.703C11.9791 13.1906 12.203 13.4145 12.203 13.6906V14.4506C12.203 14.7267 11.9791 14.9506 11.703 14.9506H9.66223C9.38609 14.9506 9.16223 15.1745 9.16223 15.4506V15.9905C9.16223 16.3639 8.76787 16.6055 8.43521 16.436L4.66751 14.516C4.30354 14.3306 4.30354 13.8105 4.66751 13.6251L8.43521 11.7051ZM7.92441 7.1C8.36624 7.1 8.72441 6.74183 8.72441 6.3C8.72441 5.85817 8.36624 5.5 7.92441 5.5C7.48259 5.5 7.12441 5.85817 7.12441 6.3C7.12441 6.74183 7.48259 7.1 7.92441 7.1ZM11.3752 6.3C11.3752 6.74183 11.017 7.1 10.5752 7.1C10.1334 7.1 9.7752 6.74183 9.7752 6.3C9.7752 5.85817 10.1334 5.5 10.5752 5.5C11.017 5.5 11.3752 5.85817 11.3752 6.3Z" fill="black"/>
|
||||
</g>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.16239 12.1506C9.16239 11.7772 8.76803 11.5355 8.43537 11.7051L4.66767 13.625C4.30369 13.8105 4.30369 14.3306 4.66767 14.516L8.43537 16.436C8.76803 16.6055 9.16239 16.3639 9.16239 15.9905L9.16239 15.4506C9.16239 15.1744 9.38625 14.9506 9.66239 14.9506H11.7031C11.9793 14.9506 12.2031 14.7267 12.2031 14.4506V13.6906C12.2031 13.4144 11.9793 13.1906 11.7031 13.1906H9.66239C9.38624 13.1906 9.16239 12.9667 9.16239 12.6906L9.16239 12.1506Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.8405 12.6406C12.8405 13.0139 13.2349 13.2556 13.5676 13.0861L17.3353 11.1661C17.6992 10.9806 17.6992 10.4606 17.3353 10.2751L13.5676 8.35513C13.2349 8.18561 12.8405 8.42726 12.8405 8.80062L12.8405 9.34055C12.8405 9.61669 12.6167 9.84055 12.3405 9.84055H10.2998C10.0237 9.84055 9.7998 10.0644 9.7998 10.3405V11.1005C9.7998 11.3767 10.0237 11.6005 10.2998 11.6005H12.3405C12.6167 11.6005 12.8405 11.8244 12.8405 12.1005L12.8405 12.6406Z" fill="black"/>
|
||||
<circle cx="5.3" cy="6.3" r="0.8" fill="black"/>
|
||||
<circle cx="7.92402" cy="6.3" r="0.8" fill="black"/>
|
||||
<circle cx="10.5754" cy="6.3" r="0.8" fill="black"/>
|
||||
<path d="M13.5672 13.0861L13.9758 13.888L13.9758 13.888L13.5672 13.0861ZM13.5672 8.35515L13.1586 9.15704L13.1586 9.15704L13.5672 8.35515ZM17.3349 10.2751L17.7435 9.47325L17.7435 9.47325L17.3349 10.2751ZM17.3349 11.1661L17.7435 11.968L17.7435 11.968L17.3349 11.1661ZM8.43521 11.7051L8.84384 12.507L8.84385 12.507L8.43521 11.7051ZM8.43521 16.436L8.84385 15.6341L8.84385 15.6341L8.43521 16.436ZM4.66751 14.516L5.07615 13.7142L5.07615 13.7142L4.66751 14.516ZM4.66751 13.6251L5.07614 14.4269L5.07615 14.4269L4.66751 13.6251ZM2.9 5C2.9 4.39249 3.39249 3.9 4 3.9V2.1C2.39837 2.1 1.1 3.39837 1.1 5H2.9ZM2.9 17V5H1.1V17H2.9ZM4 18.1C3.39249 18.1 2.9 17.6075 2.9 17H1.1C1.1 18.6016 2.39837 19.9 4 19.9V18.1ZM18 18.1H4V19.9H18V18.1ZM19.1 17C19.1 17.6075 18.6075 18.1 18 18.1V19.9C19.6016 19.9 20.9 18.6016 20.9 17H19.1ZM19.1 5V17H20.9V5H19.1ZM18 3.9C18.6075 3.9 19.1 4.39249 19.1 5H20.9C20.9 3.39837 19.6016 2.1 18 2.1V3.9ZM4 3.9H18V2.1H4V3.9ZM5.3 8C6.23888 8 7 7.23888 7 6.3H5.2C5.2 6.24477 5.24477 6.2 5.3 6.2V8ZM3.6 6.3C3.6 7.23888 4.36112 8 5.3 8V6.2C5.35523 6.2 5.4 6.24477 5.4 6.3H3.6ZM5.3 4.6C4.36112 4.6 3.6 5.36112 3.6 6.3H5.4C5.4 6.35523 5.35523 6.4 5.3 6.4V4.6ZM7 6.3C7 5.36112 6.23888 4.6 5.3 4.6V6.4C5.24477 6.4 5.2 6.35523 5.2 6.3H7ZM11.9402 12.6406C11.9402 13.686 13.0444 14.3626 13.9758 13.888L13.1586 12.2842C13.4247 12.1486 13.7402 12.3419 13.7402 12.6406H11.9402ZM11.9402 12.1006V12.6406H13.7402V12.1006H11.9402ZM12.3402 12.5006C12.1193 12.5006 11.9402 12.3215 11.9402 12.1006H13.7402C13.7402 11.3274 13.1134 10.7006 12.3402 10.7006V12.5006ZM10.2995 12.5006H12.3402V10.7006H10.2995V12.5006ZM8.89945 11.1006C8.89945 11.8738 9.52626 12.5006 10.2995 12.5006V10.7006C10.5204 10.7006 10.6995 10.8797 10.6995 11.1006H8.89945ZM8.89945 10.3406V11.1006H10.6995V10.3406H8.89945ZM10.2995 8.94058C9.52626 8.94058 8.89945 9.56738 8.89945 10.3406H10.6995C10.6995 10.5615 10.5204 10.7406 10.2995 10.7406V8.94058ZM12.3402 8.94058H10.2995V10.7406H12.3402V8.94058ZM11.9402 9.34058C11.9402 9.11966 12.1193 8.94058 12.3402 8.94058V10.7406C13.1134 10.7406 13.7402 10.1138 13.7402 9.34058H11.9402ZM11.9402 8.80065V9.34058H13.7402V8.80065H11.9402ZM13.9758 7.55327C13.0444 7.07861 11.9402 7.75524 11.9402 8.80065H13.7402C13.7402 9.09933 13.4247 9.29266 13.1586 9.15704L13.9758 7.55327ZM17.7435 9.47325L13.9758 7.55327L13.1586 9.15704L16.9263 11.077L17.7435 9.47325ZM17.7435 11.968C18.7627 11.4487 18.7627 9.99259 17.7435 9.47325L16.9263 11.077C16.6351 10.9286 16.6351 10.5126 16.9263 10.3642L17.7435 11.968ZM13.9758 13.888L17.7435 11.968L16.9263 10.3642L13.1586 12.2842L13.9758 13.888ZM10.0622 12.1506C10.0622 11.1052 8.95802 10.4285 8.02658 10.9032L8.84385 12.507C8.57772 12.6426 8.26223 12.4493 8.26223 12.1506H10.0622ZM10.0622 12.6906V12.1506H8.26223V12.6906H10.0622ZM9.66223 12.2906C9.88315 12.2906 10.0622 12.4697 10.0622 12.6906H8.26223C8.26223 13.4638 8.88903 14.0906 9.66223 14.0906V12.2906ZM11.703 12.2906H9.66223V14.0906H11.703V12.2906ZM13.103 13.6906C13.103 12.9174 12.4762 12.2906 11.703 12.2906V14.0906C11.4821 14.0906 11.303 13.9115 11.303 13.6906H13.103ZM13.103 14.4506V13.6906H11.303V14.4506H13.103ZM11.703 15.8506C12.4762 15.8506 13.103 15.2238 13.103 14.4506H11.303C11.303 14.2297 11.4821 14.0506 11.703 14.0506V15.8506ZM9.66223 15.8506H11.703V14.0506H9.66223V15.8506ZM10.0622 15.4506C10.0622 15.6715 9.88314 15.8506 9.66223 15.8506V14.0506C8.88903 14.0506 8.26223 14.6774 8.26223 15.4506H10.0622ZM10.0622 15.9905V15.4506H8.26223V15.9905H10.0622ZM8.02658 17.2379C8.95803 17.7126 10.0622 17.0359 10.0622 15.9905H8.26223C8.26223 15.6918 8.57772 15.4985 8.84385 15.6341L8.02658 17.2379ZM4.25888 15.3179L8.02658 17.2379L8.84385 15.6341L5.07615 13.7142L4.25888 15.3179ZM4.25888 12.8232C3.23975 13.3425 3.23975 14.7986 4.25888 15.3179L5.07615 13.7142C5.36733 13.8625 5.36733 14.2786 5.07614 14.4269L4.25888 12.8232ZM8.02658 10.9032L4.25888 12.8232L5.07615 14.4269L8.84384 12.507L8.02658 10.9032ZM7.82441 6.3C7.82441 6.24477 7.86919 6.2 7.92441 6.2V8C8.8633 8 9.62441 7.23888 9.62441 6.3H7.82441ZM7.92441 6.4C7.86919 6.4 7.82441 6.35523 7.82441 6.3H9.62441C9.62441 5.36112 8.8633 4.6 7.92441 4.6V6.4ZM8.02441 6.3C8.02441 6.35523 7.97964 6.4 7.92441 6.4V4.6C6.98553 4.6 6.22441 5.36112 6.22441 6.3H8.02441ZM7.92441 6.2C7.97964 6.2 8.02441 6.24477 8.02441 6.3H6.22441C6.22441 7.23888 6.98553 8 7.92441 8V6.2ZM10.5752 8C11.5141 8 12.2752 7.23888 12.2752 6.3H10.4752C10.4752 6.24477 10.52 6.2 10.5752 6.2V8ZM8.8752 6.3C8.8752 7.23888 9.63631 8 10.5752 8V6.2C10.6304 6.2 10.6752 6.24477 10.6752 6.3H8.8752ZM10.5752 4.6C9.63631 4.6 8.8752 5.36112 8.8752 6.3H10.6752C10.6752 6.35523 10.6304 6.4 10.5752 6.4V4.6ZM12.2752 6.3C12.2752 5.36112 11.5141 4.6 10.5752 4.6V6.4C10.52 6.4 10.4752 6.35523 10.4752 6.3H12.2752Z" fill="black" mask="url(#path-1-inside-1)"/>
|
||||
<defs>
|
||||
<filter id="filter0_i" x="2" y="3" width="18" height="16.3718" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 456 B After Width: | Height: | Size: 324 B |
@@ -1,21 +0,0 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<mask id="path-1-inside-1" fill="white">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3C2.89543 3 2 3.89543 2 5V17C2 18.1046 2.89543 19 4 19H18C19.1046 19 20 18.1046 20 17V5C20 3.89543 19.1046 3 18 3H4ZM6.1 6.3C6.1 6.74183 5.74183 7.1 5.3 7.1C4.85817 7.1 4.5 6.74183 4.5 6.3C4.5 5.85817 4.85817 5.5 5.3 5.5C5.74183 5.5 6.1 5.85817 6.1 6.3ZM13.5672 13.0861C13.2345 13.2556 12.8402 13.014 12.8402 12.6406V12.1006C12.8402 11.8244 12.6163 11.6006 12.3402 11.6006H10.2995C10.0233 11.6006 9.79945 11.3767 9.79945 11.1006V10.3406C9.79945 10.0644 10.0233 9.84058 10.2995 9.84058H12.3402C12.6163 9.84058 12.8402 9.61672 12.8402 9.34058V8.80065C12.8402 8.42728 13.2345 8.18563 13.5672 8.35515L17.3349 10.2751C17.6989 10.4606 17.6989 10.9806 17.3349 11.1661L13.5672 13.0861ZM8.43521 11.7051C8.76787 11.5356 9.16223 11.7772 9.16223 12.1506V12.6906C9.16223 12.9667 9.38609 13.1906 9.66223 13.1906H11.703C11.9791 13.1906 12.203 13.4145 12.203 13.6906V14.4506C12.203 14.7267 11.9791 14.9506 11.703 14.9506H9.66223C9.38609 14.9506 9.16223 15.1745 9.16223 15.4506V15.9905C9.16223 16.3639 8.76787 16.6055 8.43521 16.436L4.66751 14.516C4.30354 14.3306 4.30354 13.8105 4.66751 13.6251L8.43521 11.7051ZM7.92441 7.1C8.36624 7.1 8.72441 6.74183 8.72441 6.3C8.72441 5.85817 8.36624 5.5 7.92441 5.5C7.48259 5.5 7.12441 5.85817 7.12441 6.3C7.12441 6.74183 7.48259 7.1 7.92441 7.1ZM11.3752 6.3C11.3752 6.74183 11.017 7.1 10.5752 7.1C10.1334 7.1 9.7752 6.74183 9.7752 6.3C9.7752 5.85817 10.1334 5.5 10.5752 5.5C11.017 5.5 11.3752 5.85817 11.3752 6.3Z"/>
|
||||
</mask>
|
||||
<g filter="url(#filter0_i)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3C2.89543 3 2 3.89543 2 5V17C2 18.1046 2.89543 19 4 19H18C19.1046 19 20 18.1046 20 17V5C20 3.89543 19.1046 3 18 3H4ZM6.1 6.3C6.1 6.74183 5.74183 7.1 5.3 7.1C4.85817 7.1 4.5 6.74183 4.5 6.3C4.5 5.85817 4.85817 5.5 5.3 5.5C5.74183 5.5 6.1 5.85817 6.1 6.3ZM13.5672 13.0861C13.2345 13.2556 12.8402 13.014 12.8402 12.6406V12.1006C12.8402 11.8244 12.6163 11.6006 12.3402 11.6006H10.2995C10.0233 11.6006 9.79945 11.3767 9.79945 11.1006V10.3406C9.79945 10.0644 10.0233 9.84058 10.2995 9.84058H12.3402C12.6163 9.84058 12.8402 9.61672 12.8402 9.34058V8.80065C12.8402 8.42728 13.2345 8.18563 13.5672 8.35515L17.3349 10.2751C17.6989 10.4606 17.6989 10.9806 17.3349 11.1661L13.5672 13.0861ZM8.43521 11.7051C8.76787 11.5356 9.16223 11.7772 9.16223 12.1506V12.6906C9.16223 12.9667 9.38609 13.1906 9.66223 13.1906H11.703C11.9791 13.1906 12.203 13.4145 12.203 13.6906V14.4506C12.203 14.7267 11.9791 14.9506 11.703 14.9506H9.66223C9.38609 14.9506 9.16223 15.1745 9.16223 15.4506V15.9905C9.16223 16.3639 8.76787 16.6055 8.43521 16.436L4.66751 14.516C4.30354 14.3306 4.30354 13.8105 4.66751 13.6251L8.43521 11.7051ZM7.92441 7.1C8.36624 7.1 8.72441 6.74183 8.72441 6.3C8.72441 5.85817 8.36624 5.5 7.92441 5.5C7.48259 5.5 7.12441 5.85817 7.12441 6.3C7.12441 6.74183 7.48259 7.1 7.92441 7.1ZM11.3752 6.3C11.3752 6.74183 11.017 7.1 10.5752 7.1C10.1334 7.1 9.7752 6.74183 9.7752 6.3C9.7752 5.85817 10.1334 5.5 10.5752 5.5C11.017 5.5 11.3752 5.85817 11.3752 6.3Z" fill="black"/>
|
||||
</g>
|
||||
<path d="M13.5672 13.0861L13.9758 13.888L13.9758 13.888L13.5672 13.0861ZM13.5672 8.35515L13.1586 9.15704L13.1586 9.15704L13.5672 8.35515ZM17.3349 10.2751L17.7435 9.47325L17.7435 9.47325L17.3349 10.2751ZM17.3349 11.1661L17.7435 11.968L17.7435 11.968L17.3349 11.1661ZM8.43521 11.7051L8.84384 12.507L8.84385 12.507L8.43521 11.7051ZM8.43521 16.436L8.84385 15.6341L8.84385 15.6341L8.43521 16.436ZM4.66751 14.516L5.07615 13.7142L5.07615 13.7142L4.66751 14.516ZM4.66751 13.6251L5.07614 14.4269L5.07615 14.4269L4.66751 13.6251ZM2.9 5C2.9 4.39249 3.39249 3.9 4 3.9V2.1C2.39837 2.1 1.1 3.39837 1.1 5H2.9ZM2.9 17V5H1.1V17H2.9ZM4 18.1C3.39249 18.1 2.9 17.6075 2.9 17H1.1C1.1 18.6016 2.39837 19.9 4 19.9V18.1ZM18 18.1H4V19.9H18V18.1ZM19.1 17C19.1 17.6075 18.6075 18.1 18 18.1V19.9C19.6016 19.9 20.9 18.6016 20.9 17H19.1ZM19.1 5V17H20.9V5H19.1ZM18 3.9C18.6075 3.9 19.1 4.39249 19.1 5H20.9C20.9 3.39837 19.6016 2.1 18 2.1V3.9ZM4 3.9H18V2.1H4V3.9ZM5.3 8C6.23888 8 7 7.23888 7 6.3H5.2C5.2 6.24477 5.24477 6.2 5.3 6.2V8ZM3.6 6.3C3.6 7.23888 4.36112 8 5.3 8V6.2C5.35523 6.2 5.4 6.24477 5.4 6.3H3.6ZM5.3 4.6C4.36112 4.6 3.6 5.36112 3.6 6.3H5.4C5.4 6.35523 5.35523 6.4 5.3 6.4V4.6ZM7 6.3C7 5.36112 6.23888 4.6 5.3 4.6V6.4C5.24477 6.4 5.2 6.35523 5.2 6.3H7ZM11.9402 12.6406C11.9402 13.686 13.0444 14.3626 13.9758 13.888L13.1586 12.2842C13.4247 12.1486 13.7402 12.3419 13.7402 12.6406H11.9402ZM11.9402 12.1006V12.6406H13.7402V12.1006H11.9402ZM12.3402 12.5006C12.1193 12.5006 11.9402 12.3215 11.9402 12.1006H13.7402C13.7402 11.3274 13.1134 10.7006 12.3402 10.7006V12.5006ZM10.2995 12.5006H12.3402V10.7006H10.2995V12.5006ZM8.89945 11.1006C8.89945 11.8738 9.52626 12.5006 10.2995 12.5006V10.7006C10.5204 10.7006 10.6995 10.8797 10.6995 11.1006H8.89945ZM8.89945 10.3406V11.1006H10.6995V10.3406H8.89945ZM10.2995 8.94058C9.52626 8.94058 8.89945 9.56738 8.89945 10.3406H10.6995C10.6995 10.5615 10.5204 10.7406 10.2995 10.7406V8.94058ZM12.3402 8.94058H10.2995V10.7406H12.3402V8.94058ZM11.9402 9.34058C11.9402 9.11966 12.1193 8.94058 12.3402 8.94058V10.7406C13.1134 10.7406 13.7402 10.1138 13.7402 9.34058H11.9402ZM11.9402 8.80065V9.34058H13.7402V8.80065H11.9402ZM13.9758 7.55327C13.0444 7.07861 11.9402 7.75524 11.9402 8.80065H13.7402C13.7402 9.09933 13.4247 9.29266 13.1586 9.15704L13.9758 7.55327ZM17.7435 9.47325L13.9758 7.55327L13.1586 9.15704L16.9263 11.077L17.7435 9.47325ZM17.7435 11.968C18.7627 11.4487 18.7627 9.99259 17.7435 9.47325L16.9263 11.077C16.6351 10.9286 16.6351 10.5126 16.9263 10.3642L17.7435 11.968ZM13.9758 13.888L17.7435 11.968L16.9263 10.3642L13.1586 12.2842L13.9758 13.888ZM10.0622 12.1506C10.0622 11.1052 8.95802 10.4285 8.02658 10.9032L8.84385 12.507C8.57772 12.6426 8.26223 12.4493 8.26223 12.1506H10.0622ZM10.0622 12.6906V12.1506H8.26223V12.6906H10.0622ZM9.66223 12.2906C9.88315 12.2906 10.0622 12.4697 10.0622 12.6906H8.26223C8.26223 13.4638 8.88903 14.0906 9.66223 14.0906V12.2906ZM11.703 12.2906H9.66223V14.0906H11.703V12.2906ZM13.103 13.6906C13.103 12.9174 12.4762 12.2906 11.703 12.2906V14.0906C11.4821 14.0906 11.303 13.9115 11.303 13.6906H13.103ZM13.103 14.4506V13.6906H11.303V14.4506H13.103ZM11.703 15.8506C12.4762 15.8506 13.103 15.2238 13.103 14.4506H11.303C11.303 14.2297 11.4821 14.0506 11.703 14.0506V15.8506ZM9.66223 15.8506H11.703V14.0506H9.66223V15.8506ZM10.0622 15.4506C10.0622 15.6715 9.88314 15.8506 9.66223 15.8506V14.0506C8.88903 14.0506 8.26223 14.6774 8.26223 15.4506H10.0622ZM10.0622 15.9905V15.4506H8.26223V15.9905H10.0622ZM8.02658 17.2379C8.95803 17.7126 10.0622 17.0359 10.0622 15.9905H8.26223C8.26223 15.6918 8.57772 15.4985 8.84385 15.6341L8.02658 17.2379ZM4.25888 15.3179L8.02658 17.2379L8.84385 15.6341L5.07615 13.7142L4.25888 15.3179ZM4.25888 12.8232C3.23975 13.3425 3.23975 14.7986 4.25888 15.3179L5.07615 13.7142C5.36733 13.8625 5.36733 14.2786 5.07614 14.4269L4.25888 12.8232ZM8.02658 10.9032L4.25888 12.8232L5.07615 14.4269L8.84384 12.507L8.02658 10.9032ZM7.82441 6.3C7.82441 6.24477 7.86919 6.2 7.92441 6.2V8C8.8633 8 9.62441 7.23888 9.62441 6.3H7.82441ZM7.92441 6.4C7.86919 6.4 7.82441 6.35523 7.82441 6.3H9.62441C9.62441 5.36112 8.8633 4.6 7.92441 4.6V6.4ZM8.02441 6.3C8.02441 6.35523 7.97964 6.4 7.92441 6.4V4.6C6.98553 4.6 6.22441 5.36112 6.22441 6.3H8.02441ZM7.92441 6.2C7.97964 6.2 8.02441 6.24477 8.02441 6.3H6.22441C6.22441 7.23888 6.98553 8 7.92441 8V6.2ZM10.5752 8C11.5141 8 12.2752 7.23888 12.2752 6.3H10.4752C10.4752 6.24477 10.52 6.2 10.5752 6.2V8ZM8.8752 6.3C8.8752 7.23888 9.63631 8 10.5752 8V6.2C10.6304 6.2 10.6752 6.24477 10.6752 6.3H8.8752ZM10.5752 4.6C9.63631 4.6 8.8752 5.36112 8.8752 6.3H10.6752C10.6752 6.35523 10.6304 6.4 10.5752 6.4V4.6ZM12.2752 6.3C12.2752 5.36112 11.5141 4.6 10.5752 4.6V6.4C10.52 6.4 10.4752 6.35523 10.4752 6.3H12.2752Z" fill="black" mask="url(#path-1-inside-1)"/>
|
||||
<defs>
|
||||
<filter id="filter0_i" x="2" y="3" width="18" height="16.3718" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.371818"/>
|
||||
<feGaussianBlur stdDeviation="0.185909"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.2 0"/>
|
||||
<feBlend mode="normal" in2="shape" result="effect1_innerShadow"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 3.7 KiB |