mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-01-04 11:26:36 +01:00
Compare commits
4147 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fdffe20c0b | ||
|
|
e30393e18f | ||
|
|
6726abd37e | ||
|
|
2174e97286 | ||
|
|
698d19cb51 | ||
|
|
5ac30cec73 | ||
|
|
2e5b6df3a7 | ||
|
|
175e962c0c | ||
|
|
70f78c3189 | ||
|
|
8f12973c84 | ||
|
|
5ca11f3eac | ||
|
|
b00e5008af | ||
|
|
b8069ce657 | ||
|
|
965f3813b2 | ||
|
|
97a51fc2a9 | ||
|
|
3a7fc33943 | ||
|
|
8a006d27ca | ||
|
|
3f45a521a0 | ||
|
|
b7bcd4484a | ||
|
|
f97ed9c340 | ||
|
|
f03553e107 | ||
|
|
4394491292 | ||
|
|
fe32e10dc1 | ||
|
|
03ea90dced | ||
|
|
d7912e1e12 | ||
|
|
ce464f4816 | ||
|
|
a019ebb15e | ||
|
|
674e24fd58 | ||
|
|
eccc5b204c | ||
|
|
c99fbe54bd | ||
|
|
71ed538285 | ||
|
|
8eab2ef27c | ||
|
|
93da059454 | ||
|
|
162ff4ab15 | ||
|
|
07e600907b | ||
|
|
2c2a033e18 | ||
|
|
ccd61c2d78 | ||
|
|
877bd0954b | ||
|
|
810ee0e290 | ||
|
|
c00b4ba6ac | ||
|
|
23b854dedc | ||
|
|
d10d7d06fb | ||
|
|
b4102eabe5 | ||
|
|
3bd6e787ab | ||
|
|
1758449b51 | ||
|
|
9c3c5725af | ||
|
|
931fd66f66 | ||
|
|
d2435262ec | ||
|
|
cbb4307f6d | ||
|
|
46f5bfbe22 | ||
|
|
ca1e5d111a | ||
|
|
c76c4f026e | ||
|
|
3906896947 | ||
|
|
825e7a7533 | ||
|
|
e411e6dc75 | ||
|
|
39ebd82e20 | ||
|
|
ec22bc40bc | ||
|
|
129342edff | ||
|
|
8ca0c35242 | ||
|
|
e5f2810212 | ||
|
|
48292fb189 | ||
|
|
e6a5b589ff | ||
|
|
8ef91a528f | ||
|
|
8ea09e0c95 | ||
|
|
854828e4ca | ||
|
|
bea1cf92d8 | ||
|
|
fa37d53cd9 | ||
|
|
344013d860 | ||
|
|
61a2e5297f | ||
|
|
93627d2bbe | ||
|
|
2ef451aa4a | ||
|
|
36b628df48 | ||
|
|
146e7866a6 | ||
|
|
6424667396 | ||
|
|
beecdc8d79 | ||
|
|
6ae8d6749a | ||
|
|
ba07b52cc2 | ||
|
|
87128ceee6 | ||
|
|
773c57e609 | ||
|
|
7c42162618 | ||
|
|
466a0015e9 | ||
|
|
859e9f8b04 | ||
|
|
c5bf549dde | ||
|
|
3f5810bfdb | ||
|
|
5b86885cd1 | ||
|
|
f92bd6ffd3 | ||
|
|
aa0947061a | ||
|
|
e2c94b592f | ||
|
|
31799cd019 | ||
|
|
ec18e31ff1 | ||
|
|
5e772340bc | ||
|
|
5593f81242 | ||
|
|
3d0254bdeb | ||
|
|
bc103ce25c | ||
|
|
cfe9e2328f | ||
|
|
dd2627dbbc | ||
|
|
86d77103e9 | ||
|
|
29ed39c7ae | ||
|
|
8d9e85f4f5 | ||
|
|
73df7b5deb | ||
|
|
cd8c9c5375 | ||
|
|
147b78ffce | ||
|
|
9c341cc9bc | ||
|
|
f506980e4d | ||
|
|
6c62be1818 | ||
|
|
e05146acf9 | ||
|
|
eaec26a012 | ||
|
|
3801ad3030 | ||
|
|
4da4673e24 | ||
|
|
466ed10f3d | ||
|
|
0314b570cd | ||
|
|
18eb6b4ffd | ||
|
|
9a9424a975 | ||
|
|
51d6482ec2 | ||
|
|
334e612bce | ||
|
|
14e74376d9 | ||
|
|
58cf165eb4 | ||
|
|
7c07bc2717 | ||
|
|
83872046fa | ||
|
|
701ccfdbcc | ||
|
|
280d1907d8 | ||
|
|
8b759094f7 | ||
|
|
0aae535986 | ||
|
|
688f134051 | ||
|
|
03509e7f36 | ||
|
|
4660dd4970 | ||
|
|
12a84c01b1 | ||
|
|
06de5ffa07 | ||
|
|
7e0574cba2 | ||
|
|
b80578b1b9 | ||
|
|
36dd29c056 | ||
|
|
6f5cdb4674 | ||
|
|
c34c963121 | ||
|
|
36bcbe9d95 | ||
|
|
4634c74f9e | ||
|
|
c576bb611d | ||
|
|
5f86956a41 | ||
|
|
fd7c7ffd57 | ||
|
|
438169e64f | ||
|
|
598729f84c | ||
|
|
001c3304a2 | ||
|
|
eeeae65493 | ||
|
|
184b6c5bd0 | ||
|
|
70bc967219 | ||
|
|
944e605f06 | ||
|
|
d1372af581 | ||
|
|
3f4336697e | ||
|
|
789816084e | ||
|
|
ac94bbe575 | ||
|
|
539b834da9 | ||
|
|
094136daec | ||
|
|
5444bde283 | ||
|
|
8ade8fb2c5 | ||
|
|
844a68dae0 | ||
|
|
954705e3a0 | ||
|
|
dde19380e9 | ||
|
|
bb8cc0a305 | ||
|
|
45124c2245 | ||
|
|
6e8cc67824 | ||
|
|
c6a82ef199 | ||
|
|
bd700a5b29 | ||
|
|
1f1cff3389 | ||
|
|
d9d328173b | ||
|
|
6161531376 | ||
|
|
3807e98f23 | ||
|
|
889f20c4a7 | ||
|
|
8643bfc977 | ||
|
|
7fd5e18ef4 | ||
|
|
d753179d1e | ||
|
|
ff20ef26d8 | ||
|
|
bd3c877ca3 | ||
|
|
274c009f20 | ||
|
|
210426a020 | ||
|
|
c393db0b65 | ||
|
|
1390b57d3e | ||
|
|
4451403c1e | ||
|
|
38e03e6bb0 | ||
|
|
42ebc42c98 | ||
|
|
e1d22c74b0 | ||
|
|
9928579364 | ||
|
|
cfe2bbd75e | ||
|
|
8a81bea413 | ||
|
|
9216aa465f | ||
|
|
038087e076 | ||
|
|
de4436ccc0 | ||
|
|
5e30ad176a | ||
|
|
d011843113 | ||
|
|
0c0aec0f2a | ||
|
|
2bd6c5c664 | ||
|
|
eae0937db0 | ||
|
|
69e25cfefc | ||
|
|
163a699bff | ||
|
|
8b66932036 | ||
|
|
a2fce22973 | ||
|
|
206397dc86 | ||
|
|
ac3910580a | ||
|
|
bee1af427b | ||
|
|
ea0de4f831 | ||
|
|
5d095efe90 | ||
|
|
71765238b1 | ||
|
|
4feb0f209f | ||
|
|
7c607ad540 | ||
|
|
3f25d7ccc8 | ||
|
|
b2e72e1ca4 | ||
|
|
55fd8749c8 | ||
|
|
fd32a6f7d6 | ||
|
|
b981467f1e | ||
|
|
c219fe0d1d | ||
|
|
19b519638f | ||
|
|
85f56f4ed8 | ||
|
|
8f81b9c662 | ||
|
|
5c84de5400 | ||
|
|
b2c00b1e1a | ||
|
|
67072b99d4 | ||
|
|
07256c50ef | ||
|
|
6711a6bc7e | ||
|
|
39c61b9abd | ||
|
|
24ba7f08cf | ||
|
|
fb8e80c09c | ||
|
|
240f67f15c | ||
|
|
8d18626659 | ||
|
|
a5b22cffa2 | ||
|
|
9f8202bc4f | ||
|
|
bdd513b212 | ||
|
|
de870c843e | ||
|
|
9c32e32097 | ||
|
|
f61db8ed3f | ||
|
|
9e1711cbb9 | ||
|
|
c941b5333c | ||
|
|
8d934df0c0 | ||
|
|
2f0937951a | ||
|
|
a676537e26 | ||
|
|
b071220b6c | ||
|
|
dafc1e0c7d | ||
|
|
5a07579b73 | ||
|
|
0148669e98 | ||
|
|
75ace74d37 | ||
|
|
1ef4c43382 | ||
|
|
c1e9f2de6a | ||
|
|
55b36d44fa | ||
|
|
d2201cbb79 | ||
|
|
934949725b | ||
|
|
57972c6653 | ||
|
|
0f6428eed0 | ||
|
|
6e89ef62e4 | ||
|
|
b266e336b5 | ||
|
|
e135153c45 | ||
|
|
28cae124d1 | ||
|
|
94d8b4a122 | ||
|
|
ce835418cb | ||
|
|
3aa7a52c21 | ||
|
|
2bc3480396 | ||
|
|
7893f387d5 | ||
|
|
00187269de | ||
|
|
b3833fcf1a | ||
|
|
923972dd49 | ||
|
|
f19bad3761 | ||
|
|
b5cc24fcff | ||
|
|
d414d52156 | ||
|
|
85c0eaa598 | ||
|
|
d409a71000 | ||
|
|
0a716c253b | ||
|
|
13fd6bd6e1 | ||
|
|
b0f0940534 | ||
|
|
dc284d9cbb | ||
|
|
0a86360948 | ||
|
|
aff717ffce | ||
|
|
e49900f927 | ||
|
|
5e301133ff | ||
|
|
5b684cca9a | ||
|
|
3d36779e19 | ||
|
|
eaf54ca525 | ||
|
|
ba7a598b2e | ||
|
|
dce4b2288b | ||
|
|
2a847eebb9 | ||
|
|
25f93e8b94 | ||
|
|
7328aa7df5 | ||
|
|
d75dd71848 | ||
|
|
a8dca61a3c | ||
|
|
d32d5b8bac | ||
|
|
3d5c790fb6 | ||
|
|
5af88de27b | ||
|
|
997a7bc60f | ||
|
|
bfbd7b53a1 | ||
|
|
1dec80902d | ||
|
|
0478d99aac | ||
|
|
db9677bb4a | ||
|
|
0e32edb603 | ||
|
|
82e1be2839 | ||
|
|
ab8bec8866 | ||
|
|
3b8fa8b4ce | ||
|
|
c4cb3df306 | ||
|
|
efd5c33a92 | ||
|
|
f589103f5d | ||
|
|
19175e9bde | ||
|
|
3137aaa660 | ||
|
|
cfda69a120 | ||
|
|
1027b7de72 | ||
|
|
fb1888f01f | ||
|
|
f61e9d389f | ||
|
|
936b02865f | ||
|
|
cbd3516fc4 | ||
|
|
c2d6f740a1 | ||
|
|
305a04ce69 | ||
|
|
fdd7d6afa4 | ||
|
|
1a51f77fce | ||
|
|
8ea8db7994 | ||
|
|
cd906b0a6f | ||
|
|
85fa644aca | ||
|
|
839d3f89d8 | ||
|
|
52a06b5cdc | ||
|
|
5065239266 | ||
|
|
13426eac50 | ||
|
|
c5f90272d1 | ||
|
|
e0d6c2a4cd | ||
|
|
3c76942799 | ||
|
|
4ff888b2b0 | ||
|
|
a0eaf077de | ||
|
|
726f94e2a2 | ||
|
|
19771b171c | ||
|
|
b4223967e8 | ||
|
|
e57283460a | ||
|
|
78edaf5edc | ||
|
|
91f0d40d1a | ||
|
|
dacccf1415 | ||
|
|
8fcb76e300 | ||
|
|
24906e6fa5 | ||
|
|
570065175c | ||
|
|
e84a293642 | ||
|
|
41559d8742 | ||
|
|
6e898ae52d | ||
|
|
288d929477 | ||
|
|
807fbd4d89 | ||
|
|
6ce47e5cd9 | ||
|
|
712d5fbfa7 | ||
|
|
8d3380b388 | ||
|
|
c9855a2671 | ||
|
|
c887f0ce5b | ||
|
|
64ee0015d1 | ||
|
|
1b598ad87e | ||
|
|
c9f536c635 | ||
|
|
742f4fe36d | ||
|
|
fc34c05a2f | ||
|
|
84055a420b | ||
|
|
e5ec08ff9d | ||
|
|
06267f5a03 | ||
|
|
824bec2784 | ||
|
|
cb81f7b057 | ||
|
|
ce43b10b5b | ||
|
|
0349383d08 | ||
|
|
777e1dc48c | ||
|
|
fe8727bd94 | ||
|
|
6a531ca57c | ||
|
|
1d9c15b1cc | ||
|
|
fc4ac803aa | ||
|
|
870f1095cd | ||
|
|
4e969a3701 | ||
|
|
0a603449ad | ||
|
|
d51640c2f0 | ||
|
|
be8695777c | ||
|
|
eb825ae619 | ||
|
|
40a4a6a1a8 | ||
|
|
07dfa6f296 | ||
|
|
cb52cb2549 | ||
|
|
26b73b0745 | ||
|
|
fead0c5ad9 | ||
|
|
c3652786ff | ||
|
|
3bd6c363de | ||
|
|
48b6654ad2 | ||
|
|
2075f9fa71 | ||
|
|
96fdb6169a | ||
|
|
6d47a5477a | ||
|
|
d3b80b26e3 | ||
|
|
3ede1a0b53 | ||
|
|
aebd7657ef | ||
|
|
15938a12be | ||
|
|
f2cfd90c46 | ||
|
|
f3a55d96f5 | ||
|
|
392ca87dab | ||
|
|
ff48421e4f | ||
|
|
f6579184a2 | ||
|
|
c0c68f6acd | ||
|
|
f2fd376363 | ||
|
|
9999a2b126 | ||
|
|
2817bf4d62 | ||
|
|
845bb466c6 | ||
|
|
f64df97652 | ||
|
|
9c6b2c3e81 | ||
|
|
83e8799610 | ||
|
|
80f8c0399b | ||
|
|
f6b5840e0e | ||
|
|
b5dec2e935 | ||
|
|
79bb68d784 | ||
|
|
976116a012 | ||
|
|
64c51a49a0 | ||
|
|
cc0b808962 | ||
|
|
9b567f9ba3 | ||
|
|
9a36b005a1 | ||
|
|
2390368d03 | ||
|
|
64106cba82 | ||
|
|
69cb20e1cd | ||
|
|
2a7bf7fb5b | ||
|
|
dc744f236e | ||
|
|
9724afd9ec | ||
|
|
34e7467d16 | ||
|
|
7eccb6fc7a | ||
|
|
0445e89747 | ||
|
|
953ab958d5 | ||
|
|
5e13152c73 | ||
|
|
8c98c7df29 | ||
|
|
cedc4f710e | ||
|
|
13d61bd866 | ||
|
|
c6c9839208 | ||
|
|
2ff439dc47 | ||
|
|
dad8cbecc1 | ||
|
|
8f8b200f24 | ||
|
|
8dec9d5fe9 | ||
|
|
e671c913ab | ||
|
|
9d46fae865 | ||
|
|
315caaba1c | ||
|
|
7af4ffe341 | ||
|
|
8bf730baae | ||
|
|
0b3826d2dd | ||
|
|
d055ba1c3b | ||
|
|
649e7e103d | ||
|
|
bcdfb212fc | ||
|
|
947bf10c2f | ||
|
|
2e48b583c0 | ||
|
|
55dc5dc19d | ||
|
|
04c80915e5 | ||
|
|
be36b4aac1 | ||
|
|
2ce16bcdb7 | ||
|
|
1683f191a9 | ||
|
|
70d93a0bfc | ||
|
|
6514712054 | ||
|
|
e0a1b478a1 | ||
|
|
be5d58c849 | ||
|
|
e4f9c02d11 | ||
|
|
b8d720d06f | ||
|
|
5c1713f274 | ||
|
|
913615f1c2 | ||
|
|
9e8b0d2807 | ||
|
|
0b5749d491 | ||
|
|
23a9fa40e7 | ||
|
|
38b0d427f8 | ||
|
|
e02977edc0 | ||
|
|
24d7232559 | ||
|
|
e4ea8d2abd | ||
|
|
ebd1a6406b | ||
|
|
d1ee9ebbd9 | ||
|
|
5079ee67c3 | ||
|
|
9592fab414 | ||
|
|
f36858d074 | ||
|
|
1b8bb7c445 | ||
|
|
f499ff81f2 | ||
|
|
e80c7b6b45 | ||
|
|
f3babcb46e | ||
|
|
95e82ca359 | ||
|
|
8888739867 | ||
|
|
db6e9b6962 | ||
|
|
a0832d3fb6 | ||
|
|
1c77887629 | ||
|
|
dcd0ca8daa | ||
|
|
304981fcf2 | ||
|
|
f1bb533321 | ||
|
|
2c49df4be3 | ||
|
|
90502f7553 | ||
|
|
18f5c7f691 | ||
|
|
649606f32e | ||
|
|
0f54cc147e | ||
|
|
7781f41ebf | ||
|
|
2d2cb22806 | ||
|
|
ac10c988b9 | ||
|
|
83de1686c0 | ||
|
|
145347f7ae | ||
|
|
b8b6dbe791 | ||
|
|
d21201e996 | ||
|
|
dc35fc450b | ||
|
|
c4140dd38b | ||
|
|
ba2ef23414 | ||
|
|
3781d1e06b | ||
|
|
082a78bd92 | ||
|
|
7bfd0823db | ||
|
|
013ffe1626 | ||
|
|
b2006f2466 | ||
|
|
7d8931696d | ||
|
|
e88812458e | ||
|
|
ada42f6e94 | ||
|
|
34c3b50b48 | ||
|
|
63c36d0dbf | ||
|
|
bd80bb6bb3 | ||
|
|
8f98866d71 | ||
|
|
26bf05dd7e | ||
|
|
b815718c26 | ||
|
|
d7994ca67d | ||
|
|
b95a1fb604 | ||
|
|
b04bb2ef8d | ||
|
|
066aeec1e6 | ||
|
|
d6e46d73b5 | ||
|
|
7b767df0b5 | ||
|
|
ed36447bdf | ||
|
|
0f90af3c7d | ||
|
|
f50a8e5252 | ||
|
|
1d8ca28152 | ||
|
|
6c4129d02a | ||
|
|
9b4574ad06 | ||
|
|
4543b32bef | ||
|
|
ff69f6ed7f | ||
|
|
92a2b83bc8 | ||
|
|
30b65028fe | ||
|
|
4b72b291ef | ||
|
|
59ebe30b72 | ||
|
|
814f6213fa | ||
|
|
dce3ee440b | ||
|
|
b87d14cd61 | ||
|
|
5c10c78595 | ||
|
|
a793cf4ac2 | ||
|
|
010732108c | ||
|
|
296d103f68 | ||
|
|
1f590c45be | ||
|
|
48b816fb36 | ||
|
|
d11b5b3e02 | ||
|
|
8f8787b2e0 | ||
|
|
7581802498 | ||
|
|
371523d756 | ||
|
|
1456be9feb | ||
|
|
62f57b134a | ||
|
|
84127d7a80 | ||
|
|
8fc3f1ccbd | ||
|
|
c946f10d0c | ||
|
|
e03ef0b739 | ||
|
|
55b92ab263 | ||
|
|
fbc625478b | ||
|
|
4da8aab44f | ||
|
|
d9fd967c48 | ||
|
|
ab86fc9a5e | ||
|
|
8fb095e2f4 | ||
|
|
2fe84b7510 | ||
|
|
46ef13dd0f | ||
|
|
49b56d9b52 | ||
|
|
cff654ae69 | ||
|
|
7abb4072b5 | ||
|
|
d91fd0027a | ||
|
|
8f17f7297d | ||
|
|
aa8c31e79b | ||
|
|
cfc768caa9 | ||
|
|
c48bd9b840 | ||
|
|
c09919055a | ||
|
|
d35f1ea802 | ||
|
|
cfbf3cd4b3 | ||
|
|
a46103fc8c | ||
|
|
d032956124 | ||
|
|
ff93b38d23 | ||
|
|
5b02ee5169 | ||
|
|
aa770689f5 | ||
|
|
de67fff731 | ||
|
|
7799783c9a | ||
|
|
c854565e30 | ||
|
|
52e9d37b93 | ||
|
|
e94cb34a25 | ||
|
|
f541e7105e | ||
|
|
4060e29c63 | ||
|
|
d913285523 | ||
|
|
d98d1193fc | ||
|
|
e23b406364 | ||
|
|
0b27fc39e6 | ||
|
|
704ca4eae2 | ||
|
|
1fc3cfee68 | ||
|
|
8fb446ad47 | ||
|
|
66ff661ff5 | ||
|
|
57e69080c9 | ||
|
|
d78f7a9303 | ||
|
|
47cb34d26b | ||
|
|
8354797406 | ||
|
|
87ae1c6a9b | ||
|
|
5fb7d43aff | ||
|
|
115c391191 | ||
|
|
c73fa4b0f6 | ||
|
|
f5894ac3c2 | ||
|
|
bcbeda5102 | ||
|
|
8891c305e3 | ||
|
|
c62f98db95 | ||
|
|
96bca43089 | ||
|
|
9ffd42d477 | ||
|
|
c57f051863 | ||
|
|
ab04874c11 | ||
|
|
481a47b638 | ||
|
|
df2ef04558 | ||
|
|
c3ad095553 | ||
|
|
3f2dbfbbd2 | ||
|
|
8eca70c338 | ||
|
|
ba7302a197 | ||
|
|
d15b0a0285 | ||
|
|
3796a5ef97 | ||
|
|
5a48376a77 | ||
|
|
61669a73d9 | ||
|
|
5a2385c66b | ||
|
|
d7721065dc | ||
|
|
025f2507f4 | ||
|
|
563fb3ff5c | ||
|
|
9646ec5edd | ||
|
|
cc990a1181 | ||
|
|
c4ddb7d351 | ||
|
|
ab0047a9b7 | ||
|
|
39ec10cbba | ||
|
|
65b6513207 | ||
|
|
beb4494534 | ||
|
|
983ff901f2 | ||
|
|
5d66473a4f | ||
|
|
ff1e04b957 | ||
|
|
53c4c6cbb8 | ||
|
|
47736603af | ||
|
|
b6e5a5e655 | ||
|
|
84018f5b61 | ||
|
|
592d3afe6d | ||
|
|
2bd2ec7a2e | ||
|
|
f25d2b3a86 | ||
|
|
886cea56f3 | ||
|
|
ed21efc003 | ||
|
|
c379cca2e5 | ||
|
|
efa04b4cd8 | ||
|
|
35a214603f | ||
|
|
3acc96cab1 | ||
|
|
14247fa75a | ||
|
|
6efec9d280 | ||
|
|
063253d5e7 | ||
|
|
f773604dec | ||
|
|
25d43354b3 | ||
|
|
b59ec5e78b | ||
|
|
f7ad935dfb | ||
|
|
1a210ae684 | ||
|
|
92c666692d | ||
|
|
761f0a78f4 | ||
|
|
0027a0af40 | ||
|
|
4f45cf1386 | ||
|
|
9dfa685fb1 | ||
|
|
40d2ef4f0a | ||
|
|
8e5a877997 | ||
|
|
d1b3f77feb | ||
|
|
a5b7234d6f | ||
|
|
398991f3c1 | ||
|
|
d01b93ae5f | ||
|
|
b31d9761fa | ||
|
|
1ba403db7b | ||
|
|
96cd135f82 | ||
|
|
c85cd4ac24 | ||
|
|
177546bab6 | ||
|
|
29e2c982d4 | ||
|
|
bc301f269a | ||
|
|
d09253e532 | ||
|
|
034079b441 | ||
|
|
22f0e2615f | ||
|
|
45bab578c4 | ||
|
|
e8de6f0ace | ||
|
|
13c2ce3f31 | ||
|
|
3bf9a3833a | ||
|
|
c035bf2d37 | ||
|
|
2b9ab05888 | ||
|
|
a8153dd8db | ||
|
|
ebe70a52d1 | ||
|
|
2282e72d03 | ||
|
|
5a590512bd | ||
|
|
6131181ea4 | ||
|
|
78946c11ea | ||
|
|
f59abe23c3 | ||
|
|
74412766fa | ||
|
|
39b0401c55 | ||
|
|
5f0e8d3d8e | ||
|
|
01ca13cccb | ||
|
|
6a9badd31b | ||
|
|
7db5d6a307 | ||
|
|
bb2049411b | ||
|
|
653ae777d5 | ||
|
|
ec803d63c8 | ||
|
|
412d80efe3 | ||
|
|
b1d662a5b1 | ||
|
|
12d9d59d85 | ||
|
|
b13e719ab3 | ||
|
|
451aea87aa | ||
|
|
d55cac80bf | ||
|
|
a1ecdc9bfa | ||
|
|
0e8c1cb0fd | ||
|
|
1c724280f5 | ||
|
|
9ff8246a9d | ||
|
|
2c45956030 | ||
|
|
1c267a55d5 | ||
|
|
f60bdc3dd4 | ||
|
|
030dfc2370 | ||
|
|
3295ea84a4 | ||
|
|
ef2041b919 | ||
|
|
4634085402 | ||
|
|
411140c3ea | ||
|
|
638cd1dd48 | ||
|
|
e3e6b23b7c | ||
|
|
ac5a3e7a65 | ||
|
|
106c316442 | ||
|
|
db229cf1bf | ||
|
|
94f66b812a | ||
|
|
a314106b7e | ||
|
|
8d72bc0ea4 | ||
|
|
1533c9315f | ||
|
|
70405045d7 | ||
|
|
3d623506a8 | ||
|
|
11df74c292 | ||
|
|
a935d69408 | ||
|
|
cffe0196e2 | ||
|
|
ac2a9deb75 | ||
|
|
282e0adfe2 | ||
|
|
ce60bcedb0 | ||
|
|
c9fd409650 | ||
|
|
8a908aa33f | ||
|
|
f9a5242e75 | ||
|
|
7dabcc00ed | ||
|
|
18f4e9db31 | ||
|
|
593ab6b014 | ||
|
|
656c33e942 | ||
|
|
4330338285 | ||
|
|
44c41d52b2 | ||
|
|
449a3f479f | ||
|
|
159a7c4947 | ||
|
|
30f442d774 | ||
|
|
e8685de7f7 | ||
|
|
4c08b591f1 | ||
|
|
16528888df | ||
|
|
738b5f5707 | ||
|
|
17343210c0 | ||
|
|
43aa2f5cd9 | ||
|
|
423cd20922 | ||
|
|
69d5ef36e2 | ||
|
|
0dd17cc175 | ||
|
|
16e56c4edb | ||
|
|
f46b876fd6 | ||
|
|
1181ab67ba | ||
|
|
014c26be25 | ||
|
|
99eb9429fd | ||
|
|
d3b10d0d4d | ||
|
|
d9597d5ad5 | ||
|
|
55272e5ea2 | ||
|
|
d17fc86fa4 | ||
|
|
0b391584d4 | ||
|
|
e3e02aa30b | ||
|
|
403f53a397 | ||
|
|
bfd79e1af2 | ||
|
|
5745a984aa | ||
|
|
d2f1f67a22 | ||
|
|
d98cb50d7a | ||
|
|
cc4864976a | ||
|
|
92fa8b7421 | ||
|
|
aad2e8012b | ||
|
|
b3eae80ece | ||
|
|
b58d5b6066 | ||
|
|
f1b6e6570c | ||
|
|
8e758507b1 | ||
|
|
2601d8b702 | ||
|
|
fa0545e4b3 | ||
|
|
690208fd4e | ||
|
|
3272575f70 | ||
|
|
fad3142a47 | ||
|
|
1f74dcff14 | ||
|
|
62c7183922 | ||
|
|
ef73b0a07f | ||
|
|
ec7d42d1fd | ||
|
|
256a17f2c9 | ||
|
|
165ffed9e6 | ||
|
|
b89d6d78ef | ||
|
|
6890561723 | ||
|
|
849ce04def | ||
|
|
a29baf19d0 | ||
|
|
10d6a1fa54 | ||
|
|
6ea181c286 | ||
|
|
2d890603c6 | ||
|
|
d1ca30a28f | ||
|
|
35fccf8af8 | ||
|
|
f5baa56e05 | ||
|
|
d2c1be5c2d | ||
|
|
fd6525a9de | ||
|
|
ba03a134da | ||
|
|
9184c64ecb | ||
|
|
653a9664e4 | ||
|
|
51d0cedb29 | ||
|
|
fa6d1bb23c | ||
|
|
0f3b154699 | ||
|
|
d6e2b096ca | ||
|
|
2104a1250e | ||
|
|
ca99f60964 | ||
|
|
147c08bd71 | ||
|
|
ad440f70fa | ||
|
|
bb22155482 | ||
|
|
5c1999b3d0 | ||
|
|
87f0fcfd52 | ||
|
|
f6d53bc337 | ||
|
|
720fad80c3 | ||
|
|
196055e50e | ||
|
|
73125574e6 | ||
|
|
27a35a0388 | ||
|
|
8c6085b933 | ||
|
|
bef14f551e | ||
|
|
e56c2eb6ca | ||
|
|
165365473f | ||
|
|
3bdd9a850f | ||
|
|
b84ea020f2 | ||
|
|
90efc5740f | ||
|
|
c78e6588ad | ||
|
|
a21a3827fd | ||
|
|
2effbd0baf | ||
|
|
7ed03c8b90 | ||
|
|
59ce90e924 | ||
|
|
da38e6a23d | ||
|
|
698e5ec6ea | ||
|
|
7f25e3ba97 | ||
|
|
1a3500cad3 | ||
|
|
31c30a7602 | ||
|
|
014f3b9873 | ||
|
|
49cbcf01c6 | ||
|
|
f8cc129f04 | ||
|
|
236c1208e6 | ||
|
|
4c70e75bfc | ||
|
|
e8c5f3a882 | ||
|
|
302df56ee1 | ||
|
|
ccfc4d68f3 | ||
|
|
071ea1dc97 | ||
|
|
670033c4da | ||
|
|
fa7e4cc817 | ||
|
|
67c8d80190 | ||
|
|
792ce53992 | ||
|
|
b0a25f59d9 | ||
|
|
d76234c112 | ||
|
|
6fdfd3b9e7 | ||
|
|
38350a1ae4 | ||
|
|
ce2bba751c | ||
|
|
f149736a20 | ||
|
|
40330be123 | ||
|
|
93af4fc6b0 | ||
|
|
b574d4e388 | ||
|
|
eb4b429e19 | ||
|
|
21929b1db2 | ||
|
|
a5197ee039 | ||
|
|
e974981725 | ||
|
|
9ae4dd3dfe | ||
|
|
d0e4dabe90 | ||
|
|
a3c569137e | ||
|
|
3edb360d79 | ||
|
|
f5285b48b1 | ||
|
|
c01b76e098 | ||
|
|
6adb47c447 | ||
|
|
b0b2d3a727 | ||
|
|
8410d7b08e | ||
|
|
e6408a0c37 | ||
|
|
e96c82b171 | ||
|
|
ee31813a0d | ||
|
|
ac62fd6204 | ||
|
|
25fbcc144c | ||
|
|
30cb7e62fd | ||
|
|
7c7ccc3a07 | ||
|
|
fb3f4fa0a8 | ||
|
|
2b62244806 | ||
|
|
f5dc197e8b | ||
|
|
e6060048bd | ||
|
|
f83ff068ae | ||
|
|
b21a6b76e0 | ||
|
|
70527022d9 | ||
|
|
8cddd595d4 | ||
|
|
96b79d5f06 | ||
|
|
1c7b07d614 | ||
|
|
0d59de5767 | ||
|
|
e3613c54e9 | ||
|
|
5956e6d9c1 | ||
|
|
ec895f271b | ||
|
|
751f30e316 | ||
|
|
cee8253cd3 | ||
|
|
ae4cb6e372 | ||
|
|
398f976f3e | ||
|
|
5f049beb04 | ||
|
|
a8d67a1c60 | ||
|
|
26aa9727a1 | ||
|
|
3cef696a65 | ||
|
|
397b1533f0 | ||
|
|
5680a34ec1 | ||
|
|
84a197299f | ||
|
|
4307882fa8 | ||
|
|
d2dfbff832 | ||
|
|
8cc58d0b89 | ||
|
|
971fc462ab | ||
|
|
8d2256d359 | ||
|
|
8f3b863edd | ||
|
|
4cc6c5ec35 | ||
|
|
cf53614721 | ||
|
|
efe84e58d7 | ||
|
|
cf59ad76fb | ||
|
|
2216cda2f1 | ||
|
|
595b15fcd9 | ||
|
|
a104c7f0f8 | ||
|
|
059392d257 | ||
|
|
5a1b3da394 | ||
|
|
92d7c2926c | ||
|
|
8f39697e3d | ||
|
|
ff328381af | ||
|
|
3bb3c06456 | ||
|
|
1cbcd41b17 | ||
|
|
5ebd9eb577 | ||
|
|
850d9ee095 | ||
|
|
5db1f91b01 | ||
|
|
ac6b9712ad | ||
|
|
df93f4ba99 | ||
|
|
7c20d46eeb | ||
|
|
fe432fcca8 | ||
|
|
5b1638ea59 | ||
|
|
87a1d4088b | ||
|
|
038c346500 | ||
|
|
0bcaa13056 | ||
|
|
c0e62372e6 | ||
|
|
84169cce10 | ||
|
|
c2c163ac4e | ||
|
|
ecb5d2ae1c | ||
|
|
3d619f1670 | ||
|
|
3265549911 | ||
|
|
d5c3a3e5e8 | ||
|
|
30dff09d7e | ||
|
|
85f7d19eb2 | ||
|
|
6adda5c29c | ||
|
|
4a03756b5b | ||
|
|
b1554ebf37 | ||
|
|
b6307b4fd6 | ||
|
|
6f22c7ad19 | ||
|
|
bc9add783c | ||
|
|
ee67221068 | ||
|
|
71e528139c | ||
|
|
c674fe1f04 | ||
|
|
d047e95bb5 | ||
|
|
791518d6c4 | ||
|
|
83afd55e0e | ||
|
|
7870a66790 | ||
|
|
c923e96f3e | ||
|
|
dd79834137 | ||
|
|
8995f0af55 | ||
|
|
e75a74565b | ||
|
|
1792849b98 | ||
|
|
c7fb1f6d17 | ||
|
|
a856263081 | ||
|
|
582d1320a3 | ||
|
|
3789da4305 | ||
|
|
a36f97adfb | ||
|
|
2cda53d3af | ||
|
|
74007ea465 | ||
|
|
c88a7dba6b | ||
|
|
66b7863d43 | ||
|
|
19b318a488 | ||
|
|
c606e3db43 | ||
|
|
f89ab74b29 | ||
|
|
4bbdec5044 | ||
|
|
56a727cf0d | ||
|
|
32f74e41ef | ||
|
|
e249bc5856 | ||
|
|
32b8a344a6 | ||
|
|
61c0c35e92 | ||
|
|
2eecaf4570 | ||
|
|
8f59247acb | ||
|
|
eb3ec26279 | ||
|
|
f07d37ce0d | ||
|
|
2e8602eb43 | ||
|
|
4277041b0e | ||
|
|
6801190180 | ||
|
|
067a9cf54d | ||
|
|
d31a8c203f | ||
|
|
99e8a393b6 | ||
|
|
42ba0a2642 | ||
|
|
cc0cd51658 | ||
|
|
9d3014e39c | ||
|
|
1ac3a9da4f | ||
|
|
7c80bbecd9 | ||
|
|
d55e6191c2 | ||
|
|
3875603285 | ||
|
|
a62261343c | ||
|
|
8b0a995f23 | ||
|
|
4734cb3428 | ||
|
|
34f814717b | ||
|
|
d4b56f99ff | ||
|
|
f51d51abf4 | ||
|
|
a13a0ee5a9 | ||
|
|
19f4ad0361 | ||
|
|
93dc96f150 | ||
|
|
64d9e9054c | ||
|
|
b1ed7227d7 | ||
|
|
48215c1eae | ||
|
|
7399a978f5 | ||
|
|
3737ad6524 | ||
|
|
b37695bc6f | ||
|
|
6e97d588e4 | ||
|
|
17319b15b0 | ||
|
|
0692afcd90 | ||
|
|
91ac3f7931 | ||
|
|
9d5990311f | ||
|
|
6f38cdec5a | ||
|
|
7a1f3a0cb1 | ||
|
|
99356f7880 | ||
|
|
d38d7b8ff6 | ||
|
|
834ac42d24 | ||
|
|
e80fac4900 | ||
|
|
a13c8cb71e | ||
|
|
3dc61962de | ||
|
|
5c3acf61b4 | ||
|
|
953d835ded | ||
|
|
1537ca4e71 | ||
|
|
2d94ace89f | ||
|
|
ea9c0b919f | ||
|
|
d178fa5bdb | ||
|
|
01f11d94b0 | ||
|
|
58f1a8e916 | ||
|
|
688fefc4dd | ||
|
|
ce96e34d25 | ||
|
|
a1e1d663c3 | ||
|
|
245b52d8e2 | ||
|
|
1de93be0f0 | ||
|
|
e723e87c74 | ||
|
|
c9535749f5 | ||
|
|
497a66ea38 | ||
|
|
62d9735a7e | ||
|
|
0f8fbf6a1e | ||
|
|
66c2d1cba1 | ||
|
|
69cde6092b | ||
|
|
3e9face818 | ||
|
|
4dfac02065 | ||
|
|
7551509f41 | ||
|
|
5f42866cea | ||
|
|
50d91670ec | ||
|
|
8c04421387 | ||
|
|
c39be3dbc9 | ||
|
|
8aa8c296e1 | ||
|
|
592c55c524 | ||
|
|
eafaf35790 | ||
|
|
585c66a4d0 | ||
|
|
1ecedd5566 | ||
|
|
3a0a5a7754 | ||
|
|
d329406eb8 | ||
|
|
e654999fdf | ||
|
|
efe98f7fad | ||
|
|
87bc957662 | ||
|
|
15e93d6304 | ||
|
|
5471735419 | ||
|
|
6b2955f135 | ||
|
|
1ab0a5182f | ||
|
|
dad65998cc | ||
|
|
abd30f3e41 | ||
|
|
7f42d9784e | ||
|
|
1056dac070 | ||
|
|
c05622484d | ||
|
|
59659a13f1 | ||
|
|
73c6cbb562 | ||
|
|
9f724221fa | ||
|
|
dfcd86ea09 | ||
|
|
555393d328 | ||
|
|
febacfcb79 | ||
|
|
1891bd494c | ||
|
|
ba5d53914e | ||
|
|
2ae38e20ab | ||
|
|
5f14b2e738 | ||
|
|
bc53951648 | ||
|
|
9a323e3387 | ||
|
|
72fe972cc0 | ||
|
|
88dfd90e3b | ||
|
|
1f9c1ce8e4 | ||
|
|
b4d75e3240 | ||
|
|
def0d7a519 | ||
|
|
a9cc4dabb7 | ||
|
|
e29e8ca0a3 | ||
|
|
5cda4135b1 | ||
|
|
221e153f4c | ||
|
|
3a24e4703d | ||
|
|
2b158c2b4e | ||
|
|
8b715ad9cd | ||
|
|
07cf527ddf | ||
|
|
63f1429a69 | ||
|
|
d881fc2fe0 | ||
|
|
d5090ee24b | ||
|
|
56c0a78c64 | ||
|
|
47037220e0 | ||
|
|
640fade438 | ||
|
|
98ede836d4 | ||
|
|
e75916fd92 | ||
|
|
e01ed8ad3c | ||
|
|
3beea79b38 | ||
|
|
1a29870958 | ||
|
|
7f3fae5a02 | ||
|
|
c2adf56b2f | ||
|
|
7a8f5a606c | ||
|
|
462c17a0c3 | ||
|
|
e59e3019e3 | ||
|
|
d65e2ab2d4 | ||
|
|
3f6120e122 | ||
|
|
e66e5e6f6e | ||
|
|
b0bc57466e | ||
|
|
154dc555c5 | ||
|
|
36559d0264 | ||
|
|
a722ce460c | ||
|
|
67b2f28064 | ||
|
|
8b988409e2 | ||
|
|
57c4658021 | ||
|
|
283bfde3d9 | ||
|
|
41935aa9aa | ||
|
|
9206d1f5f1 | ||
|
|
f5381ae3e3 | ||
|
|
95c4bf5854 | ||
|
|
2b4b23f726 | ||
|
|
64c17767ed | ||
|
|
32d75749a0 | ||
|
|
e776f9c7d8 | ||
|
|
3bdcf1077b | ||
|
|
da550a4a67 | ||
|
|
1655594514 | ||
|
|
c4f884f104 | ||
|
|
855f3d74fe | ||
|
|
7fc140af01 | ||
|
|
d401474981 | ||
|
|
0f6563e8e0 | ||
|
|
6cd0f83496 | ||
|
|
b428fc97e9 | ||
|
|
c14c51f551 | ||
|
|
8e18104f38 | ||
|
|
06fcc2bf46 | ||
|
|
1656b4c5b9 | ||
|
|
431f7ab37c | ||
|
|
f44109abae | ||
|
|
8cb134f56b | ||
|
|
032aa2d1d6 | ||
|
|
cbe20d9c96 | ||
|
|
e6b74b10eb | ||
|
|
8c4dbbfbec | ||
|
|
9bde15d4ac | ||
|
|
fd32dad7eb | ||
|
|
64df515c63 | ||
|
|
8908bd9889 | ||
|
|
5c3159cbca | ||
|
|
9afe72d508 | ||
|
|
c002d2c99f | ||
|
|
c768b6bd0c | ||
|
|
7903fe52b4 | ||
|
|
313b1b39a7 | ||
|
|
648f3abcbd | ||
|
|
2db98715cc | ||
|
|
5e3da57e21 | ||
|
|
dceef35aac | ||
|
|
2d23952181 | ||
|
|
518da7e81d | ||
|
|
8db1eb69dc | ||
|
|
d16ebba9e0 | ||
|
|
ee0420188c | ||
|
|
b9d14d31ae | ||
|
|
c505875fef | ||
|
|
6029f0ed36 | ||
|
|
734bed4821 | ||
|
|
26b3185933 | ||
|
|
5efa9ff0b2 | ||
|
|
ac6a013bf5 | ||
|
|
d9c4abe0df | ||
|
|
ae9e257e56 | ||
|
|
bb82a9bcf4 | ||
|
|
df61ea0a62 | ||
|
|
371926b202 | ||
|
|
fe77a7e01a | ||
|
|
e6b43e19c2 | ||
|
|
96b2145ba1 | ||
|
|
feb950be3c | ||
|
|
5b02bda277 | ||
|
|
ce4643d650 | ||
|
|
55c311cd39 | ||
|
|
8f8bfb9446 | ||
|
|
8f2a33dcaa | ||
|
|
4946daeea4 | ||
|
|
38ecc82e97 | ||
|
|
7ec8d02c1f | ||
|
|
a047ff2228 | ||
|
|
3dd181c912 | ||
|
|
3753ecd8e5 | ||
|
|
eaf05aa31a | ||
|
|
ad0f965f3a | ||
|
|
53e68c0567 | ||
|
|
9f609ac80f | ||
|
|
2b04d7a92d | ||
|
|
8f7305e347 | ||
|
|
9d3720557e | ||
|
|
aa79325d76 | ||
|
|
15b7b20500 | ||
|
|
6290630787 | ||
|
|
ad9e7b5eae | ||
|
|
fa31fbb343 | ||
|
|
ca7b6f139f | ||
|
|
a6e8cbc50d | ||
|
|
368640b59b | ||
|
|
22cb0b6afb | ||
|
|
08a7394c1b | ||
|
|
8a2fd5bf5e | ||
|
|
7add40ae93 | ||
|
|
d4da98bae5 | ||
|
|
92bbd83b33 | ||
|
|
b0c647e50c | ||
|
|
1ddd94b95c | ||
|
|
845c6be95f | ||
|
|
63d989cab4 | ||
|
|
92daf156f5 | ||
|
|
d0822ab1fe | ||
|
|
65cda38cc8 | ||
|
|
dcc1d545e9 | ||
|
|
e13967cb83 | ||
|
|
46d1bc274c | ||
|
|
81551104ce | ||
|
|
8b10fe4053 | ||
|
|
b5bd2df814 | ||
|
|
32ddf3246c | ||
|
|
8ccc996e63 | ||
|
|
bd7150d676 | ||
|
|
c35e70173b | ||
|
|
86f209a302 | ||
|
|
44943feb8b | ||
|
|
4331e9ae80 | ||
|
|
9ae97de780 | ||
|
|
d941b31c45 | ||
|
|
fed254f355 | ||
|
|
7f53877283 | ||
|
|
ca3a436fe5 | ||
|
|
d48ef90fb0 | ||
|
|
29bbe84f69 | ||
|
|
d079f0ca44 | ||
|
|
394f52a725 | ||
|
|
5828508218 | ||
|
|
2f244bca85 | ||
|
|
064d638588 | ||
|
|
7856495d59 | ||
|
|
c3bded6947 | ||
|
|
3a584e318a | ||
|
|
48d744b6bd | ||
|
|
6eba8130ba | ||
|
|
5ac7eddd03 | ||
|
|
b5dfe6320d | ||
|
|
19ee55a303 | ||
|
|
b715a008c5 | ||
|
|
1d4b834204 | ||
|
|
aa271423f9 | ||
|
|
0354026292 | ||
|
|
93752fb6cb | ||
|
|
7da8689bf2 | ||
|
|
afd22768fc | ||
|
|
e9ecdb3f56 | ||
|
|
e14ef2c671 | ||
|
|
d45c4740ad | ||
|
|
62bae55fd1 | ||
|
|
dcee505f6b | ||
|
|
ddf800de10 | ||
|
|
325db535c0 | ||
|
|
af4678ff18 | ||
|
|
cae77ae291 | ||
|
|
cab5a97117 | ||
|
|
0417b6266a | ||
|
|
fc7103f56e | ||
|
|
ffe9ec1c76 | ||
|
|
3fc738b53a | ||
|
|
7e1f554c4e | ||
|
|
5cfa8889f4 | ||
|
|
0cbe7a16e3 | ||
|
|
0cf3c097fb | ||
|
|
15061af796 | ||
|
|
2cfcad6a50 | ||
|
|
13a8ac3e50 | ||
|
|
7c5993d75b | ||
|
|
10c0325f18 | ||
|
|
367cb41121 | ||
|
|
c37884bdb7 | ||
|
|
37a551ecd3 | ||
|
|
dafc514353 | ||
|
|
aa6cb7d650 | ||
|
|
67e6688e69 | ||
|
|
5d9b71b038 | ||
|
|
2077cd4864 | ||
|
|
65276f45f1 | ||
|
|
95eb17bdb7 | ||
|
|
a88d66b48b | ||
|
|
a200c5397a | ||
|
|
87fb6fc3d1 | ||
|
|
79fcd45d5f | ||
|
|
e0ddaa74d0 | ||
|
|
d584dc5632 | ||
|
|
86704efcec | ||
|
|
6bb0f18d53 | ||
|
|
77e4984468 | ||
|
|
4e18c67ec5 | ||
|
|
6fbed4ad5c | ||
|
|
0fb42c6129 | ||
|
|
41ab94fe13 | ||
|
|
3a46f4589b | ||
|
|
14441ec144 | ||
|
|
f589dd2f26 | ||
|
|
629ba763d7 | ||
|
|
e896e1b3dd | ||
|
|
b92a127200 | ||
|
|
e02b8e227d | ||
|
|
367a7309bc | ||
|
|
6ecd2ed186 | ||
|
|
0ada26ccc2 | ||
|
|
a39faeec32 | ||
|
|
4e35b58d59 | ||
|
|
d03be75184 | ||
|
|
59b0109918 | ||
|
|
154e5aab8e | ||
|
|
5c38b9109e | ||
|
|
70b4b33823 | ||
|
|
6419c6b1ba | ||
|
|
1f9d9c619e | ||
|
|
2aa9f4c079 | ||
|
|
70495d9ce9 | ||
|
|
b3b7f8b980 | ||
|
|
b7e6d8646f | ||
|
|
466522fb12 | ||
|
|
549d68d3e8 | ||
|
|
42a54648a1 | ||
|
|
dc9b338cb9 | ||
|
|
b7d0455377 | ||
|
|
df0b11a960 | ||
|
|
111956e2f3 | ||
|
|
52c12731cb | ||
|
|
cf54a4919b | ||
|
|
ac26818005 | ||
|
|
467cf919be | ||
|
|
f48040a4d7 | ||
|
|
90ddcb30bf | ||
|
|
b713083574 | ||
|
|
fc7e7074ce | ||
|
|
e88e9bdf11 | ||
|
|
bc4ea885dc | ||
|
|
723ace2724 | ||
|
|
aeb454f31d | ||
|
|
12c44dceb6 | ||
|
|
9d1b8fbd3e | ||
|
|
124e0412b2 | ||
|
|
3a46260937 | ||
|
|
7151d5eac2 | ||
|
|
5e28d39f09 | ||
|
|
c7774d3d6c | ||
|
|
a85b84fd56 | ||
|
|
443b3c8b82 | ||
|
|
d69383d78b | ||
|
|
c355a2b61e | ||
|
|
93415ee36c | ||
|
|
0648ecf2d2 | ||
|
|
17022d50d4 | ||
|
|
c4573e46a9 | ||
|
|
fa515604dc | ||
|
|
3b12d70e45 | ||
|
|
efb86f453c | ||
|
|
569c18c9f1 | ||
|
|
91223a8431 | ||
|
|
d95e49b535 | ||
|
|
4cb89b3fc2 | ||
|
|
5e56c66201 | ||
|
|
e6393c105b | ||
|
|
bb16313024 | ||
|
|
a5ce2a5a62 | ||
|
|
3885cbd045 | ||
|
|
00940d66b1 | ||
|
|
cafba71671 | ||
|
|
cb454734b0 | ||
|
|
4f29f998c5 | ||
|
|
c241d48df3 | ||
|
|
2afc268a04 | ||
|
|
94017c1e53 | ||
|
|
cea6b7067a | ||
|
|
89b44f5126 | ||
|
|
3015ffd950 | ||
|
|
8c465d22e0 | ||
|
|
f1951d0d5f | ||
|
|
a84be2ba60 | ||
|
|
4243feaf37 | ||
|
|
e004f96b65 | ||
|
|
a98cbc3a9d | ||
|
|
5877918fe8 | ||
|
|
b45b585edf | ||
|
|
983b2ebe0e | ||
|
|
2a0e92e4e2 | ||
|
|
b351e60d52 | ||
|
|
69e7a581fd | ||
|
|
0a20be85ab | ||
|
|
3f5a54f9f1 | ||
|
|
e2c7941542 | ||
|
|
8433119ac9 | ||
|
|
43589096c3 | ||
|
|
05d14166e4 | ||
|
|
0d0f7724b6 | ||
|
|
d28152566d | ||
|
|
fb805de552 | ||
|
|
5ade906a7b | ||
|
|
8f02cbc234 | ||
|
|
59a2415a0d | ||
|
|
c1b3686190 | ||
|
|
662eeafbb5 | ||
|
|
5ff146bc69 | ||
|
|
9380a243ba | ||
|
|
587291ab86 | ||
|
|
2cd62621df | ||
|
|
3630fc63d7 | ||
|
|
de42d9f310 | ||
|
|
f5ed9f1c33 | ||
|
|
01ec472314 | ||
|
|
9ddee84954 | ||
|
|
dc0715dc2a | ||
|
|
b6b9fad5da | ||
|
|
553922bef6 | ||
|
|
4b08c0b56b | ||
|
|
ba081c7837 | ||
|
|
f4a2741ba0 | ||
|
|
e6b926c87f | ||
|
|
4be1195e5d | ||
|
|
84ef245b56 | ||
|
|
7b39bae673 | ||
|
|
7c505fd02a | ||
|
|
11f7f9a231 | ||
|
|
4f1eedcf7c | ||
|
|
99f85b800c | ||
|
|
2e4f81f63d | ||
|
|
abbaca3c71 | ||
|
|
a9b6f976a2 | ||
|
|
64b2a8d4a5 | ||
|
|
2b550b104f | ||
|
|
564e76956a | ||
|
|
dd734c3c8a | ||
|
|
35e9091863 | ||
|
|
b9e437c6cd | ||
|
|
de5f7f9b05 | ||
|
|
44a9db1c2f | ||
|
|
d7dc4bf496 | ||
|
|
1a15a062ef | ||
|
|
5b02501038 | ||
|
|
c3a98b265f | ||
|
|
b92bcd1789 | ||
|
|
949e504ad5 | ||
|
|
293a8a8199 | ||
|
|
2806c386d3 | ||
|
|
75f3a30d38 | ||
|
|
7cfe74b384 | ||
|
|
38d537bb8a | ||
|
|
b6f927c454 | ||
|
|
57c616abfe | ||
|
|
ad6ca65d4b | ||
|
|
38490195e3 | ||
|
|
6a43b8b159 | ||
|
|
a760acc399 | ||
|
|
cea5668a9f | ||
|
|
d73ab36dc3 | ||
|
|
5c01e0e852 | ||
|
|
5a13850043 | ||
|
|
96fbc968ef | ||
|
|
cf26a5da3d | ||
|
|
3e21758aac | ||
|
|
942799637e | ||
|
|
07dd33f6de | ||
|
|
a924af79c1 | ||
|
|
2422ca0847 | ||
|
|
5b900e7b9c | ||
|
|
8539a297fa | ||
|
|
b6b873f699 | ||
|
|
94ccabd5ce | ||
|
|
ea18fa95ad | ||
|
|
b5f2c8b583 | ||
|
|
90a228619e | ||
|
|
a6b7ba41ee | ||
|
|
bef8c846f8 | ||
|
|
ce2bf5ac53 | ||
|
|
2fec555756 | ||
|
|
2faaad6d3d | ||
|
|
3a4b970c62 | ||
|
|
05491309c2 | ||
|
|
e122217101 | ||
|
|
81eb7de665 | ||
|
|
c9fe2f649a | ||
|
|
6dd13e4939 | ||
|
|
6cc00a5a0f | ||
|
|
5661be3ebd | ||
|
|
59a2c5ce9c | ||
|
|
73a7adea63 | ||
|
|
3896384339 | ||
|
|
3028e70a0f | ||
|
|
64416aef2b | ||
|
|
e0340dadf4 | ||
|
|
83e0cdfa1e | ||
|
|
22ed3c0ca5 | ||
|
|
f95bc17e39 | ||
|
|
64a4451868 | ||
|
|
ead47b2aa2 | ||
|
|
3e9e6c3e73 | ||
|
|
b8e957ff9a | ||
|
|
2aa12631f8 | ||
|
|
7feaa505c2 | ||
|
|
b0e6e31d92 | ||
|
|
068e803bc8 | ||
|
|
a4749d376a | ||
|
|
71992f5b17 | ||
|
|
3897fc5666 | ||
|
|
315b303b4f | ||
|
|
d665c37bc3 | ||
|
|
c5df7d4249 | ||
|
|
c5988e412d | ||
|
|
f2744493b9 | ||
|
|
a6793588c6 | ||
|
|
958198b65a | ||
|
|
5605256c75 | ||
|
|
35c7124617 | ||
|
|
f124cd9c7e | ||
|
|
f9a756d1ff | ||
|
|
0aeecc7a99 | ||
|
|
3646e6ea13 | ||
|
|
d2a60c7287 | ||
|
|
e794604cae | ||
|
|
60fa6071b9 | ||
|
|
cdad6f74cf | ||
|
|
549de55b57 | ||
|
|
686432aa8a | ||
|
|
c2e219b446 | ||
|
|
15cefc664a | ||
|
|
38fc9f00a2 | ||
|
|
2673b9dd03 | ||
|
|
ff6c86b932 | ||
|
|
c247e49c2a | ||
|
|
0c0dddab12 | ||
|
|
1c39b76b83 | ||
|
|
f72dd7fdb6 | ||
|
|
5a5b5292a1 | ||
|
|
d6fce7c099 | ||
|
|
93e2cc367b | ||
|
|
de3ee932b6 | ||
|
|
b051a3981d | ||
|
|
ed3b4088d9 | ||
|
|
2aae667e15 | ||
|
|
a6604172d9 | ||
|
|
e85427f1da | ||
|
|
572a121492 | ||
|
|
f8f7fe4f33 | ||
|
|
b835716e36 | ||
|
|
1476395829 | ||
|
|
8156279025 | ||
|
|
1822f36aba | ||
|
|
7f1a854769 | ||
|
|
0c8e3515fe | ||
|
|
5b5f48014b | ||
|
|
d9e1dce393 | ||
|
|
79fd5dc7b1 | ||
|
|
7183bea412 | ||
|
|
6e2ad28676 | ||
|
|
444b0b30c3 | ||
|
|
cdef2dee5a | ||
|
|
a1036577a2 | ||
|
|
badcccab76 | ||
|
|
9e8facaa6f | ||
|
|
7c0c75ca42 | ||
|
|
e32d619677 | ||
|
|
6f2801cea8 | ||
|
|
76d402fcfa | ||
|
|
a55b0aeb5f | ||
|
|
75e5b1c7cd | ||
|
|
7af2f4a98a | ||
|
|
f50bcb981a | ||
|
|
08bcebfc1c | ||
|
|
ae31ecf706 | ||
|
|
4dac1ae9f8 | ||
|
|
db253cdaf8 | ||
|
|
4b05929dd5 | ||
|
|
7c174b9c05 | ||
|
|
82596b9c3f | ||
|
|
6414fe8cf8 | ||
|
|
8e2b18ea1d | ||
|
|
c57b55ede6 | ||
|
|
72a0341a0e | ||
|
|
98b9503461 | ||
|
|
417310b5c5 | ||
|
|
08d0db87d1 | ||
|
|
18bf1400a7 | ||
|
|
3b3dca4a26 | ||
|
|
82ee5bf1fd | ||
|
|
398666a8b4 | ||
|
|
7d1e60a019 | ||
|
|
d7736f798b | ||
|
|
c20be3dbea | ||
|
|
e52c5d38d3 | ||
|
|
6662cf6245 | ||
|
|
0f78f1b333 | ||
|
|
2efe58209f | ||
|
|
d420fad489 | ||
|
|
49868d8f7c | ||
|
|
dee6dc1e6c | ||
|
|
35054c1f59 | ||
|
|
f507ef5e56 | ||
|
|
57f763b0b6 | ||
|
|
7a3c326442 | ||
|
|
1842c9ed3b | ||
|
|
855f092682 | ||
|
|
cafe267bf0 | ||
|
|
81710ff3b0 | ||
|
|
1c90107571 | ||
|
|
ff0c021162 | ||
|
|
ca916deda9 | ||
|
|
f0f044b766 | ||
|
|
69758b80a5 | ||
|
|
98ed178d7b | ||
|
|
419fc15d77 | ||
|
|
72eb76191f | ||
|
|
7164260f6e | ||
|
|
f5e474f250 | ||
|
|
9a84fc5b47 | ||
|
|
248a689de2 | ||
|
|
4da33b81fd | ||
|
|
657a1aaed5 | ||
|
|
415b7bf4d1 | ||
|
|
d8c1cb2629 | ||
|
|
ea75a56d33 | ||
|
|
8e45c41f20 | ||
|
|
dacd13ee30 | ||
|
|
f49727e0b6 | ||
|
|
1fc67984a2 | ||
|
|
2cc6d2ef11 | ||
|
|
40cc4f32d0 | ||
|
|
9537dd793d | ||
|
|
96a7e4f7ac | ||
|
|
16d1245b64 | ||
|
|
06eac367f2 | ||
|
|
78a6ab89f9 | ||
|
|
f77bacb8a6 | ||
|
|
94387e8698 | ||
|
|
aebdc0c5d6 | ||
|
|
113c39c11c | ||
|
|
078656fb8b | ||
|
|
c4b49ce6cd | ||
|
|
97e98d2725 | ||
|
|
02857d1b7f | ||
|
|
04027b9c32 | ||
|
|
969d71b264 | ||
|
|
174789e2e1 | ||
|
|
eb535acb95 | ||
|
|
5540c8b06f | ||
|
|
8c17d825d9 | ||
|
|
0af6348913 | ||
|
|
0ac6c01d65 | ||
|
|
4c1dfbaddd | ||
|
|
258acfdf5a | ||
|
|
d875dab29b | ||
|
|
1f9b2cd48c | ||
|
|
6ee4a6a5b4 | ||
|
|
4989396abc | ||
|
|
398b7a5a25 | ||
|
|
3e267bc77a | ||
|
|
d84cc370c9 | ||
|
|
7f12288b2c | ||
|
|
20e89f21ff | ||
|
|
bd2cf19ec1 | ||
|
|
de47efdda5 | ||
|
|
95231faa87 | ||
|
|
567b846de1 | ||
|
|
83ce8a2197 | ||
|
|
f170cef506 | ||
|
|
c2d8ed271b | ||
|
|
e38224d758 | ||
|
|
83901e5fbb | ||
|
|
db05cc48e8 | ||
|
|
4632224e9b | ||
|
|
5684c450f4 | ||
|
|
4bcf8215b6 | ||
|
|
36a3b6f479 | ||
|
|
b31215c257 | ||
|
|
1f558590a8 | ||
|
|
ad5e2a3d0e | ||
|
|
b26255e60a | ||
|
|
852689b3df | ||
|
|
197bc54ac6 | ||
|
|
013a58e634 | ||
|
|
4dbe535e1e | ||
|
|
7ac378dcd3 | ||
|
|
965b098d66 | ||
|
|
6379c3210b | ||
|
|
7653d5fec9 | ||
|
|
7e1f7bd7fd | ||
|
|
5581e25a21 | ||
|
|
52e08a2784 | ||
|
|
f6047b8733 | ||
|
|
bea8e647d9 | ||
|
|
1cf8634152 | ||
|
|
141b63587b | ||
|
|
2b91903129 | ||
|
|
32de0ae4a4 | ||
|
|
985a0b9bce | ||
|
|
9860e2bc75 | ||
|
|
db8472a6e5 | ||
|
|
8a22da0acb | ||
|
|
cf1b53831f | ||
|
|
92f64188d5 | ||
|
|
6a0061dde3 | ||
|
|
84fbdba9f5 | ||
|
|
39cac396f5 | ||
|
|
75ed3ce60c | ||
|
|
8373204c94 | ||
|
|
6787af413e | ||
|
|
0199b4e212 | ||
|
|
121be772df | ||
|
|
f3b3e3eded | ||
|
|
02c08c942d | ||
|
|
b2370f5c5f | ||
|
|
6556e1b4a2 | ||
|
|
28acd466b3 | ||
|
|
699921d464 | ||
|
|
5c84fbba9a | ||
|
|
0b02422e7d | ||
|
|
677bff55c2 | ||
|
|
3d03bea582 | ||
|
|
278a77247d | ||
|
|
b83a8dcb5d | ||
|
|
9bce103dad | ||
|
|
dfcc4e1b3a | ||
|
|
66892aea60 | ||
|
|
5c708b43c2 | ||
|
|
e2026aedbc | ||
|
|
3184f8d275 | ||
|
|
8ec78688b8 | ||
|
|
1911fc2e65 | ||
|
|
e0446a73fa | ||
|
|
16b1bfa4d0 | ||
|
|
f015995ac4 | ||
|
|
0016836022 | ||
|
|
c543b7585a | ||
|
|
b90f1fc237 | ||
|
|
f892338098 | ||
|
|
defead108a | ||
|
|
1f8f9aaf81 | ||
|
|
3b32a3164b | ||
|
|
e5cc2ccaab | ||
|
|
2f9b753c5b | ||
|
|
cbcca9cf5b | ||
|
|
b1ac1859be | ||
|
|
cecb65cd40 | ||
|
|
74b076e31f | ||
|
|
e3057b5e46 | ||
|
|
e1e7387c73 | ||
|
|
73705bec23 | ||
|
|
cb9e045c7f | ||
|
|
92a8b5aa4d | ||
|
|
9b7f92188d | ||
|
|
77301e2930 | ||
|
|
babfc9ade3 | ||
|
|
883bbf102a | ||
|
|
e21f83267a | ||
|
|
27f0782465 | ||
|
|
d45b0dee10 | ||
|
|
2c2a29cd91 | ||
|
|
607a297c4a | ||
|
|
e177c5c94c | ||
|
|
7fb3456e83 | ||
|
|
d37bb2c7f9 | ||
|
|
20519e3b81 | ||
|
|
733613ad28 | ||
|
|
604070763d | ||
|
|
93f88800b8 | ||
|
|
9607888fc5 | ||
|
|
1e6936a8c3 | ||
|
|
56c2964e96 | ||
|
|
d5f223fc88 | ||
|
|
cdf2f6b5b4 | ||
|
|
fa3ce8de64 | ||
|
|
59d218d623 | ||
|
|
49fa1b6762 | ||
|
|
a2fe4a0b80 | ||
|
|
86e7a19a98 | ||
|
|
8c86c3dc1b | ||
|
|
2bef7631ae | ||
|
|
550d76a447 | ||
|
|
679b26cde4 | ||
|
|
79c625d737 | ||
|
|
a1d277e771 | ||
|
|
bde0f2f0ba | ||
|
|
53f830bb38 | ||
|
|
a5e3207715 | ||
|
|
b357a085c8 | ||
|
|
9722d808f9 | ||
|
|
0fdc1d0a1f | ||
|
|
f963d28ba8 | ||
|
|
09d1af9c46 | ||
|
|
5d8e894802 | ||
|
|
0ecfbfad53 | ||
|
|
ed35a143ec | ||
|
|
5089729b18 | ||
|
|
b41d2d64cb | ||
|
|
25e882eb78 | ||
|
|
4ef8f3da2b | ||
|
|
b00ce8789f | ||
|
|
b4f81a0c2a | ||
|
|
aa714f7d80 | ||
|
|
ca203435d1 | ||
|
|
ee8893a884 | ||
|
|
bf89238bdf | ||
|
|
360f7cf9c3 | ||
|
|
482ad0e5ee | ||
|
|
cd6ac4f8c2 | ||
|
|
79ac2be617 | ||
|
|
9b4b7cf5d4 | ||
|
|
9b970ae1a4 | ||
|
|
fec7912870 | ||
|
|
8bb855e657 | ||
|
|
9488864f47 | ||
|
|
beefc6a86e | ||
|
|
cc99abcd14 | ||
|
|
f8bcf52741 | ||
|
|
1a10366ab7 | ||
|
|
925b6694ac | ||
|
|
1ad16ade86 | ||
|
|
45e3f02832 | ||
|
|
ba1a681aab | ||
|
|
23bba969dd | ||
|
|
9c743acd2d | ||
|
|
62da7c7be4 | ||
|
|
07310c7714 | ||
|
|
ee93f7e018 | ||
|
|
21fae1f457 | ||
|
|
653a84d3a9 | ||
|
|
8132bbac2e | ||
|
|
197286c21e | ||
|
|
bf48729354 | ||
|
|
a504a75166 | ||
|
|
44ac22c0de | ||
|
|
df1c6b9b0b | ||
|
|
7ce45d2b11 | ||
|
|
bde0e0b86a | ||
|
|
c1232a7001 | ||
|
|
12c4dbf0e5 | ||
|
|
31a01ab227 | ||
|
|
5dc60b9f35 | ||
|
|
588f134de8 | ||
|
|
2ae867a7e0 | ||
|
|
c77b029ee2 | ||
|
|
d0648d1754 | ||
|
|
1e3486af94 | ||
|
|
8f2b2aba12 | ||
|
|
0b1232b65d | ||
|
|
969abe015c | ||
|
|
f39144cc51 | ||
|
|
725df15012 | ||
|
|
9e296cdb46 | ||
|
|
b07627611f | ||
|
|
6cad4bc986 | ||
|
|
504c08a0fc | ||
|
|
592f1cafdb | ||
|
|
71d8c2080c | ||
|
|
6095933847 | ||
|
|
92febf0b00 | ||
|
|
1c711aef3c | ||
|
|
0bec780a1b | ||
|
|
ed01a46a3f | ||
|
|
4f8fa9f9eb | ||
|
|
2f99ccdd4a | ||
|
|
2dd1013075 | ||
|
|
6552aeaa3b | ||
|
|
b92b93e233 | ||
|
|
10036b148c | ||
|
|
cccec8382f | ||
|
|
5e30721e01 | ||
|
|
d03690cffd | ||
|
|
dad732b7e6 | ||
|
|
d74b5c8764 | ||
|
|
0f19010e52 | ||
|
|
ac6ee28c5f | ||
|
|
c509c02546 | ||
|
|
1258c44bad | ||
|
|
fe65e7a0c4 | ||
|
|
76727d09bf | ||
|
|
2a49b3899a | ||
|
|
49b85d150c | ||
|
|
b54241a5b2 | ||
|
|
78a2086535 | ||
|
|
24cc5dbaa0 | ||
|
|
0093838a75 | ||
|
|
dde658a514 | ||
|
|
13996740e0 | ||
|
|
e4b017b304 | ||
|
|
a2a683d31e | ||
|
|
5040f09f0c | ||
|
|
19911d9f1f | ||
|
|
04b0f8b2a4 | ||
|
|
e453dceacd | ||
|
|
42a938b50b | ||
|
|
4cf3cff74d | ||
|
|
3ffd007cc0 | ||
|
|
28b098cfb7 | ||
|
|
fd59088528 | ||
|
|
05bd32f750 | ||
|
|
e80147d24e | ||
|
|
72e1a19ea5 | ||
|
|
b14d6c9216 | ||
|
|
c894d72b52 | ||
|
|
220dbd7e30 | ||
|
|
84d6fc2787 | ||
|
|
f6d0738c79 | ||
|
|
52615c6f52 | ||
|
|
34342599b9 | ||
|
|
42edb20b07 | ||
|
|
a14784cfd4 | ||
|
|
32440567ad | ||
|
|
25f1dc325d | ||
|
|
38feeee464 | ||
|
|
b2701ad911 | ||
|
|
d41962f9d1 | ||
|
|
ec5d01545a | ||
|
|
03ddadc1ed | ||
|
|
3e55b61ac0 | ||
|
|
5a7f022e40 | ||
|
|
f651e10684 | ||
|
|
b753f920e1 | ||
|
|
415a0cdf28 | ||
|
|
9708961654 | ||
|
|
47bcb117b4 | ||
|
|
3eb38e558e | ||
|
|
a321eb8737 | ||
|
|
62c65659cc | ||
|
|
249addebff | ||
|
|
860087d291 | ||
|
|
c63e8d32c9 | ||
|
|
91e4603917 | ||
|
|
276278db41 | ||
|
|
b58d4e306a | ||
|
|
21a57a0c58 | ||
|
|
06b1e43492 | ||
|
|
2c1ffde3ed | ||
|
|
918ebc62a2 | ||
|
|
465de438ce | ||
|
|
6ee848b279 | ||
|
|
db5f1622bd | ||
|
|
5e2f681761 | ||
|
|
ad506d78ba | ||
|
|
48b89609e2 | ||
|
|
0fd0a8b7cc | ||
|
|
2e922019d7 | ||
|
|
303d1fef6b | ||
|
|
619ed234a9 | ||
|
|
fd8fc679be | ||
|
|
5a3c852b32 | ||
|
|
4c7de77bfb | ||
|
|
b08c1eeaa9 | ||
|
|
7e91121a33 | ||
|
|
cb78e10a76 | ||
|
|
9d031c1600 | ||
|
|
7efe6f1d53 | ||
|
|
bf33c82b19 | ||
|
|
2330454838 | ||
|
|
0d0aa49eb9 | ||
|
|
c279f405cf | ||
|
|
725eee726d | ||
|
|
4c2a09369d | ||
|
|
e6e1aab098 | ||
|
|
511f71c369 | ||
|
|
3dfccea522 | ||
|
|
ced0faf916 | ||
|
|
d284ecdab4 | ||
|
|
be77bf94aa | ||
|
|
2c87c00906 | ||
|
|
0ff2e212d5 | ||
|
|
92e4b5cc16 | ||
|
|
4e3228628a | ||
|
|
dde03eca7c | ||
|
|
107595fcb2 | ||
|
|
32fb634a4d | ||
|
|
51fbcc736e | ||
|
|
360a22c537 | ||
|
|
63cb5ab883 | ||
|
|
151a937c10 | ||
|
|
4c88c9b029 | ||
|
|
24664cc859 | ||
|
|
a187456ac3 | ||
|
|
9e4752b114 | ||
|
|
de64b33bb8 | ||
|
|
e66b64650d | ||
|
|
5139bc326a | ||
|
|
826858c170 | ||
|
|
f2400ee089 | ||
|
|
6e3587dd43 | ||
|
|
7a61db9a70 | ||
|
|
da798e7a5a | ||
|
|
f385e46927 | ||
|
|
c31262b97e | ||
|
|
2e9acc1fa8 | ||
|
|
0f9da7f519 | ||
|
|
971e1cdbec | ||
|
|
9fad2d68af | ||
|
|
51180adeb4 | ||
|
|
8ded683796 | ||
|
|
31c4ab8ac0 | ||
|
|
4f9d31e832 | ||
|
|
22e13e8c40 | ||
|
|
bec52b81fd | ||
|
|
7fc168532c | ||
|
|
69b55bcbd3 | ||
|
|
c6e839271a | ||
|
|
f3a1e09042 | ||
|
|
b157ec1b28 | ||
|
|
695be89656 | ||
|
|
3f3deb8e2a | ||
|
|
06b9d68eb7 | ||
|
|
bcc9379ebc | ||
|
|
9855e2edee | ||
|
|
e60e574902 | ||
|
|
c22ab4afdf | ||
|
|
b123d95b71 | ||
|
|
1760af50c8 | ||
|
|
73e33d7ba9 | ||
|
|
201c26f7c8 | ||
|
|
1fd31d83bf | ||
|
|
7d5c827dec | ||
|
|
ce89ff3c85 | ||
|
|
e60797cd0f | ||
|
|
49c5c5bbde | ||
|
|
78f243651e | ||
|
|
776a4d657d | ||
|
|
8f0b962507 | ||
|
|
8dc8431c0e | ||
|
|
5aa15ef731 | ||
|
|
1519843f6f | ||
|
|
37a4eefc46 | ||
|
|
1efcb2f80b | ||
|
|
0acb4f5aed | ||
|
|
4f38a953ac | ||
|
|
f05767afe8 | ||
|
|
ddbf23df68 | ||
|
|
6c4ab3b7f4 | ||
|
|
4d902c01a6 | ||
|
|
d1a5ba2b8e | ||
|
|
982cac3472 | ||
|
|
431f22283d | ||
|
|
7e61b1ecad | ||
|
|
a2d685815f | ||
|
|
014c2c5249 | ||
|
|
add63d2dde | ||
|
|
81bed3d3d5 | ||
|
|
f22a30ca87 | ||
|
|
946e74a918 | ||
|
|
3cd3cf9830 | ||
|
|
bc634c5f8f | ||
|
|
7357e40d3f | ||
|
|
92bde25a49 | ||
|
|
e714cb9e8b | ||
|
|
fed81c8e22 | ||
|
|
3a65d5ce23 | ||
|
|
6d482cd934 | ||
|
|
02511b7785 | ||
|
|
b3fdc4bb96 | ||
|
|
c90dd0e818 | ||
|
|
0e2d93c630 | ||
|
|
de328c9dfd | ||
|
|
f4a2f67db3 | ||
|
|
601d6f37af | ||
|
|
a004ef65af | ||
|
|
8997c27819 | ||
|
|
2aeceb7ea8 | ||
|
|
627e99859d | ||
|
|
6ebca7fa7c | ||
|
|
3d55ad783e | ||
|
|
05f66f9bea | ||
|
|
434ba82705 | ||
|
|
cbe6d19c79 | ||
|
|
b47e7f068c | ||
|
|
20a59a2c58 | ||
|
|
57845a2739 | ||
|
|
9a8ab29330 | ||
|
|
406cc71f96 | ||
|
|
132d0631d2 | ||
|
|
3095ade94c | ||
|
|
221df3d26d | ||
|
|
40db3a5d7d | ||
|
|
ee1a1fd614 | ||
|
|
8e8be502fd | ||
|
|
ae4413d0aa | ||
|
|
51b791f9c0 | ||
|
|
767c3c942b | ||
|
|
3fcace6660 | ||
|
|
4c600f5748 | ||
|
|
d84342733d | ||
|
|
d6f0f9ec0e | ||
|
|
fbc922fe97 | ||
|
|
4be84e035f | ||
|
|
254474d12d | ||
|
|
5615987ea2 | ||
|
|
3a93246f08 | ||
|
|
633784fae2 | ||
|
|
af127468a6 | ||
|
|
f892c1284b | ||
|
|
d762b5a017 | ||
|
|
28d7835327 | ||
|
|
03438f9192 | ||
|
|
09c7955149 | ||
|
|
9a2a88a703 | ||
|
|
820ae7d6e3 | ||
|
|
9c69f22f79 | ||
|
|
85ad6b12ba | ||
|
|
79706b4a1a | ||
|
|
72180d4248 | ||
|
|
8446c9563d | ||
|
|
4df1d2093f | ||
|
|
9d98d26cc7 | ||
|
|
0c762e610f | ||
|
|
62a019cc5d | ||
|
|
36c78e9686 | ||
|
|
dcb9e34d59 | ||
|
|
cb13cfdda7 | ||
|
|
0082f56b58 | ||
|
|
b490a72c1d | ||
|
|
3c0b479669 | ||
|
|
c9ad09226b | ||
|
|
4e771ecfb7 | ||
|
|
be86cd4028 | ||
|
|
3ddbe92f37 | ||
|
|
ca67ea9b4c | ||
|
|
9f78af29bf | ||
|
|
6821a05f76 | ||
|
|
e328c5d505 | ||
|
|
f814d26a4a | ||
|
|
3fc06e6f4f | ||
|
|
d876c267d6 | ||
|
|
1268a463ac | ||
|
|
e64d75a297 | ||
|
|
1960262435 | ||
|
|
c227062a37 | ||
|
|
e9376af13c | ||
|
|
8edebb9f75 | ||
|
|
8abe31341d | ||
|
|
7900edc96c | ||
|
|
c1eca93609 | ||
|
|
cd953bc7b9 | ||
|
|
692421ee13 | ||
|
|
1e89054897 | ||
|
|
ae1112ae11 | ||
|
|
205b505242 | ||
|
|
f77cd9bd52 | ||
|
|
11948c1cce | ||
|
|
d7e6f97d9c | ||
|
|
e324856301 | ||
|
|
8fb873b085 | ||
|
|
c17eb5fce5 | ||
|
|
91e9bdfc31 | ||
|
|
c83edc1689 | ||
|
|
dcbd4f3356 | ||
|
|
3929043eec | ||
|
|
23712ce590 | ||
|
|
adb2582856 | ||
|
|
3e292d7604 | ||
|
|
b565d1ab76 | ||
|
|
2debabe664 | ||
|
|
e1fc11218f | ||
|
|
ed59d6acf5 | ||
|
|
800984489d | ||
|
|
997ea3a2f5 | ||
|
|
b9b60a1346 | ||
|
|
e8edbd5394 | ||
|
|
f3e25ae3e6 | ||
|
|
93c952b344 | ||
|
|
d818a15aea | ||
|
|
6a664d976f | ||
|
|
5b7a71fb08 | ||
|
|
b29d83968b | ||
|
|
3e14c8e80d | ||
|
|
62bbe39bb4 | ||
|
|
4305ec34d0 | ||
|
|
a9518c2e55 | ||
|
|
c4fc67301c | ||
|
|
c92db272e0 | ||
|
|
46274acb3e | ||
|
|
8a676c573a | ||
|
|
39cbc59c12 | ||
|
|
96aa6ae3ef | ||
|
|
94d07833c5 | ||
|
|
1d3acbe40b | ||
|
|
389590e45d | ||
|
|
ea3cb026c7 | ||
|
|
1efe5bff9f | ||
|
|
d2ca74ecdf | ||
|
|
df4fa549ef | ||
|
|
cc7a706f52 | ||
|
|
d4256dad30 | ||
|
|
d9320b7c05 | ||
|
|
27c9a4a6a9 | ||
|
|
18d4dc7321 | ||
|
|
6f241ef001 | ||
|
|
296be2fbd5 | ||
|
|
c1957272ea | ||
|
|
e6afd33621 | ||
|
|
b767773742 | ||
|
|
52ead7ad1b | ||
|
|
b8e083f8fc | ||
|
|
6e3f8bdefd | ||
|
|
8e55f2bf58 | ||
|
|
cd9208b541 | ||
|
|
a58e99f942 | ||
|
|
248a66fa46 | ||
|
|
3e9a0ea925 | ||
|
|
78a2c325c3 | ||
|
|
ad1f1afed0 | ||
|
|
dc34379344 | ||
|
|
b892e731d9 | ||
|
|
a1669fd34e | ||
|
|
67e53906f0 | ||
|
|
cde7f2ab1c | ||
|
|
1cd9c57f87 | ||
|
|
c625ad32c5 | ||
|
|
15eca63ff0 | ||
|
|
d149df2a6e | ||
|
|
30fdcf4efb | ||
|
|
ea54abdfde | ||
|
|
70ce6705dd | ||
|
|
5cee2e8a53 | ||
|
|
484c902cf1 | ||
|
|
b8f202642d | ||
|
|
fdbe909f3c | ||
|
|
2757dc7205 | ||
|
|
e35ad892eb | ||
|
|
140e2a026e | ||
|
|
c89ab4e47c | ||
|
|
ab05e34805 | ||
|
|
4a201c1890 | ||
|
|
cb566739be | ||
|
|
4da104c7a6 | ||
|
|
5cb54d3bbd | ||
|
|
cb3e863957 | ||
|
|
8e20e54b53 | ||
|
|
3cf4b4ed8b | ||
|
|
329392b7d6 | ||
|
|
cc3c79102a | ||
|
|
661ac4e841 | ||
|
|
10241a37c2 | ||
|
|
0eb3a5cab3 | ||
|
|
4945767bd8 | ||
|
|
217760148c | ||
|
|
210e219778 | ||
|
|
50896ee23b | ||
|
|
41432b4165 | ||
|
|
d41b8e7441 | ||
|
|
aed17bde9b | ||
|
|
5b430fc376 | ||
|
|
e1064275a0 | ||
|
|
6f8d252dc6 | ||
|
|
b89e296390 | ||
|
|
57cd5b5b10 | ||
|
|
8f8f4506ff | ||
|
|
70f40e207a | ||
|
|
99b5e3565d | ||
|
|
6ec33db50e | ||
|
|
aa4922840b | ||
|
|
28239c4a51 | ||
|
|
b26ee410d1 | ||
|
|
425a418599 | ||
|
|
e4c7ed9c3e | ||
|
|
b17106e88d | ||
|
|
4b1d2ee106 | ||
|
|
a07a42624b | ||
|
|
5fb59cd64a | ||
|
|
8ee8f2c085 | ||
|
|
a3ba2276e2 | ||
|
|
aefc90dc19 | ||
|
|
123999febd | ||
|
|
511c0dd17c | ||
|
|
68d3450ff4 | ||
|
|
e1d5dd263a | ||
|
|
e1b211ed8e | ||
|
|
08f409993a | ||
|
|
2e90cda34c | ||
|
|
b97d674108 | ||
|
|
04b9422ea6 | ||
|
|
f8cbe053cc | ||
|
|
0e241a0fc5 | ||
|
|
31916384c1 | ||
|
|
e6f17834a0 | ||
|
|
e1f2bc0a19 | ||
|
|
12d3ca2d50 | ||
|
|
aa08125e43 | ||
|
|
9ce94a8398 | ||
|
|
34a3535abe | ||
|
|
6d3ce4e3cd | ||
|
|
ac79803f1b | ||
|
|
006ec1abb8 | ||
|
|
41842048a3 | ||
|
|
52b15f29ad | ||
|
|
c8039828fa | ||
|
|
67337ba269 | ||
|
|
efb53e912a | ||
|
|
b2a47e6216 | ||
|
|
85638c23ae | ||
|
|
44c1c93e81 | ||
|
|
06c9ff49a0 | ||
|
|
bbe72f52ba | ||
|
|
98a920d8cb | ||
|
|
788f37e467 | ||
|
|
5793b85c5b | ||
|
|
03cb04823c | ||
|
|
eccc3717bc | ||
|
|
ba7698a473 | ||
|
|
f9be71eca5 | ||
|
|
a89b2ca450 | ||
|
|
41e5d2524b | ||
|
|
de55be515d | ||
|
|
eb1ef65fac | ||
|
|
6a0c6047e6 | ||
|
|
0db8898577 | ||
|
|
a38695ff8a | ||
|
|
5ab45a1185 | ||
|
|
805d892dbb | ||
|
|
f254afbd00 | ||
|
|
d7859f03db | ||
|
|
c069f6a555 | ||
|
|
67c139cae9 | ||
|
|
892fed6011 | ||
|
|
f77945111b | ||
|
|
d5348cec70 | ||
|
|
167ef06209 | ||
|
|
d64a7cb739 | ||
|
|
b2584bb01b | ||
|
|
8b8cb12763 | ||
|
|
127e28a6f4 | ||
|
|
73c46f2a85 | ||
|
|
36e1fcc24a | ||
|
|
ed0e637207 | ||
|
|
6bea03fee9 | ||
|
|
6b8a55f55b | ||
|
|
b50df5afe1 | ||
|
|
4b273a7e39 | ||
|
|
5f8c4ea143 | ||
|
|
509049d95a | ||
|
|
83280de352 | ||
|
|
a4e4c8baaa | ||
|
|
00d27bc313 | ||
|
|
78ce12bc60 | ||
|
|
7e8d7ef0c0 | ||
|
|
d1c01f476d | ||
|
|
bb3c38a3b1 | ||
|
|
8ca6e8c478 | ||
|
|
96660ebd2a | ||
|
|
9e69d01db7 | ||
|
|
1c015e31f1 | ||
|
|
bf12b127ac | ||
|
|
dd733092a1 | ||
|
|
30fd5fcf14 | ||
|
|
483940a98d | ||
|
|
615bc17cec | ||
|
|
94cf350e5c | ||
|
|
fa594e732f | ||
|
|
4c0c9eb7fb | ||
|
|
e9cd95fc6a | ||
|
|
b68675d9fd | ||
|
|
d4abfffa2f | ||
|
|
2d6d664f77 | ||
|
|
c1f08cf2ea | ||
|
|
298a8787d5 | ||
|
|
25510b23e1 | ||
|
|
1fc351b088 | ||
|
|
7db627df1b | ||
|
|
c00733ea11 | ||
|
|
7a94ee04c8 | ||
|
|
799ac545a2 | ||
|
|
11396015fb | ||
|
|
6839b4773a | ||
|
|
a2b0671d6d | ||
|
|
99e5680f33 | ||
|
|
f93bcd875a | ||
|
|
576f75d230 | ||
|
|
f28e9bdb96 | ||
|
|
7c43e814e9 | ||
|
|
d96db2a408 | ||
|
|
f1c2a66023 | ||
|
|
bf82e04ddb | ||
|
|
f4d762c19b | ||
|
|
1ed7d34200 | ||
|
|
4f5d805725 | ||
|
|
64f606daaa | ||
|
|
bde8dbba05 | ||
|
|
f6b5404a04 | ||
|
|
de08485db8 | ||
|
|
ce9f2157e8 | ||
|
|
64cd9c0dd2 | ||
|
|
ab4cc74aca | ||
|
|
8cdb5fe346 | ||
|
|
aae7987df0 | ||
|
|
1817105c94 | ||
|
|
88ca98c5a6 | ||
|
|
8717cd077c | ||
|
|
9658af4aa9 | ||
|
|
d40a79576b | ||
|
|
481bd4ac68 | ||
|
|
6625a2afd3 | ||
|
|
cc23495591 | ||
|
|
acd42f9cc6 | ||
|
|
a2e439a155 | ||
|
|
d0fac80eb4 | ||
|
|
3f90611edf | ||
|
|
d8a9630548 | ||
|
|
fbb5d4a4a6 | ||
|
|
e5753c54a6 | ||
|
|
9ab9ea4c2e | ||
|
|
faf1fae873 | ||
|
|
2301478b3f | ||
|
|
df9b09eeae | ||
|
|
7e7b2797d7 | ||
|
|
287f1ae042 | ||
|
|
a8f0d3298f | ||
|
|
af67f7782c | ||
|
|
50dae8a37b | ||
|
|
0b86941a3b | ||
|
|
5d75feebdc | ||
|
|
4bc665c0d2 | ||
|
|
5390d0668b | ||
|
|
f55724bf58 | ||
|
|
4300b3a9e0 | ||
|
|
c085b263a7 | ||
|
|
3877014f83 | ||
|
|
83b1613002 | ||
|
|
329f7a2e00 | ||
|
|
0e0785db7b | ||
|
|
9638a4a4e6 | ||
|
|
91be43169c | ||
|
|
01af7e36cd | ||
|
|
d30ca2345e | ||
|
|
e8327eed36 | ||
|
|
b85f722e09 | ||
|
|
1a400bd7fd | ||
|
|
487c485911 | ||
|
|
a54e4299aa | ||
|
|
209ec55912 | ||
|
|
390ad0561f | ||
|
|
2c3c4e7519 | ||
|
|
1078101631 | ||
|
|
c0cdf7aaa6 | ||
|
|
7eedda30db | ||
|
|
54b883397c | ||
|
|
f9c3ab3921 | ||
|
|
26be6ae7c5 | ||
|
|
31c0fc5742 | ||
|
|
1a7f8d5319 | ||
|
|
14e4a052bb | ||
|
|
ae3d8860be | ||
|
|
2eede422a4 | ||
|
|
8221f5e641 | ||
|
|
1430332b98 | ||
|
|
6cf3486387 | ||
|
|
7aeac4996b | ||
|
|
1737128b1d | ||
|
|
8ac6db8b5a | ||
|
|
24debbf349 | ||
|
|
81e252d564 | ||
|
|
1ca9389110 | ||
|
|
10fb76377c | ||
|
|
12cd7bb49f | ||
|
|
38029efe50 | ||
|
|
21bf5b11d7 | ||
|
|
bc0495fe79 | ||
|
|
ffa1b1e6a3 | ||
|
|
d4c8c84445 | ||
|
|
3836aaa9d1 | ||
|
|
4a6242b3a0 | ||
|
|
b540cc8ac4 | ||
|
|
e562b29ecd | ||
|
|
5fb0402216 | ||
|
|
bc202ecc98 | ||
|
|
5f5402aa0a | ||
|
|
335bf0cb95 | ||
|
|
6acddfb0c7 | ||
|
|
8d53187d0f | ||
|
|
164462da8b | ||
|
|
fdab2d01b9 | ||
|
|
d855853699 | ||
|
|
b686880e7f | ||
|
|
8d80f32a95 | ||
|
|
8ef4339057 | ||
|
|
71b38bba88 | ||
|
|
9d3f0d45d5 | ||
|
|
f51c391e84 | ||
|
|
909fbaab95 | ||
|
|
67655d15cc | ||
|
|
83b4a3da30 | ||
|
|
768a195c10 | ||
|
|
16e8cfdf31 | ||
|
|
c0c55a7af8 | ||
|
|
e625dc63b4 | ||
|
|
dedac39d99 | ||
|
|
fe6d7d16c8 | ||
|
|
de8e248f29 | ||
|
|
7217ef5ec5 | ||
|
|
6a33173384 | ||
|
|
b520b26bd0 | ||
|
|
1761f63acd | ||
|
|
e58b09c1ea | ||
|
|
7c7e2c4f3d | ||
|
|
20abcaa011 | ||
|
|
297e6543de | ||
|
|
ec54f9a549 | ||
|
|
c064ca3ca9 | ||
|
|
56bd31fe22 | ||
|
|
ac8e042333 | ||
|
|
718b189f19 | ||
|
|
1fa9543e47 | ||
|
|
563209d080 | ||
|
|
ca71c700c7 | ||
|
|
585e2627bf | ||
|
|
579bbe2b86 | ||
|
|
5138644dc8 | ||
|
|
2310d36604 | ||
|
|
7d9e848edb | ||
|
|
a3770a8947 | ||
|
|
06d4a82706 | ||
|
|
c0095dc385 | ||
|
|
07060a8584 | ||
|
|
784e54f217 | ||
|
|
104156d084 | ||
|
|
48180b7ee8 | ||
|
|
ef34a63f7a | ||
|
|
45483809c5 | ||
|
|
9d89c1d692 | ||
|
|
cb4fde9a0b | ||
|
|
8f17a49a24 | ||
|
|
e18e923ac6 | ||
|
|
ed3b939477 | ||
|
|
977d21c929 | ||
|
|
89f0cdffc7 | ||
|
|
9685dca4de | ||
|
|
010218b5ce | ||
|
|
52252453d9 | ||
|
|
057108882f | ||
|
|
90b3cfcf9f | ||
|
|
4231d7b50a | ||
|
|
b85632cc99 | ||
|
|
1b81570338 | ||
|
|
0e03b951d4 | ||
|
|
6d05600eaf | ||
|
|
807422c377 | ||
|
|
768cef57c7 | ||
|
|
bcf1d32cdd | ||
|
|
def67eca3b | ||
|
|
388a8b6346 | ||
|
|
7ab937cf7b | ||
|
|
4bb460528f | ||
|
|
1ab636a4f1 | ||
|
|
a6e82475a3 | ||
|
|
9de8b16aeb | ||
|
|
0baf7744bc | ||
|
|
580c2b9e84 | ||
|
|
84673f26f3 | ||
|
|
ab1efb0749 | ||
|
|
4b0532b072 | ||
|
|
d458500113 | ||
|
|
d9fe2e0974 | ||
|
|
3fddb77564 | ||
|
|
3dd7a82dcc | ||
|
|
3dac6fd1c3 | ||
|
|
7fe01f0764 | ||
|
|
d7da96b387 | ||
|
|
3f95584dac | ||
|
|
de5578c8f7 | ||
|
|
1d410fdb7d | ||
|
|
54545d0bfc | ||
|
|
01131b2296 | ||
|
|
9b2239d4fa | ||
|
|
1b55201fbd | ||
|
|
be43c2156f | ||
|
|
c393db9c9f | ||
|
|
4a749ce00d | ||
|
|
13e6c5eefc | ||
|
|
343b904607 | ||
|
|
553a6e8ff6 | ||
|
|
9423b8da57 | ||
|
|
a7470345ff | ||
|
|
2aca12a49c | ||
|
|
810ee422a1 | ||
|
|
1c10ee106e | ||
|
|
e251c59da1 | ||
|
|
df35844bb2 | ||
|
|
d8006087a2 | ||
|
|
1fa91cbb6f | ||
|
|
3aacfdca20 | ||
|
|
b886422416 | ||
|
|
a29ea0374c | ||
|
|
e6a09e7cf7 | ||
|
|
83282ebcb8 | ||
|
|
d3169b10f8 | ||
|
|
197c22c7fe | ||
|
|
cfe923b8c4 | ||
|
|
742048f24e | ||
|
|
36111aa001 | ||
|
|
8a0f80181e | ||
|
|
fd4fec5340 | ||
|
|
808523b814 | ||
|
|
5640b2157f | ||
|
|
f3d79d906e | ||
|
|
5198f70ebf | ||
|
|
de12208d4a | ||
|
|
e20247d055 | ||
|
|
0862326a79 | ||
|
|
16531653ab | ||
|
|
2f3a2d495a | ||
|
|
baa9837702 | ||
|
|
cfa7d9820b | ||
|
|
3554d9fda2 | ||
|
|
cb2eebef40 | ||
|
|
f4d0cc4dd1 | ||
|
|
d31347c0e0 | ||
|
|
911a43337b | ||
|
|
f62f15cea7 | ||
|
|
dcd27a5f7a | ||
|
|
bf4c4561ce | ||
|
|
cc6c18b5ad | ||
|
|
6b536ced92 | ||
|
|
60ca0cbae3 | ||
|
|
b16abfba9c | ||
|
|
0a34143388 | ||
|
|
1e79f202f4 | ||
|
|
90f7b5259b | ||
|
|
2d143abda6 | ||
|
|
128671f5e9 | ||
|
|
6945eb548f | ||
|
|
ca3cd36887 | ||
|
|
31da08d186 | ||
|
|
1c90b09e2d | ||
|
|
18056139fd | ||
|
|
0898632ba4 | ||
|
|
f79a493083 | ||
|
|
2b159e24a7 | ||
|
|
d8032836bf | ||
|
|
b881f3c1c8 | ||
|
|
6f42bcfa4f | ||
|
|
ade6c46cca | ||
|
|
c6d0bf8d98 | ||
|
|
c41035058a | ||
|
|
e66f7a206e | ||
|
|
cec3d986a7 | ||
|
|
c6e65b4e24 | ||
|
|
ccb7e5270c | ||
|
|
ff29b6e84f | ||
|
|
6ed9e09451 | ||
|
|
75ce6d42d0 | ||
|
|
3bb0b93c79 | ||
|
|
87834b74ef | ||
|
|
6ef434f26d | ||
|
|
15b4152dce | ||
|
|
4aa19d700d | ||
|
|
3edf667958 | ||
|
|
c9b3b6c1b8 | ||
|
|
6e3bc5e65d | ||
|
|
886e35477e | ||
|
|
2f7fbea567 | ||
|
|
b7ecbd3b51 | ||
|
|
92b636ab75 | ||
|
|
28c57f75e8 | ||
|
|
cb1305c87f | ||
|
|
392bfcca2d | ||
|
|
2f95b8f6b2 | ||
|
|
96330b6f03 | ||
|
|
b509ae78b7 | ||
|
|
3a8a16bf48 | ||
|
|
8d2cab7b12 | ||
|
|
9034d6194a | ||
|
|
f8e400deb9 | ||
|
|
13290efac1 | ||
|
|
1df4da210f | ||
|
|
d0c426a7f9 | ||
|
|
17e5bb8d53 | ||
|
|
019cd51333 | ||
|
|
d62458b07b | ||
|
|
2e01153363 | ||
|
|
50ef826114 | ||
|
|
ddb28a9b90 | ||
|
|
0656ddd50a | ||
|
|
afdbf0adbf | ||
|
|
a5f5098beb | ||
|
|
e5c98e61c8 | ||
|
|
2793c8dd03 | ||
|
|
e4e226b2c7 | ||
|
|
46f98ded10 | ||
|
|
86b2391543 | ||
|
|
00ea4f8701 | ||
|
|
f7c9a12510 | ||
|
|
b6a7e049e6 | ||
|
|
45b3863353 | ||
|
|
c2764fda45 | ||
|
|
d358a9d9fd | ||
|
|
1a08ba0b57 | ||
|
|
974efc55ac | ||
|
|
dc46277d0c | ||
|
|
052048ad4c | ||
|
|
c361d8d16b | ||
|
|
045fd20d8c | ||
|
|
fdfd684e7a | ||
|
|
0a2592893d | ||
|
|
4c6c310e0a | ||
|
|
a5aa305773 | ||
|
|
196cf1cd18 | ||
|
|
0cf654aa88 | ||
|
|
2cf20f4b6c | ||
|
|
6b0ba94288 | ||
|
|
870ad008bf | ||
|
|
767aaa80a0 | ||
|
|
5eadaa08aa | ||
|
|
5cdc3e694f | ||
|
|
e96382fdd9 | ||
|
|
a486319cc2 | ||
|
|
1432866798 | ||
|
|
4a375b6563 | ||
|
|
743658032a | ||
|
|
e2f8f5095f | ||
|
|
a22ca5b57f | ||
|
|
b43c6c00bb | ||
|
|
c56e4557f9 | ||
|
|
6b640ea55e | ||
|
|
70f8a771a9 | ||
|
|
4b4aec5bbd | ||
|
|
00198d5e49 | ||
|
|
8a19d25396 | ||
|
|
8533f6edf1 | ||
|
|
bc9693d6f6 | ||
|
|
43a03d85a8 | ||
|
|
f0d63bed58 | ||
|
|
0a3978ab8c | ||
|
|
1c09b8baef | ||
|
|
547b610454 | ||
|
|
9d39bed852 | ||
|
|
70ff7cf74c | ||
|
|
8908fb07a0 | ||
|
|
f2c4ac061c | ||
|
|
b2871d8fc5 | ||
|
|
f4c6e5a6fa | ||
|
|
67d838b5fc | ||
|
|
f15a354c29 | ||
|
|
281e03055d | ||
|
|
216e9c0125 | ||
|
|
2c14f8b43b | ||
|
|
89a77feea7 | ||
|
|
5ca880c8fd | ||
|
|
17671493bf | ||
|
|
0d687eb348 | ||
|
|
1e01f94540 | ||
|
|
335ef67971 | ||
|
|
429d0c8df8 | ||
|
|
72b41f4322 | ||
|
|
fb5938280e | ||
|
|
2d72c58ae7 | ||
|
|
ad99e8edce | ||
|
|
d463f5a032 | ||
|
|
1415f74fe5 | ||
|
|
8de84f03a0 | ||
|
|
fe85ce5885 | ||
|
|
9dc7142e4a | ||
|
|
34a8d0b99b | ||
|
|
176e2726e9 | ||
|
|
2e4a1680b9 | ||
|
|
1eddae9da6 | ||
|
|
f217dbac51 | ||
|
|
eb74414b16 | ||
|
|
ee542f0fec | ||
|
|
0c0ec29821 | ||
|
|
955ce1dd2d | ||
|
|
f32f37cfbb | ||
|
|
8684788f1f | ||
|
|
9e033d1673 | ||
|
|
69c00d272b | ||
|
|
19617e9dae | ||
|
|
f8cc54d4f2 | ||
|
|
8764aa9829 | ||
|
|
fb68f6eb60 | ||
|
|
d09c42366a | ||
|
|
0298fa602a | ||
|
|
30cbcbb3c4 | ||
|
|
1127d323d3 | ||
|
|
01e812aebf | ||
|
|
e690bae7d1 | ||
|
|
58c2c84120 | ||
|
|
a96947c7e7 | ||
|
|
45b40d903c | ||
|
|
b19033aa4f | ||
|
|
adac0f3e51 | ||
|
|
3441482e8c | ||
|
|
781845905c | ||
|
|
b3c9b58350 | ||
|
|
337a2cf319 | ||
|
|
06fa04a448 | ||
|
|
93e86b141d | ||
|
|
fc56027929 | ||
|
|
d2287328ad | ||
|
|
b91834b813 | ||
|
|
8faf991bcb | ||
|
|
84ac30b8d2 | ||
|
|
0f17aebc52 | ||
|
|
2bff13d9e1 | ||
|
|
7683db70cd | ||
|
|
94ba2ad24a | ||
|
|
e42a22d1f2 | ||
|
|
11b6946e00 | ||
|
|
ba8a675eaa | ||
|
|
10f8941258 | ||
|
|
0816fdf318 | ||
|
|
bcf43640fa | ||
|
|
1de68051e3 | ||
|
|
0c9015bb77 | ||
|
|
a8c200f25a | ||
|
|
59fbb2acb1 | ||
|
|
3b53527e9e | ||
|
|
3c53c2c56c | ||
|
|
13a51b6bd3 | ||
|
|
c8d81518cc | ||
|
|
390d49d599 | ||
|
|
3604e6fa7d | ||
|
|
206532f195 | ||
|
|
c9f38fef45 | ||
|
|
b55c05095a | ||
|
|
8f073c5b6f | ||
|
|
f45ca180e9 | ||
|
|
1eb549b137 | ||
|
|
3a9bfc84cd | ||
|
|
c9a8a2af07 | ||
|
|
f5069aef6e | ||
|
|
eb1af1e27e | ||
|
|
d84ac0df9c | ||
|
|
04275cd702 | ||
|
|
746bc7d7bd | ||
|
|
15c5e9833a | ||
|
|
b589a1a13e | ||
|
|
5102770ad5 | ||
|
|
47f396cfce | ||
|
|
759d0a825b | ||
|
|
a8869c46b8 | ||
|
|
4b31f40026 | ||
|
|
4f8dee8fcf | ||
|
|
cf5ab0ddef | ||
|
|
91e9d7431a | ||
|
|
6e13440f1f | ||
|
|
3efeb4a0a6 | ||
|
|
764a372e9f | ||
|
|
340087076e | ||
|
|
ec5716c436 | ||
|
|
3f3a34f788 | ||
|
|
e7879384b1 | ||
|
|
853ee4bef1 | ||
|
|
9be90dd035 | ||
|
|
4c7acca85a | ||
|
|
d235bf9822 | ||
|
|
688d37fe76 | ||
|
|
6c5f606682 | ||
|
|
ce5092036a | ||
|
|
b745626a9f | ||
|
|
c9d73bf1a4 | ||
|
|
6e76b7a7dd | ||
|
|
fd41f0fe0d | ||
|
|
d2e81d14d9 | ||
|
|
7d674b44d3 | ||
|
|
7d3617c27f | ||
|
|
cf6fca8e76 | ||
|
|
1560a823c3 | ||
|
|
aba41d41ac | ||
|
|
245cffc4f7 | ||
|
|
3aada68eb9 | ||
|
|
d15611fd44 | ||
|
|
82d4b866c0 | ||
|
|
4645dd0011 | ||
|
|
bec81ddbfe | ||
|
|
6e4279e30f | ||
|
|
e1131dcf3d | ||
|
|
762de84f34 | ||
|
|
e480cdbf9b | ||
|
|
95cdc89795 | ||
|
|
e7f5491239 | ||
|
|
ba78637361 | ||
|
|
b3119749d9 | ||
|
|
cb56b98222 | ||
|
|
2256183422 | ||
|
|
0bfa8219ca | ||
|
|
4c21a68139 | ||
|
|
38cf74d83b | ||
|
|
1867e56739 | ||
|
|
826a69c531 | ||
|
|
7056be0870 | ||
|
|
708dba6cb1 | ||
|
|
164a34a340 | ||
|
|
3593a918b7 | ||
|
|
7d2ac2f55d | ||
|
|
cc4b343cf4 | ||
|
|
597931f79b | ||
|
|
299864a9cf | ||
|
|
014757a0f7 | ||
|
|
032b5b8776 | ||
|
|
44107f9821 | ||
|
|
b49e45827f | ||
|
|
3cd405e9ea | ||
|
|
b17a54a2d2 | ||
|
|
2d6d4d2db0 | ||
|
|
646b7a3118 | ||
|
|
e4c7842f34 | ||
|
|
7490cb81b8 | ||
|
|
9e105a362f | ||
|
|
9c8cbdd0e6 | ||
|
|
635a8a24f2 | ||
|
|
6354d4b911 | ||
|
|
452e8ed8c5 | ||
|
|
8a93e3c64c | ||
|
|
76fc9b78fe | ||
|
|
cf685b404d | ||
|
|
747d97ecfc | ||
|
|
be5fd86aa7 | ||
|
|
963f57868d | ||
|
|
97f0516630 | ||
|
|
c896b445bd | ||
|
|
f06c4f4049 | ||
|
|
937ce34c36 | ||
|
|
cddfd1b319 | ||
|
|
c42892ee35 | ||
|
|
bb3003dc3b | ||
|
|
2858dce664 | ||
|
|
1517ae3fc9 | ||
|
|
cf9c41f437 | ||
|
|
87497d2d09 | ||
|
|
67ab979a9b | ||
|
|
05f23f89ae | ||
|
|
cdc244ec06 | ||
|
|
71308316b1 | ||
|
|
2d1dfece25 | ||
|
|
65577a67dc | ||
|
|
45d5da98ca | ||
|
|
455e067e73 | ||
|
|
6359826fd9 | ||
|
|
8325083402 | ||
|
|
0f1a1d5f56 | ||
|
|
52d6f4343c | ||
|
|
405d55f3f6 | ||
|
|
06010b1366 | ||
|
|
21aa31f963 | ||
|
|
3f709cc39e | ||
|
|
f376e1ab01 | ||
|
|
fb3ba16a92 | ||
|
|
21285f02b8 | ||
|
|
05adf6f907 | ||
|
|
06fa171f7a | ||
|
|
4eae5be995 | ||
|
|
6d02617422 | ||
|
|
c2f07d14f3 | ||
|
|
52fe91f8bc | ||
|
|
98cb0f978e | ||
|
|
977a83cce8 | ||
|
|
4d92f9bf18 | ||
|
|
c459d60fc6 | ||
|
|
ad2e8a3c96 | ||
|
|
7dd9b3fa0c | ||
|
|
340a151302 | ||
|
|
9f70af009f | ||
|
|
bf1a65b8e8 | ||
|
|
037ab02a71 | ||
|
|
0039ec2958 | ||
|
|
08571d51fa | ||
|
|
6ac33b0568 | ||
|
|
373da78b7b | ||
|
|
c3d22335e2 | ||
|
|
4216eec494 | ||
|
|
e88e912c3c | ||
|
|
d06fb83fee | ||
|
|
e0b9a81c9b | ||
|
|
192e4b8877 | ||
|
|
02d44a6cca | ||
|
|
39ba1e0582 | ||
|
|
ae121895e9 | ||
|
|
11ecf20f89 | ||
|
|
3646a7d12d | ||
|
|
db5f45da83 | ||
|
|
52a4bfa25f | ||
|
|
099b62b645 | ||
|
|
e37332a5d2 | ||
|
|
f36cc56c81 | ||
|
|
b20750b936 | ||
|
|
407f58da54 | ||
|
|
fe5bb1d885 | ||
|
|
92f45567d7 | ||
|
|
a4c0e0a59c | ||
|
|
d536377329 | ||
|
|
923f4ed045 | ||
|
|
9191cae144 | ||
|
|
e8c142353c | ||
|
|
ba1e22955e | ||
|
|
c41847c0d7 | ||
|
|
e1d7c25c98 | ||
|
|
3d8e845233 | ||
|
|
0fa126a6b8 | ||
|
|
1961816ba7 | ||
|
|
4410b679a0 | ||
|
|
e6214b3c97 | ||
|
|
7e7637a1b3 | ||
|
|
86b201623d | ||
|
|
785843198a | ||
|
|
bc0f5a9136 | ||
|
|
461e650e05 | ||
|
|
c2132e3772 | ||
|
|
174c7a776e | ||
|
|
730864609f | ||
|
|
784137fdac | ||
|
|
c6aff8424c | ||
|
|
a7a34ac6b2 | ||
|
|
57492023f9 | ||
|
|
aff1e160b4 | ||
|
|
b8d12bd0cd | ||
|
|
5ab33e831d | ||
|
|
dc3b01dc15 | ||
|
|
e96bd5a0e7 | ||
|
|
57c33fe693 | ||
|
|
fc2d7b41d8 | ||
|
|
fd139d4903 | ||
|
|
813d33fc4d | ||
|
|
26addf809e | ||
|
|
a9e090c454 | ||
|
|
59355cf79f | ||
|
|
c200c53268 | ||
|
|
a572ff9fca | ||
|
|
1ab4f99a37 | ||
|
|
99006465e6 | ||
|
|
4a7e9c16d0 | ||
|
|
d416a77866 | ||
|
|
07fe141f8a | ||
|
|
c2de80f532 | ||
|
|
e742bdfacf | ||
|
|
24950a098f | ||
|
|
bed65745cc | ||
|
|
04a4833c6e | ||
|
|
4aa0a733fc | ||
|
|
082191412e | ||
|
|
e3a7d0807e | ||
|
|
0ee3d1160a | ||
|
|
b600bce23f | ||
|
|
952b5fab89 | ||
|
|
6c705e1e25 | ||
|
|
349e8b2da7 | ||
|
|
39ce74c1e0 | ||
|
|
77cf392300 | ||
|
|
b6225ccc38 | ||
|
|
a38eaad281 | ||
|
|
1b6d8a2b8d | ||
|
|
cbc1c935bf | ||
|
|
391bf4113a | ||
|
|
718bff7469 | ||
|
|
e67f60182d | ||
|
|
6bb0d736be | ||
|
|
5bc74fc296 | ||
|
|
fea237a3ea | ||
|
|
6f3cdeda70 | ||
|
|
8476baacc7 | ||
|
|
681f57f703 | ||
|
|
03051a95cf | ||
|
|
80f31f75ad | ||
|
|
e0da4c81da | ||
|
|
57a5b90be7 | ||
|
|
98928dba9d | ||
|
|
c83577cb81 | ||
|
|
39edf1a8ed | ||
|
|
8d10c9aa41 | ||
|
|
0bcb76fa81 | ||
|
|
aceb9e4de7 | ||
|
|
a249ced37c | ||
|
|
375078a9a4 | ||
|
|
273a7d82a2 | ||
|
|
26f5e52ad8 | ||
|
|
2a32f8f681 | ||
|
|
7dad0aa1da | ||
|
|
c742b73133 | ||
|
|
fece31a9aa | ||
|
|
b22a4501cc | ||
|
|
c596039453 | ||
|
|
7eea6ebe57 | ||
|
|
b6a42ecf48 | ||
|
|
95f3d4fffa | ||
|
|
95becde93d | ||
|
|
0538d082dc | ||
|
|
c3b6b8d821 | ||
|
|
c41fbbb93e | ||
|
|
0728d96339 | ||
|
|
abc335143b | ||
|
|
dc9908eac1 | ||
|
|
6274b617f4 | ||
|
|
c5d45c6b44 | ||
|
|
ef1a195036 | ||
|
|
5ac0837be3 | ||
|
|
fbc6f78cb5 | ||
|
|
d6f9fddc94 | ||
|
|
199011feb8 | ||
|
|
98f1d5cd9b | ||
|
|
b9c83ca06d | ||
|
|
f0b7a00ae6 | ||
|
|
a8a9a93317 | ||
|
|
32e9a7fa06 | ||
|
|
88a47e7788 | ||
|
|
4b4a414259 | ||
|
|
68281dce66 | ||
|
|
221cc8ab10 | ||
|
|
c6e47a868b | ||
|
|
0c5c261196 | ||
|
|
c7372aabfd | ||
|
|
7d1dbbb27a | ||
|
|
c00583dd98 | ||
|
|
49ca3bfd00 | ||
|
|
3adc3ed5d2 | ||
|
|
bdca59b3d7 | ||
|
|
d5ab4093a9 | ||
|
|
e6df19efbc | ||
|
|
b7948c5344 | ||
|
|
a13557d71d | ||
|
|
e2338fcedf | ||
|
|
43bfeff2be | ||
|
|
1a489652ff | ||
|
|
1ac92c561b | ||
|
|
cb952b0d3a | ||
|
|
5919dd998b | ||
|
|
320f78b31b | ||
|
|
533bc4c2fe | ||
|
|
eb8aa195c2 | ||
|
|
4197580b04 | ||
|
|
0e92f7bfff | ||
|
|
927277a6cd | ||
|
|
d5696010d9 | ||
|
|
9db37c2799 | ||
|
|
7e7b41cd8c | ||
|
|
fc3a369d3d | ||
|
|
5df766466a | ||
|
|
6814130570 | ||
|
|
cb6160f1e4 | ||
|
|
b00214bdbd | ||
|
|
4643810b75 | ||
|
|
45246bccd7 | ||
|
|
78b44a1319 | ||
|
|
0e6cd0f72a | ||
|
|
0aeba7c5af | ||
|
|
525c00ea18 | ||
|
|
c056bd4d4c | ||
|
|
93682fb42b | ||
|
|
aa9ec603a9 | ||
|
|
6f83bf3af2 | ||
|
|
d5245f0730 | ||
|
|
1b4cc556be | ||
|
|
2efcbd060a | ||
|
|
68ee35d03b | ||
|
|
1b6a43ae15 | ||
|
|
8de26af246 | ||
|
|
c3fd732243 | ||
|
|
3ce0b8bc97 | ||
|
|
2846eea956 | ||
|
|
ca3bedc9a1 | ||
|
|
2d4d7b80c1 | ||
|
|
df85543337 | ||
|
|
e15baeb4a2 | ||
|
|
f16804c0f8 | ||
|
|
934a41e414 | ||
|
|
8621fe2e3c | ||
|
|
bbf2c29a4a | ||
|
|
0a148166e1 | ||
|
|
79b4716b95 | ||
|
|
57437f04c9 | ||
|
|
8bbcd267cd | ||
|
|
e885cb6c45 | ||
|
|
8182141e93 | ||
|
|
d7d2efd58e | ||
|
|
02033a675a | ||
|
|
ca0f7bb74c | ||
|
|
d676ecfaa8 | ||
|
|
a0f556b2a9 | ||
|
|
6071319acd | ||
|
|
e9ddfa6cf9 | ||
|
|
8ee94d75ca | ||
|
|
ec40956721 | ||
|
|
8504d01688 | ||
|
|
c8a932b6b3 | ||
|
|
b1ed51e72c | ||
|
|
b386af4121 | ||
|
|
0daa3a8f57 | ||
|
|
ae42c4df16 | ||
|
|
252ff9d3c5 | ||
|
|
38c9ad6986 | ||
|
|
ad84b222a5 | ||
|
|
c3e4a08b00 | ||
|
|
f589bdc78d | ||
|
|
1a8efdbf2c | ||
|
|
b78e0144de | ||
|
|
3c27b50ff6 | ||
|
|
e8e5c8dff1 | ||
|
|
f66dd51084 | ||
|
|
54096d56d3 | ||
|
|
832119f6b1 | ||
|
|
5abd4dcc66 | ||
|
|
a4936a6ff3 | ||
|
|
ebe4804b00 | ||
|
|
098db9adf6 | ||
|
|
38b3c82ece | ||
|
|
99a7453f28 | ||
|
|
8ade52c8d9 | ||
|
|
a3ca1febbc | ||
|
|
767430d065 | ||
|
|
f9e27ef67c | ||
|
|
4d25d505e0 | ||
|
|
74fb470647 | ||
|
|
6404aac986 | ||
|
|
4fcb8d5540 | ||
|
|
4251ad7d45 | ||
|
|
d87317f937 | ||
|
|
b202b75bf7 | ||
|
|
5761ede9e1 | ||
|
|
cf15cb1e13 | ||
|
|
e5c6136950 | ||
|
|
37f90e6f1c | ||
|
|
6416fe1934 | ||
|
|
3b50428f82 | ||
|
|
d4b22ee472 | ||
|
|
35c8197881 | ||
|
|
a860acaf0d | ||
|
|
dccd240b66 | ||
|
|
35522ae77d | ||
|
|
e40c1ff09e | ||
|
|
d71ddd7ad0 | ||
|
|
ba8300508d | ||
|
|
734505ee73 | ||
|
|
dd65c173a9 | ||
|
|
ebae675961 | ||
|
|
539eadf533 | ||
|
|
3beebd42a8 | ||
|
|
66e00bb79a | ||
|
|
83985aa44c | ||
|
|
bb9684f7d3 | ||
|
|
ddfe79b3ac | ||
|
|
c852ad1d45 | ||
|
|
29f535da94 | ||
|
|
d5b6744a41 | ||
|
|
cbc3cfc33b | ||
|
|
547bd46bb3 | ||
|
|
8b8a303365 | ||
|
|
7b386c4f41 | ||
|
|
5b8fa5ec8d | ||
|
|
2c81ff90da | ||
|
|
66e118abdf | ||
|
|
38791e50ea | ||
|
|
a8c6a97579 | ||
|
|
5bb90828f8 | ||
|
|
e3e5085214 | ||
|
|
9be12da34e | ||
|
|
8e7b40efec | ||
|
|
d7d71d9ff1 | ||
|
|
2d68e3d4f3 | ||
|
|
53236faaa0 | ||
|
|
daca1b3615 | ||
|
|
9a8032a673 | ||
|
|
b11972d1b7 | ||
|
|
041ea2fbb1 | ||
|
|
5167611da5 | ||
|
|
4526378b33 | ||
|
|
bc2a9cf1c0 | ||
|
|
c4a5eeabcc | ||
|
|
00836cd38b | ||
|
|
c0009c7e62 | ||
|
|
6023f415a4 | ||
|
|
f55daf65e3 | ||
|
|
fe3c23d29c | ||
|
|
f0765ba743 | ||
|
|
672c623757 | ||
|
|
e33799701b | ||
|
|
e5e64a4b6d | ||
|
|
63f1c1f7b5 | ||
|
|
005de550c1 | ||
|
|
20fd3bdc20 | ||
|
|
e29f53a82d | ||
|
|
f272470871 | ||
|
|
9c082a573c | ||
|
|
7de0a0a44a | ||
|
|
e848c78dba | ||
|
|
3f60723425 | ||
|
|
8b97914438 | ||
|
|
a8967bab39 | ||
|
|
1248307b96 | ||
|
|
de1491a310 | ||
|
|
b5a08c3ba4 | ||
|
|
49bf86a8d5 | ||
|
|
5e4cfbaf3f | ||
|
|
11aed2ab61 | ||
|
|
e6f19a4abf | ||
|
|
b3b6dc2e94 | ||
|
|
ece09a93cd | ||
|
|
9a56ebea81 | ||
|
|
287e15fddc | ||
|
|
724cb0787d | ||
|
|
d8b806966a | ||
|
|
f24a6f0e3c | ||
|
|
34c516709b | ||
|
|
6d03eac9a1 | ||
|
|
c456ef9118 | ||
|
|
4351080aea | ||
|
|
8aee2858ea | ||
|
|
da5a930e89 | ||
|
|
5131cc8e43 | ||
|
|
60f06f97fa | ||
|
|
c0216e0800 | ||
|
|
2be68342bb | ||
|
|
c43a29f058 | ||
|
|
ab14b9c8bb | ||
|
|
fa3e496aae | ||
|
|
543cd5af80 | ||
|
|
e3cdfe27d1 | ||
|
|
d946e18fa2 | ||
|
|
b33b696336 | ||
|
|
e928b4c9e0 | ||
|
|
2b27e84956 | ||
|
|
9627272b57 | ||
|
|
705354a3d6 | ||
|
|
7d52b0cc96 | ||
|
|
8662e963ac | ||
|
|
08594f0b96 | ||
|
|
7db73cbd44 | ||
|
|
cae8485092 | ||
|
|
64e020b1ad | ||
|
|
2dd2208f48 | ||
|
|
ddc28c43c8 | ||
|
|
7c889e3523 | ||
|
|
af7beb2c34 | ||
|
|
7b50febba3 | ||
|
|
00543bca17 | ||
|
|
178710dabc | ||
|
|
99d9d14d3b | ||
|
|
a07d6aa1e7 | ||
|
|
59a4abff7c | ||
|
|
df0f310ddd | ||
|
|
57a06aa122 | ||
|
|
f110dce520 | ||
|
|
3085799c3c | ||
|
|
3d9b9af55e | ||
|
|
ad21909b5c | ||
|
|
d98d00556d | ||
|
|
5c7a4323e3 | ||
|
|
183701a00a | ||
|
|
549987296c | ||
|
|
9918e49bb1 | ||
|
|
d57ef1e928 | ||
|
|
203af0fc76 | ||
|
|
a446c0a9c9 | ||
|
|
b2aba7918d | ||
|
|
fc2c877a57 | ||
|
|
f2a93887c9 | ||
|
|
b1eb48d201 | ||
|
|
d372d786ef | ||
|
|
dc8df9c62f | ||
|
|
5b3ea08b39 | ||
|
|
72a754676a | ||
|
|
cb1da686ec | ||
|
|
8a78e4e9f4 | ||
|
|
b9b59ac2e0 | ||
|
|
549b982c5f | ||
|
|
558f527f20 | ||
|
|
d897d64aa5 | ||
|
|
59463958d3 | ||
|
|
d4a606884c | ||
|
|
ff3a2f6b67 | ||
|
|
288ac62448 | ||
|
|
f5d3df65b0 | ||
|
|
fc6ac662cd | ||
|
|
cd0d9052e8 | ||
|
|
86da8cbd17 | ||
|
|
7a38143f5e | ||
|
|
818802cf5e | ||
|
|
a668ed5e24 | ||
|
|
c9edc217fd | ||
|
|
89dc9e7e7f | ||
|
|
96b6832dff | ||
|
|
881e414043 | ||
|
|
b5a8312167 | ||
|
|
ac3a282876 | ||
|
|
a3117fa61d | ||
|
|
bfa0db3ba3 | ||
|
|
79fdba969b | ||
|
|
79461d52c2 | ||
|
|
8c7bac7dbb | ||
|
|
bb3b982dea | ||
|
|
f3038e4fef | ||
|
|
cfeb637685 | ||
|
|
f37fd5c5e3 | ||
|
|
4368602684 | ||
|
|
a67ced29a3 | ||
|
|
ca8293ebdb | ||
|
|
4a95dd8ba3 | ||
|
|
1616aa87bd | ||
|
|
9d9400f4d9 | ||
|
|
a6f8eb28f2 | ||
|
|
251834143c | ||
|
|
ad8b6c806d | ||
|
|
26a6264039 | ||
|
|
2dfcee6b25 | ||
|
|
b283977281 | ||
|
|
2538a79ef0 | ||
|
|
267f2afab6 | ||
|
|
559eebbb70 | ||
|
|
326ee9a9c2 | ||
|
|
dc4c33c0d5 | ||
|
|
3fbebfc283 | ||
|
|
7273e1218a | ||
|
|
69e96f24c2 | ||
|
|
92ddf2ca41 | ||
|
|
3662afeaa7 | ||
|
|
860210628e | ||
|
|
a1988f91c1 | ||
|
|
6f6393493b | ||
|
|
878213887f | ||
|
|
805b83da9c | ||
|
|
fe4319ad07 | ||
|
|
1bda9d5a26 | ||
|
|
9ce239dedb | ||
|
|
bc86c9b57d | ||
|
|
d9b9e02412 | ||
|
|
2f7b5dd041 | ||
|
|
5ffb7bba83 | ||
|
|
436bffcb0e | ||
|
|
99ce747720 | ||
|
|
f3fbbed7ee | ||
|
|
b7c024d275 | ||
|
|
cf76c943b8 | ||
|
|
2a0e641de7 | ||
|
|
630456f700 | ||
|
|
618ba376b2 | ||
|
|
c8a445275b | ||
|
|
68b3c449a6 | ||
|
|
aee7d171c5 | ||
|
|
2089406eaf | ||
|
|
298e041b80 | ||
|
|
c79bf1ca3a | ||
|
|
207546b53c | ||
|
|
a54898b062 | ||
|
|
124803c89d | ||
|
|
825128b630 | ||
|
|
dcd20f42b9 | ||
|
|
b6f14a752c | ||
|
|
40f58d7054 | ||
|
|
485afcfa6e | ||
|
|
e82bc859f5 | ||
|
|
5615e02cdb | ||
|
|
4c5a046bc0 | ||
|
|
6b6ab5e752 | ||
|
|
6d3f3985a2 | ||
|
|
64e57c5419 | ||
|
|
7e11c319e7 | ||
|
|
12265def19 | ||
|
|
45f60ae646 | ||
|
|
72988cc6fb | ||
|
|
4d3df4cda6 | ||
|
|
a0b7768a86 | ||
|
|
7aae1b262e | ||
|
|
5ace62a5fd | ||
|
|
48e01d3ea3 | ||
|
|
d93c705737 | ||
|
|
b1a97eca39 | ||
|
|
d91088879c | ||
|
|
21e5f33487 | ||
|
|
48f7c37d3b | ||
|
|
815d911143 | ||
|
|
d90baed5b5 | ||
|
|
e767cee4c0 | ||
|
|
eafce4442c | ||
|
|
3652394dab | ||
|
|
a942882c73 | ||
|
|
b8f829dbc3 | ||
|
|
8d33644749 | ||
|
|
268df23739 | ||
|
|
6c731f50a9 | ||
|
|
dc2f3cd166 | ||
|
|
877ad53ead | ||
|
|
bc7dce6026 | ||
|
|
c24e216f26 | ||
|
|
2d05ecc81f | ||
|
|
437c1a154c | ||
|
|
82d30c6e74 | ||
|
|
998eecb94d | ||
|
|
02e22e5781 | ||
|
|
ad11ca0a87 | ||
|
|
7b0a643de3 | ||
|
|
fa53bce27a | ||
|
|
1d3f1fd7d0 | ||
|
|
5d9a94466a | ||
|
|
b5175ae8b0 | ||
|
|
38948053cc | ||
|
|
4a5a496802 | ||
|
|
30b6c8aa03 | ||
|
|
95e468c90a | ||
|
|
d74dd48d24 | ||
|
|
5ef72b81ae | ||
|
|
691cf1ce72 | ||
|
|
5b70064fa4 | ||
|
|
80e01a4d3d | ||
|
|
b30f3d6b8f | ||
|
|
4672628ee2 | ||
|
|
a112c6d9ee | ||
|
|
2b1e343186 | ||
|
|
36ce0c8271 | ||
|
|
b521318e82 | ||
|
|
9f64a384d6 | ||
|
|
4ecff94aec | ||
|
|
c7e73924c8 | ||
|
|
87958d9db8 | ||
|
|
56fa719931 | ||
|
|
6ee6cd3977 | ||
|
|
7821f41723 | ||
|
|
ddf6154600 | ||
|
|
929cc2727d | ||
|
|
4379145231 | ||
|
|
42d86fab8e | ||
|
|
cb41a4c386 | ||
|
|
672abbcaad | ||
|
|
17bc9c35a7 | ||
|
|
50587735b5 | ||
|
|
21edfdb62e | ||
|
|
bda67afd4f | ||
|
|
c4ca06d5e5 | ||
|
|
f4904e06c8 | ||
|
|
1273a6fb74 | ||
|
|
3c626fd01e | ||
|
|
00953850b3 | ||
|
|
563370f10b | ||
|
|
62a33fe7fc | ||
|
|
ea18fda0a3 | ||
|
|
1ef163f827 | ||
|
|
3f6cb3cd73 | ||
|
|
284767409a | ||
|
|
5e3d29df4c | ||
|
|
c380049b21 | ||
|
|
b49209a0d9 | ||
|
|
9d39b616f9 | ||
|
|
32e0074f26 | ||
|
|
8d746cd206 | ||
|
|
bc341d193f | ||
|
|
3ad2b2bfcc | ||
|
|
acfad7ec5b | ||
|
|
5be6511529 | ||
|
|
f20b4d570e | ||
|
|
06a9478555 | ||
|
|
6e3ca5391a | ||
|
|
2422a4200c | ||
|
|
56788c8b8f | ||
|
|
220ac2fa2d | ||
|
|
3143d0d8aa | ||
|
|
0bb1669efa | ||
|
|
288be8dd71 | ||
|
|
d3bf71a22d | ||
|
|
12abca39a2 | ||
|
|
898c8854aa | ||
|
|
492e33aeda | ||
|
|
ce9c832e00 | ||
|
|
5e0821417e | ||
|
|
ce451e4dd4 | ||
|
|
714d8c7092 | ||
|
|
6162904c59 | ||
|
|
4d65b4c7a5 | ||
|
|
4243843951 | ||
|
|
203965043e | ||
|
|
bf87500e35 | ||
|
|
a038587224 | ||
|
|
96d908094b | ||
|
|
61dc148d34 | ||
|
|
f753369d1a | ||
|
|
72c2fa3863 | ||
|
|
ba0bda6aa6 | ||
|
|
890397bae7 | ||
|
|
d9b2863382 | ||
|
|
ccc8d7e5cd | ||
|
|
50f6044a2f | ||
|
|
31281c7faa | ||
|
|
e9b545a187 | ||
|
|
be1ecdb0c8 | ||
|
|
115e08d0c8 | ||
|
|
e2a892eda3 | ||
|
|
5d536dd975 | ||
|
|
af258dcf41 | ||
|
|
bbb46a29a9 | ||
|
|
3f7c1b0750 | ||
|
|
2b211c2ba0 | ||
|
|
c20314f83c | ||
|
|
57bc1f2032 | ||
|
|
d370f7e721 | ||
|
|
00c8ebbfe8 | ||
|
|
17951d7fe0 | ||
|
|
3e5288836d | ||
|
|
6c94c3aa7b | ||
|
|
6a24794457 | ||
|
|
443e7df1b6 | ||
|
|
82106c1c8b | ||
|
|
32867d3666 | ||
|
|
384b4226f2 | ||
|
|
cecd4aa36a | ||
|
|
0dffd66651 | ||
|
|
c34afae250 | ||
|
|
128453fad1 | ||
|
|
ac3b86fb85 | ||
|
|
e303982ad8 | ||
|
|
df763c4dbd | ||
|
|
85fd46e1c6 | ||
|
|
51b37a49d5 | ||
|
|
4838813a38 | ||
|
|
9867bd257f | ||
|
|
259985d328 | ||
|
|
2c4a9897ea | ||
|
|
2dbc404544 | ||
|
|
3d622a2c5a | ||
|
|
8b342c2ddb | ||
|
|
ca1f441f5a | ||
|
|
0fefead7d5 | ||
|
|
cb9bc6ad12 | ||
|
|
b6d01133c4 | ||
|
|
9ddaee9830 | ||
|
|
a5b54c50d1 | ||
|
|
5c84ffe5dc | ||
|
|
f178c8cce2 | ||
|
|
36bcafea98 | ||
|
|
95cd051a4f | ||
|
|
125c5523e6 | ||
|
|
374ed12811 | ||
|
|
b489e54da4 | ||
|
|
e928c78749 | ||
|
|
34dbed7733 | ||
|
|
6df3066b49 | ||
|
|
10c4b93b60 | ||
|
|
3fabd2975e | ||
|
|
217a7a34f8 | ||
|
|
5855ff0d27 | ||
|
|
3c4a9a05a0 | ||
|
|
9481d04a19 | ||
|
|
90c7bf4413 | ||
|
|
0b09f788c5 | ||
|
|
3045611452 | ||
|
|
0b3d028c2f | ||
|
|
a64be42f39 | ||
|
|
8405301500 | ||
|
|
07ed6a6416 | ||
|
|
970c9e70e4 | ||
|
|
f76f29f533 | ||
|
|
c3ecf2d84e | ||
|
|
a7dfb9cb97 | ||
|
|
225d46b228 | ||
|
|
f399ef8f69 | ||
|
|
c61db8c957 | ||
|
|
30afc095b9 | ||
|
|
755e7bc232 | ||
|
|
80e38fc430 | ||
|
|
581423a87c | ||
|
|
3634ca624d | ||
|
|
be33ac3c4f | ||
|
|
1cf79d8fbc | ||
|
|
acba67f67d | ||
|
|
1573738584 | ||
|
|
5376171538 | ||
|
|
90c41aceab | ||
|
|
6e10dc2893 | ||
|
|
87ce03e13e | ||
|
|
4db7577448 | ||
|
|
afdee44dd1 | ||
|
|
d929205bec | ||
|
|
0758d4f567 | ||
|
|
db0f228f4d | ||
|
|
a30f60c2ba | ||
|
|
1d13943caf | ||
|
|
e91e4042ba | ||
|
|
18720904f9 | ||
|
|
8d2aa1fc09 | ||
|
|
0e5155c85a | ||
|
|
3144a54c5b | ||
|
|
49362ce5ab | ||
|
|
13e629e17d | ||
|
|
8eb2f66b14 | ||
|
|
4fb0279f9a | ||
|
|
5d1006f05b | ||
|
|
eee76222bd | ||
|
|
4121bbc772 | ||
|
|
7926dd9aeb | ||
|
|
20ffcfb91e | ||
|
|
961bfcc481 | ||
|
|
eee50eef46 | ||
|
|
1329f3d2c7 | ||
|
|
0e812b911e | ||
|
|
28bd5f33c6 | ||
|
|
673b72f327 | ||
|
|
3fea8eb820 | ||
|
|
6e2e067d66 | ||
|
|
e09fe4acf0 | ||
|
|
0385662197 | ||
|
|
4ba222f19c | ||
|
|
6820a05efc | ||
|
|
0982e12a80 | ||
|
|
0536a2be33 | ||
|
|
24c5aae77f | ||
|
|
a972a52be4 | ||
|
|
f473c29430 | ||
|
|
7cd9768880 | ||
|
|
0a45a6fea9 | ||
|
|
9805ab8761 | ||
|
|
b4bb98b230 | ||
|
|
e11e141b5e | ||
|
|
83e199a0de | ||
|
|
4e87211d39 | ||
|
|
88208285a4 | ||
|
|
ae062586d7 | ||
|
|
fa72389c07 | ||
|
|
ea94cb8650 | ||
|
|
39d6ccd11c | ||
|
|
a62b225fe0 | ||
|
|
a72d1a13b6 | ||
|
|
60df499584 | ||
|
|
10204a4526 | ||
|
|
a5d63bc383 | ||
|
|
fcd276dccb | ||
|
|
fc66fba577 | ||
|
|
f1697313c0 | ||
|
|
6d8244ba5c | ||
|
|
102d5fdd7f | ||
|
|
2a86b06e0c | ||
|
|
7b4d6ba57e | ||
|
|
7be02731ee | ||
|
|
3cfa4f9cb7 | ||
|
|
10302f4bc9 | ||
|
|
b576ee300b | ||
|
|
77afcc2293 | ||
|
|
574e711f33 | ||
|
|
4cab77a57d | ||
|
|
6cbc9493c9 | ||
|
|
1d5f72f9ab | ||
|
|
b8e034e33c | ||
|
|
4f8c6e64fb | ||
|
|
39aadaa220 | ||
|
|
5c373f0d25 | ||
|
|
088c3984d8 | ||
|
|
3a61a7992a | ||
|
|
d694791d0f | ||
|
|
5e9ea4196c | ||
|
|
e7f000147b | ||
|
|
15e27e7e1d | ||
|
|
855d75f1bb | ||
|
|
e8f3a30a72 | ||
|
|
948e44d867 | ||
|
|
c0e671d506 | ||
|
|
2d895b52a4 | ||
|
|
4436a72b9f | ||
|
|
f1ce98eb07 | ||
|
|
418aa44960 | ||
|
|
b91850262d | ||
|
|
ed2dc101bb | ||
|
|
d89968cfa5 | ||
|
|
5f7c1ea4f4 | ||
|
|
e307524458 | ||
|
|
53cb4189d8 | ||
|
|
3efe3d63ce | ||
|
|
e44a05f18d | ||
|
|
d9574591fd | ||
|
|
55c27516b2 | ||
|
|
659ff866e1 | ||
|
|
f01de3a69d | ||
|
|
0c75cf6055 | ||
|
|
95613a1881 | ||
|
|
7bcbe5d791 | ||
|
|
bcc2ca7ce9 | ||
|
|
365ca9180f | ||
|
|
cfe1e7745f | ||
|
|
d0d9de8583 | ||
|
|
a304d75645 | ||
|
|
9f4f27d08f | ||
|
|
73530f59de | ||
|
|
6807dcbd5d | ||
|
|
e275ce6063 | ||
|
|
6352408d87 | ||
|
|
6870e03ffe | ||
|
|
d4641b45ac | ||
|
|
fad796f834 | ||
|
|
9e874b241a | ||
|
|
3f83361a7a | ||
|
|
a75b7b9be6 | ||
|
|
e4898bbbb3 | ||
|
|
132d5ec8cc | ||
|
|
59741ed04a | ||
|
|
fad6a406a1 | ||
|
|
4ee0731472 | ||
|
|
4fe530d257 | ||
|
|
d23eb291f7 | ||
|
|
3bbe54bb71 | ||
|
|
7aca726c33 | ||
|
|
3f1064b22d | ||
|
|
6fdbc9cdfa | ||
|
|
12b03518ee | ||
|
|
fcd3a86589 | ||
|
|
2ee671a1ae | ||
|
|
47a0642c4d | ||
|
|
db1cd3efbc | ||
|
|
f6803a2c52 | ||
|
|
f8d810a787 | ||
|
|
c8d865e26b | ||
|
|
e1c7705182 | ||
|
|
6aed2ec311 | ||
|
|
4c3f51cae3 | ||
|
|
f3088d1c49 | ||
|
|
be25226172 | ||
|
|
33d7e40e7c | ||
|
|
9eefd8839c | ||
|
|
d748e34d7e | ||
|
|
cefa8326e3 | ||
|
|
60f4937aae | ||
|
|
841e90dc46 | ||
|
|
81467a86cc | ||
|
|
498634fd13 | ||
|
|
d751805254 | ||
|
|
7c2e2a01c2 | ||
|
|
0b70c5225d | ||
|
|
b07d1b027c | ||
|
|
58801f8fb6 | ||
|
|
c589978e84 | ||
|
|
36f3c293f0 | ||
|
|
54417115f3 | ||
|
|
4006e4045c | ||
|
|
bdf57b5203 | ||
|
|
1d27ffbffb | ||
|
|
c36b5c77fc | ||
|
|
ac5cd90cc6 | ||
|
|
e0eb8c83e2 | ||
|
|
b8f513fffe | ||
|
|
7d4dd9c699 | ||
|
|
a254b996e0 | ||
|
|
6b9f96697b | ||
|
|
dc5eeb8476 | ||
|
|
7d40105023 | ||
|
|
3d73dc2fb7 | ||
|
|
94f217f4d7 | ||
|
|
00319c1fe2 | ||
|
|
67ac5a9c6a | ||
|
|
79b3b0fffc | ||
|
|
ab6a29191d | ||
|
|
636350c395 | ||
|
|
c076717133 | ||
|
|
943a438a6c | ||
|
|
a104693f97 | ||
|
|
8283c89614 | ||
|
|
c9790d7bb8 | ||
|
|
80ec16b9bd | ||
|
|
479945455b | ||
|
|
4512854c2a | ||
|
|
70950b8267 | ||
|
|
eec96b8549 | ||
|
|
30961babde | ||
|
|
a00c530f36 | ||
|
|
0af1e06c57 | ||
|
|
c0d52ef905 | ||
|
|
59d9840d7b | ||
|
|
9a2ffc1d7c | ||
|
|
c8fcfcd28c | ||
|
|
ac81d38acc | ||
|
|
9bc4b74888 | ||
|
|
2ec71c9942 | ||
|
|
343da4878d | ||
|
|
45f32ba62c | ||
|
|
f157e6a9f5 | ||
|
|
33485024af | ||
|
|
90efb967fe | ||
|
|
5fa62151f6 | ||
|
|
3a55985b20 | ||
|
|
4a0411b7fc | ||
|
|
7094675d5e | ||
|
|
cf7ae90097 | ||
|
|
53b19dad87 | ||
|
|
b10caecbba | ||
|
|
60d64ad2a6 | ||
|
|
fd71200284 | ||
|
|
de13ad1cd5 | ||
|
|
97bd617566 | ||
|
|
2583b38a17 | ||
|
|
e1f71cae37 | ||
|
|
d78ecdc203 | ||
|
|
0dd540a048 | ||
|
|
d8536c20b0 | ||
|
|
1a5bc2ddfe | ||
|
|
61c1232690 | ||
|
|
2554165963 | ||
|
|
fc4778159c | ||
|
|
d2105a7169 | ||
|
|
19ec14e4c2 | ||
|
|
3dbef1400c | ||
|
|
4ca0453cff | ||
|
|
fc07979966 | ||
|
|
7dda2df54b | ||
|
|
0d95636b0f | ||
|
|
9ad424c537 | ||
|
|
8c57dde0a6 | ||
|
|
31bbf3cfd5 | ||
|
|
9d404b6679 | ||
|
|
dc274aed48 | ||
|
|
51eda2ef74 | ||
|
|
f30f6378ac | ||
|
|
3b09276395 | ||
|
|
dbdd6c701b | ||
|
|
eb094eaebb | ||
|
|
9177f4b47d | ||
|
|
d4446b2605 | ||
|
|
356db288ad | ||
|
|
8a6690b6df | ||
|
|
1281059076 | ||
|
|
4622c86ae1 | ||
|
|
5c6b741dc4 | ||
|
|
25cedff47a | ||
|
|
5971802eb9 | ||
|
|
b40ff9ef66 | ||
|
|
3b2e54a156 | ||
|
|
b3f3cd2ffd | ||
|
|
288b46947d | ||
|
|
98add4b958 | ||
|
|
99b1c5a456 | ||
|
|
305fc52e73 | ||
|
|
425b209414 | ||
|
|
58b016a9c0 | ||
|
|
6c17107f39 | ||
|
|
8b153121ac | ||
|
|
4fc1169fa3 | ||
|
|
27dde4e70d | ||
|
|
10cbe25f17 | ||
|
|
14edd948ac | ||
|
|
386b54cf6a | ||
|
|
c068366ae2 | ||
|
|
bc85b3599e | ||
|
|
4d299f5b17 | ||
|
|
224c3eb99c | ||
|
|
4e537ac4d8 | ||
|
|
fe124310de | ||
|
|
19f25e45bb | ||
|
|
1fa4be9ebb | ||
|
|
f4e74065ec | ||
|
|
f07cd08789 | ||
|
|
28bddb713b | ||
|
|
0b86e0ae41 | ||
|
|
da058197c7 | ||
|
|
cf0d7067eb | ||
|
|
baa50069cf | ||
|
|
aab0bf369d | ||
|
|
07c13d84be | ||
|
|
47982d092b | ||
|
|
ef63f11bbb | ||
|
|
46e0656fe9 | ||
|
|
bdc2decd06 | ||
|
|
69204e3998 | ||
|
|
4419c20f33 | ||
|
|
f9ffa9c387 | ||
|
|
b402bd6c0e | ||
|
|
4f7c96326d | ||
|
|
ad36bd23c8 | ||
|
|
86fe78ba95 | ||
|
|
9678f1d1f2 | ||
|
|
d0d6ddd3c1 | ||
|
|
6dcd2e4b03 | ||
|
|
b9c58adae6 | ||
|
|
b7893c2820 | ||
|
|
fd1de0ef85 | ||
|
|
9c1fba3d79 | ||
|
|
1185bd5d86 | ||
|
|
70616de215 | ||
|
|
acf564756e | ||
|
|
616b9af5ed | ||
|
|
38b20987fb | ||
|
|
5f6d3078b7 | ||
|
|
2e0a8ee657 | ||
|
|
659a1dbe53 | ||
|
|
753124ec27 | ||
|
|
73dab9ebf4 | ||
|
|
716d6aca9f | ||
|
|
ec761802eb | ||
|
|
1a782a6938 | ||
|
|
63d693b388 | ||
|
|
5b1563b851 | ||
|
|
d794c4c81f | ||
|
|
70f0d8d558 | ||
|
|
2c50adb6f2 | ||
|
|
71c4d60bbf | ||
|
|
798faff7b2 | ||
|
|
94ed77353e | ||
|
|
a7159ecf1d | ||
|
|
b65f562c61 | ||
|
|
9918b4ee42 | ||
|
|
069781bcdd | ||
|
|
3596a5588d | ||
|
|
69890972bc | ||
|
|
313dd0cc6a | ||
|
|
dc30e4f8e0 | ||
|
|
a7b3ef34d8 | ||
|
|
f0b728a71b | ||
|
|
dfce6564a1 | ||
|
|
3b924ff1e6 | ||
|
|
15bc01576a | ||
|
|
19f4f6e1cc | ||
|
|
ea4e25ea28 | ||
|
|
fd6ea77f7b | ||
|
|
1b382e4391 | ||
|
|
091aba7aad | ||
|
|
49c151c1b4 | ||
|
|
3ffc4fad6d | ||
|
|
73dc6b768f | ||
|
|
413d8e6662 | ||
|
|
5d2ce27ea8 | ||
|
|
1d3a1a1345 | ||
|
|
9adf764af8 | ||
|
|
8ef6827bd9 | ||
|
|
79d011bd5c | ||
|
|
430ce9c136 | ||
|
|
fe7afe3dec | ||
|
|
8922cc72fc | ||
|
|
200181623e | ||
|
|
ab24afa31d | ||
|
|
b38fa395ce | ||
|
|
62475f9bcf | ||
|
|
674d6389b7 | ||
|
|
7ae98ca9fe | ||
|
|
13ed55ac10 | ||
|
|
fce020f4dd | ||
|
|
8c2376457b | ||
|
|
1dde832e31 | ||
|
|
8c86ae2461 | ||
|
|
695abb481d | ||
|
|
7f769e00b9 | ||
|
|
b2e4544b52 | ||
|
|
7d1ee33e1f | ||
|
|
2ade16a87a | ||
|
|
67fd2b4ac0 | ||
|
|
26294a5742 | ||
|
|
db8371d3af | ||
|
|
f308496ef9 | ||
|
|
a0507bd14d | ||
|
|
92d95db40b | ||
|
|
2309d30909 | ||
|
|
0f023113ec | ||
|
|
b3e5f09c83 | ||
|
|
2f5a4f63b6 | ||
|
|
85515079d6 | ||
|
|
a9123d2966 | ||
|
|
efdd8daa01 | ||
|
|
8f2d69b7f7 | ||
|
|
18ee6ecf80 | ||
|
|
5a3669cbe7 | ||
|
|
a1c78b3a44 | ||
|
|
4e0ea5f941 | ||
|
|
c425313ae6 | ||
|
|
4736921d05 | ||
|
|
45aedd8111 | ||
|
|
445f06f4b3 | ||
|
|
b8fbc837dc | ||
|
|
72bcc16a46 | ||
|
|
729640d6ec | ||
|
|
fcdb9e39c6 | ||
|
|
953adadd62 | ||
|
|
a9fa1fb66b | ||
|
|
8c7547ab03 | ||
|
|
e94fed0137 | ||
|
|
353a8ff768 | ||
|
|
3442081d20 | ||
|
|
67f14d6a62 | ||
|
|
9e1980f843 | ||
|
|
495e0ce89b | ||
|
|
76fa97e0a0 | ||
|
|
cc49948a59 | ||
|
|
5adcbb775d | ||
|
|
02ed3e4e8b | ||
|
|
f9ff9af094 | ||
|
|
529b8c2183 | ||
|
|
fa3ae62254 | ||
|
|
71ccbb9336 | ||
|
|
9f22a6d26d | ||
|
|
4db3bd7423 | ||
|
|
4393b0c80d | ||
|
|
c217828c18 | ||
|
|
a502f69b34 | ||
|
|
6f3e0f5162 | ||
|
|
0e44cae1e3 | ||
|
|
99b0defcf7 | ||
|
|
c6be74ac5b | ||
|
|
84af5a277e | ||
|
|
266e3ab270 | ||
|
|
1da5a0a4ca | ||
|
|
2c17d450dd | ||
|
|
41c4cbe3a6 | ||
|
|
c7dfaac61a | ||
|
|
36018fe570 | ||
|
|
e8b284a89c | ||
|
|
a8ea9a8dbe | ||
|
|
78f26a3689 | ||
|
|
671db12336 | ||
|
|
a5dc3bcc75 | ||
|
|
54819eb367 | ||
|
|
71ec4ad403 | ||
|
|
8644fb66c0 | ||
|
|
71b5d4fe5a | ||
|
|
abedc0be80 | ||
|
|
63072205d6 | ||
|
|
0ac7d9829a | ||
|
|
7989ca7504 | ||
|
|
56118a7142 | ||
|
|
93d8f66afc | ||
|
|
ea0e80b12b | ||
|
|
cfdb5456aa | ||
|
|
5baeadbe92 | ||
|
|
8a57a32233 | ||
|
|
af954a0578 | ||
|
|
b6bbd6899e | ||
|
|
f7edc853da | ||
|
|
820d0cde86 | ||
|
|
2249bbb0f5 | ||
|
|
4a37a6f497 | ||
|
|
0ce742fa8a | ||
|
|
86725b1ef1 | ||
|
|
7a3ec4194e | ||
|
|
53120faeba | ||
|
|
c9ca331d30 | ||
|
|
cce3749563 | ||
|
|
f389b1ae93 | ||
|
|
a275ce8738 | ||
|
|
03dfa19c0e | ||
|
|
b5087002d2 | ||
|
|
4df5cdd312 | ||
|
|
73867d87d7 | ||
|
|
76009ca6eb | ||
|
|
935d26f956 | ||
|
|
8d931e290a | ||
|
|
1cd846fbf1 | ||
|
|
c284d5d2f4 | ||
|
|
713a794e9a | ||
|
|
e1cc09a837 | ||
|
|
3ebb35ac6a | ||
|
|
3f377d4efc | ||
|
|
881d265579 | ||
|
|
70339423d0 | ||
|
|
a5f3359d32 | ||
|
|
13f00edefd | ||
|
|
97b5526cc1 | ||
|
|
3901422a54 | ||
|
|
2db2136117 | ||
|
|
fc40ed52f3 | ||
|
|
b2081dcbc9 | ||
|
|
fd42549733 | ||
|
|
07d002da48 | ||
|
|
dc51bc39ab | ||
|
|
411932c96b | ||
|
|
1eb3f449e2 | ||
|
|
188e7910dd | ||
|
|
5893564f46 | ||
|
|
bdf77b2782 | ||
|
|
ece5cc7dd5 | ||
|
|
db18b0f8e2 | ||
|
|
94cd2c0599 | ||
|
|
87225e64fa | ||
|
|
fffb97ea8d | ||
|
|
57b381311c | ||
|
|
121db63778 | ||
|
|
dcf52085ae | ||
|
|
2d339ba00a | ||
|
|
422e19724a | ||
|
|
f25f4f7dc8 | ||
|
|
c8fca3d63f | ||
|
|
fd1ee23adc | ||
|
|
a540165280 |
14
.gitattributes
vendored
14
.gitattributes
vendored
@@ -1 +1,15 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
*.cs text eol=crlf
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
*.rc diff
|
||||
|
||||
33
.github/ISSUE_TEMPLATE/bug_report.md
vendored
33
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,8 +1,8 @@
|
||||
---
|
||||
name: Bug report
|
||||
name: 🐛 Bug report
|
||||
about: Report errors or unexpected behavior
|
||||
title: ''
|
||||
labels: ''
|
||||
labels: Issue-Bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
@@ -12,26 +12,27 @@ assignees: ''
|
||||
Instead, send dumps/traces to secure@microsoft.com, referencing this GitHub issue.
|
||||
-->
|
||||
|
||||
# Environment
|
||||
## ℹ Computer information
|
||||
|
||||
```
|
||||
Windows build number: [run "ver" at a command prompt]
|
||||
PowerToys version:
|
||||
PowerToy module for which you are reporting the bug (if applicable):
|
||||
```
|
||||
- PowerToys version:
|
||||
- PowerToy Utility:
|
||||
- Running PowerToys as Admin:
|
||||
- Windows build number: [run "winver"]
|
||||
|
||||
# Steps to reproduce
|
||||
## 📝 Provide detailed reproduction steps (if any)
|
||||
|
||||
<!-- A description of how to trigger this bug. -->
|
||||
1. …
|
||||
2. …
|
||||
3. …
|
||||
|
||||
# Expected behavior
|
||||
### ✔️ Expected result
|
||||
|
||||
<!-- A description of what you're expecting, possibly containing screenshots or reference material. -->
|
||||
_What is the expected result of the above steps?_
|
||||
|
||||
# Actual behavior
|
||||
### ❌ Actual result
|
||||
|
||||
<!-- What's actually happening? -->
|
||||
_What is the actual result of the above steps?_
|
||||
|
||||
# Screenshots
|
||||
## 📷 Screenshots
|
||||
|
||||
<!-- If applicable, add screenshots to help explain your problem. -->
|
||||
_Are there any useful screenshots? WinKey+Shift+S and then just paste them directly into the form_
|
||||
|
||||
15
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
15
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: "\U0001F4F7 VideoConference"
|
||||
url: https://github.com/microsoft/PowerToys/issues/6246
|
||||
about: Report Bug for the VideoConference Power Toy
|
||||
- name: "\U0001F6A8 Microsoft Security Response Center (MSRC)"
|
||||
url: https://msrc.microsoft.com/create-report
|
||||
about: Report security bugs
|
||||
- name: "\U0001F4DA PowerToys user documentation"
|
||||
url: https://github.com/microsoft/PowerToys/wiki
|
||||
about: Documentation for users of PowerToys
|
||||
- name: "\U0001F4DA PowerToys dev documentation"
|
||||
url: https://github.com/microsoft/PowerToys/tree/master/doc/devdocs
|
||||
about: Documentation for people interested in developing for PowerToys
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
---
|
||||
name: Documentation Issue
|
||||
name: "\U0001F4DA Documentation Issue"
|
||||
about: Report issues in our documentation
|
||||
title: ''
|
||||
labels: ''
|
||||
labels: Issue-Docs
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Briefly describe which document needs to be corrected and why. -->
|
||||
|
||||
## 📝 Provide a description of requested docs changes
|
||||
|
||||
_What is the purpose and what should be changed?_
|
||||
|
||||
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,21 +1,16 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
name: "⭐ Feature request"
|
||||
about: Propose something new.
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
# Summary of the new feature/enhancement
|
||||
## 📝 Provide a description of the new feature
|
||||
|
||||
<!--
|
||||
A clear and concise description of what the problem is that the new feature would solve.
|
||||
Describe why and how a user would use this new functionality (if applicable).
|
||||
-->
|
||||
_What is the expected behavior of the proposed feature? What is the scenario this would be used?_
|
||||
|
||||
# Proposed technical implementation details (optional)
|
||||
---
|
||||
|
||||
<!--
|
||||
A clear and concise description of what you want to happen.
|
||||
-->
|
||||
If you'd like to see this feature implemented, add a 👍 reaction to this post.
|
||||
|
||||
15
.github/pull_request_template.md
vendored
15
.github/pull_request_template.md
vendored
@@ -1,19 +1,18 @@
|
||||
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
|
||||
## Summary of the Pull Request
|
||||
|
||||
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
|
||||
## References
|
||||
_What is this about?_
|
||||
|
||||
<!-- Please review the items on the PR checklist before submitting-->
|
||||
## PR Checklist
|
||||
* [ ] Closes #xxx
|
||||
* [ ] Applies to #xxx
|
||||
* [ ] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/PowerToys) and sign the CLA
|
||||
* [ ] Tests added/passed
|
||||
* [ ] Requires documentation to be updated
|
||||
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
|
||||
|
||||
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
|
||||
## Detailed Description of the Pull Request / Additional comments
|
||||
## Info on Pull Request
|
||||
|
||||
_What does this include?_
|
||||
|
||||
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
|
||||
## Validation Steps Performed
|
||||
|
||||
_How does someone test & validate?_
|
||||
|
||||
14
.gitignore
vendored
14
.gitignore
vendored
@@ -301,6 +301,8 @@ __pycache__/
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
ImageResizer/tools/**
|
||||
!ImageResizer/tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
@@ -328,3 +330,15 @@ ASALocalRun/
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Temp build files
|
||||
src/settings/settings-html/200.html
|
||||
src/settings/settings-html/404.html
|
||||
|
||||
# Temp telemetry files.
|
||||
src/common/Telemetry/*.etl
|
||||
|
||||
# Don't ignore MergeModules
|
||||
!**/MergeModules/Release/
|
||||
!**/MergeModules/Debug/
|
||||
/src/modules/previewpane/SvgThumbnailProvider/$(SolutionDir)$(Platform)/$(Configuration)/modules/FileExplorerPreview/SvgThumbnailProvider.xml
|
||||
|
||||
7
.gitmodules
vendored
Normal file
7
.gitmodules
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
[submodule "deps/spdlog"]
|
||||
path = deps/spdlog
|
||||
url = https://github.com/gabime/spdlog.git
|
||||
|
||||
[submodule "deps/cxxopts"]
|
||||
path = deps/cxxopts
|
||||
url = https://github.com/jarro2783/cxxopts.git
|
||||
10
.pipelines/build-bootstrapper.cmd
Normal file
10
.pipelines/build-bootstrapper.cmd
Normal file
@@ -0,0 +1,10 @@
|
||||
cd /D "%~dp0"
|
||||
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.18362.0
|
||||
pushd .
|
||||
cd ..
|
||||
set SolutionDir=%cd%
|
||||
popd
|
||||
SET IsPipeline=1
|
||||
call msbuild ../installer/PowerToysBootstrapper/PowerToysBootstrapper.sln /p:Configuration=Release /p:Platform=x64 /p:CIBuild=true || exit /b 1
|
||||
|
||||
5
.pipelines/build-installer.cmd
Normal file
5
.pipelines/build-installer.cmd
Normal file
@@ -0,0 +1,5 @@
|
||||
cd /D "%~dp0"
|
||||
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.18362.0
|
||||
SET IsPipeline=1
|
||||
call msbuild ../installer/PowerToysSetup.sln /p:Configuration=Release /p:Platform=x64 /p:CIBuild=true || exit /b 1
|
||||
33
.pipelines/build-localization.cmd
Normal file
33
.pipelines/build-localization.cmd
Normal file
@@ -0,0 +1,33 @@
|
||||
@echo off
|
||||
rem This script will fail to run unless you have the appropriate permissions
|
||||
|
||||
cd /D "%~dp0"
|
||||
|
||||
echo Preparing localization build...
|
||||
|
||||
setlocal
|
||||
|
||||
rem In this sample, the repo root is identical to the script directory path. Adjust the value of the RepoRoot variable accordingly based on your environment.
|
||||
rem Again, ensure the RepoRoot variable is set to the real repo root location, otherwise the localization toolset wouldn't work as intended.
|
||||
rem Note that the resolved %~dp0 ends with \.
|
||||
set RepoRootWithoutBackslash=%~dp0..
|
||||
set RepoRoot=%RepoRootWithoutBackslash%\
|
||||
set OutDir=%RepoRoot%out
|
||||
set NUGET_PACKAGES=%RepoRoot%packages
|
||||
set LocalizationXLocPkgVer=2.0.0
|
||||
|
||||
echo Running localization build...
|
||||
|
||||
set XLocPath=%NUGET_PACKAGES%\Localization.XLoc.%LocalizationXLocPkgVer%
|
||||
set LocProjectDirectory=%RepoRootWithoutBackslash%
|
||||
|
||||
rem Run the localization tool on all LocProject.json files in the src directory and it's subdirectories (directory format must not end with \)
|
||||
dotnet "%XLocPath%\tools\netcore\Microsoft.Localization.XLoc.dll" /f "%LocProjectDirectory%"
|
||||
|
||||
echo Localization build finished with exit code '%errorlevel%'.
|
||||
|
||||
rem Move UWP resource files to correct file paths as per file path expected by UWP project
|
||||
cd %RepoRootWithoutBackslash%
|
||||
powershell -NonInteractive -executionpolicy Unrestricted ".\tools\localization\move_uwp_resources.ps1"
|
||||
|
||||
exit /b %errorlevel%
|
||||
@@ -1,2 +1,6 @@
|
||||
cd /D "%~dp0"
|
||||
dotnet build --no-restore ..\PowerToys.sln || exit /b 1
|
||||
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.18362.0
|
||||
call msbuild -m ../PowerToys.sln /p:Configuration=Release /p:Platform=x64 /p:CIBuild=true || exit /b 1
|
||||
SET PTRoot=..
|
||||
call "..\installer\PowerToysSetup\publish.cmd"
|
||||
|
||||
@@ -3,6 +3,8 @@ trigger:
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
- dev/build-features
|
||||
- dev/PowerLauncher
|
||||
paths:
|
||||
exclude:
|
||||
- doc/*
|
||||
@@ -13,6 +15,8 @@ pr:
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
- dev/build-features
|
||||
- dev/PowerLauncher
|
||||
|
||||
# 0.0.yyMM.dd##
|
||||
# 0.0.1904.0900
|
||||
@@ -1,7 +1,7 @@
|
||||
parameters:
|
||||
configuration: 'Release'
|
||||
platform: ''
|
||||
additionalBuildArguments: ''
|
||||
additionalBuildArguments: '-m /p:CIBuild=true'
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}${{ parameters.configuration }}
|
||||
@@ -10,8 +10,10 @@ jobs:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
pool: { vmImage: windows-2019 }
|
||||
|
||||
timeoutInMinutes: 120
|
||||
strategy:
|
||||
maxParallel: 10
|
||||
steps:
|
||||
- template: build-powertoys-steps.yml
|
||||
parameters:
|
||||
additionalBuildArguments: ${{ parameters.additionalBuildArguments }}
|
||||
additionalBuildArguments: ${{ parameters.additionalBuildArguments }}
|
||||
108
.pipelines/ci/templates/build-powertoys-steps.yml
Normal file
108
.pipelines/ci/templates/build-powertoys-steps.yml
Normal file
@@ -0,0 +1,108 @@
|
||||
parameters:
|
||||
additionalBuildArguments: ''
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
submodules: true
|
||||
clean: true
|
||||
|
||||
- task: NuGetToolInstaller@0
|
||||
displayName: Ensure NuGet 5.5.0
|
||||
inputs:
|
||||
versionSpec: 5.5.0
|
||||
|
||||
- task: VisualStudioTestPlatformInstaller@1
|
||||
displayName: Ensure VSTest Platform
|
||||
|
||||
- task: NuGetCommand@2
|
||||
displayName: Restore NuGet packages for PowerToys.sln
|
||||
inputs:
|
||||
command: restore
|
||||
feedsToUse: config
|
||||
configPath: NuGet.config
|
||||
restoreSolution: PowerToys.sln
|
||||
restoreDirectory: '$(Build.SourcesDirectory)\packages'
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: 'Build PowerToys.sln'
|
||||
inputs:
|
||||
solution: '**\PowerToys.sln'
|
||||
vsVersion: 16.0
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
msbuildArgs: ${{ parameters.additionalBuildArguments }}
|
||||
maximumCpuCount: true
|
||||
|
||||
- task: NuGetCommand@2
|
||||
displayName: Restore NuGet packages for PowerToysSetup.sln
|
||||
inputs:
|
||||
command: restore
|
||||
feedsToUse: config
|
||||
configPath: NuGet.config
|
||||
restoreSolution: installer\PowerToysSetup.sln
|
||||
restoreDirectory: '$(Build.SourcesDirectory)\installer\packages'
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: 'Build PowerToysSetup.sln'
|
||||
inputs:
|
||||
solution: '**\installer\PowerToysSetup.sln'
|
||||
vsVersion: 16.0
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
msbuildArgs: ${{ parameters.additionalBuildArguments }}
|
||||
maximumCpuCount: true
|
||||
|
||||
- task: NuGetCommand@2
|
||||
displayName: Restore NuGet packages for PowerToysBootstrapper.sln
|
||||
inputs:
|
||||
command: restore
|
||||
feedsToUse: config
|
||||
configPath: NuGet.config
|
||||
restoreSolution: installer\PowerToysBootstrapper\PowerToysBootstrapper.sln
|
||||
restoreDirectory: '$(Build.SourcesDirectory)\installer\PowerToysBootstrapper\packages'
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: 'Build PowerToysBootstrapper.sln'
|
||||
inputs:
|
||||
solution: '**\installer\PowerToysBootstrapper\PowerToysBootstrapper.sln'
|
||||
vsVersion: 16.0
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
msbuildArgs: ${{ parameters.additionalBuildArguments }}
|
||||
maximumCpuCount: true
|
||||
|
||||
|
||||
# directly not doing WinAppDriver testing
|
||||
- task: VSTest@2
|
||||
displayName: 'Run .Net Core Tests'
|
||||
inputs:
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
testSelector: 'testAssemblies'
|
||||
testAssemblyVer2: |
|
||||
**\Microsoft.Plugin.Folder.UnitTest.dll
|
||||
**\Microsoft.Plugin.Program.UnitTests.dll
|
||||
**\Microsoft.Plugin.Calculator.UnitTest.dll
|
||||
**\Microsoft.Plugin.Uri.UnitTests.dll
|
||||
**\Wox.Test.dll
|
||||
**\*Microsoft.PowerToys.Settings.UI.UnitTests.dll
|
||||
**\UnitTest-ColorPickerUI.dll
|
||||
!**\obj\**
|
||||
# .NetFramework assemblies
|
||||
- task: VSTest@2
|
||||
displayName: 'Run .Net Framework Tests'
|
||||
inputs:
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
testSelector: 'testAssemblies'
|
||||
testAssemblyVer2: |
|
||||
**\ImageResizer.Test.dll
|
||||
**\KeyboardManagerTest.dll
|
||||
**\UnitTests-CommonLib.dll
|
||||
**\PreviewPaneUnitTests.dll #this is the markdown tests
|
||||
**\UnitTests-PreviewHandlerCommon.dll
|
||||
**\UnitTests-SvgPreviewHandler.dll
|
||||
**\powerpreviewTest.dll
|
||||
!**\obj\**
|
||||
# **\PowerRenameUnitTests.dll
|
||||
4
.pipelines/packages.config
Normal file
4
.pipelines/packages.config
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.PowerToys.Telemetry" version="2.0" />
|
||||
</packages>
|
||||
21
.pipelines/pipeline.user.windows.buddy.yml
Normal file
21
.pipelines/pipeline.user.windows.buddy.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
static_analysis_options:
|
||||
fxcop_options:
|
||||
disable_tool_scan: false
|
||||
policheck_options:
|
||||
fail_on_error: true
|
||||
moderncop_options:
|
||||
fail_on_error: true
|
||||
files_to_scan:
|
||||
- from: 'src'
|
||||
exclude:
|
||||
- '**/just.config.js'
|
||||
- '**/webpack.config.js'
|
||||
- '**/webpack.serve.config.js'
|
||||
- '**/dist/bundle.js'
|
||||
binskim_options:
|
||||
disable_tool_scan: false
|
||||
files_to_scan:
|
||||
- from: 'installer/packages'
|
||||
exclude:
|
||||
- 'WiX.3.11.1/**/*.dll'
|
||||
- 'Wix.3.11.1/**/*.exe'
|
||||
@@ -2,42 +2,180 @@ environment:
|
||||
host:
|
||||
os: 'windows'
|
||||
flavor: 'server'
|
||||
version: '2016'
|
||||
version: '2019'
|
||||
runtime:
|
||||
provider: 'appcontainer'
|
||||
image: 'cdpxwinrs4test.azurecr.io/global/vse2017u7-external-azsdk-mobile-ext-win1803:latest-nodetools'
|
||||
source_mode: 'link'
|
||||
image: 'cdpxwin1809.azurecr.io/global/vse2019:latest'
|
||||
source_mode: 'map'
|
||||
|
||||
version:
|
||||
name: 'PowerToys'
|
||||
major: 1
|
||||
minor: 0
|
||||
|
||||
signing_options:
|
||||
profile: 'azure'
|
||||
profile: 'external_distribution'
|
||||
|
||||
package_sources:
|
||||
nuget:
|
||||
feeds:
|
||||
'Nuget': 'https://api.nuget.org/v3/index.json'
|
||||
'Toolset': 'https://msazure.pkgs.visualstudio.com/_packaging/Toolset/nuget/v3/index.json'
|
||||
'CloudES-CDP': 'https://cloudes.pkgs.visualstudio.com/_packaging/CDP/nuget/v3/index.json'
|
||||
'CloudES-Internal': 'https://cloudes.pkgs.visualstudio.com/_packaging/Internal/nuget/v3/index.json'
|
||||
'MsNugetMirror': 'https://msazure.pkgs.visualstudio.com/_packaging/MsNugetMirror/nuget/v3/index.json'
|
||||
'NugetMirror': 'https://msazure.pkgs.visualstudio.com/_packaging/NugetMirror/nuget/v3/index.json'
|
||||
'CorextMirror': 'https://msazure.pkgs.visualstudio.com/_packaging/CorextMirror/nuget/v3/index.json'
|
||||
'Official': 'https://msazure.pkgs.visualstudio.com/_packaging/Official/nuget/v3/index.json'
|
||||
'Toolset': 'https://msazure.pkgs.visualstudio.com/_packaging/Toolset/nuget/v3/index.json'
|
||||
'AzureCXP': 'https://msazure.pkgs.visualstudio.com/_packaging/AzureCXP/nuget/v3/index.json'
|
||||
'PipelineBuildSupplement': 'https://msazure.pkgs.visualstudio.com/_packaging/PipelineBuildSupplement/nuget/v3/index.json'
|
||||
|
||||
restore:
|
||||
commands:
|
||||
- !!defaultcommand
|
||||
name: 'Restore CSharp'
|
||||
name: 'Restore Power Toys Telemetry'
|
||||
command: '.pipelines\restore-telemetry.cmd'
|
||||
- !!defaultcommand
|
||||
name: 'Restore Power Toys'
|
||||
command: '.pipelines\restore.cmd'
|
||||
|
||||
- !!defaultcommand
|
||||
name: 'Restore Installer'
|
||||
command: '.pipelines\restore-installer.cmd'
|
||||
- !!defaultcommand
|
||||
name: 'Restore Localization packages'
|
||||
command: '.pipelines\restore-localization.cmd'
|
||||
|
||||
|
||||
build:
|
||||
commands:
|
||||
# Localize the files before the Build PowerToys step to generate translated resx files from the lcl files
|
||||
- !!buildcommand
|
||||
name: 'Build CSharp'
|
||||
command: '.pipelines\build.cmd'
|
||||
name: 'Localize Power Toys'
|
||||
command: '.pipelines\build-localization.cmd'
|
||||
artifacts:
|
||||
- from: '**\bin'
|
||||
to: 'Build_Output'
|
||||
- from: 'out\loc'
|
||||
to: 'loc'
|
||||
include:
|
||||
- '**/*'
|
||||
- !!buildcommand
|
||||
name: 'Build Power Toys'
|
||||
command: '.pipelines\build.cmd'
|
||||
artifacts:
|
||||
- to: 'Symbols'
|
||||
include:
|
||||
- 'x64/**/*.pdb'
|
||||
exclude:
|
||||
- 'x64/Release/obj/**/*.pdb'
|
||||
- from: 'x64/Release'
|
||||
to: 'Build_Output'
|
||||
include:
|
||||
- 'action_runner.exe'
|
||||
- 'modules\ColorPicker\ColorPicker.dll'
|
||||
- 'modules\ColorPicker\ColorPicker.exe'
|
||||
- '**\*.resources.dll'
|
||||
- 'modules\FancyZones\fancyzones.dll'
|
||||
- 'modules\FancyZones\FancyZonesEditor.exe'
|
||||
- 'modules\FileExplorerPreview\MarkdownPreviewHandler.dll'
|
||||
- 'modules\FileExplorerPreview\powerpreview.dll'
|
||||
- 'modules\FileExplorerPreview\PreviewHandlerCommon.dll'
|
||||
- 'modules\FileExplorerPreview\SvgPreviewHandler.dll'
|
||||
- 'modules\FileExplorerPreview\SVGThumbnailProvider.dll'
|
||||
- 'modules\ImageResizer\ImageResizer.exe'
|
||||
- 'modules\ImageResizer\ImageResizerExt.dll'
|
||||
- 'modules\KeyboardManager\KeyboardManager.dll'
|
||||
- 'modules\launcher\Microsoft.PowerToys.Settings.UI.Lib.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Calculator\Microsoft.Plugin.Calculator.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Calculator\Wox.Infrastructure.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Calculator\Wox.Plugin.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Folder\Microsoft.Plugin.Folder.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Folder\Wox.Infrastructure.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Folder\Wox.Plugin.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Indexer\Microsoft.Plugin.Indexer.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Indexer\Wox.Infrastructure.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Program\Microsoft.Plugin.Program.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Program\Wox.Infrastructure.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Program\Wox.Plugin.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Shell\Microsoft.Plugin.Shell.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Shell\Wox.Infrastructure.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.Shell\Wox.Plugin.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\Microsoft.Plugin.WindowWalker.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\Wox.Infrastructure.dll'
|
||||
- 'modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\Wox.Plugin.dll'
|
||||
- 'modules\launcher\PowerLauncher.dll'
|
||||
- 'modules\launcher\PowerLauncher.exe'
|
||||
- 'modules\launcher\PowerLauncher.Telemetry.dll'
|
||||
- 'modules\launcher\PowerLauncher.UI.exe'
|
||||
- 'modules\launcher\PowerToysInterop.dll'
|
||||
- 'modules\launcher\Telemetry.dll'
|
||||
- 'modules\launcher\Wox.Core.dll'
|
||||
- 'modules\launcher\Wox.dll'
|
||||
- 'modules\launcher\Wox.Infrastructure.dll'
|
||||
- 'modules\launcher\Wox.Plugin.dll'
|
||||
- 'modules\Microsoft.Launcher.dll'
|
||||
- 'modules\PowerRename\PowerRenameExt.dll'
|
||||
- 'modules\ShortcutGuide\ShortcutGuide.dll'
|
||||
- 'Notifications.dll'
|
||||
- 'os-detection.dll'
|
||||
- 'PowerToys.exe'
|
||||
- 'PowerToysInterop.dll'
|
||||
- 'PowerToysSettings.exe'
|
||||
- 'SettingsUIRunner\Microsoft.PowerToys.Settings.UI.exe'
|
||||
- 'SettingsUIRunner\Microsoft.PowerToys.Settings.UI.Lib.dll'
|
||||
- 'SettingsUIRunner\Microsoft.PowerToys.Settings.UI.Runner.dll'
|
||||
- 'SettingsUIRunner\Microsoft.PowerToys.Settings.UI.Runner.exe'
|
||||
- 'SettingsUIRunner\PowerToysInterop.dll'
|
||||
- 'SettingsUIRunner\Telemetry.dll'
|
||||
signing_options:
|
||||
sign_inline: true # This does signing a soon as this command completes
|
||||
- !!buildcommand
|
||||
name: 'Build Power Toys Installer'
|
||||
command: '.pipelines\build-installer.cmd'
|
||||
artifacts:
|
||||
- from: 'installer\PowerToysSetup\x64\Release'
|
||||
to: 'Build_Installer_Output'
|
||||
include:
|
||||
- 'PowerToysSetup-*.msi'
|
||||
signing_options:
|
||||
sign_inline: true # This does signing a soon as this command completes
|
||||
- !!buildcommand
|
||||
name: 'Build Power Toys Bootstrapper'
|
||||
command: '.pipelines\build-bootstrapper.cmd'
|
||||
artifacts:
|
||||
- to: 'Symbols'
|
||||
include:
|
||||
- 'installer\PowerToysBootstrapper\x64\Release\PowerToysSetup-*.pdb'
|
||||
- from: 'installer\PowerToysBootstrapper\x64\Release'
|
||||
to: 'Build_Installer_Output'
|
||||
include:
|
||||
- 'PowerToysSetup-*.exe'
|
||||
signing_options:
|
||||
sign_inline: true # This does signing a soon as this command completes
|
||||
|
||||
|
||||
#package:
|
||||
# commands:
|
||||
# - !!buildcommand
|
||||
# name: 'Build MSIX package'
|
||||
# command: 'installer\msix\build_msix_cdpx.cmd'
|
||||
# artifacts:
|
||||
# - from: 'installer\msix\bin'
|
||||
# to: 'Build_MSIX_Package_Output'
|
||||
# include:
|
||||
# - '*.msix'
|
||||
# - '*.msixbundle'
|
||||
# signing_options:
|
||||
# profile: '400'
|
||||
|
||||
static_analysis_options:
|
||||
binskim_options:
|
||||
files_to_scan:
|
||||
- from: 'installer/packages'
|
||||
exclude:
|
||||
- 'WiX.*/**/*.dll'
|
||||
- 'Wix.*/**/*.exe'
|
||||
moderncop_options:
|
||||
files_to_scan:
|
||||
- from: 'src'
|
||||
exclude:
|
||||
- '**/just.config.js'
|
||||
- '**/webpack.config.js'
|
||||
- '**/webpack.serve.config.js'
|
||||
- '**/dist/bundle.js'
|
||||
policheck_options:
|
||||
files_to_scan:
|
||||
- exclude:
|
||||
- '**/*.lcl'
|
||||
|
||||
|
||||
3
.pipelines/restore-installer.cmd
Normal file
3
.pipelines/restore-installer.cmd
Normal file
@@ -0,0 +1,3 @@
|
||||
cd /D "%~dp0"
|
||||
|
||||
nuget restore ../installer/PowerToysSetup.sln || exit /b 1
|
||||
32
.pipelines/restore-localization.cmd
Normal file
32
.pipelines/restore-localization.cmd
Normal file
@@ -0,0 +1,32 @@
|
||||
@echo off
|
||||
|
||||
cd /D "%~dp0"
|
||||
|
||||
echo Installing nuget packages
|
||||
|
||||
setlocal
|
||||
|
||||
rem In this sample, the repo root is identical to the script directory path. Adjust the value of the RepoRoot variable accordingly based on your environment.
|
||||
rem Again, ensure the RepoRoot variable is set to the real repo root location, otherwise the localization toolset wouldn't work as intended.
|
||||
rem Note that the resolved %~dp0 ends with \.
|
||||
set RepoRoot=%~dp0..\
|
||||
set OutDir=%RepoRoot%out
|
||||
set NUGET_PACKAGES=%RepoRoot%packages
|
||||
set LocalizationXLocPkgVer=2.0.0
|
||||
|
||||
nuget install Localization.XLoc -Version %LocalizationXLocPkgVer% -OutputDirectory "%NUGET_PACKAGES%" -NonInteractive -Verbosity detailed
|
||||
if "%errorlevel%" neq "0" (
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
|
||||
nuget install LSBuild.XLoc -OutputDirectory "%NUGET_PACKAGES%" -NonInteractive -Verbosity detailed
|
||||
if "%errorlevel%" neq "0" (
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
|
||||
nuget install Localization.Languages -OutputDirectory "%NUGET_PACKAGES%" -NonInteractive -Verbosity detailed
|
||||
if "%errorlevel%" neq "0" (
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
|
||||
exit /b %errorlevel%
|
||||
6
.pipelines/restore-telemetry.cmd
Normal file
6
.pipelines/restore-telemetry.cmd
Normal file
@@ -0,0 +1,6 @@
|
||||
cd /D "%~dp0"
|
||||
|
||||
call nuget.exe restore -PackagesDirectory . packages.config || exit /b 1
|
||||
|
||||
move /Y "Microsoft.PowerToys.Telemetry.2.0.0\build\include\TraceLoggingDefines.h" "..\src\common\Telemetry\TraceLoggingDefines.h" || exit /b 1
|
||||
move /Y "Microsoft.PowerToys.Telemetry.2.0.0\build\include\TelemetryBase.cs" "..\src\common\Telemetry\TelemetryBase.cs" || exit /b 1
|
||||
@@ -1,3 +1,3 @@
|
||||
cd /D "%~dp0"
|
||||
|
||||
dotnet restore ..\PowerToys.sln || exit /b 1
|
||||
nuget restore ../PowerToys.sln || exit /b 1
|
||||
|
||||
9
CODE_OF_CONDUCT.md
Normal file
9
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Microsoft Open Source Code of Conduct
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
|
||||
Resources:
|
||||
|
||||
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
|
||||
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
|
||||
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
|
||||
65
COMMUNITY.md
Normal file
65
COMMUNITY.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Community
|
||||
|
||||
The PowerToys team is extremely grateful to have the support of an amazing active community. The work you do is incredibly important. PowerToys wouldn’t be near what it is without your help filing bugs, updating documentation, guiding the design, or writing features. We want to say thanks and to recognize your work. This is a living document dedicated to highlighting the high impact community members and their contributions.
|
||||
|
||||
Names are in alphabetical order based on first name.
|
||||
|
||||
## High impact community members
|
||||
|
||||
### [@Niels9001](https://github.com/niels9001/) - [Niels Laute](https://nielslaute.com/)
|
||||
|
||||
Niels has helped drive large sums of our update toward a new [consistent and modern UX](https://github.com/microsoft/PowerToys/issues/891). This includes the [launcher work](https://github.com/microsoft/PowerToys/issues/44) and [icon design](https://github.com/microsoft/PowerToys/issues/1118).
|
||||
|
||||
### [@riverar](https://github.com/riverar) - [Rafael Rivera](https://withinrafael.com/)
|
||||
|
||||
Rafael has helped do the [upgrade from CppWinRT 1.x to 2.0](https://github.com/microsoft/PowerToys/issues/1907). He directly provided feedback to the CppWinRT team for bugs from this migration as well.
|
||||
|
||||
### [@royvou](https://github.com/royvou)
|
||||
Roy has helped out contributing a features to PowerToys Run
|
||||
|
||||
## Open source projects
|
||||
|
||||
As PowerToys creates new utilities, some will be based off existing technology. We'll continue to do our best to contribute back to these projects but their efforts were the base of some of our projects. We want to be sure their work is directly recognized.
|
||||
|
||||
### [@jjw24](https://github.com/jjw24/) - Jeremy Wu
|
||||
|
||||
Their fork of Wox was the base of PowerToys Run.
|
||||
|
||||
### [WoX Launcher](https://github.com/Wox-launcher/Wox/)
|
||||
|
||||
Initial base of jjw24's fork, which makes it the base of PowerToys Run.
|
||||
|
||||
## Microsoft community members
|
||||
|
||||
We would like to also directly call out some extremely helpful Microsoft employees that have directly contributed to PowerToys. This isn't their day job and was work they did out of passion. We want to say thank you and recognize your work.
|
||||
|
||||
### [@betsegaw](https://github.com/betsegaw/) - [Betsegaw Tadele](http://www.dreamsofameaningfullife.com/)
|
||||
|
||||
Window Walker, inside PowerToys Run, is from Beta.
|
||||
|
||||
### [@TheMrJukes](https://github.com/TheMrJukes/) - Bret Anderson
|
||||
|
||||
The base of FancyZones and a lot of performance adjustments are from the hard work of Bret.
|
||||
|
||||
### [@bricelam](https://github.com/bricelam/) - [Brice Lambson](https://bricelam.net/)
|
||||
|
||||
Image Resizer is from Brice.
|
||||
|
||||
### [@chrdavis](https://github.com/chrdavis/) - Chris Davis
|
||||
|
||||
PowerRename is from Chris's SmartRename and icon rendering for SVGs in File Explorer
|
||||
|
||||
### [@martinchrzan](https://github.com/martinchrzan/) - Martin Chrzan
|
||||
|
||||
Color Picker is from Martin.
|
||||
|
||||
<!--
|
||||
@alekhyareddy28
|
||||
@jyuwono
|
||||
@laviusmotileng-ms
|
||||
@ryanbodrug-microsoft
|
||||
@saahmedm
|
||||
@somil55
|
||||
@traies
|
||||
@udit3333
|
||||
-->
|
||||
@@ -121,6 +121,12 @@ When you'd like the team to take a look, (even if the work is not yet fully-comp
|
||||
|
||||
Once your code has been reviewed and approved by the requisite number of team members, it will be merged into the master branch. Once merged, your PR will be automatically closed.
|
||||
|
||||
### How can I become a collaborateur on the PowerToys team
|
||||
|
||||
Be a great community member. Just help out a lot and make useful additions, filing bugs/suggestions, help develop fixes and features, code reviews, and always, docs. Lets continue to make the PowerToys repository a great spot to learn and make a great set of utilities.
|
||||
|
||||
When the time comes, Microsoft will reach out and help make you a formal team member. Just make sure they can reach out to you :)
|
||||
|
||||
---
|
||||
|
||||
## Thank you
|
||||
34
LICENSE
34
LICENSE
@@ -1,21 +1,21 @@
|
||||
MIT License
|
||||
The MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
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:
|
||||
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 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
|
||||
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.
|
||||
|
||||
BIN
MTNDWidget.jpg
BIN
MTNDWidget.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 5.7 KiB |
209
NOTICE.md
Normal file
209
NOTICE.md
Normal file
@@ -0,0 +1,209 @@
|
||||
# NOTICES AND INFORMATION
|
||||
This software incorporates material from third parties.
|
||||
|
||||
## PowerToy: Color Picker
|
||||
|
||||
### Martin Chrzan's Color Picker
|
||||
|
||||
**Source**: https://github.com/martinchrzan/ColorPicker
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 martinchrzan
|
||||
|
||||
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.
|
||||
|
||||
## PowerToy: ImageResizer
|
||||
|
||||
### Brice Lams's Image Resizer License
|
||||
|
||||
**Source**: https://github.com/bricelam/ImageResizer/
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Brice Lambson. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
## PowerToy: Launcher
|
||||
|
||||
### Wox License
|
||||
|
||||
**Fork project source**: https://github.com/jjw24/Wox/
|
||||
**Base project source**: https://github.com/Wox-launcher/Wox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Wox
|
||||
|
||||
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.
|
||||
|
||||
### Beta Tadele's Window Walker License
|
||||
|
||||
**Source**: https://github.com/betsegaw/windowwalker
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright 2020 Betsegaw Tadele
|
||||
|
||||
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.
|
||||
|
||||
### Squirrel.Windows License
|
||||
|
||||
**Source**: https://github.com/Squirrel/Squirrel.Windows/
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012 GitHub, Inc.
|
||||
|
||||
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.
|
||||
|
||||
## PowerToy: PowerRename
|
||||
|
||||
### Chris Davis's SmartRename License
|
||||
|
||||
**Source**: https://github.com/chrdavis/SmartRename
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Chris Davis
|
||||
|
||||
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.
|
||||
|
||||
## PowerToy: Installer
|
||||
|
||||
### spdlog
|
||||
**Source**: https://github.com/gabime/spdlog
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Gabi Melman.
|
||||
|
||||
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.
|
||||
|
||||
-- NOTE: Third party dependency used by this software --
|
||||
This software depends on the fmt lib (MIT License),
|
||||
and users must comply to its license: https://github.com/fmtlib/fmt/blob/master/LICENSE.rst
|
||||
|
||||
|
||||
### cxxopts
|
||||
**Source**: https://github.com/jarro2783
|
||||
|
||||
Copyright (c) 2014 Jarryd Beck
|
||||
|
||||
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.
|
||||
762
PowerToys.sln
762
PowerToys.sln
@@ -1,120 +1,642 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28803.452
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runner", "src\runner\runner.vcxproj", "{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{48804216-2A0E-4168-A6D8-9CD068D14227} = {48804216-2A0E-4168-A6D8-9CD068D14227}
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA} = {A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}
|
||||
{07C389E3-6BC8-41CF-923E-307B1265FA2D} = {07C389E3-6BC8-41CF-923E-307B1265FA2D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "src\common\common.vcxproj", "{74485049-C722-400F-ABE5-86AC52D929B3}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shortcut_guide", "src\modules\shortcut_guide\shortcut_guide.vcxproj", "{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_powertoy", "src\modules\example_powertoy\example_powertoy.vcxproj", "{44CC9375-3E6E-4D99-8913-7FB748807EBD}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{4574FDD0-F61D-4376-98BF-E5A1262C11EC}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "interface", "interface", "{3BB8493E-D18E-4485-A320-CB40F90F55AE}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
src\modules\interface\lowlevel_keyboard_event_data.h = src\modules\interface\lowlevel_keyboard_event_data.h
|
||||
src\modules\interface\powertoy_module_interface.h = src\modules\interface\powertoy_module_interface.h
|
||||
src\modules\interface\win_hook_event_data.h = src\modules\interface\win_hook_event_data.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "settings", "src\editor\settings.vcxproj", "{07C389E3-6BC8-41CF-923E-307B1265FA2D}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fancyzones", "fancyzones", "{D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FancyZonesLib", "src\modules\fancyzones\lib\FancyZonesLib.vcxproj", "{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fancyzones", "src\modules\fancyzones\dll\FancyZonesModule.vcxproj", "{48804216-2A0E-4168-A6D8-9CD068D14227}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481} = {5CCC8468-DEC8-4D36-99D4-5C891BEBD481}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests-FancyZones", "src\modules\fancyzones\tests\UnitTests\UnitTests.vcxproj", "{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpprestsdk", "deps\cpprestsdk\cpprestsdk.vcxproj", "{4E577735-DFAB-41AF-8A6E-B6E8872A2928}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deps", "deps", "{1FAF749F-0D6F-4BF5-A563-31A4B5279D27}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{1AFB6476-670D-4E80-A464-657E01DFF482}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests-CommonLib", "src\common\UnitTests-CommonLib\UnitTests-CommonLib.vcxproj", "{1A066C63-64B3-45F8-92FE-664E1CCE8077}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FancyZonesEditor", "src\modules\fancyzones\editor\FancyZonesEditor\FancyZonesEditor.csproj", "{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Debug|x64.Build.0 = Debug|x64
|
||||
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Release|x64.ActiveCfg = Release|x64
|
||||
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Release|x64.Build.0 = Release|x64
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3}.Debug|x64.Build.0 = Debug|x64
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3}.Release|x64.ActiveCfg = Release|x64
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3}.Release|x64.Build.0 = Release|x64
|
||||
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Debug|x64.Build.0 = Debug|x64
|
||||
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Release|x64.ActiveCfg = Release|x64
|
||||
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Release|x64.Build.0 = Release|x64
|
||||
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Release|x64.ActiveCfg = Release|x64
|
||||
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|x64.Build.0 = Debug|x64
|
||||
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|x64.ActiveCfg = Release|x64
|
||||
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|x64.Build.0 = Release|x64
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|x64.Build.0 = Debug|x64
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|x64.ActiveCfg = Release|x64
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|x64.Build.0 = Release|x64
|
||||
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|x64.Build.0 = Debug|x64
|
||||
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x64.ActiveCfg = Release|x64
|
||||
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x64.Build.0 = Release|x64
|
||||
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Debug|x64.Build.0 = Debug|x64
|
||||
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|x64.ActiveCfg = Release|x64
|
||||
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|x64.Build.0 = Release|x64
|
||||
{4E577735-DFAB-41AF-8A6E-B6E8872A2928}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4E577735-DFAB-41AF-8A6E-B6E8872A2928}.Debug|x64.Build.0 = Debug|x64
|
||||
{4E577735-DFAB-41AF-8A6E-B6E8872A2928}.Release|x64.ActiveCfg = Release|x64
|
||||
{4E577735-DFAB-41AF-8A6E-B6E8872A2928}.Release|x64.Build.0 = Release|x64
|
||||
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Debug|x64.Build.0 = Debug|x64
|
||||
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Release|x64.ActiveCfg = Release|x64
|
||||
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Release|x64.Build.0 = Release|x64
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Debug|x64.Build.0 = Debug|x64
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Release|x64.ActiveCfg = Release|x64
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{44CC9375-3E6E-4D99-8913-7FB748807EBD} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{3BB8493E-D18E-4485-A320-CB40F90F55AE} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{D1D6BC88-09AE-4FB4-AD24-5DED46A791DD} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{48804216-2A0E-4168-A6D8-9CD068D14227} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{4E577735-DFAB-41AF-8A6E-B6E8872A2928} = {1FAF749F-0D6F-4BF5-A563-31A4B5279D27}
|
||||
{1A066C63-64B3-45F8-92FE-664E1CCE8077} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28803.452
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runner", "src\runner\runner.vcxproj", "{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{217DF501-135C-4E38-BFC8-99D4821032EA} = {217DF501-135C-4E38-BFC8-99D4821032EA}
|
||||
{0E072714-D127-460B-AFAD-B4C40B412798} = {0E072714-D127-460B-AFAD-B4C40B412798}
|
||||
{48804216-2A0E-4168-A6D8-9CD068D14227} = {48804216-2A0E-4168-A6D8-9CD068D14227}
|
||||
{51920F1F-C28C-4ADF-8660-4238766796C2} = {51920F1F-C28C-4ADF-8660-4238766796C2}
|
||||
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB} = {6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}
|
||||
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73} = {031AC72E-FA28-4AB7-B690-6F7B9C28AA73}
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
{0485F45C-EA7A-4BB5-804B-3E8D14699387} = {0485F45C-EA7A-4BB5-804B-3E8D14699387}
|
||||
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D} = {D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481} = {5CCC8468-DEC8-4D36-99D4-5C891BEBD481}
|
||||
{BA58206B-1493-4C75-BFEA-A85768A1E156} = {BA58206B-1493-4C75-BFEA-A85768A1E156}
|
||||
{0B593A6C-4143-4337-860E-DB5710FB87DB} = {0B593A6C-4143-4337-860E-DB5710FB87DB}
|
||||
{E364F67B-BB12-4E91-B639-355866EBCD8B} = {E364F67B-BB12-4E91-B639-355866EBCD8B}
|
||||
{DA425894-6E13-404F-8DCB-78584EC0557A} = {DA425894-6E13-404F-8DCB-78584EC0557A}
|
||||
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34} = {2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}
|
||||
{A7D5099E-F0FD-4BF3-8522-5A682759F915} = {A7D5099E-F0FD-4BF3-8522-5A682759F915}
|
||||
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B} = {0B43679E-EDFA-4DA0-AD30-F4628B308B1B}
|
||||
{B25AC7A5-FB9F-4789-B392-D5C85E948670} = {B25AC7A5-FB9F-4789-B392-D5C85E948670}
|
||||
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F} = {E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}
|
||||
{AF2349B8-E5B6-4004-9502-687C1C7730B1} = {AF2349B8-E5B6-4004-9502-687C1C7730B1}
|
||||
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA} = {A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}
|
||||
{17DA04DF-E393-4397-9CF0-84DABE11032E} = {17DA04DF-E393-4397-9CF0-84DABE11032E}
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99} = {F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}
|
||||
{07C389E3-6BC8-41CF-923E-307B1265FA2D} = {07C389E3-6BC8-41CF-923E-307B1265FA2D}
|
||||
{655C9AF2-18D3-4DA6-80E4-85504A7722BA} = {655C9AF2-18D3-4DA6-80E4-85504A7722BA}
|
||||
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9} = {89F34AF7-1C34-4A72-AA6E-534BCF972BD9}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "src\common\common.vcxproj", "{74485049-C722-400F-ABE5-86AC52D929B3}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShortcutGuide", "src\modules\shortcut_guide\shortcut_guide.vcxproj", "{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{4574FDD0-F61D-4376-98BF-E5A1262C11EC}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "interface", "interface", "{3BB8493E-D18E-4485-A320-CB40F90F55AE}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
src\modules\interface\powertoy_module_interface.h = src\modules\interface\powertoy_module_interface.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "settings", "src\settings\settings.vcxproj", "{07C389E3-6BC8-41CF-923E-307B1265FA2D}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fancyzones", "fancyzones", "{D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FancyZonesLib", "src\modules\fancyzones\lib\FancyZonesLib.vcxproj", "{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fancyzones", "src\modules\fancyzones\dll\FancyZonesModule.vcxproj", "{48804216-2A0E-4168-A6D8-9CD068D14227}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481} = {5CCC8468-DEC8-4D36-99D4-5C891BEBD481}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests-FancyZones", "src\modules\fancyzones\tests\UnitTests\UnitTests.vcxproj", "{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99} = {F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{1AFB6476-670D-4E80-A464-657E01DFF482}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests-CommonLib", "src\common\UnitTests-CommonLib\UnitTests-CommonLib.vcxproj", "{1A066C63-64B3-45F8-92FE-664E1CCE8077}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FancyZonesEditor", "src\modules\fancyzones\editor\FancyZonesEditor\FancyZonesEditor.csproj", "{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "powerrename", "powerrename", "{89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameExt", "src\modules\powerrename\dll\PowerRenameExt.vcxproj", "{B25AC7A5-FB9F-4789-B392-D5C85E948670}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{0E072714-D127-460B-AFAD-B4C40B412798} = {0E072714-D127-460B-AFAD-B4C40B412798}
|
||||
{51920F1F-C28C-4ADF-8660-4238766796C2} = {51920F1F-C28C-4ADF-8660-4238766796C2}
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameLib", "src\modules\powerrename\lib\PowerRenameLib.vcxproj", "{51920F1F-C28C-4ADF-8660-4238766796C2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameUI", "src\modules\powerrename\ui\PowerRenameUI.vcxproj", "{0E072714-D127-460B-AFAD-B4C40B412798}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{51920F1F-C28C-4ADF-8660-4238766796C2} = {51920F1F-C28C-4ADF-8660-4238766796C2}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameTest", "src\modules\powerrename\testapp\PowerRenameTest.vcxproj", "{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{0E072714-D127-460B-AFAD-B4C40B412798} = {0E072714-D127-460B-AFAD-B4C40B412798}
|
||||
{51920F1F-C28C-4ADF-8660-4238766796C2} = {51920F1F-C28C-4ADF-8660-4238766796C2}
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameUnitTests", "src\modules\powerrename\unittests\PowerRenameLibUnitTests.vcxproj", "{2151F984-E006-4A9F-92EF-C6DDE3DC8413}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{0E072714-D127-460B-AFAD-B4C40B412798} = {0E072714-D127-460B-AFAD-B4C40B412798}
|
||||
{51920F1F-C28C-4ADF-8660-4238766796C2} = {51920F1F-C28C-4ADF-8660-4238766796C2}
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
{B25AC7A5-FB9F-4789-B392-D5C85E948670} = {B25AC7A5-FB9F-4789-B392-D5C85E948670}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{BEEAB7F2-FFF6-45AB-9CDB-B04CC0734B88}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ModuleTemplateCompileTest", "tools\project_template\ModuleTemplate\ModuleTemplateCompileTest.vcxproj", "{64A80062-4D8B-4229-8A38-DFA1D7497749}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameUWPUI", "src\modules\powerrename\UWPui\PowerRenameUWPUI.vcxproj", "{0485F45C-EA7A-4BB5-804B-3E8D14699387}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{0E072714-D127-460B-AFAD-B4C40B412798} = {0E072714-D127-460B-AFAD-B4C40B412798}
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "notifications", "src\common\notifications_winrt\notifications.vcxproj", "{0B593A6C-4143-4337-860E-DB5710FB87DB}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "notifications_dll", "src\common\notifications\notifications_dll.vcxproj", "{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {74485049-C722-400F-ABE5-86AC52D929B3}
|
||||
{0B593A6C-4143-4337-860E-DB5710FB87DB} = {0B593A6C-4143-4337-860E-DB5710FB87DB}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManager", "src\modules\keyboardmanager\dll\KeyboardManager.vcxproj", "{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "imageresizer", "imageresizer", "{6C7F47CC-2151-44A3-A546-41C70025132C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageResizerUI", "src\modules\imageresizer\ui\ImageResizerUI.csproj", "{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageResizerExt", "src\modules\imageresizer\dll\ImageResizerExt.vcxproj", "{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageResizerUITest", "src\modules\imageresizer\tests\ImageResizerUITest.csproj", "{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerUI", "src\modules\keyboardmanager\ui\KeyboardManagerUI.vcxproj", "{EAF23649-EF6E-478B-980E-81FAD96CCA2A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "action_runner", "src\action_runner\action_runner.vcxproj", "{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{17DA04DF-E393-4397-9CF0-84DABE11032E} = {17DA04DF-E393-4397-9CF0-84DABE11032E}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "updating", "src\common\updating\updating.vcxproj", "{17DA04DF-E393-4397-9CF0-84DABE11032E}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "keyboardmanager", "keyboardmanager", "{38BDB927-829B-4C65-9CD9-93FB05D66D65}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerCommon", "src\modules\keyboardmanager\common\KeyboardManagerCommon.vcxproj", "{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "launcher", "launcher", "{C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox.Core", "src\modules\launcher\Wox.Core\Wox.Core.csproj", "{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox.Infrastructure", "src\modules\launcher\Wox.Infrastructure\Wox.Infrastructure.csproj", "{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox.Plugin", "src\modules\launcher\Wox.Plugin\Wox.Plugin.csproj", "{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox.Test", "src\modules\launcher\Wox.Test\Wox.Test.csproj", "{FF742965-9A80-41A5-B042-D6C7D3A21708}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{4AFC9975-2456-4C70-94A4-84073C1CED93}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Calculator", "src\modules\launcher\Plugins\Microsoft.Plugin.Calculator\Microsoft.Plugin.Calculator.csproj", "{59BD9891-3837-438A-958D-ADC7F91F6F7E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.WindowWalker", "src\modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\Microsoft.Plugin.WindowWalker.csproj", "{74F1B9ED-F59C-4FE7-B473-7B453E30837E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Program", "src\modules\launcher\Plugins\Microsoft.Plugin.Program\Microsoft.Plugin.Program.csproj", "{FDB3555B-58EF-4AE6-B5F1-904719637AB4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Shell", "src\modules\launcher\Plugins\Microsoft.Plugin.Shell\Microsoft.Plugin.Shell.csproj", "{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Indexer", "src\modules\launcher\Plugins\Microsoft.Plugin.Indexer\Microsoft.Plugin.Indexer.csproj", "{F8B870EB-D5F5-45BA-9CF7-A5C459818820}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80} = {8451ECDD-2EA4-4966-BB0A-7BBC40138E80}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Launcher", "src\modules\launcher\Microsoft.Launcher\Microsoft.Launcher.vcxproj", "{E364F67B-BB12-4E91-B639-355866EBCD8B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2} = {F97E5003-F263-4D4A-A964-0F1F3C82DEF2}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerLauncher", "src\modules\launcher\PowerLauncher\PowerLauncher.csproj", "{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{03276A39-D4E9-417C-8FFD-200B0EE5E871} = {03276A39-D4E9-417C-8FFD-200B0EE5E871}
|
||||
{FDB3555B-58EF-4AE6-B5F1-904719637AB4} = {FDB3555B-58EF-4AE6-B5F1-904719637AB4}
|
||||
{59BD9891-3837-438A-958D-ADC7F91F6F7E} = {59BD9891-3837-438A-958D-ADC7F91F6F7E}
|
||||
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} = {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}
|
||||
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4} = {787B8AA6-CA93-4C84-96FE-DF31110AD1C4}
|
||||
{F8B870EB-D5F5-45BA-9CF7-A5C459818820} = {F8B870EB-D5F5-45BA-9CF7-A5C459818820}
|
||||
{74F1B9ED-F59C-4FE7-B473-7B453E30837E} = {74F1B9ED-F59C-4FE7-B473-7B453E30837E}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{E775CC2C-24CB-48D6-9C3A-BE4CCE0DB17A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "win-app-driver", "src\tests\win-app-driver\win-app-driver.csproj", "{880ED251-9E16-4713-9A70-D35FE0C01669}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "previewpane", "previewpane", "{2F305555-C296-497E-AC20-5FA1B237996A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PreviewHandlerCommon", "src\modules\previewpane\Common\PreviewHandlerCommon.csproj", "{AF2349B8-E5B6-4004-9502-687C1C7730B1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarkdownPreviewHandler", "src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewHandler.csproj", "{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-MarkdownPreviewHandler", "src\modules\previewpane\PreviewPaneUnitTests\UnitTests-MarkdownPreviewHandler.csproj", "{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SvgPreviewHandler", "src\modules\previewpane\SvgPreviewHandler\SvgPreviewHandler.csproj", "{DA425894-6E13-404F-8DCB-78584EC0557A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-SvgPreviewHandler", "src\modules\previewpane\UnitTests-SvgPreviewHandler\UnitTests-SvgPreviewHandler.csproj", "{060D75DA-2D1C-48E6-A4A1-6F0718B64661}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-PreviewHandlerCommon", "src\modules\previewpane\UnitTests-PreviewHandlerCommon\UnitTests-PreviewHandlerCommon.csproj", "{748417CA-F17E-487F-9411-CAFB6D3F4877}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "powerpreview", "src\modules\previewpane\powerpreview\powerpreview.vcxproj", "{217DF501-135C-4E38-BFC8-99D4821032EA}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "powerpreviewTest", "src\modules\previewpane\powerpreviewTest\powerpreviewTest.vcxproj", "{47310AB4-9034-4BD1-8D8B-E88AD21A171B}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "core", "core", "{C3081D9A-1586-441A-B5F4-ED815B3719C1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Settings.UI.Runner", "src\core\Microsoft.PowerToys.Settings.UI.Runner\Microsoft.PowerToys.Settings.UI.Runner.csproj", "{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerToys.Settings.UI", "src\core\Microsoft.PowerToys.Settings.UI\Microsoft.PowerToys.Settings.UI.csproj", "{A7D5099E-F0FD-4BF3-8522-5A682759F915}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4981CCD1-4CD9-4A49-B240-00AA46493FF8}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
src\.editorconfig = src\.editorconfig
|
||||
src\tests\win-app-driver\packages.config = src\tests\win-app-driver\packages.config
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Settings.UI.Library", "src\core\Microsoft.PowerToys.Settings.UI.Library\Microsoft.PowerToys.Settings.UI.Library.csproj", "{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "interop", "src\common\interop\interop.vcxproj", "{F055103B-F80B-4D0C-BF48-057C55620033}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common-md-flag", "src\common\common-md-flag\common-md-flag.vcxproj", "{985B3F2F-CEED-4C0A-A249-69257E719145}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Interop.Tests", "src\common\interop-tests\Microsoft.Interop.Tests.csproj", "{437AD818-3F1F-4CA5-A79B-25233A157026}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Folder", "src\modules\launcher\Plugins\Microsoft.Plugin.Folder\Microsoft.Plugin.Folder.csproj", "{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerLauncher.Telemetry", "src\modules\launcher\PowerLauncher.Telemetry\PowerLauncher.Telemetry.csproj", "{08C8C05F-0362-41BC-818C-724572DF8B06}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Telemetry", "src\common\ManagedTelemetry\Telemetry\Telemetry.csproj", "{5D00D290-4016-4CFE-9E41-1E7C724509BA}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerTest", "src\modules\keyboardmanager\test\KeyboardManagerTest.vcxproj", "{62173D9A-6724-4C00-A1C8-FB646480A9EC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManagedCommon", "src\common\ManagedCommon\ManagedCommon.csproj", "{4AED67B6-55FD-486F-B917-E543DEE2CB3C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Program.UnitTests", "src\modules\launcher\Plugins\Microsoft.Plugin.Program.UnitTests\Microsoft.Plugin.Program.UnitTests.csproj", "{42851751-CBC8-45A6-97F5-7A0753F7B4D1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-SvgThumbnailProvider", "src\modules\previewpane\UnitTests-SvgThumbnailProvider\UnitTests-SvgThumbnailProvider.csproj", "{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SvgThumbnailProvider", "src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj", "{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ColorPicker", "src\modules\colorPicker\ColorPicker\ColorPicker.vcxproj", "{655C9AF2-18D3-4DA6-80E4-85504A7722BA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColorPickerUI", "src\modules\colorPicker\ColorPickerUI\ColorPickerUI.csproj", "{BA58206B-1493-4C75-BFEA-A85768A1E156}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "colorpicker", "colorpicker", "{1D78B84B-CA39-406C-98F4-71F7EC266CC0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Uri", "src\modules\launcher\Plugins\Microsoft.Plugin.Uri\Microsoft.Plugin.Uri.csproj", "{03276A39-D4E9-417C-8FFD-200B0EE5E871}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Uri.UnitTests", "src\modules\launcher\Plugins\Microsoft.Plugin.Uri.UnitTests\Microsoft.Plugin.Uri.UnitTests.csproj", "{B81FB7B6-D30E-428F-908A-41422EFC1172}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Settings.UI.UnitTests", "src\core\Microsoft.PowerToys.Settings.UI.UnitTests\Microsoft.PowerToys.Settings.UI.UnitTests.csproj", "{0F85E674-34AE-443D-954C-8321EB8B93B1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Calculator.UnitTest", "src\modules\launcher\Plugins\Microsoft.Plugin.Calculator.UnitTest\Microsoft.Plugin.Calculator.UnitTest.csproj", "{632BBE62-5421-49EA-835A-7FFA4F499BD6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Folder.UnitTests", "src\modules\launcher\Plugins\Microsoft.Plugin.Folder.UnitTests\Microsoft.Plugin.Folder.UnitTests.csproj", "{4FA206A5-F69F-4193-BF8F-F6EEB496734C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest-ColorPickerUI", "src\modules\colorPicker\UnitTest-ColorPickerUI\UnitTest-ColorPickerUI.csproj", "{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logging", "src\logging\logging.vcxproj", "{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Debug|x64.Build.0 = Debug|x64
|
||||
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Release|x64.ActiveCfg = Release|x64
|
||||
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Release|x64.Build.0 = Release|x64
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3}.Debug|x64.Build.0 = Debug|x64
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3}.Release|x64.ActiveCfg = Release|x64
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3}.Release|x64.Build.0 = Release|x64
|
||||
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Debug|x64.Build.0 = Debug|x64
|
||||
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Release|x64.ActiveCfg = Release|x64
|
||||
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Release|x64.Build.0 = Release|x64
|
||||
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|x64.Build.0 = Debug|x64
|
||||
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|x64.ActiveCfg = Release|x64
|
||||
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|x64.Build.0 = Release|x64
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|x64.Build.0 = Debug|x64
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|x64.ActiveCfg = Release|x64
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|x64.Build.0 = Release|x64
|
||||
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|x64.Build.0 = Debug|x64
|
||||
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x64.ActiveCfg = Release|x64
|
||||
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x64.Build.0 = Release|x64
|
||||
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Debug|x64.Build.0 = Debug|x64
|
||||
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|x64.ActiveCfg = Release|x64
|
||||
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|x64.Build.0 = Release|x64
|
||||
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Debug|x64.Build.0 = Debug|x64
|
||||
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Release|x64.ActiveCfg = Release|x64
|
||||
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Release|x64.Build.0 = Release|x64
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Debug|x64.Build.0 = Debug|x64
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Release|x64.ActiveCfg = Release|x64
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Release|x64.Build.0 = Release|x64
|
||||
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Debug|x64.Build.0 = Debug|x64
|
||||
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Release|x64.ActiveCfg = Release|x64
|
||||
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Release|x64.Build.0 = Release|x64
|
||||
{51920F1F-C28C-4ADF-8660-4238766796C2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{51920F1F-C28C-4ADF-8660-4238766796C2}.Debug|x64.Build.0 = Debug|x64
|
||||
{51920F1F-C28C-4ADF-8660-4238766796C2}.Release|x64.ActiveCfg = Release|x64
|
||||
{51920F1F-C28C-4ADF-8660-4238766796C2}.Release|x64.Build.0 = Release|x64
|
||||
{0E072714-D127-460B-AFAD-B4C40B412798}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0E072714-D127-460B-AFAD-B4C40B412798}.Debug|x64.Build.0 = Debug|x64
|
||||
{0E072714-D127-460B-AFAD-B4C40B412798}.Release|x64.ActiveCfg = Release|x64
|
||||
{0E072714-D127-460B-AFAD-B4C40B412798}.Release|x64.Build.0 = Release|x64
|
||||
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Debug|x64.Build.0 = Debug|x64
|
||||
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Release|x64.ActiveCfg = Release|x64
|
||||
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Release|x64.Build.0 = Release|x64
|
||||
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Debug|x64.Build.0 = Debug|x64
|
||||
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Release|x64.ActiveCfg = Release|x64
|
||||
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Release|x64.Build.0 = Release|x64
|
||||
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Debug|x64.Build.0 = Debug|x64
|
||||
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Release|x64.ActiveCfg = Release|x64
|
||||
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Release|x64.Build.0 = Release|x64
|
||||
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Debug|x64.Build.0 = Debug|x64
|
||||
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Release|x64.ActiveCfg = Release|x64
|
||||
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Release|x64.Build.0 = Release|x64
|
||||
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|x64.Build.0 = Debug|x64
|
||||
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|x64.ActiveCfg = Release|x64
|
||||
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|x64.Build.0 = Release|x64
|
||||
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Debug|x64.Build.0 = Debug|x64
|
||||
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Release|x64.ActiveCfg = Release|x64
|
||||
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Release|x64.Build.0 = Release|x64
|
||||
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Debug|x64.Build.0 = Debug|x64
|
||||
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Release|x64.ActiveCfg = Release|x64
|
||||
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Release|x64.Build.0 = Release|x64
|
||||
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Debug|x64.Build.0 = Debug|x64
|
||||
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Release|x64.ActiveCfg = Release|x64
|
||||
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Release|x64.Build.0 = Release|x64
|
||||
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Debug|x64.Build.0 = Debug|x64
|
||||
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Release|x64.ActiveCfg = Release|x64
|
||||
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Release|x64.Build.0 = Release|x64
|
||||
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Debug|x64.Build.0 = Debug|x64
|
||||
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Release|x64.ActiveCfg = Release|x64
|
||||
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Release|x64.Build.0 = Release|x64
|
||||
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|x64.Build.0 = Debug|x64
|
||||
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|x64.ActiveCfg = Release|x64
|
||||
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|x64.Build.0 = Release|x64
|
||||
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|x64.Build.0 = Debug|x64
|
||||
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|x64.ActiveCfg = Release|x64
|
||||
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|x64.Build.0 = Release|x64
|
||||
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|x64.Build.0 = Debug|x64
|
||||
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|x64.ActiveCfg = Release|x64
|
||||
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|x64.Build.0 = Release|x64
|
||||
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Debug|x64.Build.0 = Debug|x64
|
||||
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Release|x64.ActiveCfg = Release|x64
|
||||
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Release|x64.Build.0 = Release|x64
|
||||
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Debug|x64.Build.0 = Debug|x64
|
||||
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Release|x64.ActiveCfg = Release|x64
|
||||
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Release|x64.Build.0 = Release|x64
|
||||
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Debug|x64.Build.0 = Debug|x64
|
||||
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Release|x64.ActiveCfg = Release|x64
|
||||
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Release|x64.Build.0 = Release|x64
|
||||
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Debug|x64.Build.0 = Debug|x64
|
||||
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|x64.ActiveCfg = Release|x64
|
||||
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|x64.Build.0 = Release|x64
|
||||
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|x64.Build.0 = Debug|x64
|
||||
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Release|x64.ActiveCfg = Release|x64
|
||||
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Release|x64.Build.0 = Release|x64
|
||||
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Debug|x64.Build.0 = Debug|x64
|
||||
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x64.ActiveCfg = Release|x64
|
||||
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x64.Build.0 = Release|x64
|
||||
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Debug|x64.Build.0 = Debug|x64
|
||||
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Release|x64.ActiveCfg = Release|x64
|
||||
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Release|x64.Build.0 = Release|x64
|
||||
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Debug|x64.Build.0 = Debug|x64
|
||||
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Release|x64.ActiveCfg = Release|x64
|
||||
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Release|x64.Build.0 = Release|x64
|
||||
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Debug|x64.Build.0 = Debug|x64
|
||||
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Release|x64.ActiveCfg = Release|x64
|
||||
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Release|x64.Build.0 = Release|x64
|
||||
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Debug|x64.Build.0 = Debug|x64
|
||||
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Release|x64.ActiveCfg = Release|x64
|
||||
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Release|x64.Build.0 = Release|x64
|
||||
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Debug|x64.Build.0 = Debug|x64
|
||||
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Release|x64.ActiveCfg = Release|x64
|
||||
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Release|x64.Build.0 = Release|x64
|
||||
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Debug|x64.Build.0 = Debug|x64
|
||||
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Release|x64.ActiveCfg = Release|x64
|
||||
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Release|x64.Build.0 = Release|x64
|
||||
{880ED251-9E16-4713-9A70-D35FE0C01669}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{880ED251-9E16-4713-9A70-D35FE0C01669}.Debug|x64.Build.0 = Debug|x64
|
||||
{880ED251-9E16-4713-9A70-D35FE0C01669}.Release|x64.ActiveCfg = Release|x64
|
||||
{880ED251-9E16-4713-9A70-D35FE0C01669}.Release|x64.Build.0 = Release|x64
|
||||
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Debug|x64.Build.0 = Debug|x64
|
||||
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Release|x64.ActiveCfg = Release|x64
|
||||
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Release|x64.Build.0 = Release|x64
|
||||
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Debug|x64.Build.0 = Debug|x64
|
||||
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Release|x64.ActiveCfg = Release|x64
|
||||
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Release|x64.Build.0 = Release|x64
|
||||
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Debug|x64.Build.0 = Debug|x64
|
||||
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Release|x64.ActiveCfg = Release|x64
|
||||
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Release|x64.Build.0 = Release|x64
|
||||
{DA425894-6E13-404F-8DCB-78584EC0557A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DA425894-6E13-404F-8DCB-78584EC0557A}.Debug|x64.Build.0 = Debug|x64
|
||||
{DA425894-6E13-404F-8DCB-78584EC0557A}.Release|x64.ActiveCfg = Release|x64
|
||||
{DA425894-6E13-404F-8DCB-78584EC0557A}.Release|x64.Build.0 = Release|x64
|
||||
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Debug|x64.Build.0 = Debug|x64
|
||||
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Release|x64.ActiveCfg = Release|x64
|
||||
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Release|x64.Build.0 = Release|x64
|
||||
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Debug|x64.Build.0 = Debug|x64
|
||||
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Release|x64.ActiveCfg = Release|x64
|
||||
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Release|x64.Build.0 = Release|x64
|
||||
{217DF501-135C-4E38-BFC8-99D4821032EA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{217DF501-135C-4E38-BFC8-99D4821032EA}.Debug|x64.Build.0 = Debug|x64
|
||||
{217DF501-135C-4E38-BFC8-99D4821032EA}.Release|x64.ActiveCfg = Release|x64
|
||||
{217DF501-135C-4E38-BFC8-99D4821032EA}.Release|x64.Build.0 = Release|x64
|
||||
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Debug|x64.Build.0 = Debug|x64
|
||||
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Release|x64.ActiveCfg = Release|x64
|
||||
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Release|x64.Build.0 = Release|x64
|
||||
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Debug|x64.Build.0 = Debug|x64
|
||||
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Release|x64.ActiveCfg = Release|x64
|
||||
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Release|x64.Build.0 = Release|x64
|
||||
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Debug|x64.Build.0 = Debug|x64
|
||||
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|x64.ActiveCfg = Release|x64
|
||||
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|x64.Build.0 = Release|x64
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|x64.Build.0 = Debug|x64
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Release|x64.ActiveCfg = Release|x64
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Release|x64.Build.0 = Release|x64
|
||||
{F055103B-F80B-4D0C-BF48-057C55620033}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F055103B-F80B-4D0C-BF48-057C55620033}.Debug|x64.Build.0 = Debug|x64
|
||||
{F055103B-F80B-4D0C-BF48-057C55620033}.Release|x64.ActiveCfg = Release|x64
|
||||
{F055103B-F80B-4D0C-BF48-057C55620033}.Release|x64.Build.0 = Release|x64
|
||||
{985B3F2F-CEED-4C0A-A249-69257E719145}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{985B3F2F-CEED-4C0A-A249-69257E719145}.Debug|x64.Build.0 = Debug|x64
|
||||
{985B3F2F-CEED-4C0A-A249-69257E719145}.Release|x64.ActiveCfg = Release|x64
|
||||
{985B3F2F-CEED-4C0A-A249-69257E719145}.Release|x64.Build.0 = Release|x64
|
||||
{437AD818-3F1F-4CA5-A79B-25233A157026}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{437AD818-3F1F-4CA5-A79B-25233A157026}.Debug|x64.Build.0 = Debug|x64
|
||||
{437AD818-3F1F-4CA5-A79B-25233A157026}.Release|x64.ActiveCfg = Release|x64
|
||||
{437AD818-3F1F-4CA5-A79B-25233A157026}.Release|x64.Build.0 = Release|x64
|
||||
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Debug|x64.Build.0 = Debug|x64
|
||||
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Release|x64.ActiveCfg = Release|x64
|
||||
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Release|x64.Build.0 = Release|x64
|
||||
{08C8C05F-0362-41BC-818C-724572DF8B06}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{08C8C05F-0362-41BC-818C-724572DF8B06}.Debug|x64.Build.0 = Debug|x64
|
||||
{08C8C05F-0362-41BC-818C-724572DF8B06}.Release|x64.ActiveCfg = Release|x64
|
||||
{08C8C05F-0362-41BC-818C-724572DF8B06}.Release|x64.Build.0 = Release|x64
|
||||
{5D00D290-4016-4CFE-9E41-1E7C724509BA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5D00D290-4016-4CFE-9E41-1E7C724509BA}.Debug|x64.Build.0 = Debug|x64
|
||||
{5D00D290-4016-4CFE-9E41-1E7C724509BA}.Release|x64.ActiveCfg = Release|x64
|
||||
{5D00D290-4016-4CFE-9E41-1E7C724509BA}.Release|x64.Build.0 = Release|x64
|
||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Debug|x64.Build.0 = Debug|x64
|
||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Release|x64.ActiveCfg = Release|x64
|
||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Release|x64.Build.0 = Release|x64
|
||||
{4AED67B6-55FD-486F-B917-E543DEE2CB3C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4AED67B6-55FD-486F-B917-E543DEE2CB3C}.Debug|x64.Build.0 = Debug|x64
|
||||
{4AED67B6-55FD-486F-B917-E543DEE2CB3C}.Release|x64.ActiveCfg = Release|x64
|
||||
{4AED67B6-55FD-486F-B917-E543DEE2CB3C}.Release|x64.Build.0 = Release|x64
|
||||
{42851751-CBC8-45A6-97F5-7A0753F7B4D1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{42851751-CBC8-45A6-97F5-7A0753F7B4D1}.Debug|x64.Build.0 = Debug|x64
|
||||
{42851751-CBC8-45A6-97F5-7A0753F7B4D1}.Release|x64.ActiveCfg = Release|x64
|
||||
{42851751-CBC8-45A6-97F5-7A0753F7B4D1}.Release|x64.Build.0 = Release|x64
|
||||
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}.Debug|x64.Build.0 = Debug|x64
|
||||
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}.Release|x64.ActiveCfg = Release|x64
|
||||
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}.Release|x64.Build.0 = Release|x64
|
||||
{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}.Debug|x64.Build.0 = Debug|x64
|
||||
{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}.Release|x64.ActiveCfg = Release|x64
|
||||
{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}.Release|x64.Build.0 = Release|x64
|
||||
{655C9AF2-18D3-4DA6-80E4-85504A7722BA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{655C9AF2-18D3-4DA6-80E4-85504A7722BA}.Debug|x64.Build.0 = Debug|x64
|
||||
{655C9AF2-18D3-4DA6-80E4-85504A7722BA}.Release|x64.ActiveCfg = Release|x64
|
||||
{655C9AF2-18D3-4DA6-80E4-85504A7722BA}.Release|x64.Build.0 = Release|x64
|
||||
{BA58206B-1493-4C75-BFEA-A85768A1E156}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BA58206B-1493-4C75-BFEA-A85768A1E156}.Debug|x64.Build.0 = Debug|x64
|
||||
{BA58206B-1493-4C75-BFEA-A85768A1E156}.Release|x64.ActiveCfg = Release|x64
|
||||
{BA58206B-1493-4C75-BFEA-A85768A1E156}.Release|x64.Build.0 = Release|x64
|
||||
{03276A39-D4E9-417C-8FFD-200B0EE5E871}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{03276A39-D4E9-417C-8FFD-200B0EE5E871}.Debug|x64.Build.0 = Debug|x64
|
||||
{03276A39-D4E9-417C-8FFD-200B0EE5E871}.Release|x64.ActiveCfg = Release|x64
|
||||
{03276A39-D4E9-417C-8FFD-200B0EE5E871}.Release|x64.Build.0 = Release|x64
|
||||
{B81FB7B6-D30E-428F-908A-41422EFC1172}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B81FB7B6-D30E-428F-908A-41422EFC1172}.Debug|x64.Build.0 = Debug|x64
|
||||
{B81FB7B6-D30E-428F-908A-41422EFC1172}.Release|x64.ActiveCfg = Release|x64
|
||||
{B81FB7B6-D30E-428F-908A-41422EFC1172}.Release|x64.Build.0 = Release|x64
|
||||
{0F85E674-34AE-443D-954C-8321EB8B93B1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0F85E674-34AE-443D-954C-8321EB8B93B1}.Debug|x64.Build.0 = Debug|x64
|
||||
{0F85E674-34AE-443D-954C-8321EB8B93B1}.Release|x64.ActiveCfg = Release|x64
|
||||
{0F85E674-34AE-443D-954C-8321EB8B93B1}.Release|x64.Build.0 = Release|x64
|
||||
{632BBE62-5421-49EA-835A-7FFA4F499BD6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{632BBE62-5421-49EA-835A-7FFA4F499BD6}.Debug|x64.Build.0 = Debug|x64
|
||||
{632BBE62-5421-49EA-835A-7FFA4F499BD6}.Release|x64.ActiveCfg = Release|x64
|
||||
{632BBE62-5421-49EA-835A-7FFA4F499BD6}.Release|x64.Build.0 = Release|x64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Debug|x64.Build.0 = Debug|x64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|x64.ActiveCfg = Release|x64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|x64.Build.0 = Release|x64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Debug|x64.Build.0 = Debug|x64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Release|x64.ActiveCfg = Release|x64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Release|x64.Build.0 = Release|x64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.Build.0 = Debug|x64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Release|x64.ActiveCfg = Release|x64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{74485049-C722-400F-ABE5-86AC52D929B3} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{3BB8493E-D18E-4485-A320-CB40F90F55AE} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{D1D6BC88-09AE-4FB4-AD24-5DED46A791DD} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{48804216-2A0E-4168-A6D8-9CD068D14227} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{1A066C63-64B3-45F8-92FE-664E1CCE8077} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{B25AC7A5-FB9F-4789-B392-D5C85E948670} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{51920F1F-C28C-4ADF-8660-4238766796C2} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{0E072714-D127-460B-AFAD-B4C40B412798} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{2151F984-E006-4A9F-92EF-C6DDE3DC8413} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{64A80062-4D8B-4229-8A38-DFA1D7497749} = {BEEAB7F2-FFF6-45AB-9CDB-B04CC0734B88}
|
||||
{0485F45C-EA7A-4BB5-804B-3E8D14699387} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{0B593A6C-4143-4337-860E-DB5710FB87DB} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{6C7F47CC-2151-44A3-A546-41C70025132C} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34} = {6C7F47CC-2151-44A3-A546-41C70025132C}
|
||||
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B} = {6C7F47CC-2151-44A3-A546-41C70025132C}
|
||||
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8} = {6C7F47CC-2151-44A3-A546-41C70025132C}
|
||||
{EAF23649-EF6E-478B-980E-81FAD96CCA2A} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{17DA04DF-E393-4397-9CF0-84DABE11032E} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{38BDB927-829B-4C65-9CD9-93FB05D66D65} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{FF742965-9A80-41A5-B042-D6C7D3A21708} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{4AFC9975-2456-4C70-94A4-84073C1CED93} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{59BD9891-3837-438A-958D-ADC7F91F6F7E} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{74F1B9ED-F59C-4FE7-B473-7B453E30837E} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{FDB3555B-58EF-4AE6-B5F1-904719637AB4} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{F8B870EB-D5F5-45BA-9CF7-A5C459818820} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{E364F67B-BB12-4E91-B639-355866EBCD8B} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{880ED251-9E16-4713-9A70-D35FE0C01669} = {E775CC2C-24CB-48D6-9C3A-BE4CCE0DB17A}
|
||||
{2F305555-C296-497E-AC20-5FA1B237996A} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{AF2349B8-E5B6-4004-9502-687C1C7730B1} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{DA425894-6E13-404F-8DCB-78584EC0557A} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{060D75DA-2D1C-48E6-A4A1-6F0718B64661} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{748417CA-F17E-487F-9411-CAFB6D3F4877} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{217DF501-135C-4E38-BFC8-99D4821032EA} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{47310AB4-9034-4BD1-8D8B-E88AD21A171B} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||
{A7D5099E-F0FD-4BF3-8522-5A682759F915} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||
{F055103B-F80B-4D0C-BF48-057C55620033} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{985B3F2F-CEED-4C0A-A249-69257E719145} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{437AD818-3F1F-4CA5-A79B-25233A157026} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{08C8C05F-0362-41BC-818C-724572DF8B06} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{5D00D290-4016-4CFE-9E41-1E7C724509BA} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{4AED67B6-55FD-486F-B917-E543DEE2CB3C} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{42851751-CBC8-45A6-97F5-7A0753F7B4D1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{655C9AF2-18D3-4DA6-80E4-85504A7722BA} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
|
||||
{BA58206B-1493-4C75-BFEA-A85768A1E156} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
|
||||
{1D78B84B-CA39-406C-98F4-71F7EC266CC0} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{03276A39-D4E9-417C-8FFD-200B0EE5E871} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{B81FB7B6-D30E-428F-908A-41422EFC1172} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{0F85E674-34AE-443D-954C-8321EB8B93B1} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||
{632BBE62-5421-49EA-835A-7FFA4F499BD6} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
285
README.md
285
README.md
@@ -1,107 +1,248 @@
|
||||
# Overview
|
||||
|
||||
PowerToys is a set of utilities for power users to tune and streamline their Windows experience for greater productivity.
|
||||
<img src="./doc/images/overview/PT%20hero%20image.png"/>
|
||||
|
||||
Inspired by the [Windows 95 era PowerToys project](https://en.wikipedia.org/wiki/Microsoft_PowerToys), this reboot provides power users with ways to squeeze more efficiency out of the Windows 10 shell and customize it for individual workflows. A great overview of the Windows 95 PowerToys can be found [here](https://socket3.wordpress.com/2016/10/22/using-windows-95-powertoys/).
|
||||
Microsoft PowerToys is a set of utilities for power users to tune and streamline their Windows experience for greater productivity. Inspired by the [Windows 95 era PowerToys project](https://en.wikipedia.org/wiki/Microsoft_PowerToys), this reboot provides power users with ways to squeeze more efficiency out of the Windows 10 shell and customize it for individual workflows. A great overview of the Windows 95 PowerToys can be found [here](https://socket3.wordpress.com/2016/10/22/using-windows-95-powertoys/).
|
||||
|
||||
The first preview of these utilities can be installed from [here](https://github.com/Microsoft/powertoys/releases).
|
||||
For a video overview of PowerToys, including install steps and a walkthrough of the available utilities, check out the [PowerToys: Utilities to customize Windows 10](https://www.youtube.com/watch?v=F-d7KiwpnMA) episode of Tabs vs Spaces on YouTube.
|
||||
|
||||

|
||||
[Downloading & Release notes][github-release-link] | [What's Happening](#whats-happening) | [Contributing to PowerToys](#contributing) | [Known issues](#known-issues)
|
||||
|
||||
# What's Happening
|
||||
## Build status
|
||||
|
||||
## September Update
|
||||
The first preview release of the PowerToys utilities and source code is now live! This release includes two preview quality utilities as well as the tools and docs to make it easy to create new PowerToys utilities.
|
||||
| Branch | Status x64 |
|
||||
|---|---|
|
||||
| Master | [](https://dev.azure.com/ms/PowerToys/_build/latest?definitionId=219&branchName=master) |
|
||||
| Stable | [](https://dev.azure.com/ms/PowerToys/_build/latest?definitionId=219&branchName=stable) |
|
||||
| Installer | [](https://github-private.visualstudio.com/microsoft/_build/latest?definitionId=61&branchName=master) |
|
||||
|
||||
1. [FancyZones](/src/modules/fancyzones/) - FancyZones is a window manager that makes it easy to create copmlex window layouts and quickly position windows into those layouts. The FancyZones backlog can be found [here](https://github.com/Microsoft/PowerToys/tree/master/doc/planning/FancyZonesBacklog.md)
|
||||
## Current PowerToy Utilities
|
||||
|
||||

|
||||
### Color Picker
|
||||
|
||||
FanzyZones Video Tutorial
|
||||
[](https://www.youtube.com/watch?v=rTtGzZYAXgY)
|
||||
[<img align="left" src="https://aka.ms/powerToysColorPickerImageSmall" />](https://aka.ms/PowerToysOverview_ColorPicker) [ColorPicker](https://aka.ms/PowerToysOverview_ColorPicker) is a simple and quick system-wide color picker with <kbd>Win</kbd>+<kbd>Shift</kbd>+<kbd>C</kbd>. Color Picker allows to pick colors from any currently running application and automatically copies the HEX or RGB values to your clipboard. This code is based on [Martin Chrzan's Color Picker](https://github.com/martinchrzan/ColorPicker).
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
2. [Windows key shortcut guide](/src/modules/shortcut_guide) - The shortcut guide appears when a user holds the Windows key down for more than one second and shows the available shortcuts for the current state of the desktop. The shortcut guide backlog can be found [here](https://github.com/Microsoft/PowerToys/tree/master/doc/planning/ShortcutGuideBacklog.md)
|
||||
### FancyZones
|
||||
|
||||

|
||||
[<img align="left" src="https://aka.ms/powerToysFancyZoneImageSmall" />](https://aka.ms/PowerToysOverview_FancyZones) [FancyZones](https://aka.ms/PowerToysOverview_FancyZones) is a window manager that makes it easy to create complex window layouts and quickly position windows into those layouts.
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
Additional utilities in the pipeline are:
|
||||
### File Explorer Add-ons
|
||||
|
||||
* Maximize to new desktop widget - The MTND widget shows a pop-up button when a user hovers over the maximize / restore button on any window. Clicking it creates a new desktop, sends the app to that desktop and maximizes the app on the new desktop.
|
||||
* [Process terminate tool](https://github.com/indierawk2k2/PowerToys-1/blob/master/specs/Terminate%20Spec.md)
|
||||
* [Batch file renamer](https://github.com/indierawk2k2/PowerToys-1/blob/master/specs/File%20Classification%20Spec.md)
|
||||
* [Animated gif screen recorder](https://github.com/indierawk2k2/PowerToys-1/blob/master/specs/GIF%20Maker%20Spec.md)
|
||||
[<img align="left" src="https://aka.ms/powerToysPowerPreviewImageSmall" />](https://aka.ms/PowerToysOverview_FileExplorerAddOns) [File Explorer](https://aka.ms/PowerToysOverview_FileExplorerAddOns) add-ons will enable SVG icon rendering and Preview Pane additions for File Explorer.
|
||||
|
||||
# Backlog
|
||||
Preview Pane is an existing feature in the File Explorer. To enable it, you just click the View tab in the ribbon and then click "Preview Pane". PowerToys will now enable two types of files to be previewed: Markdown (.md) & SVG (.svg)
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
The full backlog of utilities can be found [here](https://github.com/Microsoft/PowerToys/tree/master/doc/planning/PowerToysBacklog.md)
|
||||
### Image Resizer
|
||||
|
||||
# Where to download PowerToys
|
||||
[<img align="left" src="https://aka.ms/powerToysImageResizerImageSmall" />](https://aka.ms/PowerToysOverview_ImageResizer) [Image Resizer](https://aka.ms/PowerToysOverview_ImageResizer) is a Windows Shell Extension for quickly resizing images. With a simple right click from File Explorer, resize one or many images instantly. This code is based on [Brice Lambson's Image Resizer](https://github.com/bricelam/ImageResizer).
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
The latest release of PowerToys can be downloaded from https://github.com/microsoft/PowerToys/releases <br />
|
||||
Click on `Assets` to show the files available in the release and then click on `PowerToysSetup.msi` to download the PowerToys installer. <br />
|
||||
PDB symbols for the release are available in a separate zip file `PDB symbols.zip`.
|
||||
### Keyboard Manager
|
||||
|
||||
# Developer Guidance
|
||||
[<img align="left" src="https://aka.ms/powerToysKBMImageSmall" />](https://aka.ms/PowerToysOverview_KeyboardManager) [Keyboard Manager](https://aka.ms/PowerToysOverview_KeyboardManager) allows you to customize the keyboard to be more productive by remapping keys and creating your own keyboard shortcuts. This PowerToy requires Windows 10 1903 (build 18362) or later.
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
## Build Prerequisites
|
||||
* Windows 10 1803 (build 10.0.17134.0) or above in order to build and run PowerToys.
|
||||
* Visual Studio 2019 Community edition or higher, with the 'Desktop Development with C++' component and the Windows 10 SDK version 10.0.18362.0 or higher.
|
||||
|
||||
## Building the Code
|
||||
* Open `powertoys.sln` in Visual Studio, in the `Solutions Configuration` drop-down menu select `Release` or `Debug`, from the `Build` menu choose `Build Solution`.
|
||||
* The PowerToys binaries will be located in your repo under `x64\Release`.
|
||||
* If you want to copy the `PowerToys.exe` binary to a different location, you'll also need to copy the `modules` and the `svgs` folders.
|
||||
### PowerRename
|
||||
|
||||
## Prerequisites to Build the Installer
|
||||
* Install the [WiX Toolset Visual Studio 2019 Extension](https://marketplace.visualstudio.com/items?itemName=RobMensching.WiXToolset).
|
||||
* Install the [WiX Toolset build tools](https://wixtoolset.org/releases/).
|
||||
|
||||
## Building the .msi Installer
|
||||
* From the `installer` folder open `PowerToysSetup.sln` in Visual Studio, in the `Solutions Configuration` drop-down menu select `Release` or `Debug`, from the `Build` menu choose `Build Solution`.
|
||||
* The resulting `PowerToysSetup.msi` installer will be available in the `installer\PowerToysSetup\x64\Release\` folder.
|
||||
[<img align="left" src="https://aka.ms/powerToysPowerRenameImageSmall" />](https://aka.ms/PowerToysOverview_PowerRename) [PowerRename](https://aka.ms/PowerToysOverview_PowerRename) is a Windows Shell Extension for advanced bulk renaming using search and replace or regular expressions. PowerRename allows simple search and replace or more advanced regular expression matching. While you type in the search and replace input fields, the preview area will show what the items will be renamed to. PowerRename then calls into the Windows Explorer file operations engine to perform the rename. This has the benefit of allowing the rename operation to be undone after PowerRename exits. This code is based on [Chris Davis's SmartRename](https://github.com/chrdavis/SmartRename).
|
||||
<br/>
|
||||
|
||||
## Debugging
|
||||
The following configuration issue only applies if the user is a member of the Administrators group.
|
||||
|
||||
Some PowerToys modules require to run with the highest permission level if the current user is a member of the Administrators group. The highest permission level is required in order to be able to perform some actions when an elevated application (e.g. Task Manager) is in the foreground or is the target of an action. Without elevated privileges some PowerToys modules will still work but with some limitations:
|
||||
- the `FancyZones` module will be not be able to move an elevated window to a zone.
|
||||
- the `Shortcut Guide` module will not appear if the foreground window belongs to an elevated application.
|
||||
|
||||
In order to run and debug PowerToys from Visual Studio when the user is a member of the Administrators group, Visual Studio has to be started with elevated privileges. If you want to avoid running Visual Studio with elevated privileges and don't mind the limitations described above, you can do the following: open the `runner` project properties and navigate to the `Linker -> Manifest File` settings, edit the `UAC Execution Level` property and change it from `highestAvailable (/level='highestAvailable')` to `asInvoker (/level='asInvoker')`, save the changes.
|
||||
|
||||
## How to create new PowerToys
|
||||
### PowerToys Run
|
||||
|
||||
See the instructions on [how to install the PowerToys Module project template](tools/project_template). <br />
|
||||
Specifications for the [PowerToys settings API](doc/specs/PowerToys-settings.md).
|
||||
[<img align="left" src="https://aka.ms/powerToysPowerLauncherImageSmall" />](https://aka.ms/PowerToysOverview_PowerToysRun) [PowerToys Run](https://aka.ms/PowerToysOverview_PowerToysRun) is a new toy in PowerToys that can help you search and launch your app instantly with a simple <kbd>Alt</kbd>+<kbd>Space</kbd> and start typing! It is open source and modular for additional plugins. Window Walker is now inside too! This PowerToy requires Windows 10 1903 (build 18362) or later.
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
## Coding Guidance
|
||||
### Shortcut Guide
|
||||
|
||||
Please review these brief docs below relating to our coding standards etc.
|
||||
[<img align="left" src="https://aka.ms/powerToysShortcutGuideImageSmall" />](https://aka.ms/PowerToysOverview_ShortcutGuide) [Windows key shortcut guide](https://aka.ms/PowerToysOverview_ShortcutGuide) appears when a user holds the Windows key down for more than one second and shows the available shortcuts for the current state of the desktop.
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
> 👉 If you find something missing from these docs, feel free to contribute to any of our documentation files anywhere in the repository (or make some new ones\!)
|
||||
### Video Conference Mute (Experimental)
|
||||
|
||||
This is a work in progress as we learn what we'll need to provide people in order to be effective contributors to our project.
|
||||
- [Coding Style](doc/coding/style.md)
|
||||
- [Code Organization](doc/coding/organization.md)
|
||||
[<img align="left" src="https://aka.ms/powerToysVideoConferenceImageSmall" />](https://aka.ms/PowerToysOverview_VideoConference) [Video Conference Mute](https://aka.ms/PowerToysOverview_VideoConference) is a quick and easy way to do a global "mute" of both your microphone and webcam via <kbd>Win</kbd>+<kbd>N</kbd>. Just set your webcam in the target application to the PowerToys VideoConference camera.
|
||||
|
||||
# Contributing
|
||||
This project welcomes contributions and suggestions and we are excited to work with the power user community to build a set of tools for helping you get the most our of Windows.
|
||||
**Note:** This is only included in the [pre-release experimental version of PowerToys installer][github-prerelease-link]. This PowerToy requires Windows 10 1903 (build 18362) or later.
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
We ask that **before you start work on a feature that you would like to contribute**, please read our [Contributor's Guide](contributing.md). We will be happy to work with you to figure out the best approach, provide guidance and mentorship throughout feature development, and help avoid any wasted or duplicate effort.
|
||||
## Installing and running Microsoft PowerToys
|
||||
|
||||
> ⚠ **Note**: PowerToys is still a nascent project and the team is actively working out of this repository. We will be periodically re-structuring the code to make it easier to comprehend, navigate, build, test, and contribute to, so **DO expect significant changes to code layout on a regular basis**.
|
||||
#### Requirements
|
||||
- Windows 10 1803 (build 17134) or later.
|
||||
- Have [.NET Core 3.1 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet-core/thank-you/runtime-desktop-3.1.4-windows-x64-installer). The installer should handle this but we want to directly make people aware.
|
||||
|
||||
> ⚠ **License Info**: Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.
|
||||
#### 0.18 users for updating via notifications
|
||||
|
||||
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
|
||||
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
|
||||
provided by the bot. You will only need to do this once across all repos using our CLA.
|
||||
- We adjusted how upgrading works in 0.20. In 0.19 we accounted for this upcoming change but if you are going from 0.18 to 0.21, please directly use the installer file.
|
||||
|
||||
# Code of Conduct
|
||||
### Via GitHub with EXE [Recommended]
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct][conduct-code]. <br />
|
||||
For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [opencode@microsoft.com][conduct-email] with any additional questions or comments.
|
||||
Install from the [Microsoft PowerToys GitHub releases page][github-release-link]. Click on `Assets` to show the files available in the release and then click on `PowerToysSetup-0.23.2-x64.exe` to download the PowerToys installer.
|
||||
|
||||
[conduct-code]: https://opensource.microsoft.com/codeofconduct/
|
||||
[conduct-FAQ]: https://opensource.microsoft.com/codeofconduct/faq/
|
||||
[conduct-email]: mailto:opencode@microsoft.com
|
||||
This is our preferred method.
|
||||
|
||||
### Via WinGet (Preview)
|
||||
Download PowerToys from [WinGet](https://github.com/microsoft/winget-cli/releases). To install PowerToys, run the following command from the command line / PowerShell:
|
||||
|
||||
```powershell
|
||||
WinGet install powertoys
|
||||
```
|
||||
|
||||
### Experiential PowerToys utility with Video conference muting
|
||||
|
||||
Install the [pre-release experimental version of PowerToys][github-prerelease-link] to try out this version. It includes all improvements from 0.23 in addition to the Video conference utility. Click on `Assets` to show the files available in the release and then download the .exe installer.
|
||||
|
||||
### Other install methods
|
||||
|
||||
There are [community driven install methods](./doc/unofficalInstallMethods.md) such as Chocolatey and Scoop. If these are your preferred install solutions, this will have the install instructions.
|
||||
|
||||
### Known issues
|
||||
|
||||
- Color Picker at times won't work when PT is running elevated - [#5348](https://github.com/microsoft/PowerToys/issues/5348). We are currently working on a fix now for this.
|
||||
|
||||
### Processor support
|
||||
|
||||
We currently support the matrix below.
|
||||
|
||||
| x64 | x86 | ARM |
|
||||
|:---:|:---:|:---:|
|
||||
| [Supported][github-release-link] | [Issue #602](https://github.com/microsoft/PowerToys/issues/602) | [Issue #490](https://github.com/microsoft/PowerToys/issues/490) |
|
||||
|
||||
## What's Happening
|
||||
|
||||
### September 2020 Update
|
||||
|
||||
Our goals for 0.23 release cycle was to focus on stability, accessibility, localization and quality of life improvements for both the development team and our end users. We have a full accessibility pass being done starting end of September to audit all of PowerToys. Our localization efforts now had data flowing both directions as well.
|
||||
|
||||
Our [prioritized roadmap][roadmap] of features and utilities that the core team is focusing on.
|
||||
|
||||
#### Highlights from September
|
||||
|
||||
- We shipped [v0.23][github-release-link]! (0.24 Experimental build coming shortly)
|
||||
|
||||
**General**
|
||||
|
||||
- Localization pipeline is flowing from our Github to the loc system and back. 0.25 should be localized now.
|
||||
- The EXE installer should be at parity now with the MSI. Please go to the wiki for [installer args](https://github.com/microsoft/PowerToys/wiki/Installer-arguments-for-exe)
|
||||
|
||||
**FancyZones**
|
||||
|
||||
- Fixed bug on not seeing a newly attached screen
|
||||
- Fixed spanning across monitors bug
|
||||
- Added in default layout for new users, a Priority Grid
|
||||
- Added keyboard support to grow / shrink to multiple zones
|
||||
- General bug fixes
|
||||
|
||||
**PT Run**
|
||||
|
||||
- Multiple crash bugs fixed. Prioritized any users reported along with top hits from Watson reporting
|
||||
- Stopped PT Run from interfering with an install
|
||||
- Fixed folder bug if it had a # in it (Thanks @jjw24 for the PR!)
|
||||
- Fixed a screen flicker for
|
||||
- General bug fixes
|
||||
- Allow Command Line args in PowerToys Run (Thanks @@royvou)
|
||||
|
||||
**Keyboard manager**
|
||||
|
||||
- Multiple crash bugs fixed. Prioritized any users reported along with top hits from Watson reporting
|
||||
- Fixed multiple accessibility issues.
|
||||
- General bug fixes
|
||||
|
||||
**Preview Pane**
|
||||
|
||||
- Added in Frontmatter and better (but still basic) latex support.
|
||||
|
||||
**Settings**
|
||||
|
||||
- Fixed scaling issue for responsive design on Image Resizer
|
||||
- Fixed crash on empty color value.
|
||||
- Fixed crash for toggling FancyZones on/off
|
||||
- Fixed 0x00 NFTS crash for settings
|
||||
- Fixed multiple accessibility issues.
|
||||
- Layout adjustments (Thanks @niels9001)
|
||||
- General bug fixes
|
||||
|
||||
**Dev related**
|
||||
|
||||
- FxCop is being rolled out across all PowerToys. This should catch a lot of possible leaks.
|
||||
- Unified PT Run's log system
|
||||
- PT Run's calc plugin now has unit tests (Thanks @P-Storm)
|
||||
- Dev setup install script now supports VS preview (Thanks @TobiasSekan)
|
||||
- @CaelestisZ, @kameshkotwani, @adriancampos, @RahulDas782 for doc tweaks
|
||||
- Thanks @Aaron-Junker, @jay-o-way and @htcfreek for helping triage!
|
||||
- Thanks for everyone that filled an issue. It really does help us prioritize
|
||||
|
||||
#### Video / GIF capture functional spec for public review
|
||||
|
||||
Deondre Davis created our [functional spec for creating a light weight, video / GIF recording tool](https://github.com/microsoft/PowerToys/pull/6900). We encourage everyone to review it and please leave comments in the pull request so we can adjust as needed. We'll be closing it for feedback on October 12th, 2020.
|
||||
|
||||
This is for work [post-stabilization of current roadmap work](https://github.com/microsoft/PowerToys/wiki/Roadmap#post-stabilization) and is only the spec for what we are thinking about support. Just want to set expectations here.
|
||||
|
||||
### What is being planned for 0.25
|
||||
|
||||
For [0.25](https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F13), we are proactively working on:
|
||||
|
||||
- Stability
|
||||
- Localization
|
||||
- Improve interactions with elevated windows and keeping most of the PT utilities non-elevated so we still have a 'shell' like experience
|
||||
- OOBE work
|
||||
|
||||
### PowerToys roadmap
|
||||
|
||||
Our [prioritized roadmap][roadmap] of features and utilities that the core team is focusing on.
|
||||
|
||||
## Developer Guidance
|
||||
|
||||
Please read the [developer docs](/doc/devdocs) for a detailed breakdown.
|
||||
|
||||
## Contributing
|
||||
|
||||
This project welcomes contributions of all types. Help spec'ing, design, documentation, finding bugs are ways everyone can help on top of coding features / bug fixes. We are excited to work with the power user community to build a set of tools for helping you get the most out of Windows.
|
||||
|
||||
We ask that **before you start work on a feature that you would like to contribute**, please read our [Contributor's Guide](CONTRIBUTING.md). We will be happy to work with you to figure out the best approach, provide guidance and mentorship throughout feature development, and help avoid any wasted or duplicate effort.
|
||||
|
||||
### ⚠ State of code ⚠
|
||||
|
||||
PowerToys is still a very fluidic project and the team is actively working out of this repository. We will be periodically re-structuring/refactoring the code to make it easier to comprehend, navigate, build, test, and contribute to, so **DO expect significant changes to code layout on a regular basis**.
|
||||
|
||||
### License Info
|
||||
|
||||
Most contributions require you to agree to a [Contributor License Agreement (CLA)][oss-CLA] declaring that you have the right to, and actually do, grant us the rights to use your contribution.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct][oss-conduct-code].
|
||||
|
||||
## Privacy Statement
|
||||
|
||||
The application logs basic telemetry. Our Telemetry Data page (Coming Soon) has the trends from the telemetry. Please read the [Microsoft privacy statement][privacyLink] for more information.
|
||||
|
||||
[oss-CLA]: https://cla.opensource.microsoft.com
|
||||
[oss-conduct-code]: CODE_OF_CONDUCT.md
|
||||
[github-release-link]: https://github.com/microsoft/PowerToys/releases/
|
||||
[github-prerelease-link]: https://github.com/microsoft/PowerToys/releases/tag/v0.24.0-Experimental
|
||||
[roadmap]: https://github.com/microsoft/PowerToys/wiki/Roadmap
|
||||
[privacyLink]: http://go.microsoft.com/fwlink/?LinkId=521839
|
||||
[vidConfOverview]: https://aka.ms/PowerToysOverview_VideoConference
|
||||
|
||||
41
SECURITY.md
Normal file
41
SECURITY.md
Normal file
@@ -0,0 +1,41 @@
|
||||
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.2 BLOCK -->
|
||||
|
||||
## Security
|
||||
|
||||
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [many more](https://opensource.microsoft.com/).
|
||||
|
||||
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets Microsoft's [definition](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)) of a security vulnerability, please report it to us as described below.
|
||||
|
||||
## Reporting Security Issues
|
||||
|
||||
**Please do not report security vulnerabilities through public GitHub issues.**
|
||||
|
||||
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
|
||||
|
||||
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc).
|
||||
|
||||
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
|
||||
|
||||
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
|
||||
|
||||
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
|
||||
* Full paths of source file(s) related to the manifestation of the issue
|
||||
* The location of the affected source code (tag/branch/commit or direct URL)
|
||||
* Any special configuration required to reproduce the issue
|
||||
* Step-by-step instructions to reproduce the issue
|
||||
* Proof-of-concept or exploit code (if possible)
|
||||
* Impact of the issue, including how an attacker might exploit the issue
|
||||
|
||||
This information will help us triage your report more quickly.
|
||||
|
||||
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.
|
||||
|
||||
## Preferred Languages
|
||||
|
||||
We prefer all communications to be in English.
|
||||
|
||||
## Policy
|
||||
|
||||
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd).
|
||||
|
||||
<!-- END MICROSOFT SECURITY.MD BLOCK -->
|
||||
18
SUPPORT.md
Normal file
18
SUPPORT.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Support
|
||||
|
||||
## How to file issues and get help
|
||||
|
||||
This project uses [GitHub Issues][gh-issue] to [track bugs][gh-bug] and [feature requests][gh-feature]. Please search the existing issues before filing new issues to avoid duplicates. For new issues, file your bug or
|
||||
feature request as a new Issue.
|
||||
|
||||
For help and questions about using this project, please look at our Wiki for using PowerToys and our [Contributor's Guide][contributor] if you want to work on PowerToys.
|
||||
|
||||
## Microsoft Support Policy
|
||||
|
||||
Support for PowerToys is limited to the resources listed above.
|
||||
|
||||
[gh-issue]: https://github.com/microsoft/PowerToys/issues/new/choose
|
||||
[gh-bug]: https://github.com/microsoft/PowerToys/issues/new?assignees=&labels=Issue-Bug&template=bug_report.md&title=
|
||||
[gh-feature]: https://github.com/microsoft/PowerToys/issues/new?assignees=&labels=&template=feature_request.md&title=
|
||||
[wiki]: https://github.com/microsoft/PowerToys/wiki
|
||||
[contributor]: https://github.com/microsoft/PowerToys/blob/master/CONTRIBUTING.md
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 324 KiB |
@@ -1,35 +0,0 @@
|
||||
parameters:
|
||||
additionalBuildArguments: ''
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: true
|
||||
clean: true
|
||||
|
||||
- task: NuGetToolInstaller@0
|
||||
displayName: Ensure NuGet 4.8.1
|
||||
inputs:
|
||||
versionSpec: 4.8.1
|
||||
|
||||
- task: VisualStudioTestPlatformInstaller@1
|
||||
displayName: Ensure VSTest Platform
|
||||
|
||||
- task: NuGetCommand@2
|
||||
displayName: Restore NuGet packages
|
||||
inputs:
|
||||
command: restore
|
||||
feedsToUse: config
|
||||
configPath: NuGet.config
|
||||
restoreSolution: PowerToys.sln
|
||||
restoreDirectory: '$(Build.SourcesDirectory)\packages'
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: 'Build solution **\PowerToys.sln'
|
||||
inputs:
|
||||
solution: '**\PowerToys.sln'
|
||||
vsVersion: 15.0
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
msbuildArgs: ${{ parameters.additionalBuildArguments }}
|
||||
clean: true
|
||||
maximumCpuCount: true
|
||||
12
deps/cpprestsdk/README.md
vendored
12
deps/cpprestsdk/README.md
vendored
@@ -1,12 +0,0 @@
|
||||
# C++ Rest SDK - JSON library
|
||||
|
||||
This JSON library is taken from the C++ REST SDK in https://github.com/microsoft/cpprestsdk
|
||||
|
||||
Based in the [v2.10.13 release](https://github.com/microsoft/cpprestsdk/tree/v2.10.13/Release), it consists of the needed files to build and use the JSON classes described in `include/cpprest/json.h`.
|
||||
|
||||
Changes made to the files in order to build in the PowerToys project:
|
||||
- Removal of `#include` references to files that are not needed.
|
||||
- `#include "pch.h"` instead of `#include "stdafx.h"` to use the PowerToys pre-compiled header.
|
||||
- `#define _NO_ASYNCRTIMP` in [`include/cpprest/details/cpprest_compat.h`](./include/cpprest/details/cpprest_compat.h) since this class will be statically linked.
|
||||
|
||||
The contents of the C++ Rest SDK license are included in [license.txt](./license.txt).
|
||||
697
deps/cpprestsdk/include/cpprest/asyncrt_utils.h
vendored
697
deps/cpprestsdk/include/cpprest/asyncrt_utils.h
vendored
@@ -1,697 +0,0 @@
|
||||
/***
|
||||
* Copyright (C) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
*
|
||||
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
*
|
||||
* Various common utilities.
|
||||
*
|
||||
* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
|
||||
*
|
||||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
****/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpprest/details/basic_types.h"
|
||||
//#include "pplx/pplxtasks.h"
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <vector>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#if !defined(ANDROID) && !defined(__ANDROID__) && defined(HAVE_XLOCALE_H) // CodePlex 269
|
||||
/* Systems using glibc: xlocale.h has been removed from glibc 2.26
|
||||
The above include of locale.h is sufficient
|
||||
Further details: https://sourceware.org/git/?p=glibc.git;a=commit;h=f0be25b6336db7492e47d2e8e72eb8af53b5506d */
|
||||
#include <xlocale.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/// Various utilities for string conversions and date and time manipulation.
|
||||
namespace utility
|
||||
{
|
||||
// Left over from VS2010 support, remains to avoid breaking.
|
||||
typedef std::chrono::seconds seconds;
|
||||
|
||||
/// Functions for converting to/from std::chrono::seconds to xml string.
|
||||
namespace timespan
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a timespan/interval in seconds to xml duration string as specified by
|
||||
/// http://www.w3.org/TR/xmlschema-2/#duration
|
||||
/// </summary>
|
||||
_ASYNCRTIMP utility::string_t __cdecl seconds_to_xml_duration(utility::seconds numSecs);
|
||||
|
||||
/// <summary>
|
||||
/// Converts an xml duration to timespan/interval in seconds
|
||||
/// http://www.w3.org/TR/xmlschema-2/#duration
|
||||
/// </summary>
|
||||
_ASYNCRTIMP utility::seconds __cdecl xml_duration_to_seconds(const utility::string_t& timespanString);
|
||||
} // namespace timespan
|
||||
|
||||
/// Functions for Unicode string conversions.
|
||||
namespace conversions
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a UTF-16 string to a UTF-8 string.
|
||||
/// </summary>
|
||||
/// <param name="w">A two byte character UTF-16 string.</param>
|
||||
/// <returns>A single byte character UTF-8 string.</returns>
|
||||
_ASYNCRTIMP std::string __cdecl utf16_to_utf8(const utf16string& w);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a UTF-8 string to a UTF-16
|
||||
/// </summary>
|
||||
/// <param name="s">A single byte character UTF-8 string.</param>
|
||||
/// <returns>A two byte character UTF-16 string.</returns>
|
||||
_ASYNCRTIMP utf16string __cdecl utf8_to_utf16(const std::string& s);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a ASCII (us-ascii) string to a UTF-16 string.
|
||||
/// </summary>
|
||||
/// <param name="s">A single byte character us-ascii string.</param>
|
||||
/// <returns>A two byte character UTF-16 string.</returns>
|
||||
_ASYNCRTIMP utf16string __cdecl usascii_to_utf16(const std::string& s);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Latin1 (iso-8859-1) string to a UTF-16 string.
|
||||
/// </summary>
|
||||
/// <param name="s">A single byte character UTF-8 string.</param>
|
||||
/// <returns>A two byte character UTF-16 string.</returns>
|
||||
_ASYNCRTIMP utf16string __cdecl latin1_to_utf16(const std::string& s);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Latin1 (iso-8859-1) string to a UTF-8 string.
|
||||
/// </summary>
|
||||
/// <param name="s">A single byte character UTF-8 string.</param>
|
||||
/// <returns>A single byte character UTF-8 string.</returns>
|
||||
_ASYNCRTIMP utf8string __cdecl latin1_to_utf8(const std::string& s);
|
||||
|
||||
/// <summary>
|
||||
/// Converts to a platform dependent Unicode string type.
|
||||
/// </summary>
|
||||
/// <param name="s">A single byte character UTF-8 string.</param>
|
||||
/// <returns>A platform dependent string type.</returns>
|
||||
#ifdef _UTF16_STRINGS
|
||||
_ASYNCRTIMP utility::string_t __cdecl to_string_t(std::string&& s);
|
||||
#else
|
||||
inline utility::string_t&& to_string_t(std::string&& s) { return std::move(s); }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Converts to a platform dependent Unicode string type.
|
||||
/// </summary>
|
||||
/// <param name="s">A two byte character UTF-16 string.</param>
|
||||
/// <returns>A platform dependent string type.</returns>
|
||||
#ifdef _UTF16_STRINGS
|
||||
inline utility::string_t&& to_string_t(utf16string&& s) { return std::move(s); }
|
||||
#else
|
||||
_ASYNCRTIMP utility::string_t __cdecl to_string_t(utf16string&& s);
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Converts to a platform dependent Unicode string type.
|
||||
/// </summary>
|
||||
/// <param name="s">A single byte character UTF-8 string.</param>
|
||||
/// <returns>A platform dependent string type.</returns>
|
||||
#ifdef _UTF16_STRINGS
|
||||
_ASYNCRTIMP utility::string_t __cdecl to_string_t(const std::string& s);
|
||||
#else
|
||||
inline const utility::string_t& to_string_t(const std::string& s) { return s; }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Converts to a platform dependent Unicode string type.
|
||||
/// </summary>
|
||||
/// <param name="s">A two byte character UTF-16 string.</param>
|
||||
/// <returns>A platform dependent string type.</returns>
|
||||
#ifdef _UTF16_STRINGS
|
||||
inline const utility::string_t& to_string_t(const utf16string& s) { return s; }
|
||||
#else
|
||||
_ASYNCRTIMP utility::string_t __cdecl to_string_t(const utf16string& s);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Converts to a UTF-16 from string.
|
||||
/// </summary>
|
||||
/// <param name="value">A single byte character UTF-8 string.</param>
|
||||
/// <returns>A two byte character UTF-16 string.</returns>
|
||||
_ASYNCRTIMP utf16string __cdecl to_utf16string(const std::string& value);
|
||||
|
||||
/// <summary>
|
||||
/// Converts to a UTF-16 from string.
|
||||
/// </summary>
|
||||
/// <param name="value">A two byte character UTF-16 string.</param>
|
||||
/// <returns>A two byte character UTF-16 string.</returns>
|
||||
inline const utf16string& to_utf16string(const utf16string& value) { return value; }
|
||||
/// <summary>
|
||||
/// Converts to a UTF-16 from string.
|
||||
/// </summary>
|
||||
/// <param name="value">A two byte character UTF-16 string.</param>
|
||||
/// <returns>A two byte character UTF-16 string.</returns>
|
||||
inline utf16string&& to_utf16string(utf16string&& value) { return std::move(value); }
|
||||
|
||||
/// <summary>
|
||||
/// Converts to a UTF-8 string.
|
||||
/// </summary>
|
||||
/// <param name="value">A single byte character UTF-8 string.</param>
|
||||
/// <returns>A single byte character UTF-8 string.</returns>
|
||||
inline std::string&& to_utf8string(std::string&& value) { return std::move(value); }
|
||||
|
||||
/// <summary>
|
||||
/// Converts to a UTF-8 string.
|
||||
/// </summary>
|
||||
/// <param name="value">A single byte character UTF-8 string.</param>
|
||||
/// <returns>A single byte character UTF-8 string.</returns>
|
||||
inline const std::string& to_utf8string(const std::string& value) { return value; }
|
||||
|
||||
/// <summary>
|
||||
/// Converts to a UTF-8 string.
|
||||
/// </summary>
|
||||
/// <param name="value">A two byte character UTF-16 string.</param>
|
||||
/// <returns>A single byte character UTF-8 string.</returns>
|
||||
_ASYNCRTIMP std::string __cdecl to_utf8string(const utf16string& value);
|
||||
|
||||
/// <summary>
|
||||
/// Encode the given byte array into a base64 string
|
||||
/// </summary>
|
||||
_ASYNCRTIMP utility::string_t __cdecl to_base64(const std::vector<unsigned char>& data);
|
||||
|
||||
/// <summary>
|
||||
/// Encode the given 8-byte integer into a base64 string
|
||||
/// </summary>
|
||||
_ASYNCRTIMP utility::string_t __cdecl to_base64(uint64_t data);
|
||||
|
||||
/// <summary>
|
||||
/// Decode the given base64 string to a byte array
|
||||
/// </summary>
|
||||
_ASYNCRTIMP std::vector<unsigned char> __cdecl from_base64(const utility::string_t& str);
|
||||
|
||||
template<typename Source>
|
||||
CASABLANCA_DEPRECATED("All locale-sensitive APIs will be removed in a future update. Use stringstreams directly if "
|
||||
"locale support is required.")
|
||||
utility::string_t print_string(const Source& val, const std::locale& loc = std::locale())
|
||||
{
|
||||
utility::ostringstream_t oss;
|
||||
oss.imbue(loc);
|
||||
oss << val;
|
||||
if (oss.bad())
|
||||
{
|
||||
throw std::bad_cast();
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
CASABLANCA_DEPRECATED("All locale-sensitive APIs will be removed in a future update. Use stringstreams directly if "
|
||||
"locale support is required.")
|
||||
inline utility::string_t print_string(const utility::string_t& val) { return val; }
|
||||
|
||||
namespace details
|
||||
{
|
||||
#if defined(__ANDROID__)
|
||||
template<class T>
|
||||
inline std::string to_string(const T t)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.imbue(std::locale::classic());
|
||||
os << t;
|
||||
return os.str();
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline utility::string_t to_string_t(const T t)
|
||||
{
|
||||
#ifdef _UTF16_STRINGS
|
||||
using std::to_wstring;
|
||||
return to_wstring(t);
|
||||
#else
|
||||
#if !defined(__ANDROID__)
|
||||
using std::to_string;
|
||||
#endif
|
||||
return to_string(t);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Source>
|
||||
utility::string_t print_string(const Source& val)
|
||||
{
|
||||
utility::ostringstream_t oss;
|
||||
oss.imbue(std::locale::classic());
|
||||
oss << val;
|
||||
if (oss.bad())
|
||||
{
|
||||
throw std::bad_cast();
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
inline const utility::string_t& print_string(const utility::string_t& val) { return val; }
|
||||
|
||||
template<typename Source>
|
||||
utf8string print_utf8string(const Source& val)
|
||||
{
|
||||
return conversions::to_utf8string(print_string(val));
|
||||
}
|
||||
inline const utf8string& print_utf8string(const utf8string& val) { return val; }
|
||||
|
||||
template<typename Target>
|
||||
Target scan_string(const utility::string_t& str)
|
||||
{
|
||||
Target t;
|
||||
utility::istringstream_t iss(str);
|
||||
iss.imbue(std::locale::classic());
|
||||
iss >> t;
|
||||
if (iss.bad())
|
||||
{
|
||||
throw std::bad_cast();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
inline const utility::string_t& scan_string(const utility::string_t& str) { return str; }
|
||||
} // namespace details
|
||||
|
||||
template<typename Target>
|
||||
CASABLANCA_DEPRECATED("All locale-sensitive APIs will be removed in a future update. Use stringstreams directly if "
|
||||
"locale support is required.")
|
||||
Target scan_string(const utility::string_t& str, const std::locale& loc = std::locale())
|
||||
{
|
||||
Target t;
|
||||
utility::istringstream_t iss(str);
|
||||
iss.imbue(loc);
|
||||
iss >> t;
|
||||
if (iss.bad())
|
||||
{
|
||||
throw std::bad_cast();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
CASABLANCA_DEPRECATED("All locale-sensitive APIs will be removed in a future update. Use stringstreams directly if "
|
||||
"locale support is required.")
|
||||
inline utility::string_t scan_string(const utility::string_t& str) { return str; }
|
||||
} // namespace conversions
|
||||
|
||||
namespace details
|
||||
{
|
||||
/// <summary>
|
||||
/// Cross platform RAII container for setting thread local locale.
|
||||
/// </summary>
|
||||
class scoped_c_thread_locale
|
||||
{
|
||||
public:
|
||||
_ASYNCRTIMP scoped_c_thread_locale();
|
||||
_ASYNCRTIMP ~scoped_c_thread_locale();
|
||||
|
||||
#if !defined(ANDROID) && !defined(__ANDROID__) // CodePlex 269
|
||||
#ifdef _WIN32
|
||||
typedef _locale_t xplat_locale;
|
||||
#else
|
||||
typedef locale_t xplat_locale;
|
||||
#endif
|
||||
|
||||
static _ASYNCRTIMP xplat_locale __cdecl c_locale();
|
||||
#endif
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
std::string m_prevLocale;
|
||||
int m_prevThreadSetting;
|
||||
#elif !(defined(ANDROID) || defined(__ANDROID__))
|
||||
locale_t m_prevLocale;
|
||||
#endif
|
||||
scoped_c_thread_locale(const scoped_c_thread_locale&);
|
||||
scoped_c_thread_locale& operator=(const scoped_c_thread_locale&);
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Our own implementation of alpha numeric instead of std::isalnum to avoid
|
||||
/// taking global lock for performance reasons.
|
||||
/// </summary>
|
||||
inline bool __cdecl is_alnum(const unsigned char uch) CPPREST_NOEXCEPT
|
||||
{ // test if uch is an alnum character
|
||||
// special casing char to avoid branches
|
||||
// clang-format off
|
||||
static CPPREST_CONSTEXPR bool is_alnum_table[UCHAR_MAX + 1] = {
|
||||
/* X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 XA XB XC XD XE XF */
|
||||
/* 0X */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 1X */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 2X */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 3X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0-9 */
|
||||
/* 4X */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A-Z */
|
||||
/* 5X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
||||
/* 6X */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a-z */
|
||||
/* 7X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
|
||||
/* non-ASCII values initialized to 0 */
|
||||
};
|
||||
// clang-format on
|
||||
return (is_alnum_table[uch]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Our own implementation of alpha numeric instead of std::isalnum to avoid
|
||||
/// taking global lock for performance reasons.
|
||||
/// </summary>
|
||||
inline bool __cdecl is_alnum(const char ch) CPPREST_NOEXCEPT { return (is_alnum(static_cast<unsigned char>(ch))); }
|
||||
|
||||
/// <summary>
|
||||
/// Our own implementation of alpha numeric instead of std::isalnum to avoid
|
||||
/// taking global lock for performance reasons.
|
||||
/// </summary>
|
||||
template<class Elem>
|
||||
inline bool __cdecl is_alnum(Elem ch) CPPREST_NOEXCEPT
|
||||
{
|
||||
// assumes 'x' == L'x' for the ASCII range
|
||||
typedef typename std::make_unsigned<Elem>::type UElem;
|
||||
const auto uch = static_cast<UElem>(ch);
|
||||
return (uch <= static_cast<UElem>('z') && is_alnum(static_cast<unsigned char>(uch)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simplistic implementation of make_unique. A better implementation would be based on variadic templates
|
||||
/// and therefore not be compatible with Dev10.
|
||||
/// </summary>
|
||||
template<typename _Type>
|
||||
std::unique_ptr<_Type> make_unique()
|
||||
{
|
||||
return std::unique_ptr<_Type>(new _Type());
|
||||
}
|
||||
|
||||
template<typename _Type, typename _Arg1>
|
||||
std::unique_ptr<_Type> make_unique(_Arg1&& arg1)
|
||||
{
|
||||
return std::unique_ptr<_Type>(new _Type(std::forward<_Arg1>(arg1)));
|
||||
}
|
||||
|
||||
template<typename _Type, typename _Arg1, typename _Arg2>
|
||||
std::unique_ptr<_Type> make_unique(_Arg1&& arg1, _Arg2&& arg2)
|
||||
{
|
||||
return std::unique_ptr<_Type>(new _Type(std::forward<_Arg1>(arg1), std::forward<_Arg2>(arg2)));
|
||||
}
|
||||
|
||||
template<typename _Type, typename _Arg1, typename _Arg2, typename _Arg3>
|
||||
std::unique_ptr<_Type> make_unique(_Arg1&& arg1, _Arg2&& arg2, _Arg3&& arg3)
|
||||
{
|
||||
return std::unique_ptr<_Type>(
|
||||
new _Type(std::forward<_Arg1>(arg1), std::forward<_Arg2>(arg2), std::forward<_Arg3>(arg3)));
|
||||
}
|
||||
|
||||
template<typename _Type, typename _Arg1, typename _Arg2, typename _Arg3, typename _Arg4>
|
||||
std::unique_ptr<_Type> make_unique(_Arg1&& arg1, _Arg2&& arg2, _Arg3&& arg3, _Arg4&& arg4)
|
||||
{
|
||||
return std::unique_ptr<_Type>(new _Type(
|
||||
std::forward<_Arg1>(arg1), std::forward<_Arg2>(arg2), std::forward<_Arg3>(arg3), std::forward<_Arg4>(arg4)));
|
||||
}
|
||||
|
||||
template<typename _Type, typename _Arg1, typename _Arg2, typename _Arg3, typename _Arg4, typename _Arg5>
|
||||
std::unique_ptr<_Type> make_unique(_Arg1&& arg1, _Arg2&& arg2, _Arg3&& arg3, _Arg4&& arg4, _Arg5&& arg5)
|
||||
{
|
||||
return std::unique_ptr<_Type>(new _Type(std::forward<_Arg1>(arg1),
|
||||
std::forward<_Arg2>(arg2),
|
||||
std::forward<_Arg3>(arg3),
|
||||
std::forward<_Arg4>(arg4),
|
||||
std::forward<_Arg5>(arg5)));
|
||||
}
|
||||
|
||||
template<typename _Type, typename _Arg1, typename _Arg2, typename _Arg3, typename _Arg4, typename _Arg5, typename _Arg6>
|
||||
std::unique_ptr<_Type> make_unique(_Arg1&& arg1, _Arg2&& arg2, _Arg3&& arg3, _Arg4&& arg4, _Arg5&& arg5, _Arg6&& arg6)
|
||||
{
|
||||
return std::unique_ptr<_Type>(new _Type(std::forward<_Arg1>(arg1),
|
||||
std::forward<_Arg2>(arg2),
|
||||
std::forward<_Arg3>(arg3),
|
||||
std::forward<_Arg4>(arg4),
|
||||
std::forward<_Arg5>(arg5),
|
||||
std::forward<_Arg6>(arg6)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cross platform utility function for performing case insensitive string equality comparison.
|
||||
/// </summary>
|
||||
/// <param name="left">First string to compare.</param>
|
||||
/// <param name="right">Second strong to compare.</param>
|
||||
/// <returns>true if the strings are equivalent, false otherwise</returns>
|
||||
_ASYNCRTIMP bool __cdecl str_iequal(const std::string& left, const std::string& right) CPPREST_NOEXCEPT;
|
||||
|
||||
/// <summary>
|
||||
/// Cross platform utility function for performing case insensitive string equality comparison.
|
||||
/// </summary>
|
||||
/// <param name="left">First string to compare.</param>
|
||||
/// <param name="right">Second strong to compare.</param>
|
||||
/// <returns>true if the strings are equivalent, false otherwise</returns>
|
||||
_ASYNCRTIMP bool __cdecl str_iequal(const std::wstring& left, const std::wstring& right) CPPREST_NOEXCEPT;
|
||||
|
||||
/// <summary>
|
||||
/// Cross platform utility function for performing case insensitive string less-than comparison.
|
||||
/// </summary>
|
||||
/// <param name="left">First string to compare.</param>
|
||||
/// <param name="right">Second strong to compare.</param>
|
||||
/// <returns>true if a lowercase view of left is lexicographically less than a lowercase view of right; otherwise,
|
||||
/// false.</returns>
|
||||
_ASYNCRTIMP bool __cdecl str_iless(const std::string& left, const std::string& right) CPPREST_NOEXCEPT;
|
||||
|
||||
/// <summary>
|
||||
/// Cross platform utility function for performing case insensitive string less-than comparison.
|
||||
/// </summary>
|
||||
/// <param name="left">First string to compare.</param>
|
||||
/// <param name="right">Second strong to compare.</param>
|
||||
/// <returns>true if a lowercase view of left is lexicographically less than a lowercase view of right; otherwise,
|
||||
/// false.</returns>
|
||||
_ASYNCRTIMP bool __cdecl str_iless(const std::wstring& left, const std::wstring& right) CPPREST_NOEXCEPT;
|
||||
|
||||
/// <summary>
|
||||
/// Convert a string to lowercase in place.
|
||||
/// </summary>
|
||||
/// <param name="target">The string to convert to lowercase.</param>
|
||||
_ASYNCRTIMP void __cdecl inplace_tolower(std::string& target) CPPREST_NOEXCEPT;
|
||||
|
||||
/// <summary>
|
||||
/// Convert a string to lowercase in place.
|
||||
/// </summary>
|
||||
/// <param name="target">The string to convert to lowercase.</param>
|
||||
_ASYNCRTIMP void __cdecl inplace_tolower(std::wstring& target) CPPREST_NOEXCEPT;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/// <summary>
|
||||
/// Category error type for Windows OS errors.
|
||||
/// </summary>
|
||||
class windows_category_impl : public std::error_category
|
||||
{
|
||||
public:
|
||||
virtual const char* name() const CPPREST_NOEXCEPT { return "windows"; }
|
||||
|
||||
virtual std::string message(int errorCode) const CPPREST_NOEXCEPT;
|
||||
|
||||
virtual std::error_condition default_error_condition(int errorCode) const CPPREST_NOEXCEPT;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets the one global instance of the windows error category.
|
||||
/// </summary>
|
||||
/// </returns>An error category instance.</returns>
|
||||
_ASYNCRTIMP const std::error_category& __cdecl windows_category();
|
||||
|
||||
#else
|
||||
|
||||
/// <summary>
|
||||
/// Gets the one global instance of the linux error category.
|
||||
/// </summary>
|
||||
/// </returns>An error category instance.</returns>
|
||||
_ASYNCRTIMP const std::error_category& __cdecl linux_category();
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Gets the one global instance of the current platform's error category.
|
||||
/// </summary>
|
||||
_ASYNCRTIMP const std::error_category& __cdecl platform_category();
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of std::system_error from a OS error code.
|
||||
/// </summary>
|
||||
inline std::system_error __cdecl create_system_error(unsigned long errorCode)
|
||||
{
|
||||
std::error_code code((int)errorCode, platform_category());
|
||||
return std::system_error(code, code.message());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a std::error_code from a OS error code.
|
||||
/// </summary>
|
||||
inline std::error_code __cdecl create_error_code(unsigned long errorCode)
|
||||
{
|
||||
return std::error_code((int)errorCode, platform_category());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the corresponding error message from a OS error code.
|
||||
/// </summary>
|
||||
inline utility::string_t __cdecl create_error_message(unsigned long errorCode)
|
||||
{
|
||||
return utility::conversions::to_string_t(create_error_code(errorCode).message());
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
class datetime
|
||||
{
|
||||
public:
|
||||
typedef uint64_t interval_type;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the supported date and time string formats.
|
||||
/// </summary>
|
||||
enum date_format
|
||||
{
|
||||
RFC_1123,
|
||||
ISO_8601
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current UTC time.
|
||||
/// </summary>
|
||||
static _ASYNCRTIMP datetime __cdecl utc_now();
|
||||
|
||||
/// <summary>
|
||||
/// An invalid UTC timestamp value.
|
||||
/// </summary>
|
||||
enum : interval_type
|
||||
{
|
||||
utc_timestamp_invalid = static_cast<interval_type>(-1)
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Returns seconds since Unix/POSIX time epoch at 01-01-1970 00:00:00.
|
||||
/// If time is before epoch, utc_timestamp_invalid is returned.
|
||||
/// </summary>
|
||||
static interval_type utc_timestamp()
|
||||
{
|
||||
const auto seconds = utc_now().to_interval() / _secondTicks;
|
||||
if (seconds >= 11644473600LL)
|
||||
{
|
||||
return seconds - 11644473600LL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return utc_timestamp_invalid;
|
||||
}
|
||||
}
|
||||
|
||||
datetime() : m_interval(0) {}
|
||||
|
||||
/// <summary>
|
||||
/// Creates <c>datetime</c> from a string representing time in UTC in RFC 1123 format.
|
||||
/// </summary>
|
||||
/// <returns>Returns a <c>datetime</c> of zero if not successful.</returns>
|
||||
static _ASYNCRTIMP datetime __cdecl from_string(const utility::string_t& timestring, date_format format = RFC_1123);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string representation of the <c>datetime</c>.
|
||||
/// </summary>
|
||||
_ASYNCRTIMP utility::string_t to_string(date_format format = RFC_1123) const;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the integral time value.
|
||||
/// </summary>
|
||||
interval_type to_interval() const { return m_interval; }
|
||||
|
||||
datetime operator-(interval_type value) const { return datetime(m_interval - value); }
|
||||
|
||||
datetime operator+(interval_type value) const { return datetime(m_interval + value); }
|
||||
|
||||
bool operator==(datetime dt) const { return m_interval == dt.m_interval; }
|
||||
|
||||
bool operator!=(const datetime& dt) const { return !(*this == dt); }
|
||||
|
||||
static interval_type from_milliseconds(unsigned int milliseconds) { return milliseconds * _msTicks; }
|
||||
|
||||
static interval_type from_seconds(unsigned int seconds) { return seconds * _secondTicks; }
|
||||
|
||||
static interval_type from_minutes(unsigned int minutes) { return minutes * _minuteTicks; }
|
||||
|
||||
static interval_type from_hours(unsigned int hours) { return hours * _hourTicks; }
|
||||
|
||||
static interval_type from_days(unsigned int days) { return days * _dayTicks; }
|
||||
|
||||
bool is_initialized() const { return m_interval != 0; }
|
||||
|
||||
private:
|
||||
friend int operator-(datetime t1, datetime t2);
|
||||
|
||||
static const interval_type _msTicks = static_cast<interval_type>(10000);
|
||||
static const interval_type _secondTicks = 1000 * _msTicks;
|
||||
static const interval_type _minuteTicks = 60 * _secondTicks;
|
||||
static const interval_type _hourTicks = 60 * 60 * _secondTicks;
|
||||
static const interval_type _dayTicks = 24 * 60 * 60 * _secondTicks;
|
||||
|
||||
// Private constructor. Use static methods to create an instance.
|
||||
datetime(interval_type interval) : m_interval(interval) {}
|
||||
|
||||
// Storing as hundreds of nanoseconds 10e-7, i.e. 1 here equals 100ns.
|
||||
interval_type m_interval;
|
||||
};
|
||||
|
||||
inline int operator-(datetime t1, datetime t2)
|
||||
{
|
||||
auto diff = (t1.m_interval - t2.m_interval);
|
||||
|
||||
// Round it down to seconds
|
||||
diff /= 10 * 1000 * 1000;
|
||||
|
||||
return static_cast<int>(diff);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Nonce string generator class.
|
||||
/// </summary>
|
||||
class nonce_generator
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
/// Define default nonce length.
|
||||
/// </summary>
|
||||
enum
|
||||
{
|
||||
default_length = 32
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Nonce generator constructor.
|
||||
/// </summary>
|
||||
/// <param name="length">Length of the generated nonce string.</param>
|
||||
nonce_generator(int length = default_length)
|
||||
: m_random(static_cast<unsigned int>(utility::datetime::utc_timestamp())), m_length(length)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a nonce string containing random alphanumeric characters (A-Za-z0-9).
|
||||
/// Length of the generated string is set by length().
|
||||
/// </summary>
|
||||
/// <returns>The generated nonce string.</returns>
|
||||
_ASYNCRTIMP utility::string_t generate();
|
||||
|
||||
/// <summary>
|
||||
/// Get length of generated nonce string.
|
||||
/// </summary>
|
||||
/// <returns>Nonce string length.</returns>
|
||||
int length() const { return m_length; }
|
||||
|
||||
/// <summary>
|
||||
/// Set length of the generated nonce string.
|
||||
/// </summary>
|
||||
/// <param name="length">Lenght of nonce string.</param>
|
||||
void set_length(int length) { m_length = length; }
|
||||
|
||||
private:
|
||||
std::mt19937 m_random;
|
||||
int m_length;
|
||||
};
|
||||
|
||||
} // namespace utility
|
||||
391
deps/cpprestsdk/include/cpprest/base_uri.h
vendored
391
deps/cpprestsdk/include/cpprest/base_uri.h
vendored
@@ -1,391 +0,0 @@
|
||||
/***
|
||||
* Copyright (C) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
*
|
||||
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
*
|
||||
* Protocol independent support for URIs.
|
||||
*
|
||||
* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
|
||||
*
|
||||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
****/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpprest/asyncrt_utils.h"
|
||||
#include "cpprest/details/basic_types.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace web
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
struct uri_components
|
||||
{
|
||||
uri_components() : m_path(_XPLATSTR("/")), m_port(-1) {}
|
||||
|
||||
uri_components(const uri_components&) = default;
|
||||
uri_components& operator=(const uri_components&) = default;
|
||||
|
||||
// This is for VS2013 compatibility -- replace with '= default' when VS2013 is completely dropped.
|
||||
uri_components(uri_components&& other) CPPREST_NOEXCEPT : m_scheme(std::move(other.m_scheme)),
|
||||
m_host(std::move(other.m_host)),
|
||||
m_user_info(std::move(other.m_user_info)),
|
||||
m_path(std::move(other.m_path)),
|
||||
m_query(std::move(other.m_query)),
|
||||
m_fragment(std::move(other.m_fragment)),
|
||||
m_port(other.m_port)
|
||||
{
|
||||
}
|
||||
|
||||
// This is for VS2013 compatibility -- replace with '= default' when VS2013 is completely dropped.
|
||||
uri_components& operator=(uri_components&& other) CPPREST_NOEXCEPT
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
m_scheme = std::move(other.m_scheme);
|
||||
m_host = std::move(other.m_host);
|
||||
m_user_info = std::move(other.m_user_info);
|
||||
m_path = std::move(other.m_path);
|
||||
m_query = std::move(other.m_query);
|
||||
m_fragment = std::move(other.m_fragment);
|
||||
m_port = other.m_port;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
_ASYNCRTIMP utility::string_t join();
|
||||
|
||||
utility::string_t m_scheme;
|
||||
utility::string_t m_host;
|
||||
utility::string_t m_user_info;
|
||||
utility::string_t m_path;
|
||||
utility::string_t m_query;
|
||||
utility::string_t m_fragment;
|
||||
int m_port;
|
||||
};
|
||||
} // namespace details
|
||||
|
||||
/// <summary>
|
||||
/// A single exception type to represent errors in parsing, encoding, and decoding URIs.
|
||||
/// </summary>
|
||||
class uri_exception : public std::exception
|
||||
{
|
||||
public:
|
||||
uri_exception(std::string msg) : m_msg(std::move(msg)) {}
|
||||
|
||||
~uri_exception() CPPREST_NOEXCEPT {}
|
||||
|
||||
const char* what() const CPPREST_NOEXCEPT { return m_msg.c_str(); }
|
||||
|
||||
private:
|
||||
std::string m_msg;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// A flexible, protocol independent URI implementation.
|
||||
///
|
||||
/// URI instances are immutable. Querying the various fields on an empty URI will return empty strings. Querying
|
||||
/// various diagnostic members on an empty URI will return false.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This implementation accepts both URIs ('http://msn.com/path') and URI relative-references
|
||||
/// ('/path?query#frag').
|
||||
///
|
||||
/// This implementation does not provide any scheme-specific handling -- an example of this
|
||||
/// would be the following: 'http://path1/path'. This is a valid URI, but it's not a valid
|
||||
/// http-uri -- that is, it's syntactically correct but does not conform to the requirements
|
||||
/// of the http scheme (http requires a host).
|
||||
/// We could provide this by allowing a pluggable 'scheme' policy-class, which would provide
|
||||
/// extra capability for validating and canonicalizing a URI according to scheme, and would
|
||||
/// introduce a layer of type-safety for URIs of differing schemes, and thus differing semantics.
|
||||
///
|
||||
/// One issue with implementing a scheme-independent URI facility is that of comparing for equality.
|
||||
/// For instance, these URIs are considered equal 'http://msn.com', 'http://msn.com:80'. That is --
|
||||
/// the 'default' port can be either omitted or explicit. Since we don't have a way to map a scheme
|
||||
/// to it's default port, we don't have a way to know these are equal. This is just one of a class of
|
||||
/// issues with regard to scheme-specific behavior.
|
||||
/// </remarks>
|
||||
class uri
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
/// The various components of a URI. This enum is used to indicate which
|
||||
/// URI component is being encoded to the encode_uri_component. This allows
|
||||
/// specific encoding to be performed.
|
||||
///
|
||||
/// Scheme and port don't allow '%' so they don't need to be encoded.
|
||||
/// </summary>
|
||||
class components
|
||||
{
|
||||
public:
|
||||
enum component
|
||||
{
|
||||
user_info,
|
||||
host,
|
||||
path,
|
||||
query,
|
||||
fragment,
|
||||
full_uri
|
||||
};
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Encodes a URI component according to RFC 3986.
|
||||
/// Note if a full URI is specified instead of an individual URI component all
|
||||
/// characters not in the unreserved set are escaped.
|
||||
/// </summary>
|
||||
/// <param name="raw">The URI as a string.</param>
|
||||
/// <returns>The encoded string.</returns>
|
||||
_ASYNCRTIMP static utility::string_t __cdecl encode_uri(const utility::string_t& raw,
|
||||
uri::components::component = components::full_uri);
|
||||
|
||||
/// <summary>
|
||||
/// Encodes a string by converting all characters except for RFC 3986 unreserved characters to their
|
||||
/// hexadecimal representation.
|
||||
/// </summary>
|
||||
/// <returns>The encoded string.</returns>
|
||||
_ASYNCRTIMP static utility::string_t __cdecl encode_data_string(const utility::string_t& data);
|
||||
|
||||
/// <summary>
|
||||
/// Decodes an encoded string.
|
||||
/// </summary>
|
||||
/// <param name="encoded">The URI as a string.</param>
|
||||
/// <returns>The decoded string.</returns>
|
||||
_ASYNCRTIMP static utility::string_t __cdecl decode(const utility::string_t& encoded);
|
||||
|
||||
/// <summary>
|
||||
/// Splits a path into its hierarchical components.
|
||||
/// </summary>
|
||||
/// <param name="path">The path as a string</param>
|
||||
/// <returns>A <c>std::vector<utility::string_t></c> containing the segments in the path.</returns>
|
||||
_ASYNCRTIMP static std::vector<utility::string_t> __cdecl split_path(const utility::string_t& path);
|
||||
|
||||
/// <summary>
|
||||
/// Splits a query into its key-value components.
|
||||
/// </summary>
|
||||
/// <param name="query">The query string</param>
|
||||
/// <returns>A <c>std::map<utility::string_t, utility::string_t></c> containing the key-value components of
|
||||
/// the query.</returns>
|
||||
_ASYNCRTIMP static std::map<utility::string_t, utility::string_t> __cdecl split_query(
|
||||
const utility::string_t& query);
|
||||
|
||||
/// <summary>
|
||||
/// Validates a string as a URI.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This function accepts both uris ('http://msn.com') and uri relative-references ('path1/path2?query').
|
||||
/// </remarks>
|
||||
/// <param name="uri_string">The URI string to be validated.</param>
|
||||
/// <returns><c>true</c> if the given string represents a valid URI, <c>false</c> otherwise.</returns>
|
||||
_ASYNCRTIMP static bool __cdecl validate(const utility::string_t& uri_string);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an empty uri
|
||||
/// </summary>
|
||||
uri() : m_uri(_XPLATSTR("/")) {}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a URI from the given encoded string. This will throw an exception if the string
|
||||
/// does not contain a valid URI. Use uri::validate if processing user-input.
|
||||
/// </summary>
|
||||
/// <param name="uri_string">A pointer to an encoded string to create the URI instance.</param>
|
||||
_ASYNCRTIMP uri(const utility::char_t* uri_string);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a URI from the given encoded string. This will throw an exception if the string
|
||||
/// does not contain a valid URI. Use uri::validate if processing user-input.
|
||||
/// </summary>
|
||||
/// <param name="uri_string">An encoded URI string to create the URI instance.</param>
|
||||
_ASYNCRTIMP uri(const utility::string_t& uri_string);
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor.
|
||||
/// </summary>
|
||||
uri(const uri&) = default;
|
||||
|
||||
/// <summary>
|
||||
/// Copy assignment operator.
|
||||
/// </summary>
|
||||
uri& operator=(const uri&) = default;
|
||||
|
||||
/// <summary>
|
||||
/// Move constructor.
|
||||
/// </summary>
|
||||
// This is for VS2013 compatibility -- replace with '= default' when VS2013 is completely dropped.
|
||||
uri(uri&& other) CPPREST_NOEXCEPT : m_uri(std::move(other.m_uri)), m_components(std::move(other.m_components)) {}
|
||||
|
||||
/// <summary>
|
||||
/// Move assignment operator
|
||||
/// </summary>
|
||||
// This is for VS2013 compatibility -- replace with '= default' when VS2013 is completely dropped.
|
||||
uri& operator=(uri&& other) CPPREST_NOEXCEPT
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
m_uri = std::move(other.m_uri);
|
||||
m_components = std::move(other.m_components);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the scheme component of the URI as an encoded string.
|
||||
/// </summary>
|
||||
/// <returns>The URI scheme as a string.</returns>
|
||||
const utility::string_t& scheme() const { return m_components.m_scheme; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the user information component of the URI as an encoded string.
|
||||
/// </summary>
|
||||
/// <returns>The URI user information as a string.</returns>
|
||||
const utility::string_t& user_info() const { return m_components.m_user_info; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the host component of the URI as an encoded string.
|
||||
/// </summary>
|
||||
/// <returns>The URI host as a string.</returns>
|
||||
const utility::string_t& host() const { return m_components.m_host; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the port component of the URI. Returns -1 if no port is specified.
|
||||
/// </summary>
|
||||
/// <returns>The URI port as an integer.</returns>
|
||||
int port() const { return m_components.m_port; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the path component of the URI as an encoded string.
|
||||
/// </summary>
|
||||
/// <returns>The URI path as a string.</returns>
|
||||
const utility::string_t& path() const { return m_components.m_path; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the query component of the URI as an encoded string.
|
||||
/// </summary>
|
||||
/// <returns>The URI query as a string.</returns>
|
||||
const utility::string_t& query() const { return m_components.m_query; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the fragment component of the URI as an encoded string.
|
||||
/// </summary>
|
||||
/// <returns>The URI fragment as a string.</returns>
|
||||
const utility::string_t& fragment() const { return m_components.m_fragment; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new uri object with the same authority portion as this one, omitting the resource and query portions.
|
||||
/// </summary>
|
||||
/// <returns>The new uri object with the same authority.</returns>
|
||||
_ASYNCRTIMP uri authority() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path, query, and fragment portion of this uri, which may be empty.
|
||||
/// </summary>
|
||||
/// <returns>The new URI object with the path, query and fragment portion of this URI.</returns>
|
||||
_ASYNCRTIMP uri resource() const;
|
||||
|
||||
/// <summary>
|
||||
/// An empty URI specifies no components, and serves as a default value
|
||||
/// </summary>
|
||||
bool is_empty() const { return this->m_uri.empty() || this->m_uri == _XPLATSTR("/"); }
|
||||
|
||||
/// <summary>
|
||||
/// A loopback URI is one which refers to a hostname or ip address with meaning only on the local machine.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Examples include "localhost", or ip addresses in the loopback range (127.0.0.0/24).
|
||||
/// </remarks>
|
||||
/// <returns><c>true</c> if this URI references the local host, <c>false</c> otherwise.</returns>
|
||||
bool is_host_loopback() const
|
||||
{
|
||||
return !is_empty() &&
|
||||
((host() == _XPLATSTR("localhost")) || (host().size() > 4 && host().substr(0, 4) == _XPLATSTR("127.")));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A wildcard URI is one which refers to all hostnames that resolve to the local machine (using the * or +)
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// http://*:80
|
||||
/// </example>
|
||||
bool is_host_wildcard() const
|
||||
{
|
||||
return !is_empty() && (this->host() == _XPLATSTR("*") || this->host() == _XPLATSTR("+"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A portable URI is one with a hostname that can be resolved globally (used from another machine).
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if this URI can be resolved globally (used from another machine), <c>false</c>
|
||||
/// otherwise.</returns> <remarks> The hostname "localhost" is a reserved name that is guaranteed to resolve to the
|
||||
/// local machine, and cannot be used for inter-machine communication. Likewise the hostnames "*" and "+" on Windows
|
||||
/// represent wildcards, and do not map to a resolvable address.
|
||||
/// </remarks>
|
||||
bool is_host_portable() const { return !(is_empty() || is_host_loopback() || is_host_wildcard()); }
|
||||
|
||||
/// <summary>
|
||||
/// A default port is one where the port is unspecified, and will be determined by the operating system.
|
||||
/// The choice of default port may be dictated by the scheme (http -> 80) or not.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if this URI instance has a default port, <c>false</c> otherwise.</returns>
|
||||
bool is_port_default() const { return !is_empty() && this->port() == 0; }
|
||||
|
||||
/// <summary>
|
||||
/// An "authority" URI is one with only a scheme, optional userinfo, hostname, and (optional) port.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if this is an "authority" URI, <c>false</c> otherwise.</returns>
|
||||
bool is_authority() const { return !is_empty() && is_path_empty() && query().empty() && fragment().empty(); }
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the other URI has the same authority as this one
|
||||
/// </summary>
|
||||
/// <param name="other">The URI to compare the authority with.</param>
|
||||
/// <returns><c>true</c> if both the URI's have the same authority, <c>false</c> otherwise.</returns>
|
||||
bool has_same_authority(const uri& other) const { return !is_empty() && this->authority() == other.authority(); }
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the path portion of this URI is empty
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if the path portion of this URI is empty, <c>false</c> otherwise.</returns>
|
||||
bool is_path_empty() const { return path().empty() || path() == _XPLATSTR("/"); }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the full (encoded) URI as a string.
|
||||
/// </summary>
|
||||
/// <returns>The full encoded URI string.</returns>
|
||||
utility::string_t to_string() const { return m_uri; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns an URI resolved against <c>this</c> as the base URI
|
||||
/// according to RFC3986, Section 5 (https://tools.ietf.org/html/rfc3986#section-5).
|
||||
/// </summary>
|
||||
/// <param name="relativeUri">The relative URI to be resolved against <c>this</c> as base.</param>
|
||||
/// <returns>The new resolved URI string.</returns>
|
||||
_ASYNCRTIMP utility::string_t resolve_uri(const utility::string_t& relativeUri) const;
|
||||
|
||||
_ASYNCRTIMP bool operator==(const uri& other) const;
|
||||
|
||||
bool operator<(const uri& other) const { return m_uri < other.m_uri; }
|
||||
|
||||
bool operator!=(const uri& other) const { return !(this->operator==(other)); }
|
||||
|
||||
private:
|
||||
friend class uri_builder;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a URI from the given URI components.
|
||||
/// </summary>
|
||||
/// <param name="components">A URI components object to create the URI instance.</param>
|
||||
_ASYNCRTIMP uri(const details::uri_components& components);
|
||||
|
||||
// Used by uri_builder
|
||||
static utility::string_t __cdecl encode_query_impl(const utf8string& raw);
|
||||
|
||||
utility::string_t m_uri;
|
||||
details::uri_components m_components;
|
||||
};
|
||||
|
||||
} // namespace web
|
||||
7482
deps/cpprestsdk/include/cpprest/details/SafeInt3.hpp
vendored
7482
deps/cpprestsdk/include/cpprest/details/SafeInt3.hpp
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,131 +0,0 @@
|
||||
/***
|
||||
* Copyright (C) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
*
|
||||
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
*
|
||||
* Platform-dependent type definitions
|
||||
*
|
||||
* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
|
||||
*
|
||||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
****/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpprest/details/cpprest_compat.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#include <cstdint>
|
||||
#endif
|
||||
|
||||
#include "cpprest/details/SafeInt3.hpp"
|
||||
|
||||
namespace utility
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#define _UTF16_STRINGS
|
||||
#endif
|
||||
|
||||
// We should be using a 64-bit size type for most situations that do
|
||||
// not involve specifying the size of a memory allocation or buffer.
|
||||
typedef uint64_t size64_t;
|
||||
|
||||
#ifndef _WIN32
|
||||
typedef uint32_t HRESULT; // Needed for PPLX
|
||||
#endif
|
||||
|
||||
#ifdef _UTF16_STRINGS
|
||||
//
|
||||
// On Windows, all strings are wide
|
||||
//
|
||||
typedef wchar_t char_t;
|
||||
typedef std::wstring string_t;
|
||||
#define _XPLATSTR(x) L##x
|
||||
typedef std::wostringstream ostringstream_t;
|
||||
typedef std::wofstream ofstream_t;
|
||||
typedef std::wostream ostream_t;
|
||||
typedef std::wistream istream_t;
|
||||
typedef std::wifstream ifstream_t;
|
||||
typedef std::wistringstream istringstream_t;
|
||||
typedef std::wstringstream stringstream_t;
|
||||
#define ucout std::wcout
|
||||
#define ucin std::wcin
|
||||
#define ucerr std::wcerr
|
||||
#else
|
||||
//
|
||||
// On POSIX platforms, all strings are narrow
|
||||
//
|
||||
typedef char char_t;
|
||||
typedef std::string string_t;
|
||||
#define _XPLATSTR(x) x
|
||||
typedef std::ostringstream ostringstream_t;
|
||||
typedef std::ofstream ofstream_t;
|
||||
typedef std::ostream ostream_t;
|
||||
typedef std::istream istream_t;
|
||||
typedef std::ifstream ifstream_t;
|
||||
typedef std::istringstream istringstream_t;
|
||||
typedef std::stringstream stringstream_t;
|
||||
#define ucout std::cout
|
||||
#define ucin std::cin
|
||||
#define ucerr std::cerr
|
||||
#endif // endif _UTF16_STRINGS
|
||||
|
||||
#ifndef _TURN_OFF_PLATFORM_STRING
|
||||
// The 'U' macro can be used to create a string or character literal of the platform type, i.e. utility::char_t.
|
||||
// If you are using a library causing conflicts with 'U' macro, it can be turned off by defining the macro
|
||||
// '_TURN_OFF_PLATFORM_STRING' before including the C++ REST SDK header files, and e.g. use '_XPLATSTR' instead.
|
||||
#define U(x) _XPLATSTR(x)
|
||||
#endif // !_TURN_OFF_PLATFORM_STRING
|
||||
|
||||
} // namespace utility
|
||||
|
||||
typedef char utf8char;
|
||||
typedef std::string utf8string;
|
||||
typedef std::stringstream utf8stringstream;
|
||||
typedef std::ostringstream utf8ostringstream;
|
||||
typedef std::ostream utf8ostream;
|
||||
typedef std::istream utf8istream;
|
||||
typedef std::istringstream utf8istringstream;
|
||||
|
||||
#ifdef _UTF16_STRINGS
|
||||
typedef wchar_t utf16char;
|
||||
typedef std::wstring utf16string;
|
||||
typedef std::wstringstream utf16stringstream;
|
||||
typedef std::wostringstream utf16ostringstream;
|
||||
typedef std::wostream utf16ostream;
|
||||
typedef std::wistream utf16istream;
|
||||
typedef std::wistringstream utf16istringstream;
|
||||
#else
|
||||
typedef char16_t utf16char;
|
||||
typedef std::u16string utf16string;
|
||||
typedef std::basic_stringstream<utf16char> utf16stringstream;
|
||||
typedef std::basic_ostringstream<utf16char> utf16ostringstream;
|
||||
typedef std::basic_ostream<utf16char> utf16ostream;
|
||||
typedef std::basic_istream<utf16char> utf16istream;
|
||||
typedef std::basic_istringstream<utf16char> utf16istringstream;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Include on everything except Windows Desktop ARM, unless explicitly excluded.
|
||||
#if !defined(CPPREST_EXCLUDE_WEBSOCKETS)
|
||||
#if defined(WINAPI_FAMILY)
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && defined(_M_ARM)
|
||||
#define CPPREST_EXCLUDE_WEBSOCKETS
|
||||
#endif
|
||||
#else
|
||||
#if defined(_M_ARM)
|
||||
#define CPPREST_EXCLUDE_WEBSOCKETS
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,91 +0,0 @@
|
||||
/***
|
||||
* Copyright (C) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
*
|
||||
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
*
|
||||
* Standard macros and definitions.
|
||||
* This header has minimal dependency on windows headers and is safe for use in the public API
|
||||
*
|
||||
* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
|
||||
*
|
||||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
****/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#if _MSC_VER >= 1900
|
||||
#define CPPREST_NOEXCEPT noexcept
|
||||
#define CPPREST_CONSTEXPR constexpr
|
||||
#else
|
||||
#define CPPREST_NOEXCEPT
|
||||
#define CPPREST_CONSTEXPR const
|
||||
#endif // _MSC_VER >= 1900
|
||||
|
||||
#define CASABLANCA_UNREFERENCED_PARAMETER(x) (x)
|
||||
|
||||
#include <sal.h>
|
||||
|
||||
#else // ^^^ _WIN32 ^^^ // vvv !_WIN32 vvv
|
||||
|
||||
#define __declspec(x) __attribute__((x))
|
||||
#define dllimport
|
||||
#define novtable /* no novtable equivalent */
|
||||
#define __assume(x) \
|
||||
do \
|
||||
{ \
|
||||
if (!(x)) __builtin_unreachable(); \
|
||||
} while (false)
|
||||
#define CASABLANCA_UNREFERENCED_PARAMETER(x) (void)x
|
||||
#define CPPREST_NOEXCEPT noexcept
|
||||
#define CPPREST_CONSTEXPR constexpr
|
||||
|
||||
#include <assert.h>
|
||||
#define _ASSERTE(x) assert(x)
|
||||
|
||||
// No SAL on non Windows platforms
|
||||
#include "cpprest/details/nosal.h"
|
||||
|
||||
#if !defined(__cdecl)
|
||||
#if defined(cdecl)
|
||||
#define __cdecl __attribute__((cdecl))
|
||||
#else // ^^^ defined cdecl ^^^ // vvv !defined cdecl vvv
|
||||
#define __cdecl
|
||||
#endif // defined cdecl
|
||||
#endif // not defined __cdecl
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
// This is needed to disable the use of __thread inside the boost library.
|
||||
// Android does not support thread local storage -- if boost is included
|
||||
// without this macro defined, it will create references to __tls_get_addr
|
||||
// which (while able to link) will not be available at runtime and prevent
|
||||
// the .so from loading.
|
||||
#if not defined BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION
|
||||
#define BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION
|
||||
#endif // not defined BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION
|
||||
#endif // defined(__ANDROID__)
|
||||
|
||||
#ifdef __clang__
|
||||
#include <cstdio>
|
||||
#endif // __clang__
|
||||
#endif // _WIN32
|
||||
|
||||
#define _NO_ASYNCRTIMP
|
||||
|
||||
#ifdef _NO_ASYNCRTIMP
|
||||
#define _ASYNCRTIMP
|
||||
#else // ^^^ _NO_ASYNCRTIMP ^^^ // vvv !_NO_ASYNCRTIMP vvv
|
||||
#ifdef _ASYNCRT_EXPORT
|
||||
#define _ASYNCRTIMP __declspec(dllexport)
|
||||
#else // ^^^ _ASYNCRT_EXPORT ^^^ // vvv !_ASYNCRT_EXPORT vvv
|
||||
#define _ASYNCRTIMP __declspec(dllimport)
|
||||
#endif // _ASYNCRT_EXPORT
|
||||
#endif // _NO_ASYNCRTIMP
|
||||
|
||||
#ifdef CASABLANCA_DEPRECATION_NO_WARNINGS
|
||||
#define CASABLANCA_DEPRECATED(x)
|
||||
#else
|
||||
#define CASABLANCA_DEPRECATED(x) __declspec(deprecated(x))
|
||||
#endif // CASABLANCA_DEPRECATION_NO_WARNINGS
|
||||
@@ -1,223 +0,0 @@
|
||||
/***
|
||||
* Copyright (C) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
*
|
||||
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
*
|
||||
* utility classes used by the different web:: clients
|
||||
*
|
||||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
****/
|
||||
#pragma once
|
||||
|
||||
#include "cpprest/asyncrt_utils.h"
|
||||
#include "cpprest/uri.h"
|
||||
|
||||
namespace web
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
class zero_memory_deleter
|
||||
{
|
||||
public:
|
||||
_ASYNCRTIMP void operator()(::utility::string_t* data) const;
|
||||
};
|
||||
typedef std::unique_ptr<::utility::string_t, zero_memory_deleter> plaintext_string;
|
||||
|
||||
#if defined(_WIN32) && !defined(CPPREST_TARGET_XP)
|
||||
#if defined(__cplusplus_winrt)
|
||||
class winrt_encryption
|
||||
{
|
||||
public:
|
||||
winrt_encryption() {}
|
||||
_ASYNCRTIMP winrt_encryption(const std::wstring& data);
|
||||
_ASYNCRTIMP plaintext_string decrypt() const;
|
||||
|
||||
private:
|
||||
::pplx::task<Windows::Storage::Streams::IBuffer ^> m_buffer;
|
||||
};
|
||||
#else
|
||||
class win32_encryption
|
||||
{
|
||||
public:
|
||||
win32_encryption() {}
|
||||
_ASYNCRTIMP win32_encryption(const std::wstring& data);
|
||||
_ASYNCRTIMP ~win32_encryption();
|
||||
_ASYNCRTIMP plaintext_string decrypt() const;
|
||||
|
||||
private:
|
||||
std::vector<char> m_buffer;
|
||||
size_t m_numCharacters;
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
} // namespace details
|
||||
|
||||
/// <summary>
|
||||
/// Represents a set of user credentials (user name and password) to be used
|
||||
/// for authentication.
|
||||
/// </summary>
|
||||
class credentials
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
/// Constructs an empty set of credentials without a user name or password.
|
||||
/// </summary>
|
||||
credentials() {}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs credentials from given user name and password.
|
||||
/// </summary>
|
||||
/// <param name="username">User name as a string.</param>
|
||||
/// <param name="password">Password as a string.</param>
|
||||
credentials(utility::string_t username, const utility::string_t& password)
|
||||
: m_username(std::move(username)), m_password(password)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The user name associated with the credentials.
|
||||
/// </summary>
|
||||
/// <returns>A string containing the user name.</returns>
|
||||
const utility::string_t& username() const { return m_username; }
|
||||
|
||||
/// <summary>
|
||||
/// The password for the user name associated with the credentials.
|
||||
/// </summary>
|
||||
/// <returns>A string containing the password.</returns>
|
||||
CASABLANCA_DEPRECATED(
|
||||
"This API is deprecated for security reasons to avoid unnecessary password copies stored in plaintext.")
|
||||
utility::string_t password() const
|
||||
{
|
||||
#if defined(_WIN32) && !defined(CPPREST_TARGET_XP)
|
||||
return utility::string_t(*m_password.decrypt());
|
||||
#else
|
||||
return m_password;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if credentials have been set
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if user name and password is set, <c>false</c> otherwise.</returns>
|
||||
bool is_set() const { return !m_username.empty(); }
|
||||
|
||||
details::plaintext_string _internal_decrypt() const
|
||||
{
|
||||
// Encryption APIs not supported on XP
|
||||
#if defined(_WIN32) && !defined(CPPREST_TARGET_XP)
|
||||
return m_password.decrypt();
|
||||
#else
|
||||
return details::plaintext_string(new ::utility::string_t(m_password));
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
::utility::string_t m_username;
|
||||
|
||||
#if defined(_WIN32) && !defined(CPPREST_TARGET_XP)
|
||||
#if defined(__cplusplus_winrt)
|
||||
details::winrt_encryption m_password;
|
||||
#else
|
||||
details::win32_encryption m_password;
|
||||
#endif
|
||||
#else
|
||||
::utility::string_t m_password;
|
||||
#endif
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// web_proxy represents the concept of the web proxy, which can be auto-discovered,
|
||||
/// disabled, or specified explicitly by the user.
|
||||
/// </summary>
|
||||
class web_proxy
|
||||
{
|
||||
enum web_proxy_mode_internal
|
||||
{
|
||||
use_default_,
|
||||
use_auto_discovery_,
|
||||
disabled_,
|
||||
user_provided_
|
||||
};
|
||||
|
||||
public:
|
||||
enum web_proxy_mode
|
||||
{
|
||||
use_default = use_default_,
|
||||
use_auto_discovery = use_auto_discovery_,
|
||||
disabled = disabled_
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a proxy with the default settings.
|
||||
/// </summary>
|
||||
web_proxy() : m_address(_XPLATSTR("")), m_mode(use_default_) {}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a proxy with specified mode.
|
||||
/// </summary>
|
||||
/// <param name="mode">Mode to use.</param>
|
||||
web_proxy(web_proxy_mode mode) : m_address(_XPLATSTR("")), m_mode(static_cast<web_proxy_mode_internal>(mode)) {}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a proxy explicitly with provided address.
|
||||
/// </summary>
|
||||
/// <param name="address">Proxy URI to use.</param>
|
||||
web_proxy(uri address) : m_address(address), m_mode(user_provided_) {}
|
||||
|
||||
/// <summary>
|
||||
/// Gets this proxy's URI address. Returns an empty URI if not explicitly set by user.
|
||||
/// </summary>
|
||||
/// <returns>A reference to this proxy's URI.</returns>
|
||||
const uri& address() const { return m_address; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the credentials used for authentication with this proxy.
|
||||
/// </summary>
|
||||
/// <returns>Credentials to for this proxy.</returns>
|
||||
const web::credentials& credentials() const { return m_credentials; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the credentials to use for authentication with this proxy.
|
||||
/// </summary>
|
||||
/// <param name="cred">Credentials to use for this proxy.</param>
|
||||
void set_credentials(web::credentials cred)
|
||||
{
|
||||
if (m_mode == disabled_)
|
||||
{
|
||||
throw std::invalid_argument("Cannot attach credentials to a disabled proxy");
|
||||
}
|
||||
m_credentials = std::move(cred);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this proxy was constructed with default settings.
|
||||
/// </summary>
|
||||
/// <returns>True if default, false otherwise.</param>
|
||||
bool is_default() const { return m_mode == use_default_; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if using a proxy is disabled.
|
||||
/// </summary>
|
||||
/// <returns>True if disabled, false otherwise.</returns>
|
||||
bool is_disabled() const { return m_mode == disabled_; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the auto discovery protocol, WPAD, is to be used.
|
||||
/// </summary>
|
||||
/// <returns>True if auto discovery enabled, false otherwise.</returns>
|
||||
bool is_auto_discovery() const { return m_mode == use_auto_discovery_; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a proxy address is explicitly specified by the user.
|
||||
/// </summary>
|
||||
/// <returns>True if a proxy address was explicitly specified, false otherwise.</returns>
|
||||
bool is_specified() const { return m_mode == user_provided_; }
|
||||
|
||||
private:
|
||||
web::uri m_address;
|
||||
web_proxy_mode_internal m_mode;
|
||||
web::credentials m_credentials;
|
||||
};
|
||||
|
||||
} // namespace web
|
||||
1786
deps/cpprestsdk/include/cpprest/json.h
vendored
1786
deps/cpprestsdk/include/cpprest/json.h
vendored
File diff suppressed because it is too large
Load Diff
21
deps/cpprestsdk/include/cpprest/uri.h
vendored
21
deps/cpprestsdk/include/cpprest/uri.h
vendored
@@ -1,21 +0,0 @@
|
||||
/***
|
||||
* Copyright (C) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
*
|
||||
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
*
|
||||
* Protocol independent support for URIs.
|
||||
*
|
||||
* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
|
||||
*
|
||||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
****/
|
||||
#pragma once
|
||||
|
||||
#ifndef CASA_URI_H
|
||||
#define CASA_URI_H
|
||||
|
||||
#include "cpprest/base_uri.h"
|
||||
#include "cpprest/uri_builder.h"
|
||||
|
||||
#endif
|
||||
295
deps/cpprestsdk/include/cpprest/uri_builder.h
vendored
295
deps/cpprestsdk/include/cpprest/uri_builder.h
vendored
@@ -1,295 +0,0 @@
|
||||
/***
|
||||
* Copyright (C) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
*
|
||||
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
*
|
||||
* Builder style class for creating URIs.
|
||||
*
|
||||
* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
|
||||
*
|
||||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
****/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpprest/base_uri.h"
|
||||
#include <string>
|
||||
|
||||
namespace web
|
||||
{
|
||||
/// <summary>
|
||||
/// Builder for constructing URIs incrementally.
|
||||
/// </summary>
|
||||
class uri_builder
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
/// Creates a builder with an initially empty URI.
|
||||
/// </summary>
|
||||
uri_builder() = default;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a builder with a existing URI object.
|
||||
/// </summary>
|
||||
/// <param name="uri_str">Encoded string containing the URI.</param>
|
||||
uri_builder(const uri& uri_str) : m_uri(uri_str.m_components) {}
|
||||
|
||||
/// <summary>
|
||||
/// Get the scheme component of the URI as an encoded string.
|
||||
/// </summary>
|
||||
/// <returns>The URI scheme as a string.</returns>
|
||||
const utility::string_t& scheme() const { return m_uri.m_scheme; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the user information component of the URI as an encoded string.
|
||||
/// </summary>
|
||||
/// <returns>The URI user information as a string.</returns>
|
||||
const utility::string_t& user_info() const { return m_uri.m_user_info; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the host component of the URI as an encoded string.
|
||||
/// </summary>
|
||||
/// <returns>The URI host as a string.</returns>
|
||||
const utility::string_t& host() const { return m_uri.m_host; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the port component of the URI. Returns -1 if no port is specified.
|
||||
/// </summary>
|
||||
/// <returns>The URI port as an integer.</returns>
|
||||
int port() const { return m_uri.m_port; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the path component of the URI as an encoded string.
|
||||
/// </summary>
|
||||
/// <returns>The URI path as a string.</returns>
|
||||
const utility::string_t& path() const { return m_uri.m_path; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the query component of the URI as an encoded string.
|
||||
/// </summary>
|
||||
/// <returns>The URI query as a string.</returns>
|
||||
const utility::string_t& query() const { return m_uri.m_query; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the fragment component of the URI as an encoded string.
|
||||
/// </summary>
|
||||
/// <returns>The URI fragment as a string.</returns>
|
||||
const utility::string_t& fragment() const { return m_uri.m_fragment; }
|
||||
|
||||
/// <summary>
|
||||
/// Set the scheme of the URI.
|
||||
/// </summary>
|
||||
/// <param name="scheme">Uri scheme.</param>
|
||||
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
||||
uri_builder& set_scheme(const utility::string_t& scheme)
|
||||
{
|
||||
m_uri.m_scheme = scheme;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the user info component of the URI.
|
||||
/// </summary>
|
||||
/// <param name="user_info">User info as a decoded string.</param>
|
||||
/// <param name="do_encoding">Specify whether to apply URI encoding to the given string.</param>
|
||||
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
||||
uri_builder& set_user_info(const utility::string_t& user_info, bool do_encoding = false)
|
||||
{
|
||||
if (do_encoding)
|
||||
{
|
||||
m_uri.m_user_info = uri::encode_uri(user_info, uri::components::user_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uri.m_user_info = user_info;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the host component of the URI.
|
||||
/// </summary>
|
||||
/// <param name="host">Host as a decoded string.</param>
|
||||
/// <param name="do_encoding">Specify whether to apply URI encoding to the given string.</param>
|
||||
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
||||
uri_builder& set_host(const utility::string_t& host, bool do_encoding = false)
|
||||
{
|
||||
if (do_encoding)
|
||||
{
|
||||
m_uri.m_host = uri::encode_uri(host, uri::components::host);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uri.m_host = host;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the port component of the URI.
|
||||
/// </summary>
|
||||
/// <param name="port">Port as an integer.</param>
|
||||
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
||||
uri_builder& set_port(int port)
|
||||
{
|
||||
m_uri.m_port = port;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the port component of the URI.
|
||||
/// </summary>
|
||||
/// <param name="port">Port as a string.</param>
|
||||
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
||||
/// <remarks>When string can't be converted to an integer the port is left unchanged.</remarks>
|
||||
_ASYNCRTIMP uri_builder& set_port(const utility::string_t& port);
|
||||
|
||||
/// <summary>
|
||||
/// Set the path component of the URI.
|
||||
/// </summary>
|
||||
/// <param name="path">Path as a decoded string.</param>
|
||||
/// <param name="do_encoding">Specify whether to apply URI encoding to the given string.</param>
|
||||
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
||||
uri_builder& set_path(const utility::string_t& path, bool do_encoding = false)
|
||||
{
|
||||
if (do_encoding)
|
||||
{
|
||||
m_uri.m_path = uri::encode_uri(path, uri::components::path);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uri.m_path = path;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the query component of the URI.
|
||||
/// </summary>
|
||||
/// <param name="query">Query as a decoded string.</param>
|
||||
/// <param name="do_encoding">Specify whether apply URI encoding to the given string.</param>
|
||||
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
||||
uri_builder& set_query(const utility::string_t& query, bool do_encoding = false)
|
||||
{
|
||||
if (do_encoding)
|
||||
{
|
||||
m_uri.m_query = uri::encode_uri(query, uri::components::query);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uri.m_query = query;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the fragment component of the URI.
|
||||
/// </summary>
|
||||
/// <param name="fragment">Fragment as a decoded string.</param>
|
||||
/// <param name="do_encoding">Specify whether to apply URI encoding to the given string.</param>
|
||||
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
||||
uri_builder& set_fragment(const utility::string_t& fragment, bool do_encoding = false)
|
||||
{
|
||||
if (do_encoding)
|
||||
{
|
||||
m_uri.m_fragment = uri::encode_uri(fragment, uri::components::fragment);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uri.m_fragment = fragment;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all components of the underlying URI in this uri_builder.
|
||||
/// </summary>
|
||||
void clear() { m_uri = details::uri_components(); }
|
||||
|
||||
/// <summary>
|
||||
/// Appends another path to the path of this uri_builder.
|
||||
/// </summary>
|
||||
/// <param name="path">Path to append as a already encoded string.</param>
|
||||
/// <param name="do_encoding">Specify whether to apply URI encoding to the given string.</param>
|
||||
/// <returns>A reference to this uri_builder to support chaining.</returns>
|
||||
_ASYNCRTIMP uri_builder& append_path(const utility::string_t& path, bool do_encoding = false);
|
||||
|
||||
/// <summary>
|
||||
/// Appends the raw contents of the path argument to the path of this uri_builder with no separator de-duplication.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The path argument is appended after adding a '/' separator without regards to the contents of path. If an empty
|
||||
/// string is provided, this function will immediately return without changes to the stored path value. For example:
|
||||
/// if the current contents are "/abc" and path="/xyz", the result will be "/abc//xyz".
|
||||
/// </remarks>
|
||||
/// <param name="path">Path to append as a already encoded string.</param>
|
||||
/// <param name="do_encoding">Specify whether to apply URI encoding to the given string.</param>
|
||||
/// <returns>A reference to this uri_builder to support chaining.</returns>
|
||||
_ASYNCRTIMP uri_builder& append_path_raw(const utility::string_t& path, bool do_encoding = false);
|
||||
|
||||
/// <summary>
|
||||
/// Appends another query to the query of this uri_builder.
|
||||
/// </summary>
|
||||
/// <param name="query">Query to append as a decoded string.</param>
|
||||
/// <param name="do_encoding">Specify whether to apply URI encoding to the given string.</param>
|
||||
/// <returns>A reference to this uri_builder to support chaining.</returns>
|
||||
_ASYNCRTIMP uri_builder& append_query(const utility::string_t& query, bool do_encoding = false);
|
||||
|
||||
/// <summary>
|
||||
/// Appends an relative uri (Path, Query and fragment) at the end of the current uri.
|
||||
/// </summary>
|
||||
/// <param name="relative_uri">The relative uri to append.</param>
|
||||
/// <returns>A reference to this uri_builder to support chaining.</returns>
|
||||
_ASYNCRTIMP uri_builder& append(const uri& relative_uri);
|
||||
|
||||
/// <summary>
|
||||
/// Appends another query to the query of this uri_builder, encoding it first. This overload is useful when building
|
||||
/// a query segment of the form "element=10", where the right hand side of the query is stored as a type other than
|
||||
/// a string, for instance, an integral type.
|
||||
/// </summary>
|
||||
/// <param name="name">The name portion of the query string</param>
|
||||
/// <param name="value">The value portion of the query string</param>
|
||||
/// <returns>A reference to this uri_builder to support chaining.</returns>
|
||||
template<typename T>
|
||||
uri_builder& append_query(const utility::string_t& name, const T& value, bool do_encoding = true)
|
||||
{
|
||||
if (do_encoding)
|
||||
append_query_encode_impl(name, utility::conversions::details::print_utf8string(value));
|
||||
else
|
||||
append_query_no_encode_impl(name, utility::conversions::details::print_string(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combine and validate the URI components into a encoded string. An exception will be thrown if the URI is
|
||||
/// invalid.
|
||||
/// </summary>
|
||||
/// <returns>The created URI as a string.</returns>
|
||||
_ASYNCRTIMP utility::string_t to_string() const;
|
||||
|
||||
/// <summary>
|
||||
/// Combine and validate the URI components into a URI class instance. An exception will be thrown if the URI is
|
||||
/// invalid.
|
||||
/// </summary>
|
||||
/// <returns>The create URI as a URI class instance.</returns>
|
||||
_ASYNCRTIMP uri to_uri() const;
|
||||
|
||||
/// <summary>
|
||||
/// Validate the generated URI from all existing components of this uri_builder.
|
||||
/// </summary>
|
||||
/// <returns>Whether the URI is valid.</returns>
|
||||
_ASYNCRTIMP bool is_valid();
|
||||
|
||||
private:
|
||||
_ASYNCRTIMP void append_query_encode_impl(const utility::string_t& name, const utf8string& value);
|
||||
_ASYNCRTIMP void append_query_no_encode_impl(const utility::string_t& name, const utility::string_t& value);
|
||||
|
||||
details::uri_components m_uri;
|
||||
};
|
||||
} // namespace web
|
||||
10
deps/cpprestsdk/include/cpprest/version.h
vendored
10
deps/cpprestsdk/include/cpprest/version.h
vendored
@@ -1,10 +0,0 @@
|
||||
/***
|
||||
* Copyright (C) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
*
|
||||
*/
|
||||
#define CPPREST_VERSION_MINOR 10
|
||||
#define CPPREST_VERSION_MAJOR 2
|
||||
#define CPPREST_VERSION_REVISION 13
|
||||
|
||||
#define CPPREST_VERSION (CPPREST_VERSION_MAJOR * 100000 + CPPREST_VERSION_MINOR * 100 + CPPREST_VERSION_REVISION)
|
||||
34
deps/cpprestsdk/pch.h
vendored
34
deps/cpprestsdk/pch.h
vendored
@@ -1,34 +0,0 @@
|
||||
#include <winrt/base.h>
|
||||
#include <Windows.h>
|
||||
#include <dxgi1_3.h>
|
||||
#include <d3d11_2.h>
|
||||
#include <d2d1_3.h>
|
||||
#include <d2d1_3helper.h>
|
||||
#include <d2d1helper.h>
|
||||
#include <dwrite.h>
|
||||
#include <dcomp.h>
|
||||
#include <dwmapi.h>
|
||||
#include <Shobjidl.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <condition_variable>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
#include <unordered_set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// cpprestsdk headers
|
||||
#include "cpprest/details/basic_types.h"
|
||||
#include "cpprest/details/cpprest_compat.h"
|
||||
#include "cpprest/version.h"
|
||||
// json
|
||||
#include "cpprest/json.h"
|
||||
// utilities
|
||||
#include "cpprest/asyncrt_utils.h"
|
||||
#include "cpprest/details/web_utilities.h"
|
||||
475
deps/cpprestsdk/src/json/json.cpp
vendored
475
deps/cpprestsdk/src/json/json.cpp
vendored
@@ -1,475 +0,0 @@
|
||||
/***
|
||||
* Copyright (C) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
*
|
||||
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
*
|
||||
* HTTP Library: JSON parser and writer
|
||||
*
|
||||
* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
|
||||
*
|
||||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
****/
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
using namespace web;
|
||||
|
||||
bool json::details::g_keep_json_object_unsorted = false;
|
||||
void json::keep_object_element_order(bool keep_order) { json::details::g_keep_json_object_unsorted = keep_order; }
|
||||
|
||||
utility::ostream_t& web::json::operator<<(utility::ostream_t& os, const web::json::value& val)
|
||||
{
|
||||
val.serialize(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
utility::istream_t& web::json::operator>>(utility::istream_t& is, json::value& val)
|
||||
{
|
||||
val = json::value::parse(is);
|
||||
return is;
|
||||
}
|
||||
|
||||
web::json::value::value()
|
||||
: m_value(utility::details::make_unique<web::json::details::_Null>())
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
, m_kind(value::Null)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value::value(int32_t value)
|
||||
: m_value(utility::details::make_unique<web::json::details::_Number>(value))
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
, m_kind(value::Number)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value::value(uint32_t value)
|
||||
: m_value(utility::details::make_unique<web::json::details::_Number>(value))
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
, m_kind(value::Number)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value::value(int64_t value)
|
||||
: m_value(utility::details::make_unique<web::json::details::_Number>(value))
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
, m_kind(value::Number)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value::value(uint64_t value)
|
||||
: m_value(utility::details::make_unique<web::json::details::_Number>(value))
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
, m_kind(value::Number)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value::value(double value)
|
||||
: m_value(utility::details::make_unique<web::json::details::_Number>(value))
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
, m_kind(value::Number)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value::value(bool value)
|
||||
: m_value(utility::details::make_unique<web::json::details::_Boolean>(value))
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
, m_kind(value::Boolean)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value::value(utility::string_t value)
|
||||
: m_value(utility::details::make_unique<web::json::details::_String>(std::move(value)))
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
, m_kind(value::String)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value::value(utility::string_t value, bool has_escape_chars)
|
||||
: m_value(utility::details::make_unique<web::json::details::_String>(std::move(value), has_escape_chars))
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
, m_kind(value::String)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value::value(const utility::char_t* value)
|
||||
: m_value(utility::details::make_unique<web::json::details::_String>(value))
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
, m_kind(value::String)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value::value(const utility::char_t* value, bool has_escape_chars)
|
||||
: m_value(utility::details::make_unique<web::json::details::_String>(utility::string_t(value), has_escape_chars))
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
, m_kind(value::String)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value::value(const value& other)
|
||||
: m_value(other.m_value->_copy_value())
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
, m_kind(other.m_kind)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value& web::json::value::operator=(const value& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
m_value = std::unique_ptr<details::_Value>(other.m_value->_copy_value());
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
m_kind = other.m_kind;
|
||||
#endif
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
web::json::value::value(value&& other) CPPREST_NOEXCEPT : m_value(std::move(other.m_value))
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
,
|
||||
m_kind(other.m_kind)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
web::json::value& web::json::value::operator=(web::json::value&& other) CPPREST_NOEXCEPT
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
m_value.swap(other.m_value);
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
m_kind = other.m_kind;
|
||||
#endif
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
web::json::value web::json::value::null() { return web::json::value(); }
|
||||
|
||||
web::json::value web::json::value::number(double value) { return web::json::value(value); }
|
||||
|
||||
web::json::value web::json::value::number(int32_t value) { return web::json::value(value); }
|
||||
|
||||
web::json::value web::json::value::number(uint32_t value) { return web::json::value(value); }
|
||||
|
||||
web::json::value web::json::value::number(int64_t value) { return web::json::value(value); }
|
||||
|
||||
web::json::value web::json::value::number(uint64_t value) { return web::json::value(value); }
|
||||
|
||||
web::json::value web::json::value::boolean(bool value) { return web::json::value(value); }
|
||||
|
||||
web::json::value web::json::value::string(utility::string_t value)
|
||||
{
|
||||
std::unique_ptr<details::_Value> ptr = utility::details::make_unique<details::_String>(std::move(value));
|
||||
return web::json::value(std::move(ptr)
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
,
|
||||
value::String
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
web::json::value web::json::value::string(utility::string_t value, bool has_escape_chars)
|
||||
{
|
||||
std::unique_ptr<details::_Value> ptr =
|
||||
utility::details::make_unique<details::_String>(std::move(value), has_escape_chars);
|
||||
return web::json::value(std::move(ptr)
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
,
|
||||
value::String
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
web::json::value web::json::value::string(const std::string& value)
|
||||
{
|
||||
std::unique_ptr<details::_Value> ptr =
|
||||
utility::details::make_unique<details::_String>(utility::conversions::to_utf16string(value));
|
||||
return web::json::value(std::move(ptr)
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
,
|
||||
value::String
|
||||
#endif
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
web::json::value web::json::value::object(bool keep_order)
|
||||
{
|
||||
std::unique_ptr<details::_Value> ptr = utility::details::make_unique<details::_Object>(keep_order);
|
||||
return web::json::value(std::move(ptr)
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
,
|
||||
value::Object
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
web::json::value web::json::value::object(std::vector<std::pair<::utility::string_t, value>> fields, bool keep_order)
|
||||
{
|
||||
std::unique_ptr<details::_Value> ptr =
|
||||
utility::details::make_unique<details::_Object>(std::move(fields), keep_order);
|
||||
return web::json::value(std::move(ptr)
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
,
|
||||
value::Object
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
web::json::value web::json::value::array()
|
||||
{
|
||||
std::unique_ptr<details::_Value> ptr = utility::details::make_unique<details::_Array>();
|
||||
return web::json::value(std::move(ptr)
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
,
|
||||
value::Array
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
web::json::value web::json::value::array(size_t size)
|
||||
{
|
||||
std::unique_ptr<details::_Value> ptr = utility::details::make_unique<details::_Array>(size);
|
||||
return web::json::value(std::move(ptr)
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
,
|
||||
value::Array
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
web::json::value web::json::value::array(std::vector<value> elements)
|
||||
{
|
||||
std::unique_ptr<details::_Value> ptr = utility::details::make_unique<details::_Array>(std::move(elements));
|
||||
return web::json::value(std::move(ptr)
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
,
|
||||
value::Array
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
const web::json::number& web::json::value::as_number() const { return m_value->as_number(); }
|
||||
|
||||
double web::json::value::as_double() const { return m_value->as_double(); }
|
||||
|
||||
int web::json::value::as_integer() const { return m_value->as_integer(); }
|
||||
|
||||
bool web::json::value::as_bool() const { return m_value->as_bool(); }
|
||||
|
||||
json::array& web::json::value::as_array() { return m_value->as_array(); }
|
||||
|
||||
const json::array& web::json::value::as_array() const { return m_value->as_array(); }
|
||||
|
||||
json::object& web::json::value::as_object() { return m_value->as_object(); }
|
||||
|
||||
const json::object& web::json::value::as_object() const { return m_value->as_object(); }
|
||||
|
||||
bool web::json::number::is_int32() const
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case signed_type:
|
||||
return m_intval >= (std::numeric_limits<int32_t>::min)() && m_intval <= (std::numeric_limits<int32_t>::max)();
|
||||
case unsigned_type: return m_uintval <= (std::numeric_limits<int32_t>::max)();
|
||||
case double_type:
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool web::json::number::is_uint32() const
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case signed_type: return m_intval >= 0 && m_intval <= (std::numeric_limits<uint32_t>::max)();
|
||||
case unsigned_type: return m_uintval <= (std::numeric_limits<uint32_t>::max)();
|
||||
case double_type:
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool web::json::number::is_int64() const
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case signed_type: return true;
|
||||
case unsigned_type: return m_uintval <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)());
|
||||
case double_type:
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool web::json::details::_String::has_escape_chars(const _String& str)
|
||||
{
|
||||
return std::any_of(std::begin(str.m_string), std::end(str.m_string), [](utility::string_t::value_type const x) {
|
||||
if (x <= 31)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (x == '"')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (x == '\\')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
web::json::value::value_type json::value::type() const { return m_value->type(); }
|
||||
|
||||
bool json::value::is_integer() const
|
||||
{
|
||||
if (!is_number())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return m_value->is_integer();
|
||||
}
|
||||
|
||||
bool json::value::is_double() const
|
||||
{
|
||||
if (!is_number())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return m_value->is_double();
|
||||
}
|
||||
|
||||
json::value& web::json::details::_Object::index(const utility::string_t& key) { return m_object[key]; }
|
||||
|
||||
bool web::json::details::_Object::has_field(const utility::string_t& key) const
|
||||
{
|
||||
return m_object.find(key) != m_object.end();
|
||||
}
|
||||
|
||||
bool web::json::value::has_number_field(const utility::string_t& key) const
|
||||
{
|
||||
return has_field(key) && at(key).is_number();
|
||||
}
|
||||
|
||||
bool web::json::value::has_integer_field(const utility::string_t& key) const
|
||||
{
|
||||
return has_field(key) && at(key).is_integer();
|
||||
}
|
||||
|
||||
bool web::json::value::has_double_field(const utility::string_t& key) const
|
||||
{
|
||||
return has_field(key) && at(key).is_double();
|
||||
}
|
||||
|
||||
bool web::json::value::has_boolean_field(const utility::string_t& key) const
|
||||
{
|
||||
return has_field(key) && at(key).is_boolean();
|
||||
}
|
||||
|
||||
bool web::json::value::has_string_field(const utility::string_t& key) const
|
||||
{
|
||||
return has_field(key) && at(key).is_string();
|
||||
}
|
||||
|
||||
bool web::json::value::has_array_field(const utility::string_t& key) const
|
||||
{
|
||||
return has_field(key) && at(key).is_array();
|
||||
}
|
||||
|
||||
bool web::json::value::has_object_field(const utility::string_t& key) const
|
||||
{
|
||||
return has_field(key) && at(key).is_object();
|
||||
}
|
||||
|
||||
utility::string_t json::value::to_string() const
|
||||
{
|
||||
#ifndef _WIN32
|
||||
utility::details::scoped_c_thread_locale locale;
|
||||
#endif
|
||||
return m_value->to_string();
|
||||
}
|
||||
|
||||
bool json::value::operator==(const json::value& other) const
|
||||
{
|
||||
if (this->m_value.get() == other.m_value.get()) return true;
|
||||
if (this->type() != other.type()) return false;
|
||||
|
||||
switch (this->type())
|
||||
{
|
||||
case Null: return true;
|
||||
case Number: return this->as_number() == other.as_number();
|
||||
case Boolean: return this->as_bool() == other.as_bool();
|
||||
case String: return this->as_string() == other.as_string();
|
||||
case Object:
|
||||
return static_cast<const json::details::_Object*>(this->m_value.get())
|
||||
->is_equal(static_cast<const json::details::_Object*>(other.m_value.get()));
|
||||
case Array:
|
||||
return static_cast<const json::details::_Array*>(this->m_value.get())
|
||||
->is_equal(static_cast<const json::details::_Array*>(other.m_value.get()));
|
||||
}
|
||||
__assume(0);
|
||||
}
|
||||
|
||||
void web::json::value::erase(size_t index) { return this->as_array().erase(index); }
|
||||
|
||||
void web::json::value::erase(const utility::string_t& key) { return this->as_object().erase(key); }
|
||||
|
||||
// at() overloads
|
||||
web::json::value& web::json::value::at(size_t index) { return this->as_array().at(index); }
|
||||
|
||||
const web::json::value& web::json::value::at(size_t index) const { return this->as_array().at(index); }
|
||||
|
||||
web::json::value& web::json::value::at(const utility::string_t& key) { return this->as_object().at(key); }
|
||||
|
||||
const web::json::value& web::json::value::at(const utility::string_t& key) const { return this->as_object().at(key); }
|
||||
|
||||
web::json::value& web::json::value::operator[](const utility::string_t& key)
|
||||
{
|
||||
if (this->is_null())
|
||||
{
|
||||
m_value.reset(new web::json::details::_Object(details::g_keep_json_object_unsorted));
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
m_kind = value::Object;
|
||||
#endif
|
||||
}
|
||||
return m_value->index(key);
|
||||
}
|
||||
|
||||
web::json::value& web::json::value::operator[](size_t index)
|
||||
{
|
||||
if (this->is_null())
|
||||
{
|
||||
m_value.reset(new web::json::details::_Array());
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
m_kind = value::Array;
|
||||
#endif
|
||||
}
|
||||
return m_value->index(index);
|
||||
}
|
||||
|
||||
// Remove once VS 2013 is no longer supported.
|
||||
#if defined(_WIN32) && _MSC_VER < 1900
|
||||
static web::json::details::json_error_category_impl instance;
|
||||
#endif
|
||||
const web::json::details::json_error_category_impl& web::json::details::json_error_category()
|
||||
{
|
||||
#if !defined(_WIN32) || _MSC_VER >= 1900
|
||||
static web::json::details::json_error_category_impl instance;
|
||||
#endif
|
||||
return instance;
|
||||
}
|
||||
1279
deps/cpprestsdk/src/json/json_parsing.cpp
vendored
1279
deps/cpprestsdk/src/json/json_parsing.cpp
vendored
File diff suppressed because it is too large
Load Diff
254
deps/cpprestsdk/src/json/json_serialization.cpp
vendored
254
deps/cpprestsdk/src/json/json_serialization.cpp
vendored
@@ -1,254 +0,0 @@
|
||||
/***
|
||||
* Copyright (C) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
*
|
||||
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
*
|
||||
* HTTP Library: JSON parser and writer
|
||||
*
|
||||
* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
|
||||
*
|
||||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
****/
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
using namespace web;
|
||||
using namespace web::json;
|
||||
using namespace utility;
|
||||
using namespace utility::conversions;
|
||||
|
||||
//
|
||||
// JSON Serialization
|
||||
//
|
||||
|
||||
#ifdef _WIN32
|
||||
void web::json::value::serialize(std::ostream& stream) const
|
||||
{
|
||||
// This has better performance than writing directly to stream.
|
||||
std::string str;
|
||||
m_value->serialize_impl(str);
|
||||
stream << str;
|
||||
}
|
||||
void web::json::value::format(std::basic_string<wchar_t>& string) const { m_value->format(string); }
|
||||
#endif
|
||||
|
||||
void web::json::value::serialize(utility::ostream_t& stream) const
|
||||
{
|
||||
#ifndef _WIN32
|
||||
utility::details::scoped_c_thread_locale locale;
|
||||
#endif
|
||||
|
||||
// This has better performance than writing directly to stream.
|
||||
utility::string_t str;
|
||||
m_value->serialize_impl(str);
|
||||
stream << str;
|
||||
}
|
||||
|
||||
void web::json::value::format(std::basic_string<char>& string) const { m_value->format(string); }
|
||||
|
||||
template<typename CharType>
|
||||
void web::json::details::append_escape_string(std::basic_string<CharType>& str,
|
||||
const std::basic_string<CharType>& escaped)
|
||||
{
|
||||
for (const auto& ch : escaped)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case '\"':
|
||||
str += '\\';
|
||||
str += '\"';
|
||||
break;
|
||||
case '\\':
|
||||
str += '\\';
|
||||
str += '\\';
|
||||
break;
|
||||
case '\b':
|
||||
str += '\\';
|
||||
str += 'b';
|
||||
break;
|
||||
case '\f':
|
||||
str += '\\';
|
||||
str += 'f';
|
||||
break;
|
||||
case '\r':
|
||||
str += '\\';
|
||||
str += 'r';
|
||||
break;
|
||||
case '\n':
|
||||
str += '\\';
|
||||
str += 'n';
|
||||
break;
|
||||
case '\t':
|
||||
str += '\\';
|
||||
str += 't';
|
||||
break;
|
||||
default:
|
||||
|
||||
// If a control character then must unicode escaped.
|
||||
if (ch >= 0 && ch <= 0x1F)
|
||||
{
|
||||
static const std::array<CharType, 16> intToHex = {
|
||||
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}};
|
||||
str += '\\';
|
||||
str += 'u';
|
||||
str += '0';
|
||||
str += '0';
|
||||
str += intToHex[(ch & 0xF0) >> 4];
|
||||
str += intToHex[ch & 0x0F];
|
||||
}
|
||||
else
|
||||
{
|
||||
str += ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void web::json::details::format_string(const utility::string_t& key, utility::string_t& str)
|
||||
{
|
||||
str.push_back('"');
|
||||
append_escape_string(str, key);
|
||||
str.push_back('"');
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void web::json::details::format_string(const utility::string_t& key, std::string& str)
|
||||
{
|
||||
str.push_back('"');
|
||||
append_escape_string(str, utility::conversions::to_utf8string(key));
|
||||
str.push_back('"');
|
||||
}
|
||||
#endif
|
||||
|
||||
void web::json::details::_String::format(std::basic_string<char>& str) const
|
||||
{
|
||||
str.push_back('"');
|
||||
|
||||
if (m_has_escape_char)
|
||||
{
|
||||
append_escape_string(str, utility::conversions::to_utf8string(m_string));
|
||||
}
|
||||
else
|
||||
{
|
||||
str.append(utility::conversions::to_utf8string(m_string));
|
||||
}
|
||||
|
||||
str.push_back('"');
|
||||
}
|
||||
|
||||
void web::json::details::_Number::format(std::basic_string<char>& stream) const
|
||||
{
|
||||
if (m_number.m_type != number::type::double_type)
|
||||
{
|
||||
// #digits + 1 to avoid loss + 1 for the sign + 1 for null terminator.
|
||||
const size_t tempSize = std::numeric_limits<uint64_t>::digits10 + 3;
|
||||
char tempBuffer[tempSize];
|
||||
|
||||
#ifdef _WIN32
|
||||
// This can be improved performance-wise if we implement our own routine
|
||||
if (m_number.m_type == number::type::signed_type)
|
||||
_i64toa_s(m_number.m_intval, tempBuffer, tempSize, 10);
|
||||
else
|
||||
_ui64toa_s(m_number.m_uintval, tempBuffer, tempSize, 10);
|
||||
|
||||
const auto numChars = strnlen_s(tempBuffer, tempSize);
|
||||
#else
|
||||
int numChars;
|
||||
if (m_number.m_type == number::type::signed_type)
|
||||
numChars = snprintf(tempBuffer, tempSize, "%" PRId64, m_number.m_intval);
|
||||
else
|
||||
numChars = snprintf(tempBuffer, tempSize, "%" PRIu64, m_number.m_uintval);
|
||||
#endif
|
||||
stream.append(tempBuffer, numChars);
|
||||
}
|
||||
else
|
||||
{
|
||||
// #digits + 2 to avoid loss + 1 for the sign + 1 for decimal point + 5 for exponent (e+xxx) + 1 for null
|
||||
// terminator
|
||||
const size_t tempSize = std::numeric_limits<double>::digits10 + 10;
|
||||
char tempBuffer[tempSize];
|
||||
#ifdef _WIN32
|
||||
const auto numChars = _sprintf_s_l(tempBuffer,
|
||||
tempSize,
|
||||
"%.*g",
|
||||
utility::details::scoped_c_thread_locale::c_locale(),
|
||||
std::numeric_limits<double>::digits10 + 2,
|
||||
m_number.m_value);
|
||||
#else
|
||||
const auto numChars =
|
||||
snprintf(tempBuffer, tempSize, "%.*g", std::numeric_limits<double>::digits10 + 2, m_number.m_value);
|
||||
#endif
|
||||
stream.append(tempBuffer, numChars);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void web::json::details::_String::format(std::basic_string<wchar_t>& str) const
|
||||
{
|
||||
str.push_back(L'"');
|
||||
|
||||
if (m_has_escape_char)
|
||||
{
|
||||
append_escape_string(str, m_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
str.append(m_string);
|
||||
}
|
||||
|
||||
str.push_back(L'"');
|
||||
}
|
||||
|
||||
void web::json::details::_Number::format(std::basic_string<wchar_t>& stream) const
|
||||
{
|
||||
if (m_number.m_type != number::type::double_type)
|
||||
{
|
||||
// #digits + 1 to avoid loss + 1 for the sign + 1 for null terminator.
|
||||
const size_t tempSize = std::numeric_limits<uint64_t>::digits10 + 3;
|
||||
wchar_t tempBuffer[tempSize];
|
||||
|
||||
if (m_number.m_type == number::type::signed_type)
|
||||
_i64tow_s(m_number.m_intval, tempBuffer, tempSize, 10);
|
||||
else
|
||||
_ui64tow_s(m_number.m_uintval, tempBuffer, tempSize, 10);
|
||||
|
||||
stream.append(tempBuffer, wcsnlen_s(tempBuffer, tempSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
// #digits + 2 to avoid loss + 1 for the sign + 1 for decimal point + 5 for exponent (e+xxx) + 1 for null
|
||||
// terminator
|
||||
const size_t tempSize = std::numeric_limits<double>::digits10 + 10;
|
||||
wchar_t tempBuffer[tempSize];
|
||||
const int numChars = _swprintf_s_l(tempBuffer,
|
||||
tempSize,
|
||||
L"%.*g",
|
||||
utility::details::scoped_c_thread_locale::c_locale(),
|
||||
std::numeric_limits<double>::digits10 + 2,
|
||||
m_number.m_value);
|
||||
stream.append(tempBuffer, numChars);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const utility::string_t& web::json::details::_String::as_string() const { return m_string; }
|
||||
|
||||
const utility::string_t& web::json::value::as_string() const { return m_value->as_string(); }
|
||||
|
||||
utility::string_t json::value::serialize() const
|
||||
{
|
||||
#ifndef _WIN32
|
||||
utility::details::scoped_c_thread_locale locale;
|
||||
#endif
|
||||
return m_value->to_string();
|
||||
}
|
||||
1490
deps/cpprestsdk/src/utilities/asyncrt_utils.cpp
vendored
1490
deps/cpprestsdk/src/utilities/asyncrt_utils.cpp
vendored
File diff suppressed because it is too large
Load Diff
260
deps/cpprestsdk/src/utilities/base64.cpp
vendored
260
deps/cpprestsdk/src/utilities/base64.cpp
vendored
@@ -1,260 +0,0 @@
|
||||
/***
|
||||
* Copyright (C) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
*
|
||||
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
*
|
||||
* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
|
||||
*
|
||||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
****/
|
||||
#include "pch.h"
|
||||
|
||||
using namespace web;
|
||||
using namespace utility;
|
||||
|
||||
std::vector<unsigned char> _from_base64(const utility::string_t& str);
|
||||
utility::string_t _to_base64(const unsigned char* ptr, size_t size);
|
||||
|
||||
std::vector<unsigned char> __cdecl conversions::from_base64(const utility::string_t& str) { return _from_base64(str); }
|
||||
|
||||
utility::string_t __cdecl conversions::to_base64(const std::vector<unsigned char>& input)
|
||||
{
|
||||
if (input.size() == 0)
|
||||
{
|
||||
// return empty string
|
||||
return utility::string_t();
|
||||
}
|
||||
|
||||
return _to_base64(&input[0], input.size());
|
||||
}
|
||||
|
||||
utility::string_t __cdecl conversions::to_base64(uint64_t input)
|
||||
{
|
||||
return _to_base64(reinterpret_cast<const unsigned char*>(&input), sizeof(input));
|
||||
}
|
||||
|
||||
static const char* _base64_enctbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
const std::array<unsigned char, 128> _base64_dectbl = {
|
||||
{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62,
|
||||
255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 254, 255, 255, 255, 0,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
||||
23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
|
||||
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255}};
|
||||
|
||||
struct _triple_byte
|
||||
{
|
||||
unsigned char _1_1 : 2;
|
||||
unsigned char _0 : 6;
|
||||
unsigned char _2_1 : 4;
|
||||
unsigned char _1_2 : 4;
|
||||
unsigned char _3 : 6;
|
||||
unsigned char _2_2 : 2;
|
||||
};
|
||||
|
||||
struct _double_byte
|
||||
{
|
||||
unsigned char _1_1 : 2;
|
||||
unsigned char _0 : 6;
|
||||
unsigned char _2_1 : 4;
|
||||
unsigned char _1_2 : 4;
|
||||
};
|
||||
|
||||
struct _single_byte
|
||||
{
|
||||
unsigned char _1_1 : 2;
|
||||
unsigned char _0 : 6;
|
||||
};
|
||||
|
||||
//
|
||||
// A note on the implementation of BASE64 encoding and decoding:
|
||||
//
|
||||
// This is a fairly basic and naive implementation; there is probably a lot of room for
|
||||
// performance improvement, as well as for adding options such as support for URI-safe base64,
|
||||
// ignoring CRLF, relaxed validation rules, etc. The decoder is currently pretty strict.
|
||||
//
|
||||
|
||||
#ifdef __GNUC__
|
||||
// gcc is concerned about the bitfield uses in the code, something we simply need to ignore.
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#endif
|
||||
std::vector<unsigned char> _from_base64(const utility::string_t& input)
|
||||
{
|
||||
std::vector<unsigned char> result;
|
||||
|
||||
if (input.empty()) return result;
|
||||
|
||||
size_t padding = 0;
|
||||
|
||||
// Validation
|
||||
{
|
||||
auto size = input.size();
|
||||
|
||||
if ((size % 4) != 0)
|
||||
{
|
||||
throw std::runtime_error("length of base64 string is not an even multiple of 4");
|
||||
}
|
||||
|
||||
for (auto iter = input.begin(); iter != input.end(); ++iter, --size)
|
||||
{
|
||||
const size_t ch_sz = static_cast<size_t>(*iter);
|
||||
if (ch_sz >= _base64_dectbl.size() || _base64_dectbl[ch_sz] == 255)
|
||||
{
|
||||
throw std::runtime_error("invalid character found in base64 string");
|
||||
}
|
||||
if (_base64_dectbl[ch_sz] == 254)
|
||||
{
|
||||
padding++;
|
||||
// padding only at the end
|
||||
if (size > 2)
|
||||
{
|
||||
throw std::runtime_error("invalid padding character found in base64 string");
|
||||
}
|
||||
if (size == 2)
|
||||
{
|
||||
const size_t ch2_sz = static_cast<size_t>(*(iter + 1));
|
||||
if (ch2_sz >= _base64_dectbl.size() || _base64_dectbl[ch2_sz] != 254)
|
||||
{
|
||||
throw std::runtime_error("invalid padding character found in base64 string");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto size = input.size();
|
||||
const char_t* ptr = &input[0];
|
||||
|
||||
auto outsz = (size / 4) * 3;
|
||||
outsz -= padding;
|
||||
|
||||
result.resize(outsz);
|
||||
|
||||
size_t idx = 0;
|
||||
for (; size > 4; ++idx)
|
||||
{
|
||||
unsigned char target[3];
|
||||
memset(target, 0, sizeof(target));
|
||||
_triple_byte* record = reinterpret_cast<_triple_byte*>(target);
|
||||
|
||||
unsigned char val0 = _base64_dectbl[ptr[0]];
|
||||
unsigned char val1 = _base64_dectbl[ptr[1]];
|
||||
unsigned char val2 = _base64_dectbl[ptr[2]];
|
||||
unsigned char val3 = _base64_dectbl[ptr[3]];
|
||||
|
||||
record->_0 = val0;
|
||||
record->_1_1 = val1 >> 4;
|
||||
result[idx] = target[0];
|
||||
|
||||
record->_1_2 = val1 & 0xF;
|
||||
record->_2_1 = val2 >> 2;
|
||||
result[++idx] = target[1];
|
||||
|
||||
record->_2_2 = val2 & 0x3;
|
||||
record->_3 = val3 & 0x3F;
|
||||
result[++idx] = target[2];
|
||||
|
||||
ptr += 4;
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
// Handle the last four bytes separately, to avoid having the conditional statements
|
||||
// in all the iterations (a performance issue).
|
||||
|
||||
{
|
||||
unsigned char target[3];
|
||||
memset(target, 0, sizeof(target));
|
||||
_triple_byte* record = reinterpret_cast<_triple_byte*>(target);
|
||||
|
||||
unsigned char val0 = _base64_dectbl[ptr[0]];
|
||||
unsigned char val1 = _base64_dectbl[ptr[1]];
|
||||
unsigned char val2 = _base64_dectbl[ptr[2]];
|
||||
unsigned char val3 = _base64_dectbl[ptr[3]];
|
||||
|
||||
record->_0 = val0;
|
||||
record->_1_1 = val1 >> 4;
|
||||
result[idx] = target[0];
|
||||
|
||||
record->_1_2 = val1 & 0xF;
|
||||
if (val2 != 254)
|
||||
{
|
||||
record->_2_1 = val2 >> 2;
|
||||
result[++idx] = target[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
// There shouldn't be any information (ones) in the unused bits,
|
||||
if (record->_1_2 != 0)
|
||||
{
|
||||
throw std::runtime_error("Invalid end of base64 string");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
record->_2_2 = val2 & 0x3;
|
||||
if (val3 != 254)
|
||||
{
|
||||
record->_3 = val3 & 0x3F;
|
||||
result[++idx] = target[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
// There shouldn't be any information (ones) in the unused bits.
|
||||
if (record->_2_2 != 0)
|
||||
{
|
||||
throw std::runtime_error("Invalid end of base64 string");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
utility::string_t _to_base64(const unsigned char* ptr, size_t size)
|
||||
{
|
||||
utility::string_t result;
|
||||
|
||||
for (; size >= 3;)
|
||||
{
|
||||
const _triple_byte* record = reinterpret_cast<const _triple_byte*>(ptr);
|
||||
unsigned char idx0 = record->_0;
|
||||
unsigned char idx1 = (record->_1_1 << 4) | record->_1_2;
|
||||
unsigned char idx2 = (record->_2_1 << 2) | record->_2_2;
|
||||
unsigned char idx3 = record->_3;
|
||||
result.push_back(char_t(_base64_enctbl[idx0]));
|
||||
result.push_back(char_t(_base64_enctbl[idx1]));
|
||||
result.push_back(char_t(_base64_enctbl[idx2]));
|
||||
result.push_back(char_t(_base64_enctbl[idx3]));
|
||||
size -= 3;
|
||||
ptr += 3;
|
||||
}
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
const _single_byte* record = reinterpret_cast<const _single_byte*>(ptr);
|
||||
unsigned char idx0 = record->_0;
|
||||
unsigned char idx1 = (record->_1_1 << 4);
|
||||
result.push_back(char_t(_base64_enctbl[idx0]));
|
||||
result.push_back(char_t(_base64_enctbl[idx1]));
|
||||
result.push_back('=');
|
||||
result.push_back('=');
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
const _double_byte* record = reinterpret_cast<const _double_byte*>(ptr);
|
||||
unsigned char idx0 = record->_0;
|
||||
unsigned char idx1 = (record->_1_1 << 4) | record->_1_2;
|
||||
unsigned char idx2 = (record->_2_1 << 2);
|
||||
result.push_back(char_t(_base64_enctbl[idx0]));
|
||||
result.push_back(char_t(_base64_enctbl[idx1]));
|
||||
result.push_back(char_t(_base64_enctbl[idx2]));
|
||||
result.push_back('=');
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
157
deps/cpprestsdk/src/utilities/web_utilities.cpp
vendored
157
deps/cpprestsdk/src/utilities/web_utilities.cpp
vendored
@@ -1,157 +0,0 @@
|
||||
/***
|
||||
* Copyright (C) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
*
|
||||
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
*
|
||||
* Credential and proxy utilities.
|
||||
*
|
||||
* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
|
||||
*
|
||||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
****/
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(__cplusplus_winrt)
|
||||
#include <Wincrypt.h>
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus_winrt)
|
||||
#include <robuffer.h>
|
||||
#endif
|
||||
|
||||
namespace web
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
#if defined(_WIN32) && !defined(CPPREST_TARGET_XP)
|
||||
#if defined(__cplusplus_winrt)
|
||||
|
||||
// Helper function to zero out memory of an IBuffer.
|
||||
void winrt_secure_zero_buffer(Windows::Storage::Streams::IBuffer ^ buffer)
|
||||
{
|
||||
Microsoft::WRL::ComPtr<IInspectable> bufferInspectable(reinterpret_cast<IInspectable*>(buffer));
|
||||
Microsoft::WRL::ComPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess;
|
||||
bufferInspectable.As(&bufferByteAccess);
|
||||
|
||||
// This shouldn't happen but if can't get access to the raw bytes for some reason
|
||||
// then we can't zero out.
|
||||
byte* rawBytes;
|
||||
if (bufferByteAccess->Buffer(&rawBytes) == S_OK)
|
||||
{
|
||||
SecureZeroMemory(rawBytes, buffer->Length);
|
||||
}
|
||||
}
|
||||
|
||||
winrt_encryption::winrt_encryption(const std::wstring& data)
|
||||
{
|
||||
auto provider = ref new Windows::Security::Cryptography::DataProtection::DataProtectionProvider(
|
||||
ref new Platform::String(L"Local=user"));
|
||||
|
||||
// Create buffer containing plain text password.
|
||||
Platform::ArrayReference<unsigned char> arrayref(
|
||||
reinterpret_cast<unsigned char*>(const_cast<std::wstring::value_type*>(data.c_str())),
|
||||
static_cast<unsigned int>(data.size()) * sizeof(std::wstring::value_type));
|
||||
Windows::Storage::Streams::IBuffer ^ plaintext =
|
||||
Windows::Security::Cryptography::CryptographicBuffer::CreateFromByteArray(arrayref);
|
||||
m_buffer = pplx::create_task(provider->ProtectAsync(plaintext));
|
||||
m_buffer.then(
|
||||
[plaintext](pplx::task<Windows::Storage::Streams::IBuffer ^>) { winrt_secure_zero_buffer(plaintext); });
|
||||
}
|
||||
|
||||
plaintext_string winrt_encryption::decrypt() const
|
||||
{
|
||||
// To fully guarantee asynchrony would require significant impact on existing code. This code path
|
||||
// is never run on a user's thread and is only done once when setting up a connection.
|
||||
auto encrypted = m_buffer.get();
|
||||
auto provider = ref new Windows::Security::Cryptography::DataProtection::DataProtectionProvider();
|
||||
auto plaintext = pplx::create_task(provider->UnprotectAsync(encrypted)).get();
|
||||
|
||||
// Get access to raw bytes in plain text buffer.
|
||||
Microsoft::WRL::ComPtr<IInspectable> bufferInspectable(reinterpret_cast<IInspectable*>(plaintext));
|
||||
Microsoft::WRL::ComPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess;
|
||||
bufferInspectable.As(&bufferByteAccess);
|
||||
byte* rawPlaintext;
|
||||
const auto& result = bufferByteAccess->Buffer(&rawPlaintext);
|
||||
if (result != S_OK)
|
||||
{
|
||||
throw ::utility::details::create_system_error(result);
|
||||
}
|
||||
|
||||
// Construct string and zero out memory from plain text buffer.
|
||||
auto data = plaintext_string(
|
||||
new std::wstring(reinterpret_cast<const std::wstring::value_type*>(rawPlaintext), plaintext->Length / 2));
|
||||
SecureZeroMemory(rawPlaintext, plaintext->Length);
|
||||
return std::move(data);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
win32_encryption::win32_encryption(const std::wstring& data) : m_numCharacters(data.size())
|
||||
{
|
||||
// Early return because CryptProtectMemory crashes with empty string
|
||||
if (m_numCharacters == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.size() > (std::numeric_limits<DWORD>::max)() / sizeof(wchar_t))
|
||||
{
|
||||
throw std::length_error("Encryption string too long");
|
||||
}
|
||||
|
||||
const auto dataSizeDword = static_cast<DWORD>(data.size() * sizeof(wchar_t));
|
||||
|
||||
// Round up dataSizeDword to be a multiple of CRYPTPROTECTMEMORY_BLOCK_SIZE
|
||||
static_assert(CRYPTPROTECTMEMORY_BLOCK_SIZE == 16, "Power of 2 assumptions in this bit masking violated");
|
||||
const auto mask = static_cast<DWORD>(CRYPTPROTECTMEMORY_BLOCK_SIZE - 1u);
|
||||
const auto dataNumBytes = (dataSizeDword & ~mask) + ((dataSizeDword & mask) != 0) * CRYPTPROTECTMEMORY_BLOCK_SIZE;
|
||||
assert((dataNumBytes % CRYPTPROTECTMEMORY_BLOCK_SIZE) == 0);
|
||||
assert(dataNumBytes >= dataSizeDword);
|
||||
m_buffer.resize(dataNumBytes);
|
||||
memcpy_s(m_buffer.data(), m_buffer.size(), data.c_str(), dataNumBytes);
|
||||
if (!CryptProtectMemory(m_buffer.data(), dataNumBytes, CRYPTPROTECTMEMORY_SAME_PROCESS))
|
||||
{
|
||||
throw ::utility::details::create_system_error(GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
win32_encryption::~win32_encryption() { SecureZeroMemory(m_buffer.data(), m_buffer.size()); }
|
||||
|
||||
plaintext_string win32_encryption::decrypt() const
|
||||
{
|
||||
// Copy the buffer and decrypt to avoid having to re-encrypt.
|
||||
auto result = plaintext_string(new std::wstring(reinterpret_cast<const std::wstring::value_type*>(m_buffer.data()),
|
||||
m_buffer.size() / sizeof(wchar_t)));
|
||||
auto& data = *result;
|
||||
if (!m_buffer.empty())
|
||||
{
|
||||
if (!CryptUnprotectMemory(&data[0], static_cast<DWORD>(m_buffer.size()), CRYPTPROTECTMEMORY_SAME_PROCESS))
|
||||
{
|
||||
throw ::utility::details::create_system_error(GetLastError());
|
||||
}
|
||||
|
||||
assert(m_numCharacters <= m_buffer.size());
|
||||
SecureZeroMemory(&data[m_numCharacters], data.size() - m_numCharacters);
|
||||
data.erase(m_numCharacters);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void zero_memory_deleter::operator()(::utility::string_t* data) const
|
||||
{
|
||||
CASABLANCA_UNREFERENCED_PARAMETER(data);
|
||||
#if defined(_WIN32)
|
||||
SecureZeroMemory(&(*data)[0], data->size() * sizeof(::utility::string_t::value_type));
|
||||
delete data;
|
||||
#endif
|
||||
}
|
||||
} // namespace details
|
||||
|
||||
} // namespace web
|
||||
1
deps/cxxopts
vendored
Submodule
1
deps/cxxopts
vendored
Submodule
Submodule deps/cxxopts added at 12e496da3d
8
deps/cxxopts.props
vendored
Normal file
8
deps/cxxopts.props
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<Project>
|
||||
<Import Project="restore_git_submodules.props" Condition="'$(RestoreGitSubmodulesImported)' == ''" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)cxxopts\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
12
deps/restore_git_submodules.props
vendored
Normal file
12
deps/restore_git_submodules.props
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<RestoreGitSubmodulesImported>true</RestoreGitSubmodulesImported>
|
||||
</PropertyGroup>
|
||||
<Target Name="RestoreGitSubmodules" BeforeTargets="PrepareForBuild">
|
||||
<Exec IgnoreExitCode="true"
|
||||
EchoOff="true"
|
||||
StandardOutputImportance="low"
|
||||
StandardErrorImportance="low"
|
||||
Command="git submodule update --init" />
|
||||
</Target>
|
||||
</Project>
|
||||
1
deps/spdlog
vendored
Submodule
1
deps/spdlog
vendored
Submodule
Submodule deps/spdlog added at cbe9448650
9
deps/spdlog.props
vendored
Normal file
9
deps/spdlog.props
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<Project>
|
||||
<Import Project="restore_git_submodules.props" Condition="'$(RestoreGitSubmodulesImported)' == ''" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)spdlog\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>SPDLOG_WCHAR_TO_UTF8_SUPPORT;SPDLOG_COMPILED_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
@@ -1,29 +0,0 @@
|
||||
# Code Organization
|
||||
|
||||
## Rules
|
||||
|
||||
- **Follow the pattern of what you already see in the code**
|
||||
- Try to package new ideas/components into libraries that have nicely defined interfaces
|
||||
- Package new ideas into classes or refactor existing ideas into a class as you extend
|
||||
|
||||
## Code Overview
|
||||
|
||||
General project organization:
|
||||
|
||||
#### The [`build`](/build) folder
|
||||
Contains the Azure pipeline CI build scripts.
|
||||
|
||||
#### The [`deps`](/deps) folder
|
||||
Contains other projects, that PowerToys uses as dependency.
|
||||
|
||||
#### The [`doc`](/doc) folder
|
||||
Documentation for the project, including a [coding guide](/doc/coding) and [design docs](/doc/specs).
|
||||
|
||||
#### The [`installer`](/installer) folder
|
||||
Contains the source code of the PowerToys installer.
|
||||
|
||||
#### The [`src`](/src) folder
|
||||
Contains the source code of the PowerToys runner and of all of the PowerToys modules. **This is where the most of the magic happens.**
|
||||
|
||||
#### The [`tools`](/tools) folder
|
||||
Various tools used by PowerToys. Includes the Visual Studio 2019 project template for new PowerToys.
|
||||
@@ -1,5 +0,0 @@
|
||||
# Coding Style
|
||||
|
||||
## Philosophy
|
||||
1. If it's inserting something into the existing classes/functions, try to follow the existing style as closely as possible.
|
||||
1. If it's brand new code or refactoring a complete class or area of the code, please follow as Modern C++ of a style as you can and reference the [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines) as much as you possibly can.
|
||||
109
doc/devdocs/common.md
Normal file
109
doc/devdocs/common.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Classes and structures
|
||||
|
||||
#### class Animation: [header](/src/common/animation.h) [source](/src/common/animation.cpp)
|
||||
Animation helper class with two easing-in animations: linear and exponential.
|
||||
|
||||
#### class AsyncMessageQueue: [header](/src/common/async_message_queue.h)
|
||||
Header-only asynchronous message queue. Used by `TwoWayPipeMessageIPC`.
|
||||
|
||||
#### class TwoWayPipeMessageIPC: [header](/src/common/two_way_pipe_message_ipc.h)
|
||||
Header-only asynchronous IPC messaging class. Used by the runner to communicate with the settings window.
|
||||
|
||||
#### class D2DSVG: [header](/src/common/d2d_svg.h) [source](/src/common/d2d_svg.cpp)
|
||||
Class for loading, rendering and for some basic modifications of SVG graphics.
|
||||
|
||||
#### class D2DText: [header](/src/common/d2d_text.h) [source](/src/common/d2d_text.cpp)
|
||||
Class for rendering text using DirectX.
|
||||
|
||||
#### class D2DWindow: [header](/src/common/d2d_window.h) [source](/src/common/d2d_window.cpp)
|
||||
Base class for creating borderless windows, with DirectX enabled rendering pipeline.
|
||||
|
||||
#### class DPIAware: [header](/src/common/dpi_aware.h) [source](/src/common/dpi_aware.cpp)
|
||||
Helper class for creating DPI-aware applications.
|
||||
|
||||
#### struct MonitorInfo: [header](/src/common/monitors.h) [source](/src/common/monitors.cpp)
|
||||
Class for obtaining information about physical displays connected to the machine.
|
||||
|
||||
#### class Settings, class PowerToyValues, class CustomActionObject: [header](/src/common/settings_objects.h) [source](/src/common/settings_objects.cpp)
|
||||
Classes used to define settings screens for the PowerToys modules.
|
||||
|
||||
#### class Tasklist: [header](/src/common/tasklist_positions.h) [source](/src/common/tasklist_positions.cpp)
|
||||
Class that can detect the position of the windows buttons on the taskbar. It also detects which window will react to pressing `WinKey + number`.
|
||||
|
||||
#### struct WindowsColors: [header](/src/common/windows_colors.h) [source](/src/common/windows_colors.cpp)
|
||||
Class for detecting the current Windows color scheme.
|
||||
|
||||
# Helpers
|
||||
|
||||
#### Common helpers: [header](/src/common/common.h) [source](/src/common/common.cpp)
|
||||
Various helper functions.
|
||||
|
||||
#### Settings helpers: [header](/src/common/settings_helpers.h)
|
||||
Helper methods for the settings.
|
||||
|
||||
#### Start visible helper: [header](/src/common/start_visible.h) [source](/src/common/start_visible.cpp)
|
||||
Contains function to test if the Start menu is visible.
|
||||
|
||||
# Toast Notifications
|
||||
|
||||
#### Notifications API [header](/src/common/notifications.h) [source](/src/common/notifications.cpp)
|
||||
To use UWP-style toast notifications, simply include the header and call one of these functions:
|
||||
|
||||
```cpp
|
||||
void show_toast(std::wstring_view message); // #1
|
||||
|
||||
void show_toast_background_activated( // #2
|
||||
std::wstring_view message,
|
||||
std::wstring_view background_handler_id,
|
||||
std::vector<std::wstring_view> button_labels);
|
||||
```
|
||||
We might add more functions in the future if the need arises, e.g. `show_toast_xml` which will accept raw XML for rich customization.
|
||||
|
||||
Description:
|
||||
- `#1` is for sending simple notifications without any callbacks or buttons
|
||||
- `#2` is capable of showing a toast with multiple buttons and background activation
|
||||
- `message` is a plain-text argument
|
||||
|
||||
Implement a toast activation handler/callback as a function in [handler_functions.cpp](/src/common/notifications_winrt/handler_functions.cpp) and register its `background_handler_id` via `handlers_map`, e.g.:
|
||||
|
||||
```cpp
|
||||
// Your .cpp where you'd like to show a toast
|
||||
|
||||
#include <common/notifications.h>
|
||||
|
||||
void some_func() {
|
||||
// ...
|
||||
notifications::show_toast_background_activated(
|
||||
L"Toast message!", // text displayed in a toast
|
||||
L"awesome_toast", // activation handler id
|
||||
{L"Press me!", L"Also could press me!", L"I'm here to be pressed!"} // buttons in a toast
|
||||
);
|
||||
```
|
||||
|
||||
```cpp
|
||||
// handler_functions.cpp
|
||||
void awesome_toast_handler(IBackgroundTaskInstance, const size_t button_id)
|
||||
{
|
||||
switch(button_id)
|
||||
{
|
||||
case 0:
|
||||
// handle "Press me!" button click
|
||||
case 1:
|
||||
// handle "Also could press me!" button click
|
||||
case 2:
|
||||
// handle "I'm here to be pressed!" button click
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
const std::unordered_map<std::wstring_view, handler_function_t> handlers_map = {
|
||||
// ...other handlers...
|
||||
{L"awesome_toast", awesome_toast_handler}
|
||||
};}
|
||||
|
||||
```
|
||||
|
||||
Note: since _background activation_ implies that your toast handler will be invoked in a separate process, you can't share data directly from within a handler and your PT process. Also, since PT is currently a Desktop Bridge app, _foreground activation_ is [handled the same as background](https://docs.microsoft.com/en-US/windows/uwp/design/shell/tiles-and-notifications/send-local-toast-desktop-cpp-wrl#foreground-vs-background-activation), therefore we don't make a dedicated API for it. You can read more on the rationale of the current design [here](https://github.com/microsoft/PowerToys/pull/1178#issue-368768337).
|
||||
|
||||
|
||||
71
doc/devdocs/guidance.md
Normal file
71
doc/devdocs/guidance.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Coding Guidance
|
||||
|
||||
## Working With Strings
|
||||
|
||||
In order to support localization **YOU SHOULD NOT** have hardcoded UI display strings in your code. Instead, use resource files to consume strings.
|
||||
|
||||
### For CPP
|
||||
Use [`StringTable` resource][String Table] to store the strings and resource header file(`resource.h`) to store Id's linked to the UI display string. Add the strings with Id's referenced from the header file to the resource-definition script file. You can use [Visual Studio Resource Editor][VS Resource Editor] to create and manage resource files.
|
||||
|
||||
- `resource.h`:
|
||||
|
||||
XXX must be a unique int in the list (mostly the int ID of the last string id plus one):
|
||||
|
||||
```cpp
|
||||
#define IDS_MODULE_DISPLAYNAME XXX
|
||||
```
|
||||
|
||||
- `StringTable` in resource-definition script file `validmodulename.rc`:
|
||||
|
||||
```
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_MODULE_DISPLAYNAME L"Module Name"
|
||||
END
|
||||
```
|
||||
|
||||
- Use the `GET_RESOURCE_STRING(UINT resource_id)` method to consume strings in your code.
|
||||
```cpp
|
||||
#include <common.h>
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
|
||||
std::wstring GET_RESOURCE_STRING(IDS_MODULE_DISPLAYNAME)
|
||||
```
|
||||
|
||||
### For C#
|
||||
Use [XML resource file(.resx)][Resx Files] to store the UI display strings and [`Resource Manager`][Resource Manager] to consume those strings in the code. You can use [Visual Studio][Resx Files VS] to create and manage XML resources files.
|
||||
|
||||
- `Resources.resx`
|
||||
|
||||
```xml
|
||||
<data name="ValidUIDisplayString" xml:space="preserve">
|
||||
<value>Description to be displayed on UI.</value>
|
||||
<comment>This text is displayed when XYZ button clicked.</comment>
|
||||
</data>
|
||||
```
|
||||
|
||||
- Use [`Resource Manager`][Resource Manager] to consume strings in code.
|
||||
```csharp
|
||||
System.Resources.ResourceManager manager = new System.Resources.ResourceManager(baseName, assembly);
|
||||
string validUIDisplayString = manager.GetString("ValidUIDisplayString", resourceCulture);
|
||||
```
|
||||
|
||||
In case of Visual Studio is used to create the resource file. Simply use the `Resources` class in auto-generated `Resources.Designer.cs` file to access the strings which encapsulate the [`Resource Manager`][Resource Manager] logic.
|
||||
|
||||
```csharp
|
||||
string validUIDisplayString = Resources.ValidUIDisplayString;
|
||||
```
|
||||
|
||||
## More On Coding Guidance
|
||||
Please review these brief docs below relating to our coding standards etc.
|
||||
|
||||
* [Coding Style](./style.md)
|
||||
* [Code Organization](./readme.md)
|
||||
|
||||
|
||||
[VS Resource Editor]: https://docs.microsoft.com/en-us/cpp/windows/resource-editors?view=vs-2019
|
||||
[String Table]: https://docs.microsoft.com/en-us/windows/win32/menurc/stringtable-resource
|
||||
[Resx Files VS]: https://docs.microsoft.com/en-us/dotnet/framework/resources/creating-resource-files-for-desktop-apps#resource-files-in-visual-studio
|
||||
[Resx Files]: https://docs.microsoft.com/en-us/dotnet/framework/resources/creating-resource-files-for-desktop-apps#resources-in-resx-files
|
||||
[Resource Manager]: https://docs.microsoft.com/en-us/dotnet/api/system.resources.resourcemanager?view=netframework-4.8
|
||||
173
doc/devdocs/localization.md
Normal file
173
doc/devdocs/localization.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# Localization
|
||||
|
||||
## Table of Contents
|
||||
1. [Localization on the pipeline (CDPX)](#localization-on-the-pipeline-cdpx)
|
||||
1. [UWP Special case](#uwp-special-case)
|
||||
2. [Enabling localization on a new project](#enabling-localization-on-a-new-project)
|
||||
1. [C++](#c)
|
||||
2. [C#](#c-1)
|
||||
3. [UWP](#uwp)
|
||||
3. [Lcl Files](#lcl-files)
|
||||
4. [Possible Issues in localization PRs (LEGO)](#possible-issues-in-localization-prs-lego)
|
||||
5. [Enabling localized MSI for a new project](#enabling-localized-msi-for-a-new-project)
|
||||
|
||||
## Localization on the pipeline (CDPX)
|
||||
[The localization step](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/pipeline.user.windows.yml#L45-L52) is run on the pipeline before the solution is built. This step runs the [build-localization](https://github.com/microsoft/PowerToys/blob/master/.pipelines/build-localization.cmd) script, which generates resx files for all the projects with localization enabled using the `Localization.XLoc` package.
|
||||
|
||||
The [`Localization.XLoc`](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/build-localization.cmd#L24-L25) tool is run on the repo root, and it checks for all occurrences of `LocProject.json`. Each localized project has a `LocProject.json` file in the project root, which contains the location of the English resx file, list of languages for localization, and the output path where the localized resx files are to be copied to. In addition to this, some other parameters can be set, such as whether the language ID should be added as a folder in the file path or in the file name. When the CDPX pipeline is run, the localization team is notified of changes in the English resx files. For each project with localization enabled, a `loc` folder (see [this](https://github.com/microsoft/PowerToys/tree/master/src/modules/launcher/Microsoft.Launcher/loc) for example) is created in the same directory as the `LocProject.json` file. The folder contains language specific folders which in turn have a nested folder path equivalent to `OutputPath` in the `LocProject.json`. Each of these folders contain one `lcl` file. The `lcl` files contain the English resources along with their translation for that language. These are described in more detail [here](#lcl-files). Once the `.resx` files are generated, they will be used during the `Build PowerToys` step for localized versions of the modules.
|
||||
|
||||
Since the localization script requires certain nuget packages, the [`restore-localization`](https://github.com/microsoft/PowerToys/blob/master/.pipelines/restore-localization.cmd) script is run before running `build-localization` to install all the required packages. This script must [run in the `restore` step](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/pipeline.user.windows.yml#L37-L39) of pipeline because [the host is network isolated](https://onebranch.visualstudio.com/Pipeline/_wiki/wikis/Pipeline.wiki/2066/Consuming-Packages-in-a-CDPx-Pipelinhttps://onebranch.visualstudio.com/Pipeline/_wiki/wikis/Pipeline.wiki/2066/Consuming-Packages-in-a-CDPx-Pipeline?anchor=overview) at the `build` step. The [Toolset package source](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/pipeline.user.windows.yml#L23) is used for this.
|
||||
|
||||
The process and variables that can be tweaked on the pipeline are described in more detail [here](https://onebranch.visualstudio.com/Pipeline/_wiki/wikis/Pipeline.wiki/290/Localization).
|
||||
|
||||
The localized resource dlls for C# projects are added to the MSI only for build on the pipeline. This is done by checking if the [`IsPipeline` variable is defined](https://github.com/microsoft/PowerToys/blob/f92bd6ffd38014c228544bb8d68d0937ce4c2b6d/installer/PowerToysSetup/Product.wxs#L804-L805), which gets defined before building the installer on the pipeline [here](https://github.com/microsoft/PowerToys/blob/f92bd6ffd38014c228544bb8d68d0937ce4c2b6d/.pipelines/build-installer.cmd#L4). This is done because the localized resx files are only present on the pipeline, and not having this check would result in the installer project failing to build locally.
|
||||
|
||||
### UWP Special case
|
||||
C# projects normally expect localized resource files with the language id in the file name as Resources.`langId`.resx, where `langId` is generally a two character code except for language with specific variants (like zh-Hans or pt-BR):
|
||||
|
||||
For example, `path\Resources.resx` for English and `path\Resources.fr.resx` for French.
|
||||
|
||||
UWP differs from this as it expects the resources to have the same Resources.resw file name, but they should be present in language specific folders, with the full language ID (such as fr-fr, zh-hans, pt-br, etc.)
|
||||
|
||||
For example, `path\en-us\Resources.resw` for English and `path\fr-fr\Resources.resw` for French.
|
||||
|
||||
Since the pipeline generates it in this format, [a script is run](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/build-localization.cmd#L29-L31) to move these resw files to the correct format expected by all UWP projects. Currently the only UWP project is [Microsoft.PowerToys.Settings.UI](https://github.com/microsoft/PowerToys/tree/master/src/core/Microsoft.PowerToys.Settings.UI). The script used for moving the resources can be [found here](https://github.com/microsoft/PowerToys/blob/master/tools/localization/move_uwp_resources.ps1). The equivalent full language IDs for each shortened language ID obtained from the pipeline has been hardcoded in the script.
|
||||
|
||||
## Enabling localization on a new project
|
||||
To enable localization on a new project, the first step is to create a file `LocProject.json` in the project root.
|
||||
|
||||
For example, for a project in the folder `src\path` where the resx file is present in `resources\Resources.resx`, the LocProject.json file will contain the following:
|
||||
```
|
||||
{
|
||||
"Projects": [
|
||||
{
|
||||
"LanguageSet": "Azure_Languages",
|
||||
"LocItems": [
|
||||
{
|
||||
"SourceFile": "src\\path\\resources\\Resources.resx",
|
||||
"CopyOption": "LangIDOnName",
|
||||
"OutputPath": "src\\path\\resources"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
The rest of the steps depend on the project type and are covered in the sections below. The steps to add the localized files to the MSI can be found [here](#Enabling-localized-MSI-for-a-new-project).
|
||||
|
||||
### C++
|
||||
C++ projects do not support `resx` files, and instead use `rc` files along with `resource.h` files. The CDPX pipeline however doesn't support localizing `rc` files and the other alternative they support is directly translating the resources from the binary which makes it harder to maintain resources. To avoid this, a custom script has been added which expects a resx file and converts the entries to an rc file with a string table and adds resource declarations to a resource.h file so that the resources can be compiled with the C++ project.
|
||||
|
||||
If you already have a .rc file, copy the string table to a separate txt file and run the [convert-stringtable-to-resx.ps1](https://github.com/microsoft/PowerToys/blob/master/tools/build/convert-stringtable-to-resx.ps1) script on it. This script is not very robust to input, and requires the data in a specific format, where `IDS_ResName L"ResourceValue"` and any number of spaces can be present in between. The script converts this file to the format expected by [`resgen`](https://docs.microsoft.com/en-us/dotnet/framework/tools/resgen-exe-resource-file-generator#Convert), which will convert it to resx. The resource names are changed from all uppercase to title case, and the `IDS_` prefix is removed. Escape characters might have to be manually replaced, for example .rc files would have escaped double quotes as `""`, so this should be replaced with just `"` before converting to the resx files.
|
||||
|
||||
After generating the resx file, rename the existing rc and h files to ProjName.base.rc and resource.base.h. In the rc file remove the string table which is to be localized and in the .h file remove all `#define`s corresponding to localized resources. In the vcxproj of the C++ project, add the following build event:
|
||||
```
|
||||
<Target Name="GenerateResourceFiles" BeforeTargets="PrepareForBuild">
|
||||
<Exec Command="powershell -NonInteractive -executionpolicy Unrestricted $(SolutionDir)tools\build\convert-resx-to-rc.ps1 . resource.base.h resource.h ProjName.base.rc ProjName.rc" />
|
||||
</Target>
|
||||
```
|
||||
|
||||
This event runs a script which generates a resource.h and ProjName.rc in the `Generated Files` folder using the strings in all the resx files along with the existing information in resource.base.h and ProjName.base.rc. The script can be found [here](https://github.com/microsoft/PowerToys/blob/master/tools/build/convert-resx-to-rc.ps1). The script uses [`resgen`](https://docs.microsoft.com/en-us/dotnet/framework/tools/resgen-exe-resource-file-generator#Convert) to convert the resx file to a string table expected in the .rc file format. When the resources are added to the rc file the `IDS_` prefix is added and resource names are in upper case (as it was originally). Any occurrences of `"` in the string resource is escaped as `""` to prevent build errors. The string tables are added to the rc file in the following format:
|
||||
```
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
strings
|
||||
END
|
||||
|
||||
#endif
|
||||
```
|
||||
Since there is no API to identify the `AFX_TARG_*`, `LANG_*` or `SUBLANG_*` values from each langId from the pipeline, these are hardcoded in the script (for each language) as done [here](https://github.com/microsoft/PowerToys/blob/f92bd6ffd38014c228544bb8d68d0937ce4c2b6d/tools/build/convert-resx-to-rc.ps1#L50-L77). **If any other languages are added in the future, this script will have to be updated.** In order to determine what are the language codes, you can open the rc file in Resource View, right click the string table and press `Insert Copy` and choose the corresponding language. This autogenerates the required code and can be used to figure out the language codes. The files also add the resource declarations to a resource.h file, starting from 101 by default(this can be changed by an optional argument). Since the output files will be generated in `Generated Files`, any includes in these two files will require an additional `..\` and wherever resource.h is used, it will have to be included as `Generated Files\resource.h`. While adding `resource.base.h` and `ProjName.base.rc` to the vcxproj, these should be modified to not participate in the build to avoid build errors:
|
||||
```
|
||||
<None Include="Resources.resx" />
|
||||
```
|
||||
|
||||
Some rc/resource.h files might be used in multiple projects (for example, KBM). To ensure the projects build for these cases, the build event can be added to the entire directory so that the rc files are generated before any project is built. See [Directory.Build.targets](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/Directory.Build.targets) for an example.
|
||||
|
||||
Check [this PR](https://github.com/microsoft/PowerToys/pull/6104) for an example for making these changes for a C++ project.
|
||||
|
||||
### C#
|
||||
Since C# projects natively support `resx` files, the only step required here is to include all the resx files in the build. For .NET Core projects this is done automatically and the .csproj does not need to be modified. For other projects, the following line needs to be added:
|
||||
```
|
||||
<EmbeddedResource Include="Properties\Resources.*.resx" />
|
||||
```
|
||||
|
||||
**Note:** Building with localized resources may cause a build warning `Referenced assembly 'mscorlib.dll' targets a different processor` which is a VS bug. More details can be found [here](https://github.com/microsoft/PowerToys/issues/7269).
|
||||
|
||||
**Note:** If a project needs to be migrated from XAML resources to resx, the easiest way to convert the resources would be to change to format to `=` separates resources by either manually (by Ctrl+H on a text editor), or by a script, and then running [`resgen`](https://docs.microsoft.com/en-us/dotnet/framework/tools/resgen-exe-resource-file-generator#Convert) on `Developer Command Prompt for VS` to convert it to resx format.
|
||||
```
|
||||
<system:String x:Key="wox_plugin_calculator_plugin_name">Calculator</system:String>
|
||||
<system:String x:Key="wox_plugin_calculator_plugin_description">Allows to do mathematical calculations.(Try 5*3-2 in Wox)</system:String>
|
||||
<system:String x:Key="wox_plugin_calculator_not_a_number">Not a number (NaN)</system:String>
|
||||
```
|
||||
to
|
||||
```
|
||||
wox_plugin_calculator_plugin_name=Calculator
|
||||
wox_plugin_calculator_plugin_description=Allows to do mathematical calculations.(Try 5*3-2 in Wox)
|
||||
wox_plugin_calculator_not_a_number=Not a number (NaN)
|
||||
```
|
||||
After adding the resx file to the project along with the resource generator, references to the strings will have to be replaced with `Properties.Resources.resName` rather than the custom APIs. Check [this PR](https://github.com/microsoft/PowerToys/pull/6165) for an example of the changes required.
|
||||
|
||||
### UWP
|
||||
UWP projects expect `resw` files rather than `resx` (the format is almost the same). Unlike other C# projects, the files are expected in the format `fullLangId\Resources.resw`. To include these files in the build, replace the following line in the csproj:
|
||||
```
|
||||
<PRIResource Include="Strings\en-us\Resources.resw" />
|
||||
```
|
||||
to
|
||||
```
|
||||
<PRIResource Include="Strings\*\Resources.resw" />
|
||||
```
|
||||
|
||||
## Lcl Files
|
||||
Lcl files contain all the resources that are present in the English resx file, along with a translation if it has been added.
|
||||
|
||||
For example, an entry for a resource in the lcl file looks like this:
|
||||
```
|
||||
<Item ItemId=";EditKeyboard_WindowName" ItemType="0;.resx" PsrId="211" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remap keys]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Remapper des touches]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
```
|
||||
The `<Tgt>` element would not be present in the initial commits of the lcl files, as only the English version of the string would be present.
|
||||
|
||||
**Note:** The CDPX Localization system has a fail-safe check on the lcl files, where if the English string value which is present inside `<Val><![CDATA[*]]></Val>` does not match the value present in the English Resources.resx file then the translated value will not be copied to the localized resx file. This is present so that obsolete translations would not be loaded when the English resource has changed, and the English string will be used rather than the obsolete translation.
|
||||
|
||||
## Possible Issues in localization PRs (LEGO)
|
||||
Since the LEGO PRs update some of the strings in LCL files at a time, there can be multiple PRs which modify the same files, leading to merge conflicts. In most cases this would show up on GitHub as a merge conflict, but sometimes a bad git merge may occur, and the file could end up with incorrect formatting, such as two `<Tgt>` elements for a single resource. These can be fixed by ensuring the elements follow the format described in [this section](#lcl-files). To catch such errors, the build farm should be run for every LEGO PR and if any error occurs in the localization step, we should check the corresponding resx/lcl files for conflicts.
|
||||
|
||||
## Enabling localized MSI for a new project
|
||||
For C++ and UWP projects no additional files are generated with localization that need to be added to the MSI. For C++ projects all the resources are added to the dll/exe, while for UWP projects they are added to the `resources.pri` file (which is present even for an unlocalized project). To verify if the localized resources are added to the `resources.pri` file the following steps can be done:
|
||||
- Open `Developer Command Prompt for VS`
|
||||
- After navigating to the folder containing the pri file, run the following command:
|
||||
|
||||
makepri.exe dump /if .\resources.pri
|
||||
- Check the contents of the `resources.pri.xml` file that is generated from the command. The last section of the file will contain the resources with the strings in all the languages:
|
||||
```
|
||||
<NamedResource name="GeneralSettings_RunningAsAdminText" uri="ms-resource://f4f787a5-f0ae-47a9-be89-5408b1dd2b47/Resources/GeneralSettings_RunningAsAdminText">
|
||||
<Candidate qualifiers="Language-FR" type="String">
|
||||
<Value>Running as administrator</Value>
|
||||
</Candidate>
|
||||
<Candidate qualifiers="Language-EN-US" isDefault="true" type="String">
|
||||
<Value>Running as administrator</Value>
|
||||
</Candidate>
|
||||
</NamedResource>
|
||||
```
|
||||
|
||||
For C# projects, satellite dlls are generated when the project is built. For a project named `ProjName`, files are created in the format `langId\ProjName.resources.dll` where `langId` is in the same format as the lcl files. The satellite dlls need to be included with the MSI, but they must be added only if the solution is built from the build farm, as the localized resx files will not be present on local machines (and that could cause local builds of the installer to fail).
|
||||
This can be done by adding the directory name of the project [here](https://github.com/microsoft/PowerToys/blob/f92bd6ffd38014c228544bb8d68d0937ce4c2b6d/installer/PowerToysSetup/Product.wxs#L806) and a resource component for the project can be created [here](https://github.com/microsoft/PowerToys/blob/f92bd6ffd38014c228544bb8d68d0937ce4c2b6d/installer/PowerToysSetup/Product.wxs#L845-L847) in this format:
|
||||
```
|
||||
<Component Id="ProjName_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)ProjNameInstallFolder">
|
||||
<File Id="ProjName_$(var.IdSafeLanguage)_File" Source="$(var.BinX64Dir)modules\ProjName\$(var.Language)\ProjName.resources.dll" />
|
||||
</Component>
|
||||
```
|
||||
|
||||
We should also ensure the new dlls are signed by the pipeline. Currently all dlls of the form [`*.resources.dll` are signed](https://github.com/microsoft/PowerToys/blob/f92bd6ffd38014c228544bb8d68d0937ce4c2b6d/.pipelines/pipeline.user.windows.yml#L68).
|
||||
|
||||
**Note:** The resource dlls should be added to the MSI project only after the initial commit with the lcl files has been done by the Localization team. Otherwise the pipeline will fail as there wouldn't be any resx files to generate the dlls.
|
||||
9
doc/devdocs/logging.md
Normal file
9
doc/devdocs/logging.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# How to use
|
||||
|
||||
We use the awesome [spdlog](https://github.com/gabime/spdlog) library for logging as a git submodule under the `deps` directory. To use it in your project, just include [spdlog.props](../../deps/spdlog.props) in a .vcxproj like this:
|
||||
|
||||
```xml
|
||||
<Import Project="..\..\..\deps\spdlog.props" />
|
||||
```
|
||||
It'll add the required include dirs and link the library binary itself.
|
||||
You can see many example usage of the library in its repository or in the [bootstrapper project](../../installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp).
|
||||
85
doc/devdocs/modules/fancyzones.md
Normal file
85
doc/devdocs/modules/fancyzones.md
Normal file
@@ -0,0 +1,85 @@
|
||||
## FancyZones Lib
|
||||
|
||||
#### [`FancyZones.cpp`](/src/modules/fancyzones/lib/FancyZones.cpp)
|
||||
TODO
|
||||
|
||||
#### [`Settings.cpp`](/src/modules/fancyzones/lib/Settings.cpp)
|
||||
TODO
|
||||
|
||||
#### [`trace.cpp`](/src/modules/fancyzones/lib/trace.cpp)
|
||||
TODO
|
||||
|
||||
#### [`Zone.cpp`](/src/modules/fancyzones/lib/Zone.cpp)
|
||||
TODO
|
||||
|
||||
#### [`ZoneSet.cpp`](/src/modules/fancyzones/lib/ZoneSet.cpp)
|
||||
TODO
|
||||
|
||||
#### [`ZoneWindow.cpp`](/src/modules/fancyzones/lib/ZoneWindow.cpp)
|
||||
TODO
|
||||
|
||||
## FancyZones Editor
|
||||
|
||||
#### [`App.xaml.cs`](/src/modules/fancyzones/editor/App.xaml.cs)
|
||||
TODO
|
||||
|
||||
#### [`Properties\AssemblyInfo.cs`](/src/modules/fancyzones/editor/Properties\AssemblyInfo.cs)
|
||||
TODO
|
||||
|
||||
#### [`CanvasEditor.xaml.cs`](/src/modules/fancyzones/editor/CanvasEditor.xaml.cs)
|
||||
TODO
|
||||
|
||||
#### [`CanvasEditorWindow.xaml.cs`](/src/modules/fancyzones/editor/CanvasEditorWindow.xaml.cs)
|
||||
TODO
|
||||
|
||||
#### [`Models\CanvasLayoutModel.cs`](/src/modules/fancyzones/editor/Models\CanvasLayoutModel.cs)
|
||||
TODO
|
||||
|
||||
#### [`CanvasZone.xaml.cs`](/src/modules/fancyzones/editor/CanvasZone.xaml.cs)
|
||||
TODO
|
||||
|
||||
#### [`EditorOverlay.xaml.cs`](/src/modules/fancyzones/editor/EditorOverlay.xaml.cs)
|
||||
TODO
|
||||
|
||||
#### [`EditorWindow.cs`](/src/modules/fancyzones/editor/EditorWindow.cs)
|
||||
TODO
|
||||
|
||||
#### [`GridEditor.xaml.cs`](/src/modules/fancyzones/editor/GridEditor.xaml.cs)
|
||||
TODO
|
||||
|
||||
#### [`GridEditorWindow.xaml.cs`](/src/modules/fancyzones/editor/GridEditorWindow.xaml.cs)
|
||||
TODO
|
||||
|
||||
#### [`Models\GridLayoutModel.cs`](/src/modules/fancyzones/editor/Models\GridLayoutModel.cs)
|
||||
TODO
|
||||
|
||||
#### [`GridResizer.xaml.cs`](/src/modules/fancyzones/editor/GridResizer.xaml.cs)
|
||||
TODO
|
||||
|
||||
#### [`GridZone.xaml.cs`](/src/modules/fancyzones/editor/GridZone.xaml.cs)
|
||||
TODO
|
||||
|
||||
#### [`Models\LayoutModel.cs`](/src/modules/fancyzones/editor/Models/LayoutModel.cs)
|
||||
TODO
|
||||
|
||||
#### [`LayoutPreview.xaml.cs`](/src/modules/fancyzones/editor/LayoutPreview.xaml.cs)
|
||||
TODO
|
||||
|
||||
#### [`MainWindow.xaml.cs`](/src/modules/fancyzones/editor/MainWindow.xaml.cs)
|
||||
TODO
|
||||
|
||||
#### [`Properties\Resources.Designer.cs`](/src/modules/fancyzones/editor/Properties/Resources.Designer.cs)
|
||||
TODO
|
||||
|
||||
#### [`RowColInfo.cs`](/src/modules/fancyzones/editor/RowColInfo.cs)
|
||||
TODO
|
||||
|
||||
#### [`Models\Settings.cs`](/src/modules/fancyzones/editor/Models/Settings.cs)
|
||||
TODO
|
||||
|
||||
#### [`Properties\Settings.Designer.cs`](/src/modules/fancyzones/editor/Properties/Settings.Designer.cs)
|
||||
TODO
|
||||
|
||||
#### [`WindowLayout.xaml.cs`](/src/modules/fancyzones/editor/WindowLayout.xaml.cs)
|
||||
TODO
|
||||
|
||||
134
doc/devdocs/modules/interface.md
Normal file
134
doc/devdocs/modules/interface.md
Normal file
@@ -0,0 +1,134 @@
|
||||
# Interface definition
|
||||
|
||||
```cpp
|
||||
class PowertoyModuleIface {
|
||||
public:
|
||||
virtual const wchar_t* get_name() = 0;
|
||||
virtual const wchar_t** get_events() = 0;
|
||||
virtual bool get_config(wchar_t* buffer, int *buffer_size) = 0;
|
||||
virtual void set_config(const wchar_t* config) = 0;
|
||||
virtual void call_custom_action(const wchar_t* action) {};
|
||||
virtual void enable() = 0;
|
||||
virtual void disable() = 0;
|
||||
virtual bool is_enabled() = 0;
|
||||
virtual void destroy() = 0;
|
||||
};
|
||||
|
||||
typedef PowertoyModuleIface* (__cdecl *powertoy_create_func)();
|
||||
```
|
||||
|
||||
# Runtime logic
|
||||
|
||||
The PowerToys runner will, for each PowerToy DLL:
|
||||
- load the DLL,
|
||||
- call [`powertoy_create()`](#powertoy_create_func) to create the PowerToy.
|
||||
|
||||
On the received object, the runner will call:
|
||||
- [`get_name()`](#get_name) to get the name of the PowerToy,
|
||||
- [`enable()`](#enable) to initialize the PowerToy.
|
||||
|
||||
While running, the runner might call the following methods between create_powertoy()
|
||||
and destroy():
|
||||
- [`disable()`](#disable)/[`enable()`](#enable)/[`is_enabled()`](#is_enabled) to change or get the PowerToy's enabled state,
|
||||
- [`get_config()`](#get_config) to get the available configuration settings,
|
||||
- [`set_config()`](#set_config) to set settings after they have been edited in the Settings editor,
|
||||
- [`call_custom_action()`](#call_custom_action) when the user selects a custom action in the Settings editor,
|
||||
|
||||
When terminating, the runner will:
|
||||
- call [`disable()`](#disable),
|
||||
- call [`destroy()`](#destroy) which should free all the memory and delete the PowerToy object,
|
||||
- unload the DLL.
|
||||
|
||||
|
||||
# Method definition
|
||||
|
||||
This section contains a more detailed description of each of the interface methods.
|
||||
|
||||
## powertoy_create_func
|
||||
|
||||
```cpp
|
||||
typedef PowertoyModuleIface* (__cdecl *powertoy_create_func)()
|
||||
```
|
||||
|
||||
Typedef of the factory function that creates the PowerToy object.
|
||||
Must be exported by the DLL as `powertoy_create()`.
|
||||
|
||||
Called by the PowerToys runner to initialize each PowerToy.
|
||||
It will be called only once before a call to [`destroy()`](#destroy) is made.
|
||||
|
||||
The returned PowerToy should be in the disabled state. The runner will call the [`enable()`](#enable) method to start the PowerToy.
|
||||
|
||||
In case of errors returns `nullptr`.
|
||||
|
||||
## get_name
|
||||
|
||||
```cpp
|
||||
virtual const wchar_t* get_name()
|
||||
```
|
||||
|
||||
Returns the name of the PowerToy, it will be cached by the runner.
|
||||
|
||||
## get_config
|
||||
|
||||
```
|
||||
virtual bool get_config(wchar_t* buffer, int *buffer_size)
|
||||
```
|
||||
|
||||
Fills a buffer with the available configuration settings.
|
||||
|
||||
If `buffer` is a null pointer or the buffer size is not large enough sets the required buffer size in 'buffer_size' and return false.
|
||||
|
||||
Returns true if successful.
|
||||
|
||||
## set_config
|
||||
|
||||
```cpp
|
||||
virtual void set_config(const wchar_t* config)
|
||||
```
|
||||
|
||||
After the user has changed the module settings in the Settings editor, the runner calls this method to pass to the module the updated values. It's a good place to save the settings as well.
|
||||
|
||||
## call_custom_action
|
||||
|
||||
```cpp
|
||||
virtual void call_custom_action(const wchar_t* action)
|
||||
```
|
||||
|
||||
Calls a custom action in response to the user pressing the custom action button in the Settings editor.
|
||||
This can be used to spawn custom editors defined by the PowerToy.
|
||||
|
||||
## enable
|
||||
|
||||
```cpp
|
||||
virtual void enable()
|
||||
```
|
||||
|
||||
Enables the PowerToy.
|
||||
|
||||
## disable
|
||||
|
||||
```cpp
|
||||
virtual void disable()
|
||||
```
|
||||
|
||||
Disables the PowerToy, should free as much memory as possible.
|
||||
|
||||
## is_enabled
|
||||
|
||||
```cpp
|
||||
virtual bool is_enabled() = 0;
|
||||
```
|
||||
|
||||
Returns the PowerToy state.
|
||||
|
||||
## destroy
|
||||
|
||||
```cpp
|
||||
virtual void destroy()
|
||||
```
|
||||
Destroy the PowerToy and free all memory.
|
||||
|
||||
# Code organization
|
||||
|
||||
### [`powertoy_module_interface.h`](/src/modules/interface/powertoy_module_interface.h)
|
||||
Contains the PowerToys interface definition.
|
||||
6
doc/devdocs/modules/keyboardmanager/README.md
Normal file
6
doc/devdocs/modules/keyboardmanager/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Table of Contents
|
||||
The devdocs for Keyboard Manager have been divided into the following modules:
|
||||
1. [Keyboard Manager Module](keyboardmanager.md)
|
||||
2. [Keyboard Event Handlers](keyboardeventhandlers.md)
|
||||
3. [Keyboard Manager UI](keyboardmanagerui.md)
|
||||
4. [Keyboard Manager Common](keyboardmanagercommon.md)
|
||||
BIN
doc/devdocs/modules/keyboardmanager/japanese-ime.png
Normal file
BIN
doc/devdocs/modules/keyboardmanager/japanese-ime.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
84
doc/devdocs/modules/keyboardmanager/keyboardeventhandlers.md
Normal file
84
doc/devdocs/modules/keyboardmanager/keyboardeventhandlers.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# Keyboard Event Handlers (Remapping Logic)
|
||||
This file contains documentation for all the methods involved in key/shortcut remapping.
|
||||
|
||||
## Table of Contents:
|
||||
1. [HandleSingleKeyRemapEvent](#HandleSingleKeyRemapEvent)
|
||||
2. [HandleShortcutRemapEvent](#HandleShortcutRemapEvent)
|
||||
3. [HandleOSLevelShortcutRemapEvent](#HandleOSLevelShortcutRemapEvent)
|
||||
4. [HandleAppSpecificShortcutRemapEvent](#HandleAppSpecificShortcutRemapEvent)
|
||||
5. [HandleSingleKeyToggleToModEvent (Obsolete))](#HandleSingleKeyToggleToModEvent-(Obsolete---Code-from-PoC-which-is-commented-out))
|
||||
6. [Tests](#Tests)
|
||||
1. [MockedInput](#MockedInput)
|
||||
2. [Tests for single key remaps and shortcut remaps](#Tests-for-single-key-remaps-and-shortcut-remaps)
|
||||
|
||||
## HandleSingleKeyRemapEvent
|
||||
[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L13-L124) is used for handling the key to key and key to shortcut remapping logic. The general logic is as follows:
|
||||
- Check if the `dwExtraInfo` field contains the `KEYBOARDMANAGER_INJECTED_FLAG` bit set. This bit is used to indicate that the key event was generated by KBM using `SendInput`. This ensures that we don't read events generated by the key or shortcut remap methods.
|
||||
- Check if the current key is present in the list of remaps. If it isn't, return 0 (i.e. do not suppress the event).
|
||||
- If it is remapped to Disable, suppress the event.
|
||||
- If it is remapped to a key, we send the key down/up message for the target key and suppress the current key event. We have a check for filtering artificial keys, such as `VK_WIN` (which is a keycode added by us), so that it is translated to `VK_LWIN` instead.
|
||||
- If it is remapped to a shortcut, for key down we set the target modifiers first, followed by the target action key, and for key up we release the action key first, followed by the modifiers.
|
||||
- All the remapped key events that we send above are sent with `KEYBOARDMANAGER_SINGLEKEY_FLAG` on the `dwExtraInfo` field.
|
||||
|
||||
## HandleShortcutRemapEvent
|
||||
[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L178-L739) is used for handling the shortcut to shortcut and shortcut to key remapping logic. The general logic is as follows:
|
||||
- Check if any shortcut remap is currently invoked. This is required to ensure that two remaps don't occur simultaneously at a time, and we send key up events for the shortcuts only if they are actually invoked and not for artificial key up events. In addition to that, while a remap is in the middle of execution, the keyboard state will not match the physical keys, so we do not want a remap <kbd>Ctrl+A</kbd> to <kbd>Ctrl+V</kbd> to also trigger the remap from <kbd>Ctrl+V</kbd> to <kbd>Alt+V</kbd> on pressing <kbd>Ctrl+A</kbd> on the keyboard.
|
||||
- Get the remap table as per the the `activatedApp` argument (i.e. if it is empty, we get the global shortcut remap table and otherwise we get the corresponding app-specific shortcut remap table).
|
||||
- Iterate over the list of remaps in descending order of number of keys in the shortcut. This is required **for shortcut to key remaps** to ensure that if a user has both <kbd>Ctrl+A</kbd> and <kbd>Ctrl+Shift+A</kbd> remapped to some keys, and the user presses <kbd>Ctrl+Shift+A</kbd>, then we prefer the <kbd>Ctrl+Shift+A</kbd> remap. This logic would not be required if there were only shortcut to shortcut remaps, as they are invoked only on exact match.
|
||||
- If any shortcut was found to be invoked (from the first step), then we skip till we find the matching shortcut remap. If not we check if the modifiers of the original shortcut are pressed down. If they are, we check if the current key event is a key down event and it matches the action key of the original shortcut. For shortcut to shortcut and for disabling a shortcut [we have an additional step](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L208-L212) where we check if any other key is pressed apart from the original shortcut. This is required because for these two features we allow the remaps only if those exact keys are pressed. The method used for this is described in detail [here](keyboardmanagercommon.md#IsKeyboardStateClearExceptShortcut). If a win key was pressed, we store whether it was the left or the right one, in order to determine which key to set for remaps from/to the common Win key code which we added. This is so that pressing and releasing Left Win key results in that Win key getting modified and not the Right Win key.
|
||||
- If the remap is to a key, we send a dummy key event followed by releasing the original shortcut's modifiers and setting the target key (or doing nothing if it is remapped to disable) and we suppress the event.
|
||||
- If the remap is to a shortcut, if the modifiers in the original shortcut are present in the target, we only set the additional modifiers and the action key of the target. If it isn't, we send a dummy key event followed by releasing the modifiers which are not common, and setting the remaining ones in the target along with the action key.
|
||||
- For both cases, we set the `isShortcutInvoked` flag to true, and set the `KeyboardManagerState.activatedApp` if it is an app-specific shortcut remap.
|
||||
- For the `isShortcutInvoked` is true scenario (i.e. the initial remap keydown section is done) there are several cases depending on the key pressed or released:
|
||||
- [**Case 1:**](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L339-L430) If a modifier in the original shortcut is released, we need to reset back to the physical keys pressed.
|
||||
- For remap to shortcut, we release the target action key if it is currently pressed, and depending on whether all the modifiers of the original shortcut are present in the target, we release the target modifiers that are not common, and set the remaining original shortcut modifiers except the one that was released. We do not need to send the original action key as that will get generate it's own key event if it is held down.
|
||||
- For remap to key, we release the target key if it is pressed (and it is not remapped to Disable), and we set the original shortcut modifiers.
|
||||
- For both the cases we send a dummy key event at the end, since we are setting modifiers without any other key after that, and we reset all the remap variables.
|
||||
- [**Case 2:**](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L435-L461) If the original shortcut's action key is pressed again, we send the target shortcut's action key or the target key again (or for disable we just suppress the event).
|
||||
- [**Case 3:**](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L463-L527) If the original shortcut's action key is released
|
||||
- For remap to shortcut, we just release the target shortcut's action key
|
||||
- For remap to disable, we suppress the event
|
||||
- For remap to key, we check if any other keys are pressed apart from the target key. If not, we just release the target key. If there are, we reset back to the physical keys by releasing the target key and setting the original shortcut's modifiers along with a dummy key, and we reset all the remap variables. This behavior is different from remap to shortcut because if the action key is released while other keys are pressed the remap should be inactive, but such a state can't occur for shortcut to shortcut remaps since they happen only when the exact keys are pressed.
|
||||
- [**Case 4:**](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L529-L551) If a modifier in the original shortcut is pressed, suppress the event
|
||||
- [**Case 5:**](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L553-L732) If any other key is pressed
|
||||
- For remap to shortcut, we need to reset back to physical keys as the shortcut remaps can't be pressed in combination with other keys. We release the target action key if it was pressed, and we release the modifier keys of the target shortcut that are not common and set the remaining ones in the original shortcut. We then send the original shortcut's action key if the target action key was found to be pressed, and we send the current key press at the end.
|
||||
- For remap to key, if it is remapped to disable or if the target key is not found to be pressed, we reset to the physical keys, we set the original shortcut's modifiers and if is remap to Disable and the original shortcut's action key is physically pressed (this is checked by the `isOriginalActionKeyPressed` flag which we keep track of whenever the action key is pressed or released for remap to Disable), then we set the original shortcut's action key, followed by the current key press. If it is not remapped to disable and the target key is pressed, then we don't suppress the event as we allow shortcut to key remappings to be pressed along with other keys.
|
||||
- For all the above cases, dummy key isn't required as we want the current key press to behave like a normal key.
|
||||
- [**Case 6:**](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L733) If any other key is released, do not suppress the event as this event didn't appear with a corresponding key down event (such as an app sending a key up event) or we processed the key down and let it continue (for shortcut to key scenario).
|
||||
- All the remapped key events that we send above are sent with `KEYBOARDMANAGER_SHORTCUT_FLAG` on the `dwExtraInfo` field, except the usage of the current key press in Case 5, for which we don't send any extra info so that it is considered as a normal key event which may in turn invoke some other remap.
|
||||
|
||||
**Note:** Shortcuts are considered valid if they have modifiers and an action key. The reason why we haven't supported key combinations of just modifiers (which is requested in this [issue](https://github.com/microsoft/PowerToys/issues/5670)) (like remapping <kbd>Ctrl+Alt</kbd>) is because this would require more cases and handling as these remappings have to take place only on press and release and if there is no key pressed in between similar to what Start Menu does. The remapping would have to be invoked only for this specific sequence <kbd>Ctrl</kbd> key down, <kbd>Alt</kbd> key down, <kbd>Alt</kbd> key up, <kbd>Ctrl</kbd> key up (ordering between Ctrl and Alt can be swapped). If any other key is pressed in between it shouldn't be invoked, and since this logic requires tracking exact states instead of using GetAsyncKeyStates, this could cause false positives if a user is not running as admin.
|
||||
|
||||
## HandleOSLevelShortcutRemapEvent
|
||||
[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L741-L752) is used for handling global shortcut to shortcut and shortcut to key remaps. The general logic is as follows:
|
||||
- Check if the `dwExtraInfo` field is set to `KEYBOARDMANAGER_SHORTCUT_FLAG`. This indicates that the key event was generated by the KBM shortcut remap method using `SendInput`. This ensures that we don't read events generated by the shortcut remap method, but we still read events which are generated by the key remap method.
|
||||
- Call `HandleShortcutRemapEvent` without the `activatedApp` argument so that global shortcut remapping takes place if it applies for the current key event.
|
||||
|
||||
## HandleAppSpecificShortcutRemapEvent
|
||||
[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L754-L809) is used for handling app-specific shortcut to shortcut and shortcut to key remaps. The general logic is as follows:
|
||||
- Check if the `dwExtraInfo` field is set to `KEYBOARDMANAGER_SHORTCUT_FLAG`. This indicates that the key event was generated by the KBM shortcut remap method using `SendInput`. This ensures that we don't read events generated by the shortcut remap method, but we still read events which are generated by the key remap method.
|
||||
- Get the name of the process in the foreground. This is done using `GetCurrentApplication` which uses `GetForegroundWindow` to get the window handle and `get_process_path` from the common lib. This approach can fail for UWP apps in full screen, so for that scenario we use the `GetGUIThreadInfo` approach to find the correct window handle, and hence the correct process name. This method is described in more detail [here](keyboardmanagercommon.md#Foreground-app-detection)
|
||||
- By checking `KeyboardManagerState.GetActivatedApp` we check if an app-specific shortcut is currently invoked. If so, we consider this application to be the activated app. This is required because some shortcut remaps could cause the current app to lose focus and hence until the shortcut is completely released we should allow that remap to continue, otherwise the user could end up in a state where some keys do not get released. For example: remap <kbd>Ctrl+A</kbd> to <kbd>Alt+Tab</kbd> for Edge, when a user presses <kbd>Ctrl+A</kbd> the window loses focus as <kbd>Alt+Tab</kbd> gets executed.
|
||||
- If there is no app-specific shortcut currently invoked, we check if the foreground process is present in the list of app-specific remaps, either with or without the file extension and case insensitive. If it is, this is considered to be the activated app.
|
||||
- Call `HandleShortcutRemapEvent` with the `activatedApp` argument so that app-specific shortcut remapping takes place if it applies for the current key event.
|
||||
|
||||
## HandleSingleKeyToggleToModEvent (Obsolete - Code from PoC which is commented out)
|
||||
[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L126-L176) was added to support a feature for converting the behavior of a key from behaving like a toggle (like Caps Lock/Num Lock) to a modifier (like Ctrl), such that when you hold Caps Lock it would behave as if Caps Lock was active, and when it was not pressed Caps Lock would be off. For Caps Lock this would be similar to behaving like Shift, but for Num Lock there is no existing key which can substitute for this. This was added while testing out remapping for the KBM PoC, but wasn't added as a feature since it wasn't a priority.
|
||||
|
||||
## Tests
|
||||
In order to test the remapping logic, a mocked keyboard input handler had to be created because otherwise the tests would process and send actual key events. For this the [`InputInterface`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/InputInterface.h) was made, and in production code the methods are implemented using [`SendInput`](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput) and [`GetAsyncKeyState`](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate). In addition to this, [`GetCurrentApplication`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L226-L268) had to be mocked so that app-specific remapping can be tested.
|
||||
|
||||
### MockedInput
|
||||
The [`MockedInput`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/MockedInput.h) class uses a 256 size `bool` vector to store the key state for each key code. Identifying the foreground process is mocked by simply setting and getting a string value for the name of the current process.
|
||||
|
||||
[To mock the `SendInput` method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/test/MockedInput.cpp#L10-L110), the steps for processing the input are as follows. This implementation is based on public documentation for SendInput and the behavior of key messages and keyboard hooks:
|
||||
- Iterate over all the inputs in the INPUT array argument
|
||||
- If the event is a key up event, then it is considered [`WM_SYSKEYUP`](https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-syskeyup) if Alt is held down, otherwise it is `WM_KEYUP`.
|
||||
- If the event is a key down event, then it is considered [`WM_SYSKEYDOWN`](https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-syskeydown) if either Alt is held down or if it is F10, otherwise it is `WM_KEYDOWN`.
|
||||
- An optional function which can be set on the `MockedInput` handler can be used to test for the number of times a key event is received by the system with a particular condition using [`sendVirtualInputCallCondition`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/test/MockedInput.cpp#L48-L52).
|
||||
- The hook logic for a low level hook which returns 0 or 1 can be set on the `MockedInput` handler such that it behaves like a low level hook would behave with actual keyboard input. If the method returns 1, then the keyboard state is not updated, and if it returns 0 the corresponding key event is used to update the key state. This works in the recursive way as well similar to low level hooks, as `SendVirtualInput` can be called from within the hook, thus simulating identical behavior to calling `SendInput` in a low level hook (as soon as SendInput is called, the low level hook is called for the new input event, and only after those are processed it returns back to the current event, check this [blog](https://devblogs.microsoft.com/oldnewthing/20140213-00/?p=1773) for more details).
|
||||
- For updating the keyboard state, KEYUP messages result in the state for that key code being set to false, and KEYDOWN result in the state for that key code being set to true.
|
||||
- For modifiers the behavior is slightly different as if the key state of the L/R version is modified, it should also modify the common version, and if a common version is released, it should release both the L and R versions.
|
||||
|
||||
### Tests for single key remaps and shortcut remaps
|
||||
Using the MockedInput handler, all the expected (and known) key scenarios that can occur for while pressing a [remapped key](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/SingleKeyRemappingTests.cpp) or [remapped shortcut](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/OSLevelShortcutRemappingTests.cpp) are tested. The foreground app behavior which is specific to app-specific shortcuts is tested [here](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/AppSpecificShortcutRemappingTests.cpp).
|
||||
199
doc/devdocs/modules/keyboardmanager/keyboardmanager.md
Normal file
199
doc/devdocs/modules/keyboardmanager/keyboardmanager.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# Keyboard Manager module
|
||||
This file contains the documentation for the KeyboardManager PowerToy module which is called by the runner.
|
||||
## Table of Contents:
|
||||
1. [Class members](#Class-members)
|
||||
2. [Enable/Disable](#Enable/disable)
|
||||
3. [Settings format](#Settings-format)
|
||||
4. [Loading settings](#Loading-settings)
|
||||
5. [Low level keyboard hook handler](#Low-level-keyboard-hook-handler)
|
||||
6. [Custom Action to launch KBM UI](#Custom-Action-to-launch-KBM-UI)
|
||||
7. [SendInput Special Scenarios](#SendInput-Special-Scenarios)
|
||||
1. [Extended keys](#Extended-keys)
|
||||
2. [Scan code](#Scan-code)
|
||||
8. [Special Scenarios](#Special-Scenarios)
|
||||
1. [Dummy key events](#Dummy-key-events)
|
||||
2. [Suppressing Num Lock in a keyboard hook](#Suppressing-Num-Lock-in-a-keyboard-hook)
|
||||
3. [Modifier-Caps Lock interaction on Japanese IME keyboards](#Modifier-Caps-Lock-interaction-on-Japanese-IME-keyboards)
|
||||
4. [UIPI Issues (not resolved)](#UIPI-Issues-(not-resolved))
|
||||
9. [Other remapping approaches](#Other-remapping-approaches)
|
||||
1. [Registry approach](#Registry-approach)
|
||||
2. [Driver approach](#Driver-approach)
|
||||
10. [Telemetry](#Telemetry)
|
||||
|
||||
## Class members
|
||||
The `KeyboardManager` module has [3 main class members](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L54-L61):
|
||||
- A static pointer to the current object of `KeyboardManager`. This is required for using the `KeyboardManager` object in the low level keyboard hook handler as that method must be static. This is described in more detail in [this section](#Low-level-keyboard-hook-handler).
|
||||
- An object of type `Input`, which is used for all the operations that involving getting or setting keyboard states. This is wrapped in an object to allow testing the remapping methods.
|
||||
- An object of type `KeyboardManagerState`. This object contains all the data related to remappings and is also used in the sense of a View Model as it used to communicate common data that is shared between the KBM UI and the backend. This class is described in more detail [here](keyboardmanagercommon.md#keyboardmanagerstate).
|
||||
|
||||
## Enable/Disable
|
||||
On enabling KBM, the low level keyboard hook is started, and it is unhooked on disable. This is done to allow users to manually restart KBM if some other application which registers a keyboard hook was launched after PowerToys, so that it can be brought back to the highest priority hook (as the last hook to be registered receives the input first as mentioned [here](https://docs.microsoft.com/en-us/windows/win32/winmsg/about-hooks#hook-procedures)).
|
||||
|
||||
In addition to stopping the hook, any active KBM UI windows are also closed on disabling. This is done because the KBM UI uses the same keyboard hook for the Type button where you can type a key/shortcut, so if KBM is disabled the windows would not be completely functional.
|
||||
|
||||
The enable/disable code can be found [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L301-L322)
|
||||
|
||||
## Settings format
|
||||
KBM uses two sets of settings files.
|
||||
- The main `settings.json` is of the following format:
|
||||
|
||||
{
|
||||
"properties":
|
||||
{
|
||||
"activeConfiguration":
|
||||
{
|
||||
"value":"default"
|
||||
},
|
||||
"keyboardConfigurations":
|
||||
{
|
||||
"value":["default"]
|
||||
}
|
||||
},
|
||||
"name":"Keyboard Manager",
|
||||
"version":"1"
|
||||
}
|
||||
|
||||
- The `activeConfiguration` attribute stores the current remapping profile, while `keyboardConfigurations` stores all the profiles that the user has. This was added to avoid any future breaking changes for the [profiles feature](https://github.com/microsoft/PowerToys/issues/1881), which would allow users to switch between remappings
|
||||
- The profile format (`default.json`) is of the following format:
|
||||
|
||||
{
|
||||
"remapKeys":
|
||||
{
|
||||
"inProcess":
|
||||
[
|
||||
{
|
||||
"originalKeys":"91",
|
||||
"newRemapKeys":"162;70"
|
||||
},
|
||||
{
|
||||
"originalKeys":"92",
|
||||
"newRemapKeys":"162;70"
|
||||
}
|
||||
]
|
||||
},
|
||||
"remapShortcuts":
|
||||
{
|
||||
"global":
|
||||
[
|
||||
{
|
||||
"originalKeys":"164;37",
|
||||
"newRemapKeys":"162;65"
|
||||
},
|
||||
{
|
||||
"originalKeys":"162;68",
|
||||
"newRemapKeys":"91"
|
||||
}
|
||||
],
|
||||
"appSpecific":
|
||||
[
|
||||
{
|
||||
"originalKeys":"91;162;65",
|
||||
"newRemapKeys":"162;86",
|
||||
"targetApp":"msedge"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
- `originalKeys` stores the key/shortcut which is to be pressed for the remap, and `newKeys` stores the key/shortcut which is to be executed.
|
||||
- Both contain semi-colon separated virtual key codes. For `remapKeys`, `originalKeys` must have only one key code, whereas for `remapShortcuts` it must have atleast two key codes.
|
||||
- `inProcess` sub-key was added in `remapKeys` because there was a possibility of adding the registry based remapping approach (used by [SharpKeys](https://github.com/randyrants/sharpkeys)), so that would be under a separate sub-key while `inProcess` would be for keyboard hook based remaps. This was deprioritized as there weren't enough requests for it.
|
||||
- `remapShortcuts` is split into `global` and `appSpecific`, where `global` remaps would apply to all applications, whereas `appSpecific` would apply on when the `targetApp` is in focus. `targetApp` must be the process name of the app (with or without it's extension), e.g. `msedge` or `msedge.exe` for Microsoft Edge.
|
||||
|
||||
## Loading settings
|
||||
KBM settings are loaded only on the C++ side only at start up, in the [constructor](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L67-L68). The settings file may get modified from the KBM UI on applying new remappings, but the the file is not read again. The files are read from the PowerToys Settings process whenever a change is made to the file (using a FileWatcher) or whenever the KBM page is opened. The settings are updated only when the user presses the OK button from either of the Remap Keys or Remap Shortcuts windows. This is described in more detail [here](keyboardmanagerui.md#ok-and-cancel-button).
|
||||
|
||||
## Low level keyboard hook handler
|
||||
Since the [`hook_proc`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L330-L349) cannot be a member function in the class, this is declared `static` and a `static pointer` to the `KeyboardManager` project is used ([`keyboardmanager_object_ptr`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L54-L55)).
|
||||
|
||||
As seen in the code for `hook_proc`, similar to other keyboard hooks in PowerToys it consists of a main method `HandleKeyboardHookEvent` which computes whether the key needs to be suppressed and accordingly returns 1 or calls the `CallNextHook` method.
|
||||
|
||||
`HandleKeyboardHookEvent` is covered in the [next section](#HandleKeyboardHookEvent). The `SetNumLockToPreviousState` code in the above snippet is required for a special scenario with keyboard input, which is covered in [this section](#Suppressing-Num-Lock-in-a-keyboard-hook).
|
||||
|
||||
## HandleKeyboardHookEvent
|
||||
The [`HandleKeyboardHookEvent`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L384-L458) is the method which calls the corresponding remapping methods in the required order. The following checks are executed in order:
|
||||
- **`KeyboardManagerState.AreRemappingsEnabled`:** This returns false while the KBM remap tables are getting updated. If it is in this state, `HandleKeyboardHookEvent` returns `0`, i.e. the key event is not suppressed and is forwarded normally.
|
||||
- **Check for `KEYBOARDMANAGER_SUPPRESS_FLAG`:** If the key event has the suppress flag, the method returns 1 to suppress the key event.
|
||||
- **[`KeyboardManagerState.DetectSingleRemapKeyUIBackend`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L399-L408):** This method is used for handling hook operations for the single key Type UI in the Remap keys window. If the Remap keys window is open, then `HandleKeyboardHookEvent` returns `0` and the key event is forwarded normally. If the left column Type button is clicked on the Remap keys window and and the window is in focus, then the key event is suppressed and the UI is updated with the latest key from the recent key events. This method is described in more detail [here](keyboardmanagercommon.md#DetectSingleRemapKeyUIBackend-and-DetectShortcutUIBackend).
|
||||
- **[`KeyboardManagerState.DetectShortcutUIBackend(data, true)`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L410-L419):** This method is used for handling hook operations for the shortcut Type UI in the Remap keys window (when `isRemapKey` arg is `true`). If the Remap keys window is open, then `HandleKeyboardHookEvent` returns `0` and the key event is forwarded normally. If the right column Type button is clicked on the Remap keys window and and the window is in focus, then the key event is suppressed and the UI is updated with the shortcut from the recent key events. This method is described in more detail [here](keyboardmanagercommon.md#DetectSingleRemapKeyUIBackend-and-DetectShortcutUIBackend).
|
||||
- **`HandleSingleKeyRemapEvent`:** This method handles the single key remap logic. If a remapping takes place, the key event is suppressed. This method is described in more detail [here](keyboardeventhandlers.md#HandleSingleKeyRemapEvent).
|
||||
- **[`KeyboardManagerState.DetectShortcutUIBackend(data, false)`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L430-L439):** This method is used for handling hook operations for the shortcut Type UI in the Remap shortcuts window (when `isRemapKey` arg is `false`). If the Remap shortcuts window is open, then `HandleKeyboardHookEvent` returns `0` and the key event is forwarded normally. If the Type button is clicked on the Remap shortcuts window and and the window is in focus, then the key event is suppressed and the UI is updated with the shortcut from the recent key events. **Since this is executed after the single key remap method, all single key remappings are applied when the user is on the Remap shortcuts window.**
|
||||
- **`HandleAppSpecificShortcutRemapEvent`:** This method handles the app-specific shortcut remap logic. If a remapping takes place, the key event is suppressed. This method is described in more detail [here](keyboardeventhandlers.md#HandleAppSpecificShortcutRemapEvent). **Since this is executed after the single key remap method, single key remappings have precedence over shortcut remaps and are correspondingly reflected in shortcut remaps.**
|
||||
- **`HandleOSLevelShortcutRemapEvent`:** This method handles the global shortcut remap logic. If a remapping takes place, the key event is suppressed. This method is described in more detail [here](keyboardeventhandlers.md#HandleOSLevelShortcutRemapEvent). The app-specific remap method is executed before this because if a shortcut is remapped to different keys/shortcuts for a particular app and globally, the app-specific variant should be preferred if that app is in focus. **Since this is executed after the single key remap method, single key remappings have precedence over shortcut remaps and are correspondingly reflected in shortcut remaps.**
|
||||
|
||||
**Note:** Single key remaps need to be executed before shortcut remaps, because otherwise there can be several logical issues. For example if a user has Ctrl remapped to X and Ctrl+A remapped to Y, we can't detect Ctrl+A because the moment Ctrl is pressed it would be remapped to X before the system ever sees Ctrl+A. This is why the design decision was made to separate Remap keys and Remap shortcuts, and all key remaps are reflected in the shortcut remaps.
|
||||
|
||||
## Custom Action to launch KBM UI
|
||||
KBM uses the [`call_custom_action`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L249-L280) method from the `PowertoyModuleIface` in order to launch the KBM UI when the user clicks the Remap a key or Remap a shortcut button from the KBM settings page. On clicking the button, we check if there is already any active KBM UI window, and if there is it is brought to the foreground. If not, the corresponding KBM UI window is launched on a separate detached thread. The UI is described in more detail [here](keyboardmanagerui.md).
|
||||
|
||||
## SendInput Special Scenarios
|
||||
|
||||
### Extended keys
|
||||
Certain keys such as the arrow keys, <kbd>right Ctrl/Alt</kbd>, and <kbd>Del/Home/Ins</kbd>, etc need to be sent with the `KEYEVENTF_EXTENDEDKEY` flag because otherwise the NumPad versions get sent, which can cause weird behavior when NumLock is on. The code can be found [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L190-L194) and the list of extended keys in code can be found [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L73-L98). Docs about extended keys can be found [here](https://docs.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#extended-key-flag).
|
||||
|
||||
The weird behavior that is caused by this can be found at these issues:
|
||||
- https://github.com/microsoft/PowerToys/issues/3478
|
||||
- https://github.com/microsoft/PowerToys/issues/3647
|
||||
- https://github.com/microsoft/PowerToys/issues/3981
|
||||
|
||||
### Scan code
|
||||
Certain applications (such as Windows Terminal) may filter out key events which are set to scan code 0. Even though the `KEYEVENTF_SCANCODE` flag is not set, the `wScan` field is still sent, which defaults to 0. To avoid this issue we use the `MapVirtualKey` API to find the scan code from the virtual key code. Code can be found [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L196-L198).
|
||||
|
||||
## Special Scenarios
|
||||
Since we are using low level keyboard hooks and not actual OS level input handling certain scenarios with input require workarounds as do they not interact well with the OS input logic directly. These are covered in the sub-sections below.
|
||||
|
||||
### Dummy key events
|
||||
To prevent the behavior that some modifiers have that occur when you press and release the modifier without pressing any key in between, we need to send a dummy key event in between the two states. Some examples of this behavior are Win key for Start Menu and Alt key to focus the menu bar. We need to send the dummy key events at any point where an unintentional modifier press/release sequence may occur. We use the undocumented `0xFF` virtual key code for this as we haven't found any side effects of using this key code yet. Initially we used only a key up message, but it has been tweaked now to send a key down followed by key up (code can be found (here)[https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L201-L208]), as without the key down there were [compatibility issues with some apps](https://github.com/microsoft/PowerToys/issues/7133) (like Slack).
|
||||
|
||||
The dummy key event is currently used in the following places (the linked code snippets contains an example scenario of why it is required):
|
||||
- https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L251-L253
|
||||
- https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L289-L291
|
||||
- https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L382-L383
|
||||
- https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L409-L410
|
||||
- https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L509-L510
|
||||
|
||||
### Suppressing Num Lock in a keyboard hook
|
||||
The <kbd>Num Lock</kbd> key state is updated by the OS before it is intercepted by low level hooks. This causes the issue that even if you suppress a <kbd>Num Lock</kbd> key event, <kbd>Num Lock</kbd> will still get toggled. In order to work around this, in the [`hook_proc`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L340-L344) whenever we suppress a <kbd>Num Lock</kbd> key down event, we send an additional <kbd>Num Lock</kbd> key up followed by key down so that the <kbd>Num Lock</kbd> state is reverted to it's previous value before the suppressed event. These are sent with a `KEYBOARDMANAGER_SUPPRESS_FLAG` in the `dwExtraInfo` field, so that we suppress them at the start of the hook (see code [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L811-L825)). Since these events will update the <kbd>Num Lock</kbd> state before the low level hooks, by suppressing them we ensure that these are not sent to any other hooks/applications and hence are only processed by the OS.
|
||||
|
||||
This assumes that KBM is the last hook to be registered (since another hook-based app like AutoHotkey could remap NumLock to some other key which could mess up this logic).
|
||||
|
||||
### Modifier-Caps Lock interaction on Japanese IME keyboards
|
||||
While using Japanese IME on Windows, shortcuts like <kbd>Shift/Alt/Ctrl</kbd> + <kbd>Caps Lock</kbd> can be used to switch IME options.
|
||||
|
||||

|
||||
|
||||
These shortcuts are detected before low level hooks, and hence cause issues while remapping <kbd>Caps Lock</kbd> to <kbd>Shift/Alt/Ctrl</kbd> or vice-versa, as there could be an intermediate state where the system detects both the keys as being pressed. This results in a state where the modifier key does not get released since the OS suppresses the key up messages before they reach the low level hooks.
|
||||
|
||||
In order to work around this when a key down for the modifier is being processed, we send a key up for the modifier key with the `KEYBOARDMANAGER_SUPPRESS_FLAG` in the `dwExtraInfo` field, so that we suppress them at the start of the hook, and this key event would only be processed by the OS, without getting forwarded to other hooks/apps. The approach is described in more detail at [this comment](https://github.com/microsoft/PowerToys/issues/3397#issuecomment-640136416), as discussed with the AutoHotkey team. The code for the workaround can be found [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L827-L846). Tests for these scenarios have also been added at:
|
||||
- [Tests for workaround on single key remaps](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/test/SingleKeyRemappingTests.cpp#L110-L219)
|
||||
- [Tests for workaround on shortcut remaps](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/test/OSLevelShortcutRemappingTests.cpp#L1935-L2144)
|
||||
|
||||
For example, while [remapping <kbd>Ctrl</kbd> to <kbd>Caps Lock</kbd>](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L59-L63), before sending the <kbd>Caps Lock</kbd> key down message and suppressing <kbd>Ctrl</kbd>, we send a suppressed <kbd>Ctrl</kbd> key up, so that the OS doesn't see <kbd>Ctrl</kbd> and <kbd>Caps Lock</kbd> pressed together at any point. For the [<kbd>Caps Lock</kbd> to <kbd>Ctrl</kbd> scenario](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L104-L116), we send a suppressed C<kbd>Ctrl</kbd>trl key up message after sending <kbd>Ctrl</kbd> key down before <kbd>Caps Lock</kbd> suppressed. Similar logic is added for such scenarios in shortcut remapping.
|
||||
|
||||
While the above work around fixes most of the cases, there are still some scenarios where the modifier can get stuck, mentioned at this [comment](https://github.com/microsoft/PowerToys/issues/3397#issuecomment-663729278), which is why the issue is still open. This occurs if a modifier is pressed after the remap has been invoked before releasing the remapped key and it is a harder scenario to solve which requires refactoring the single key remap code.
|
||||
|
||||
### UIPI Issues (not resolved)
|
||||
`SendInput` does not work directly with certain key codes such as Play/Pause Media, Calculator key, etc as it requires UAC privileges to be injected to the OS and accordingly play the active media app or launch the Calculator app. In order to resolve this the correct approach is that the executable which calls `SendInput` needs to have the [UIAccess flag](https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-securityoverview) set to true, which will also avoid the requirement of KBM having to run as administrator to intercept key events when an elevated window is in focus. The UIAccess flag has many constraints such as it must be a signed executable and must be located in a protected path like Program Files. Since KBM currently runs out of the runner process, it would make more sense to do this work after KBM is moved to a separate executable, and it could be enabled by a separate toggle in settings only if PowerToys is installed in Program Files. [This comment](https://github.com/microsoft/PowerToys/issues/3192#issuecomment-646323661) has more details on this approach and (this)[https://github.com/microsoft/PowerToys/issues/3255] is the tracking issue.
|
||||
|
||||
## Other remapping approaches
|
||||
Other approaches for remapping which were deprioritized are:
|
||||
|
||||
### Registry approach
|
||||
This method is used by [SharpKeys](https://github.com/randyrants/sharpkeys) and involves using the [Microsoft Keyboard Scancode mapper registry key](https://github.com/randyrants/sharpkeys) to remap keys based on their scan codes. This has the advantage of being applied in all scenarios and not facing any elevation or UAC issues, however the disadvantages are that for modifying the settings the process must run elevated (as it modifies HKLM registry) and it requires a reboot to get applied. Another issue which is an advantage/disadvantage for users is that the process does not need to be running, so the remaps are applied all the time, including at the password prompt on logging in to the user's Windows account, which could get a user stuck if they orphaned a key in their password. This registry doesn't have any support for remapping shortcuts either, so the hook approach was prioritized over this.
|
||||
|
||||
### Driver approach
|
||||
Using a driver approach has the benefit of not depending on precedence orders as KBM could always run before low level hooks, and it also has the benefit of differentiating between different keyboards, allowing [multi keyboard-specific remaps](https://github.com/microsoft/PowerToys/issues/1460). The disadvantages are however that any bug or crash could have system level consequences. [Interception](https://github.com/oblitum/Interception) is an open source driver that could be used for implementing this. The approach was deprioritized due to the potential side effects.
|
||||
|
||||
## Telemetry
|
||||
Keyboard Manager emits the following telemetry events (implemented in [trace.h](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/trace.h) and [trace.cpp](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/trace.cpp)):
|
||||
- **`KeyboardManager_EnableKeyboardManager`:** Logs a `boolean` value storing the KBM toggle state. It is logged whenever KBM is enabled or disabled (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L305-L316)).
|
||||
- **`KeyboardManager_KeyRemapCount`:** Logs the number of key to key and key to shortcut remaps (i.e. all the remaps on the Remap a key window). This gets logged on saving new settings in the Remap a key window (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L159-L163)).
|
||||
- **`KeyboardManager_OSLevelShortcutRemapCount`:** Logs the number of global shortcut to shortcut and shortcut to key remaps. This gets logged on saving new settings in the Remap a shortcut window (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L220)).
|
||||
- **`KeyboardManager_AppSpecificShortcutRemapCount`:** Logs the number of app-specific shortcut to shortcut and shortcut to key remaps. This gets logged on saving new settings in the Remap a shortcut window (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L221)).
|
||||
- **`KeyboardManager_KeyToKeyRemapInvoked`:** Logs an event when a key to key remap is invoked (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L101-L102)).
|
||||
- **`KeyboardManager_KeyToShortcutRemapInvoked`:** Logs an event when a key to shortcut remap is invoked (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L101-L102)).
|
||||
- **`KeyboardManager_OSLevelShortcutToShortcutRemapInvoked`:** Logs an event when a global shortcut to shortcut remap is invoked (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L320-L321)).
|
||||
- **`KeyboardManager_OSLevelShortcutToKeyRemapInvoked`:** Logs an event when a global shortcut to key remap is invoked (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L320-L321)).
|
||||
- **`KeyboardManager_AppSpecificShortcutToShortcutRemapInvoked`:** Logs an event when an app-specific shortcut to shortcut remap is invoked (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L320-L321)).
|
||||
- **`KeyboardManager_AppSpecificShortcutToKeyRemapInvoked`:** Logs an event when an app-specific shortcut to key remap is invoked (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L320-L321)).
|
||||
- **`KeyboardManager_Error`:** Logs the occurrence of an error in KBM with the name of the method, error code and the corresponding error message. This is currently used only for logging `SetWindowsHookEx` failures (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L364-L369)).
|
||||
63
doc/devdocs/modules/keyboardmanager/keyboardmanagercommon.md
Normal file
63
doc/devdocs/modules/keyboardmanager/keyboardmanagercommon.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Keyboard Manager Common
|
||||
This project contains any code that is to be shared between the backend and UI projects. This file covers any functionality in this project which hasn't been covered along with the other modules.
|
||||
|
||||
## Table of Contents
|
||||
1. [KeyboardManagerState](#KeyboardManagerState)
|
||||
1. [UI States](#UI-States)
|
||||
2. [DetectSingleRemapKeyUIBackend and DetectShortcutUIBackend](#DetectSingleRemapKeyUIBackend-and-DetectShortcutUIBackend)
|
||||
3. [HandleKeyDelayEvent](#HandleKeyDelayEvent)
|
||||
4. [Saving remappings to file](#Saving-remappings-to-file)
|
||||
5. [Concurrent Access to remap tables](#Concurrent-Access-to-remap-tables)
|
||||
2. [KeyDelay](#KeyDelay)
|
||||
3. [Shortcut and RemapShortcut classes](#Shortcut-and-RemapShortcut-classes)
|
||||
1. [IsKeyboardStateClearExceptShortcut](#IsKeyboardStateClearExceptShortcut)
|
||||
2. [CheckModifiersKeyboardState](#CheckModifiersKeyboardState)
|
||||
3. [Tests](#Tests)
|
||||
4. [Helpers](#Helpers)
|
||||
1. [Foreground App Detection](#Foreground-App-Detection)
|
||||
|
||||
## KeyboardManagerState
|
||||
[This class](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/KeyboardManagerState.cpp) stores all the data related to remappings and is also used in the sense of a View Model as it used to communicate common data that is shared between the KBM UI and the backend. They are accessed on the UI controls using static class members of `SingleKeyRemapControl` and `ShortcutControl`.
|
||||
|
||||
### UI States
|
||||
[UI states](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.h#L27-L42) are used to keep track in which step of the UI flow is the user at, such as which Remap window they are on, or if they have one of the Type windows open. This is required because the hook needs to suppress input and update UI in some cases, and in some cases remappings have to be disabled altogether.
|
||||
|
||||
### DetectSingleRemapKeyUIBackend and DetectShortcutUIBackend
|
||||
[These methods](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.cpp#L374-L446) are [called on the low level hook](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L399-L408) in the main keyboard event handler. When the user opens any UI window the UI states are updated and in this case some remappings have to be disabled. On the Remap keys window, all remappings are disabled, while on the Remap shortcuts window, shortcut remappings are disabled.
|
||||
|
||||
In addition to this, if the user has opened the Type window, and the window is in focus, [whenever a key event is received we have to update the set of selected keys in the TextBlock](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.cpp#L266-L329) in the ContentDialog. These methods also call the `KeyDelay` handlers to check if the input is Esc/Enter and accordingly handle the Accessibility events for the Type window. When the user clicks the Type button, [variables in the KeyboardManagerState store the corresponding TextBlocks](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp#L375-L376) which appear in the ContentDialog, so that these UI controls can be updated from the hook on the dispatcher thread.
|
||||
|
||||
### HandleKeyDelayEvent
|
||||
[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.cpp#L482-L498) checks if the UI is in the foreground, and if so runs the key delay handlers that have been registered.
|
||||
|
||||
### Saving remappings to file
|
||||
The [`SaveConfigToFile`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.cpp#L500-L607) method is called on clicking the OK button on the EditKeyboardWindow or EditShortcutsWindow. Since PowerToys Settings also reads the config JSON file, [a named mutex is used](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.cpp#L582-L600) before accessing the file, with a 1 second timeout. If the mutex is obtained the settings are written to the default.json file.
|
||||
|
||||
### Concurrent Access to remap tables
|
||||
To prevent the UI thread and low level hook thread from concurrently accessing the remap tables we use an [`atomic bool` variable](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.h#L91-L92), which is set to `true` while the tables are getting updated. When this is `true` the hook will skip all remappings. Use of mutexes in the hook were removed to prevent re-entrant mutex bugs.
|
||||
|
||||
## KeyDelay
|
||||
[This class](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/KeyDelay.cpp) implements a queue based approach for processing key events and based on the time difference between key down and key up events [executes separate methods for `ShortPress`, `LongPress` or `LongPressReleased`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyDelay.h#L69-L72). The class is used for the hold Enter/Esc functionality required for making the Type window accessible and prevent keyboard traps (see [this](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp#L273-L292) for an example of it's usage). The `KeyEvents` are added to the queue from the hook thread of KBM, and a separate [`DelayThread`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyDelay.cpp#L142-L166) is used to process the key events by checking the `time` member in the key event. The thresholds for short vs long press and hold wait timeouts are `static` constants, but if the module is extended for other purposes these could be made into arguments.
|
||||
|
||||
**Note:** [Deletion of the `KeyDelay`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyDelay.cpp#L4-L12) object should never be called from the `DelayThread` i.e. from within one of the 3 handlers, as it can re-enter the mutex and would lead to a deadlock. This can be avoided by either deleting it on a separate thread or as done in the KBM UI, on the dispatcher thread. See [this PR](https://github.com/microsoft/PowerToys/pull/6959#issue-496583547) for more details on this issue.
|
||||
|
||||
## Shortcut and RemapShortcut classes
|
||||
The [`Shortcut` class](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/Shortcut.h) is a data structure for storing key combinations which are valid shortcuts and it contains several methods which are used for shortcut specific operations. [`RemapShortcut`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/RemapShortcut.h) consists of a shortcut/key union (`std::variant`), along with other boolean flags which are required on the hook side for storing any relevant keyboard states mid-execution.
|
||||
|
||||
### IsKeyboardStateClearExceptShortcut
|
||||
[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Shortcut.cpp#L665-L813) is used by the `HandleShortcutRemapEvent` to check if any other keys on the keyboard have been pressed apart from the keys in the shortcut. This is required because shortcut to shortcut remaps should not be applied if the shortcut is pressed with other keys. The method iterates over all the possible key codes, except any keys that are considered reserved, unassigned, OEM-specific or undefined, as well as mouse buttons (see list [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Shortcut.cpp#L628-L663)).
|
||||
|
||||
### CheckModifiersKeyboardState
|
||||
[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Shortcut.cpp#L517-L614) uses `GetVirtualKeyState` (internally calls `GetAsyncKeyState` in production code), to check if all the modifiers of the current shortcut are being pressed. Since Win doesn't have a non-L/R key code we check this by checking both LWIN and RWIN.
|
||||
|
||||
### Tests
|
||||
Tests for some methods in the `Shortcut` class can be found [here](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/ShortcutTests.cpp).
|
||||
|
||||
## Helpers
|
||||
[This namespace](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/Helpers.cpp) has any methods which are used across either UI or the backend which aren't specific to either. Some of these methods have tests [here](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/SetKeyEventTests.cpp).
|
||||
|
||||
### Foreground App Detection
|
||||
[`GetCurrentApplication`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L226-L268) is used for detecting the foreground process for App-specific shortcuts. The logic is very similar to that used for FZ's app exception feature, involving `GetForegroundWindow` and `get_process_path`. The one additional case which has been added is for full-screen UWP apps, where the above method fails and returns `ApplicationFrameHost.exe`. The [`GetFullscreenUWPWindowHandle`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L210-L224) uses `GetGUIThreadInfo` API to find the window linked to the GUI thread. This logic is based on [this stackoverflow answer](https://stackoverflow.com/questions/39702704/connecting-uwp-apps-hosted-by-applicationframehost-to-their-real-processes/55353165#55353165).
|
||||
|
||||
**Note:** The [`GetForegroundProcess` method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/Input.cpp#L17-L21) performs string allocation in a weird way because of exceptions that were occurring while running tests as a result of memory being allocated or deallocated across dll boundaries. Here's the comment from the PR where this was added
|
||||
> To make app-specific logic test-able, a GetForegroundProcess was added to the input interface which internally calls GetCurrentApplication. This allows us to mock this method in the test project by just setting some process name as the foreground process for that function. When I set this to just return the string name, it would goes runtime errors on the test project in debug_heap with `__acrt_first_block == header`. Based on [this stackoverflow answer](https://stackoverflow.com/a/35311928), this would happen if allocation happens in one dll's code space and deallocation happens in another. One way to avoid this is to change both the projects to MD (multi threaded dll) instead of MT(multi threaded), however that results in many compile-time errors since all the PT projects are configured as MT. To solve this, the GetForegroundProcess was rewritten such that its argument is the output variable, and we allocate memory for that string within the AppSpecificHandler method rather than in that function.
|
||||
122
doc/devdocs/modules/keyboardmanager/keyboardmanagerui.md
Normal file
122
doc/devdocs/modules/keyboardmanager/keyboardmanagerui.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Keyboard Manager UI
|
||||
|
||||
## Table of Contents:
|
||||
1. [C++ XAML Islands](#c---xaml-islands)
|
||||
1. [Debugging exceptions in XAML Islands](#debugging-exceptions-in-xaml-islands)
|
||||
2. [Build times](#build-times)
|
||||
3. [Setting custom backgrounds for Xaml Controls using brushes](#setting-custom-backgrounds-for-xaml-controls-using-brushes)
|
||||
2. [UI Structure](#ui-structure)
|
||||
3. [EditKeyboardWindow/EditShortcutsWindow](#editkeyboardwindow-editshortcutswindow)
|
||||
1. [OK and Cancel button](#ok-and-cancel-button)
|
||||
2. [Delete button](#delete-button)
|
||||
3. [Handling common modifiers in EditKeyboardWindow](#handling-common-modifiers-in-editkeyboardwindow)
|
||||
4. [SingleKeyRemapControl](#singlekeyremapcontrol)
|
||||
5. [ShortcutControl](#shortcutcontrol)
|
||||
6. [KeyDropDownControl](#keydropdowncontrol)
|
||||
1. [Localized key names](#localized-key-names)
|
||||
2. [Single Key ComboBox Selection Handler](#single-key-combobox-selection-handler)
|
||||
3. [Shortcut ComboBox Selection Handler](#shortcut-combobox-selection-handler)
|
||||
|
||||
## C++ XAML Islands
|
||||
The KBM UI is implemented as a C++ XAML Island, but all the controls are implemented in code behind rather than .xaml and .xaml.cs files. This was done as per a XAML Island Code sample and it didn't require a separate UWP project, which could be limited in terms of using hooks. There is a [tech debt item](https://github.com/microsoft/PowerToys/issues/2027) for moving this to XAML. The reason it wasn't implemented in the C# Settings was because it required communication with the low level hook thread, which could be too slow if IPC is used, since the UI needs to update on every key event.
|
||||
|
||||
**Note:** For functions which take a XAML component as argument, pass it by value and not by reference. This is because `winrt` WinUI classes store their own internal references, so they are supposed to be passed by value (and internally ref counts are incremented). Passing by reference can lead to weird behavior where the object is `null`.
|
||||
|
||||
The windows are [created as C++ windows](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L128-L140) and the window sizes are set to default by [scaling them as per DPI](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L120-L126) using the `DPIAware::Convert` API from common lib. Since the UI is launched on a new thread, the window may not be in the foreground, so [we call `SetForegroundWindow`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L146-L150).
|
||||
|
||||
`DesktopWindowXamlSource` has to be declared and [it is initialized](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L159-L162) using the [`XamlBridge`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/ui/XamlBridge.cpp), and [a second window handle](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L161-L162) is generated for the internal Xaml Island window. Most of the code was based on the [Xaml Island Sample](https://github.com/microsoft/Xaml-Islands-Samples/blob/master/Samples/Win32/SampleCppApp/XamlBridge.cpp). The `XamlBridge` class contains code which handles initializing the Xaml Island containers as well as handling special messages like keyboard navigation, and focus between islands and between the C++ window and the island. It also has methods for clearing the xaml islands and closing the window.
|
||||
|
||||
Once the UI controls are created, the parent container is set as the content for the `DesktopWindowXamlSource` and the `XamlBridge.MessageLoop` is executed. Messages are processed by the C++ window handler like [`EditKeyboardWindowProc`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L364-L404). The general structure we use for this is, for any `WM_PAINT` or `WM_SIZE` message we resize the Xaml Island window. For `WM_GETMINMAXINFO` we set minimum widths so that the window cannot be resized beyond a minimum height and width. This is done to prevent the WinUI elements from overlapping and getting cropped. If it is neither of these cases we send the message to the [`XamlBridge.MessageHandler`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/XamlBridge.cpp#L291-L301) which handles Destroy, Activation and Focus. If `WM_NCDESTROY` is received when the `XamlBridge` is `nullptr`, the window thread is terminated.
|
||||
|
||||
**Note:** `ContentDialog` in Xaml Islands requires manually settings a `XamlRoot`. This can generally be done by passing the XamlRoot from a component in the main window, such as the button used to open the dialog ([`sender.as<Button>().XamlRoot()`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/ShortcutControl.cpp#L31-L32)). [These docs]((https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.contentdialog#contentdialog-in-appwindow-or-xaml-islands)) have more details about this.
|
||||
|
||||
### Debugging exceptions in XAML Islands
|
||||
Sometimes if an exception occurs in XAML Islands, the stack trace may not always point to the correct code causing the exception and instead it will point to the Xaml Island message loop. In these cases the output window in VS will generally show the correct exception.
|
||||
|
||||
### Build times
|
||||
C++ Xaml Islands generally take several minutes to build because the `pch` which contains the WinUI headers takes longer to build and compiles to a file of several GBs. To minimize the build times, multi-processor compilation within the projects have been enabled (files are distributed for compilation to the processors), and references to the Xaml headers have been removed from the .h headers files as much as possible. Since several classes of ours had class members with UI controls like `StackPanel` (which requires definitions of the classes in order to compile), we worked around this by declaring them as `IInspectable` (the equivalent of an object pointer in winrt), and initializing them to the actual control like `StackPanel` in the constructor and accessing all their member functions by inline typecasting (for `IInspectable x;` we do `x = StackPanel();` and `x.as<StackPanel>().MemberFunction()`). Check [this](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/ShortcutControl.cpp#L19-L25) for this type of usage in `ShortcutControl`.
|
||||
|
||||
### Setting custom backgrounds for Xaml Controls using brushes
|
||||
To access the brushes available on C# Xaml, it has to be done with the `Resources.Lookup` syntax:
|
||||
`primaryButton.Background(Windows::UI::Xaml::Application::Current().Resources().Lookup(box_value(L"SystemControlBackgroundBaseMediumLowBrush")).as<Windows::UI::Xaml::Media::SolidColorBrush>());`
|
||||
|
||||
## UI Structure
|
||||
The KBM UI consists of a [`Grid` with several columns](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L200-L218). Rows are added dynamically when [the add button is pressed](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L305-L309). [A vector of vector of unique pointers to `SingleKeyRemapControl`/`ShortcutControl`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L248-L249) is created so that references to the UI components and their data are not lost until the window is closed. [`SingleKeyRemapControl`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp) is the UI class for each row of the Remap keys table, and [`ShortcutControl`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/ui/ShortcutControl.cpp) is the UI class for each row of the Remap shortcuts table. [`KeyDropDownControl`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp) is used for handling the ComboBox operations. Each of these two classes [have vectors of unique pointers to the `KeyDropDownControl` objects](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/ShortcutControl.h#L44-L45) so that references to the objects are active until the control is deleted.
|
||||
|
||||
When the UI windows are activated the `KeyboardManagerState` object [sets the `UIState` variable](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L251-L252) which is used for distinguishing if the UI is up from the keyboard hook thread. The [states are also updated](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp#L53) on opening and closing the Type window.
|
||||
|
||||
Clicking the Type Button [opens a content dialog](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp#L206-L380) which registers key delays using the [`KeyDelay` class](keyboardmanagercommon.md#KeyDelay) for Enter and Esc keys and sets the UI states such that when a key event occurs the TextBlocks on the ContentDialog are updated accordingly. On accepting the dialog the selected keys are copied into the ComboBoxes from the TextBlocks, and on closing the window the key delays are unregistered and UI states are reset.
|
||||
|
||||
Since ComboBoxes are added dynamically, handlers have been added which [update the accessible names for these controls](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp#L69-L74), which get executed whenever a drop down is added or removed.
|
||||
|
||||
When the `EditKeyboardWindow`/`EditShortcutsWindow` is created, [we iterate through the remappings](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L254-L262) stored in `KeyboardManagerState` and add rows to the UI Grid. For both the windows we have `static` buffers [`singleKeyRemapBuffer`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/SingleKeyRemapControl.h#L39-L40) and [`shortcutRemapBuffer`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/ShortcutControl.h#L42-L43) which store the corresponding key/shortcuts as per the selections in the UI if they are valid with no warnings.
|
||||
|
||||
## EditKeyboardWindow/EditShortcutsWindow
|
||||
|
||||
### OK and Cancel button
|
||||
[On pressing the OK button](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L66-L89) in `EditKeyboardWindow`, first the [`CheckIfRemappingsAreValid` method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L10-L44) is executed which performs basic validity checks on the current remappings in the remap buffer (`static SingleKeyRemapControl::singleKeyRemapBuffer`), such as if there are no NULL columns and none of the source keys are repeated. All other validity checks are assumed to happen while the user adds the remapping. If this is found to be invalid a ContentDialog is displayed which shows that some remappings are invalid and if the user proceeds only the valid ones will be applied. If it is valid [`GetOrphanedKeys`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L46-L75) is executed which checks if any keys are orphaned (i.e. the key has been remapped and no other key has been remapped to it, so there is no way to send that key code), and a dialog is shown for notifying the user with a list of orphaned keys. After this the settings are [applied by adding it to the `KeyboardManagerState.singleKeyReMap` member](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L102-L164) and they are saved to the JSON file. `EditShortcutsWindow` differs slightly from this, as there is no orphaned keys check, and [on pressing OK](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditShortcutsWindow.cpp#L32-L47) both the global and app-specific shortcuts are validated and [updated](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L166-L223).
|
||||
|
||||
The code used for updating the remapping tables in `KeyboardManagerState` can be found [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.cpp#L104-L183). For shortcut remaps, the `sortedKeys` vectors are updated and re-sorted whenever an element is added to them (like [this](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.cpp#L135-L136)).
|
||||
|
||||
On pressing OK (after confirmation dialogs) or Cancel, the window is closed and UI states are reset.
|
||||
|
||||
### Delete button
|
||||
Since there is no single method to delete the elements in a row for a Grid, [the logic](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp#L143-L188) we use involves decrementing the rowIndex for all the UI controls that appearing after the row to be deleted, and removing each of the items of the row from the Grid, followed by deleting that row definition. We also update the accessible names for all the rows since the indexing has changed. After this the corresponding row in the remap buffer is also deleted, and `SingleKeyRemapControl`/`ShortcutControl` objects are deleted from the vector.
|
||||
|
||||
### Handling common modifiers in EditKeyboardWindow
|
||||
In the SingleKeyRemap table for a remapping of the form Ctrl->X, where Ctrl is the common version and not L/R, we can't store it directly as Ctrl->X because when the hook receives the key event it only gets LCtrl or RCtrl specifically and not `VK_CONTROL`. To simplify the backend code, when [single key remappings are applied](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L116-L143), any remapping of the form Ctrl->X is split into Ctrl(L)->X and Ctrl(R)->X (i.e. both L and R versions are remapped to the same target), and when remappings are loaded in EditKeyboardWindow, we [pre-process the remap table](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L77-L100) such that if the L and R versions of a modifier are remapped to the same key/shortcut we combine them. This also results in the behavior where a user adds LCtrl->X and RCtrl->X and after closing and re-opening KBM UI it appears combined as Ctrl->X.
|
||||
|
||||
## SingleKeyRemapControl
|
||||
The left drop down column uses a single ComboBox and the Type button is linked to `createDetectKeyWindow`, whereas the right column is linked to `createDetectShortcutWindow` as the column can accept a key or a shortcut (required to support key to key and key to shortcut). The `KeyDropDownControl` for the left column in the window uses a smaller key list, without `None`.
|
||||
|
||||
## ShortcutControl
|
||||
Both the columns in are linked to `createDetectShortcutWindow`, however the drop down selection handlers differ in their logic as the left column only allows shortcuts, and the drop downs do not contain the `Disable` key, whereas the right column allows you to select both shortcuts and keys (to support shortcut to shortcut and shortcut to key), and it allows selection of `Disable`.
|
||||
|
||||
For the app-specific shortcut target app text-box, we had to validate that the shortcut row is still valid when the target app is changed (for example, <kbd>Ctrl+A</kbd> is remapped for Chrome, and another remapping for <kbd>Ctrl+A</kbd> was remapped to Edge, but the target was changed to Chrome.). For this we didn't use the TextChanged handler as every time a letter is typed it would get executed. Instead we used the [`LostFocus` handler](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/ShortcutControl.cpp#L108-L167) which gets executed whenever you focus into the box (by clicking or tabbing) and then tabbing or clicking out. In the method we perform the same shortcut buffer validation used for selections in the drop down menus and update the buffers accordingly.
|
||||
|
||||
## KeyDropDownControl
|
||||
Each ComboBox has a linked flyout, which is used to show warnings to the users whenever a user selects an invalid key from the drop down. When the warning is displayed the ComboBox is also reset to -1, i.e. no selection.
|
||||
|
||||
For selection handlers on the ComboBoxes we couldn't use just the SelectionChanged handler directly as it gets executed even on searching for elements in the drop down. Instead we used DropDownClosed (when a user opens the drop down and searches and selects something) and SelectionChanged when the drop down is not open (for setting selections programmatically or selection made by searching with tab focus on the drop down without opening it). This was required because if we execute the selection handlers while users are searching, it could cause false positive flyout warnings if the search causes an invalid value to be selected, and flyouts cause the drop down to close leading to bad UI experience.
|
||||
|
||||
### Localized key names
|
||||
For getting localized key names and symbols for each virtual key code, whenever the key lists are accessed, i.e. [whenever the drop down is opened](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp#L56-L60) or when `GetKeyName` is called in the Type window, the current `KeyboardLayout` is retrieved to ensure that the displayed key names are always updated. Since the `WM_INPUTLANGCHANGED` event was having some issues with XAML islands we weren't able to use this to update the keyboard layout. In addition to this we do not refresh the UI, so the key lists get updated only on opening/interacting with them.
|
||||
|
||||
### Single Key ComboBox Selection Handler
|
||||
On making a selection in the drop down, [the selection handler](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp#L91-L130) validates the input with the buffer from the other column and other rows. Error messages are shown using flyouts if the selection is not considered valid and the drop down and buffer for that entry are reset to empty selection. The errors that can occur on the single key ComboBox are:
|
||||
- Remap to same key (A->A)
|
||||
- Same key previously remapped (A->B and A->C)
|
||||
- Conflicting modifier previously remapped (Ctrl->A and Ctrl(left)->B, since Ctrl also includes Ctrl(left))
|
||||
If the selection is found to be valid, the `singleKeyRemapBuffer` is updated accordingly.
|
||||
For handling `Shortcut` and key in the remap buffer for the right column, we use `std::variant`, which allows us to store either of the two types and check which one of them is present in the buffer by using the `index` method.
|
||||
[`ValidateAndUpdateKeyBufferElement`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/BufferValidationHelpers.cpp#L8-L66) does not reference any UI components and instead takes all the relevant data as arguments. This method [has tests](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/BufferValidationTests.cpp) which covers all the cases that could arise from making selections on the UI.
|
||||
|
||||
### Shortcut ComboBox Selection Handler
|
||||
On making a selection in the drop down, [the selection handler](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp#L215-L295) validates the input with the buffer from the other column and other rows. Error messages are shown using flyouts if the selection is not considered valid and the drop down and buffer for that entry are reset to empty selection.
|
||||
This differs from the Single Key ComboBox handler in the sense that after validating the current selection we may perform [a set of actions](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp#L160-L204) such as:
|
||||
- Adding a drop down (if a modifier is selected)
|
||||
- Removing a drop down (if None is selected)
|
||||
- Clearing terminal empty drop downs (if an action key is selected in a non-last drop down and the remaining ones are empty)
|
||||
|
||||
After performing the corresponding action, if any, we check if the drop down resulted in an error, in which case we do [a second level of validation](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp#L224-L229) on all the drop downs in that list of drop downs. This is done because there can be cases where an error in one drop down results us setting it to empty, and the remaining selection is also invalid. For example, you have Ctrl+A -> Ctrl+Shift+A, and you change Shift to Ctrl. This would show a warning for having two Ctrls in the shortcut being invalid, after which setting that to empty would result in Ctrl+A->Ctrl+Empty+A, which is a case of remapping a shortcut to itself.
|
||||
|
||||
Once this second level of validation is done, we proceed with [updating the buffer](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp#L231-L251). Depending on the number of drop downs with valid values, this could be either a key or a shortcut (for the right columns). We also [set the buffer value for the target app](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp#L252-L267) while doing this.
|
||||
|
||||
Unlike the Single Key handler, there is a different set of errors that can occur here which are related to making a selection that is considered as a valid shortcut. The `isHybridControl` argument is used to distinguish between the differing behaviors for the two types of columns (shortcut only or shortcut/key column). The errors that can occur for this handler are:
|
||||
- Shortcut must start with modifier (selecting A on the first drop for the left column is invalid)
|
||||
- Shortcut can't have a repeated modifier (Ctrl+Ctrl(left)+A is not a shortcut)
|
||||
- Shortcut can only have upto 2 modifiers (Ctrl+Shift+Alt is not supported as we have enforced a 3 key constraint (**not a backend limitation, there is [an issue](https://github.com/microsoft/PowerToys/issues/3936) requesting to remove this**))
|
||||
- Shortcut must contain an action key (Ctrl+A and change A to None, only for left column)
|
||||
- Shortcut must have at least two keys (Ctrl+A and change Ctrl to None, only for left column)
|
||||
- Disable can't be a modifier or action key (Ctrl+Disable is invalid)
|
||||
- Shortcut can't have more than one action key (Ctrl+Shift+A, change Shift to B)
|
||||
- Remap to same shortcut(Ctrl+A->Ctrl+A)
|
||||
- Same shortcut previously remapped for same target app (Ctrl+A->B and Ctrl+A->C)
|
||||
- Conflicting shortcut previously remapped for same target app (Ctrl+A->B and Ctrl(left)+A->C, since Ctrl also includes Ctrl(left))
|
||||
- Illegal shortcut remaps like Win+L or Ctrl+Alt+Del (since these cannot be remapped using LL hooks)
|
||||
|
||||
[`ValidateShortcutBufferElement`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/BufferValidationHelpers.cpp#L68-L304) does not reference any UI components and instead takes all the relevant data as arguments. This method [has tests](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/BufferValidationTests.cpp) which covers all the cases that could arise from making selections on the UI.
|
||||
|
||||
**Note:** After updating the buffer we have [code to handle a special case](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp#L269-L279), which was required to prevent scenarios where a drop down can get deleted but the corresponding `KeyDropDownControl` object isn't deleted. The code checks if the drop down is still linked to the parent and accordingly deletes the `KeyDropDownControl` object from the vector.
|
||||
|
||||
**IgnoreKeyToShortcutWarning special case:** [An additional](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp#L177-L181) check was added to ignore the Map to Same key error when an existing remapping is loaded. This was because a remapping like Ctrl->Ctrl+A has an intermediate step of Ctrl->Ctrl, which could lead to an error of invalid input, even though Ctrl+A is valid. The only way to actually add this is from the Type button or by adding them in a different order (like typing Shift+A and then changing Shift to Ctrl). Since the intermediate check could fail, this was causing the app to crash since the Xaml Island wouldn't be completely loaded at that point and the Flyout can't be displayed. [This](https://github.com/microsoft/PowerToys/issues/6695) is the linked issue which describes the repro scenario.
|
||||
48
doc/devdocs/modules/launcher/architecture.md
Normal file
48
doc/devdocs/modules/launcher/architecture.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Architecture
|
||||
|
||||
## Overview
|
||||
`PowerToys Run` is a plugin-based .net core desktop application. It is written in WPF using `Model-View-ViewModel (MVVM)` structural design pattern. This article provides an overview of `PowerToys Run` architecture and introduces major components in the data flow.
|
||||
|
||||
Note : We refer to base application without plugins as `PowerLauncher`, which is same as the name of startup WPF project.
|
||||
|
||||
## UI
|
||||
PowerToys Run UI is written in the WPF framework. The UI code is present in the Powerlauncher project and is spanned across three high-level components: [`MainWindow.xaml`](/src/modules/launcher/PowerLauncher/MainWindow.xaml), [`LauncherControl.xaml`](/src/modules/launcher/PowerLauncher/LauncherControl.xaml) and [`ResultList.xaml`](/src/modules/launcher/PowerLauncher/LauncherControl.xaml). These components are discussed below.
|
||||
|
||||

|
||||
**Fig 1: PowerToys Run UI architecture**
|
||||
|
||||
1. **[`MainWindow.xaml`](/src/modules/launcher/PowerLauncher/MainWindow.xaml)**: This is the outermost-level UI control. It is composed of lower-level UI components such as [`LauncherControl.xaml`](/src/modules/launcher/PowerLauncher/LauncherControl.xaml) and [`ResultList.xaml`](/src/modules/launcher/PowerLauncher/LauncherControl.xaml). The corresponding code-behind file implements all the UI related functionalities such as autosuggest, key-bindings, toggling visibility of WPF window and animations.
|
||||
2. **[`LauncherControl.xaml`](/src/modules/launcher/PowerLauncher/LauncherControl.xaml)**: This control implements the UI component for editing query text.(marked in red in Fig 1) It consists of two overlapping WPF controls, `TextBox` and `TextBlock`. The outer `TextBox` is used for editing query whereas the inner `TextBlock` is used to display autosuggest text.
|
||||
3. **[`ResultList.xaml`](/src/modules/launcher/PowerLauncher/LauncherControl.xaml)**: This control implements the UI component for displaying results (marked in green in Fig 1). It consists of a `ListView` WPF control with a custom `ItemTemplate` to display application logo, name, tooltip text, and context menu.
|
||||
|
||||
## Data flow
|
||||
The backend code is written using the `Model-View-ViewModel (MVVM)` structural design pattern. Plugins act as `Model` in this project. A detailed overview of the project's structure is given [here](/doc/devdocs/modules/launcher/project_structure.md).
|
||||
|
||||
#### Flow of data between UI(view) and ViewModels
|
||||
Data flow between View and ViewModel follows typical `MVVM` scheme. Properties in viewModels are bound to WPF controls and when these properties are updated, `INotifyPropertyChanged` handler is invoked, which in turn updates UI. The diagram below provides a rough sketch of the components involved.
|
||||

|
||||
**Fig 2: Flow of data between UI and ViewModels.**
|
||||
|
||||
#### Flow of data between ViewModels and Plugins(Model)
|
||||
`PowerLauncher` interact with plugins using [`IPlugin`](/src/modules/launcher/Wox.Plugin/IPlugin.cs) and `IDelayedExecutionPlugin` interface. [`IPlugin`](/src/modules/launcher/Wox.Plugin/IPlugin.cs) is used for initialization and making queries which are fast (typically return results in less than 100ms).[`IDelayedExecutionPlugin`](/src/modules/launcher/Wox.Plugin/IDelayedExecutionPlugin.cs) is used for long-running queries and is implemented only when required. For example, [`IDelayedExecutionPlugin`](/src/modules/launcher/Wox.Plugin/IDelayedExecutionPlugin.cs) is implemented by indexer plugin for searching files with names of form \*abc\*.
|
||||
```
|
||||
public interface IPlugin
|
||||
{
|
||||
// Query plugin
|
||||
List<Result> Query(Query query);
|
||||
|
||||
// Initialize plugin
|
||||
void Init(PluginInitContext context);
|
||||
}
|
||||
|
||||
public interface IDelayedExecutionPlugin : IFeatures
|
||||
{
|
||||
// Query plugin
|
||||
List<Result> Query(Query query, bool delayedExecution);
|
||||
}
|
||||
```
|
||||

|
||||
**Fig 3: Flow of data between ViewModels and Plugins.**
|
||||
|
||||
#### Requesting services from powerlauncher
|
||||
Plugins could use the [`IPublicAPI`](/src/modules/launcher/Wox.Plugin/IPublicAPI.cs) interface to request services such as getting the current theme (for deciding logo background), displaying messages to the user, and toggling the visibility of PowerLauncher.
|
||||
20
doc/devdocs/modules/launcher/debugging.md
Normal file
20
doc/devdocs/modules/launcher/debugging.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Debugging
|
||||
`PowerToys Run` is a single exe file associated with `launcher.exe` process and debugger should be attached to this process. There are two approaches to debug `PowerToys Run`. Both these approaches differ in the compile-time and the range of functionalities that could be debugged. These methods are discussed in detail in the following sections.
|
||||
|
||||
|
||||
## Debugging Prerequisite
|
||||
Setup development environment for PowerToys by following instruction [here.](https://github.com/microsoft/PowerToys/tree/master/doc/devdocs#prerequisites-for-compiling-powertoys)
|
||||
|
||||
## Direct debugging
|
||||
This approach is used to test UI, plugins, and core `PowerToys Run` functionality. This **cannot** be used to test `PowerToys Run` settings. The approach is significantly faster compared to `Debugging with runner`, as it requires compiling projects relevant to `PowerToys Run`. Please follow the steps below for direct debugging.
|
||||
1. Right-click on `modules->launcher->PowerLauncher` and select `Set as startup Project`.
|
||||
2. Press `F5` to start debugging.
|
||||
|
||||
## Debugging with runner
|
||||
This approach can be used to test UI, plugins, core `PowerToys Run` functionality and `PowerToys Run` settings. This approach **cannot** be used to debug functions that execute on starting `launcher.exe` process. This requires building runner along with all the other modules on first compile, making it slower than `Direct debugging` approach. The subsequent compilations should be fast.
|
||||
1. Right-click on `runner` and select `Set as startup Project`.
|
||||
2. Press `F5` to start debugging.
|
||||
3. Attach debugger to `launcher.exe` process.
|
||||
1. Go to `Debug->Attach to process..`
|
||||
2. Filter and select `launcher.exe` process.
|
||||
3. Click on `Attach`.
|
||||
23
doc/devdocs/modules/launcher/plugins/calculator.md
Normal file
23
doc/devdocs/modules/launcher/plugins/calculator.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Calculator Plugin
|
||||
The Calculator plugin as the name suggests is used to perform calculations on the user entered query.
|
||||
|
||||

|
||||
|
||||
### [`CalculateHelper`](src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/CalculateHelper.cs)
|
||||
- The [`CalculateHelper.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/CalculateHelper.cs) class checks to see if the user entered query is a valid input to the calculator and only if the input is valid does it perform the operation.
|
||||
- It does so by matching the user query to a valid regex.
|
||||
|
||||
### [`CalculateEngine`](src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/CalculateEngine.cs)
|
||||
- The main computation is done in the [`CalculateEngine.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/CalculateEngine.cs) file using the `Mages` library.
|
||||
|
||||
```csharp
|
||||
var result = CalculateEngine.Interpret(query.Search, CultureInfo.CurrentUICulture);
|
||||
```
|
||||
|
||||
### [`CalculateResult`](src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/CalculateResult.cs)
|
||||
- The class which encapsulates the result of the computation.
|
||||
- It comprises of the `Result` and `RoundedResult` properties.
|
||||
|
||||
### Score
|
||||
The score of each result from the calculator plugin is `300`.
|
||||
|
||||
17
doc/devdocs/modules/launcher/plugins/folder.md
Normal file
17
doc/devdocs/modules/launcher/plugins/folder.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Folder Plugin
|
||||
The Folder plugin is used to navigate the directory structure and display the sub-folders and files within a folder.
|
||||

|
||||
|
||||
### [`FolderHelper.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Path/FolderHelper.cs)
|
||||
- The [`FolderHelper`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Path/FolderHelper.cs) class leverages the `DriveInformation` and `folderLinks` to get the folder results for a user query.
|
||||
- The [`DriveInformation`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Path/DriveInformation.cs) class gets the list of all drives on the system.
|
||||
- The [`FolderLink`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/FolderLink.cs) object corresponds to a user created link for frequently accessed projects. This was inherited from Wox but is presently not functional as we don't have the UI setup in settings to get this user input. Each folderLink object has a `nickname`, which is the name of the folder and this can be used to directly access that folder instead of entering the entire path.
|
||||
|
||||
### [`IFolderProcessor.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/IFolderProcessor.cs)
|
||||
The `IFolderProcessor` utilizes the `FolderHelper` class to extract the folders and return the results.
|
||||
There are two types of Folder Processors, based on the type of information they are processing -
|
||||
1. [`UserFolderProcessor`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/UserFolderProcessor.cs) - This Processor is currently not used in PT Run but it is used to process the user created folder links.
|
||||
2. [`InternalDirectoryProcessor`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/InternalDirectoryProcessor.cs) - This processor is used to retrieve the files and folders located within the current drive or shared folder.
|
||||
|
||||
### Score
|
||||
The first result is of score 500 and the following results are scored 10.
|
||||
39
doc/devdocs/modules/launcher/plugins/indexer.md
Normal file
39
doc/devdocs/modules/launcher/plugins/indexer.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Indexer Plugin
|
||||
The indexer plugin is used to search for files within the indexed locations of the system.
|
||||
|
||||

|
||||
|
||||
### [Drive Detection](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/DriveDetection)
|
||||
- There are two indexing modes in Windows:
|
||||
1. **Classic mode**: Only the desktop and certain customizable locations in the system are indexed. All the systems have the classic mode enabled by default.
|
||||
2. **Enhanced Mode**: This mode indexes the entire PC when enabled. The user can exclude certain locations from being indexed in this mode from the Windows Search settings options.
|
||||
- A drive detection warning is displayed to the users when only the custom mode is enabled on the system informing the user that not all the locations on their PC are indexed as this could lead to some results not showing up.
|
||||
- The [`IndexerDriveDetection.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/DriveDetection/IndexerDriveDetection.cs) file gets the status of the drive detection checkbox in the settings UI and depending on whether the enhanced mode is enabled or disabled, displays the warning.
|
||||
- To determine whether the `EnhancedMode` is enabled or not, we check the local machine registry entry for `EnableFindMyFiles`. If it is set to 1, the enhanced mode is enabled.
|
||||
|
||||
### [`OleDBSearch`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/OleDBSearch.cs)
|
||||
- The `Query` function within the [`OleDBSearch.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/OleDBSearch.cs) class takes in the query and the connection string to the SystemIndex catalog as arguments and returns a list of results.
|
||||
- It first opens a [connection][OLEDBConnection] to the Windows Indexer database, creates an [OleDB command][OLEDBCommand] and executes the command to get a list of results.
|
||||
|
||||
### [`WindowsSearchAPI`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/WindowsSearchAPI.cs)
|
||||
- The [`WindowsSearchAPI`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/WindowsSearchAPI.cs) class leverages the [`OleDBSearch.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/OleDBSearch.cs) class to execute the query.
|
||||
- It initializes the `QueryHelper` in the `InitQueryHelper()` function by creating a catalog manager to the SystemIndex catalog.
|
||||
- The metadata is initialized within the query helper, such as the number of results to retrieve, the type of information to retrieve for each file (currently we retrieve the item URL, the file name and the file attributes).
|
||||
- The query helper matches results using the name of the file only and they are sorted by the last modified date, ensuring that the recently modified files are ranked higher.
|
||||
- The File attributes are utilized to filter out hidden files from being displayed.
|
||||
|
||||
### Additional Information
|
||||
- There are two major types of queries generated by the indexer plugin:
|
||||
1. Full Text predicates - eg: [CONTAINS][Contains]
|
||||
2. Non-Full Text predicates - eg: [LIKE][Like]
|
||||
- The Full text predicates are much faster than non-full text predicates as they are based on finding matches rather than comparing the query with each item in the indexer database. Hence, queries which have the `CONTAINS` keyword are much faster than those which contain the `LIKE` keyword.
|
||||
- To prevent the indexer query from taking a long time and blocking the UI thread, there are two types of indexer queries which are executed. A simplified query and a full query, without and with the `LIKE` keyword respectively.
|
||||
- The result list is updated with the results of the full query once they are obtained.
|
||||
|
||||
### Score
|
||||
Each of the indexer plugin results has a score set to 0 so they are present at the bottom of the list.
|
||||
|
||||
[OLEDBCommand]: https://docs.microsoft.com/en-us/dotnet/api/system.data.oledb.oledbcommand?view=dotnet-plat-ext-3.1
|
||||
[OLEDBConnection]: https://docs.microsoft.com/en-us/dotnet/api/system.data.oledb.oledbconnection?view=dotnet-plat-ext-3.1
|
||||
[Contains]: https://docs.microsoft.com/en-us/windows/win32/search/-search-sql-contains
|
||||
[Like]: https://docs.microsoft.com/en-us/windows/win32/search/-search-sql-like
|
||||
35
doc/devdocs/modules/launcher/plugins/overview.md
Normal file
35
doc/devdocs/modules/launcher/plugins/overview.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Structural Overview
|
||||
The following basic functions are common to each of the plugins. They perform some rudimentary operations such as initialization of the plugin, executing the query that has been entered, loading context menu icons, updating settings when configurations are altered in the settings UI, and updating the theme of the icons when the theme changed event is triggered.
|
||||
|
||||
## IPlugin Interface
|
||||
Each plugin implements the `IPlugin` interface which comprises of the `Init()` and `Query()` functions.
|
||||
|
||||
### `Init`
|
||||
- The `Init()` function initializes the context, storage and settings of each plugin. This is equivalent to a contructor and is the first function to be called in the `Main.cs` file for each plugin.
|
||||
|
||||
### `Query`
|
||||
- For every query that the user enters into PT Run, the `PluginManager.cs` executes the `Query()` function in the `Main.cs` file corresponding to each Plugin.
|
||||
|
||||
### Context Menu Icons
|
||||
- The `ContextMenus` are loaded for each result based on the type of the result.
|
||||
- The various types of `ContextMenu` functionalities are:
|
||||
- Open containing folder
|
||||
- Run as Administrator
|
||||
- Open in console
|
||||
- Copy path
|
||||
|
||||
### UpdateSettings
|
||||
- This function updates the settings of each plugin based on the changes made by the user in the settings UI.
|
||||
- Eg: To disable drive detection in the indexer plugin, when the user checks or unchecks the drive detection check box, the `UpdateSettings()` function dispatches the changes in the check box to the plugin.
|
||||
|
||||
### ThemeChanged
|
||||
- This function is invoked when there is a change in the theme of PT Run.
|
||||
- It is used to update the `IconPath` for each plugin based on the theme.
|
||||
|
||||
### Save
|
||||
- This function saves the configurations of each plugin so that they can be loaded the next time.
|
||||
|
||||
### Score
|
||||
- The user query is executed against each of the plugins and the result list view is updated with results from each of the plugins.
|
||||
- The ordering of the results is based on the `Score` of each Result.
|
||||
- Each plugin assigns a score to a result based on it's relevance. The results with higher scores are displayed higher in the list view and vice versa.
|
||||
43
doc/devdocs/modules/launcher/plugins/program.md
Normal file
43
doc/devdocs/modules/launcher/plugins/program.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Program Plugin
|
||||
The program plugin as the name suggests is used to search for programs installed on the system.
|
||||
|
||||

|
||||
|
||||
There are broadly two different categories of applications:
|
||||
|
||||
1. Packaged applications
|
||||
2. Win32 applications
|
||||
|
||||
### [UWP](src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWP.cs)
|
||||
- The logic for indexing Packaged applications is present within the [`UWP.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWP.cs) file.
|
||||
- There can be multiple applications present within a package. The [`UWPApplication.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWPApplication.cs) file encapsulates the properties of a packaged application.
|
||||
- To index packaged applications, the `PackageManager` retrieves all the packages for the current user and indexes all the applications.
|
||||
- To retrieve the app icon for packaged applications, the assets path is retrieved from the `Application Manifest` file. There are multiple icons corresponding to each scale, target size and theme. The best icon is chosen given the theme of powerToys Run.
|
||||
|
||||
### [Win32Program](src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/Win32Program.cs)
|
||||
- Win32 programs in the following locations are indexed by PT Run-
|
||||
1. Desktop
|
||||
2. Public Desktop (Applications present on the desktop of all the users)
|
||||
3. Registry (Some programs)
|
||||
4. Start Menu
|
||||
5. Common start menu (Applications which are common to all users)
|
||||
8. Locations pointed to by the PATH environment variable.
|
||||
- To prevent applications and shortcuts present in multiple locations from showing up as duplicate results, we consider apps with the same name, executable name and full path to be the same.
|
||||
- The subtitle of the application result is set based on it's application type. It could be one of the following:
|
||||
1. Lnk Shortcuts
|
||||
2. Appref files
|
||||
3. Internet shortcut - steam and epic games
|
||||
4. PWAs
|
||||
5. Run commands - these are indexed by the PATH environment variable
|
||||
|
||||
### Score
|
||||
- The score for each application result is based on the how many letters are matched, how close the matched letters are to the actual word and the index of the matched characters.
|
||||
- There is a threshold score to decide the apps which are to be displayed and applications which have a lower score are not displayed by PT Run.
|
||||
|
||||
### Update Program List in Runtime
|
||||
- Packaged and Win32 app helpers exist to reflect changes in the list of indexed apps when applications are installed on the system while PT Run is executing.
|
||||
- Packaged applications trigger events when the package is being installed and uninstalled. PT Run listens to those events to index applications which are newly installed or to delete an app which no longer exists from the database.
|
||||
- No such events exist for Win32 applications. We therefore use FileSystem Watchers to monitor the locations that we index for newly created, deleted or renamed application files and update the indexed Win32 catalog accordingly.
|
||||
|
||||
### Additional Notes
|
||||
- Arguments can be provided to the program plugin by entering them after `--` (a double dash).
|
||||
14
doc/devdocs/modules/launcher/plugins/shell.md
Normal file
14
doc/devdocs/modules/launcher/plugins/shell.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Shell Plugin
|
||||
- Shell plugin emulates the Windows Run Prompt (Win+R).
|
||||
- Shell Plugin is one of the non-global plugins which has an action keyword set to `>`.
|
||||
|
||||

|
||||
|
||||
### Functionality
|
||||
- The Shell command expands environment variables, so `>%appdata%` works as expected.
|
||||
- On inheriting the Shell plugin from Wox, there are three different ways of executing a command, using the command prompt, powershell or the run prompt. To uphold the name of PT Run, the Shell plugin always executes commands as the Run prompt would.
|
||||
- The Shell plugin has a concept of history where the previously executed commands show up in the drop down list along with the number of times they have been executed.
|
||||
- The Run prompt has the folder plugin function where we can navigate to different locations and entering the path to a directory displays all the sub-directories. To prevent reimplementing this logic, the shell plugin references the folder plugin to implement this functionality.
|
||||
|
||||
### Score
|
||||
The Shell plugin results have a very high score of 5000. Hence, they are one of the first results in the list.
|
||||
19
doc/devdocs/modules/launcher/plugins/uri.md
Normal file
19
doc/devdocs/modules/launcher/plugins/uri.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# URI Plugin
|
||||
The URI Plugin, as the name suggests is used to directly run the URI that has been entered by the user as a query. This is done by parsing the entry and validating the URI, followed by executing it.
|
||||
|
||||

|
||||
|
||||
### [`URI Parser`](src/modules/launcher/Plugins/Microsoft.Plugin.Uri/UriHelper/ExtendedUriParser.cs)
|
||||
- The [`ExtendedUriParser.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Uri/UriHelper/ExtendedUriParser.cs) file tries to parse the user input and returns a `System.Uri` result by using the `UriBuilder`.
|
||||
- It also captures other cases which the UriBuilder does not handle such as when the input ends with a `:`, `.` or `:/`.
|
||||
|
||||
### [`URI Resolver`](src/modules/launcher/Plugins/Microsoft.Plugin.Uri/UriHelper/UriResolver.cs)
|
||||
- The [`UriResolver.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Uri/UriHelper/UriResolver.cs) file returns true for Valid hosts.
|
||||
- Currently there is no additional logic for filtering out invalid hosts and it always returns true for a valid Uri that was created by parsing the user query. It can be expanded in the future to filter out certain hosts.
|
||||
|
||||
### Default Browser Icon
|
||||
- The icon for each uri result is that of the default browser set by the user.
|
||||
- These details are obtained from the user registry and updated each time the theme of PT Run is changed.
|
||||
|
||||
### Score
|
||||
- All uri plugin results have a score of 0 which indicates that they would show up after each of the other plugins, other than the indexer plugin which also has a score of 0.
|
||||
18
doc/devdocs/modules/launcher/plugins/windowwalker.md
Normal file
18
doc/devdocs/modules/launcher/plugins/windowwalker.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Window Walker plugin
|
||||
The window walker plugin matches the user entered query with the open windows on the system.
|
||||
|
||||

|
||||
|
||||
### [`OpenWindows.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs)
|
||||
- The window walker plugin uses the `EnumWindows` function to enumerate all the open windows in the [`OpenWindows.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs) class.
|
||||
|
||||
|
||||
### [`SearchController.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/SearchController.cs)
|
||||
- The [`SearchController`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/SearchController.cs) encapsulates the functions needed to search and find matches.
|
||||
- It is responsible for updating the search text and performing a fuzzy search on all the open windows in an asynchronous manner.
|
||||
|
||||
### [`Window.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs)
|
||||
- The [`Window`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs) class represents a specific window and has functions to get the name of the process, the state of the window (whether it is visible or not), and the `SwitchTowindow` function which switches the desktop focus to the selected window. This action is performed when the user clicks on a window walker plugin result.
|
||||
|
||||
### Score
|
||||
The window walker plugin uses [`FuzzyMatching`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/FuzzyMatching.cs) to get the matching indices and calculates the score by creating a 2 dimensional array of the window and the query text.
|
||||
24
doc/devdocs/modules/launcher/project_structure.md
Normal file
24
doc/devdocs/modules/launcher/project_structure.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Project Structure
|
||||
## Overview
|
||||
`PowerToys Run` is divided across several projects to keep a logical separation between plugins and core functionality. The following sections provide a brief overview of each project.
|
||||
|
||||

|
||||
Fig 1. Project along with their dependencies in `PowerToys Run` ecosystem.
|
||||
|
||||
## Project Description
|
||||
#### [`PowerLauncher`](/src/modules/launcher/PowerLauncher)
|
||||
This is the startup project for the `PowerToys Run.` It is a WPF desktop application and follows the `Model-View-ViewModel (MVVM)` design pattern. Plugins play the role of `Model` and provide data to `ViewModel.`
|
||||
|
||||
#### [`PowerLauncher.Telemetry`](/src/modules/launcher/PowerLauncher.Telemetry)
|
||||
[`PowerLauncher.Telemetry`](/src/modules/launcher/PowerLauncher.Telemetry) is a .net core project that contains telemetry events generated by `PowerLauncher.` These events have been discussed in detail [here](/doc/devdocs/modules/launcher/telemetry.md).
|
||||
|
||||
#### [`Wox.Core`](/src/modules/launcher/Wox.Core)
|
||||
[`Wox.Core`](/src/modules/launcher/Wox.Core) is a .net core project that contains helper classes required by the `PowerLauncher` project. Two major functionalities encapsulated in this project are [`PluginManager`](/src/modules/launcher/Wox.Core/Plugin/PluginManager.cs) and [`Query Builder.`](/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs) [`PluginManager`](/src/modules/launcher/Wox.Core/Plugin/PluginManager.cs) provides an interface for managing C# plugins. [`Query Builder.`](/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs) decimate user-typed query string and creates a [`Query`](/src/modules/launcher/Wox.Plugin/Query.cs) object. [`Query`](/src/modules/launcher/Wox.Plugin/Query.cs) object contains the action keyword and cleaned query, which is then sent to all plugins.
|
||||
|
||||
#### [`Wox.Infrastructure`](/src/modules/launcher/Wox.Infrastructure)
|
||||
[`Wox.Infrastructure`](/src/modules/launcher/Wox.Infrastructure) is a .net core project that contains helper classes required for image manipulation and storage by the `PowerLauncher` project and the plugins. [`ImageLoader.cs`](/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs) class is used to load icons for `Win32` program. It also provides caching functionality to speed up image loading for frequently queried programs.
|
||||
|
||||
#### [`Wox.Plugin`](/src/modules/launcher/Wox.Plugin)
|
||||
[`Wox.Plugin`](/src/modules/launcher/Wox.Plugin) contains interfaces that facilitate communication between `PowerLauncher` and plugins. These interfaces have been discussed in detail [here](/doc/devdocs/modules/launcher/architecture.md#flow-of-data-between-viewmodels-and-pluginsmodel). It also contains a helper class for logging. [`Log.cs`](/src/modules/launcher/Wox.Plugin/Logger/Log.cs) provides an abstraction for logging error, information, and output to text files. These files are stored at `%userprofile%/appdata/local/microsoft/powertoys/powertoys run/Logs.`
|
||||
|
||||
|
||||
14
doc/devdocs/modules/launcher/readme.md
Normal file
14
doc/devdocs/modules/launcher/readme.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Table of Contents
|
||||
1. [Architecture](/doc/devdocs/modules/launcher/architecture.md)
|
||||
2. [Debugging](/doc/devdocs/modules/launcher/debugging.md)
|
||||
3. [Project Structure](/doc/devdocs/modules/launcher/project_structure.md)
|
||||
4. [Telemetry](/doc/devdocs/modules/launcher/telemetry.md)
|
||||
5. Plugins
|
||||
- [Overview](/doc/devdocs/modules/launcher/plugins/overview.md)
|
||||
- [Calculator](/doc/devdocs/modules/launcher/plugins/calculator.md)
|
||||
- [Folder](/doc/devdocs/modules/launcher/plugins/folder.md)
|
||||
- [Indexer](/doc/devdocs/modules/launcher/plugins/indexer.md)
|
||||
- [Program](/doc/devdocs/modules/launcher/plugins/program.md)
|
||||
- [Shell](/doc/devdocs/modules/launcher/plugins/shell.md)
|
||||
- [Uri](/doc/devdocs/modules/launcher/plugins/uri.md)
|
||||
- [Window Walker](/doc/devdocs/modules/launcher/plugins/windowwalker.md)
|
||||
14
doc/devdocs/modules/launcher/telemetry.md
Normal file
14
doc/devdocs/modules/launcher/telemetry.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Telemetry
|
||||
## Overview
|
||||
`PowerLauncher.Telemetry` project contains telemetry events generated by `PowerToys Run.` These event classes are derived from the [`EventBase`](/src/common/ManagedTelemetry/Telemetry/Events/EventBase.cs) class and [`IEvent`](/src/common/ManagedTelemetry/Telemetry/Events/IEvent.cs) class. [`IEvent`](/src/common/ManagedTelemetry/Telemetry/Events/IEvent.cs) class provides the lowest level abstraction, containing attributes such as privacy tags needed for every telemetry data. [`EventBase`](/src/common/ManagedTelemetry/Telemetry/Events/EventBase.cs) class provides a higher-level abstraction, having attributes common to all `PowerToys` telemetry events.
|
||||
|
||||
## Events
|
||||
The following events are generated by `PowerLauncher`:
|
||||
1. [`LauncherBootEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherBootEvent.cs): This event captures the time taken by `PowerLauncher` to load all plugins, perform cold start, and setup UI environment.
|
||||
2. [`LauncherHideEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherHideEvent.cs): This event is generated when the `PowerLauncher` window is hidden.
|
||||
3. [`LauncherColdStateHotkeyEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherColdStateHotkeyEvent.cs): This event logs time from the first Alt+Space press till the `PowerLauncher` window is visible.
|
||||
4. [`LauncherFirstDeleteEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherFirstDeleteEvent.cs): This event is generated after the first delete is pressed after `PowerLauncher` is visible.
|
||||
5. [`LauncherQueryEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherQueryEvent.cs): This event is generated for every query that is typed in the searchbox. It logs query time, number of results, and query length.
|
||||
6. [`LauncherResultActionEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherResultActionEvent.cs): This event is generated when a context menu action is triggered.
|
||||
7. [`LauncherShowEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherShowEvent.cs): This event is generated when the `PowerLauncher` window is shown.
|
||||
8. [`LauncherWarmStateHotkeyEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherWarmStateHotkeyEvent.cs): This event logs time from the Alt+Space press until the PT Run window is visible.
|
||||
26
doc/devdocs/modules/powerrename.md
Normal file
26
doc/devdocs/modules/powerrename.md
Normal file
@@ -0,0 +1,26 @@
|
||||
#### [`dllmain.cpp`](/src/modules/powerrename/dll/dllmain.cpp)
|
||||
TODO
|
||||
|
||||
#### [`PowerRenameExt.cpp`](/src/modules/powerrename/dll/PowerRenameExt.cpp)
|
||||
TODO
|
||||
|
||||
#### [`Helpers.cpp`](/src/modules/powerrename/lib/Helpers.cpp)
|
||||
TODO
|
||||
|
||||
#### [`PowerRenameItem.cpp`](/src/modules/powerrename/lib/PowerRenameItem.cpp)
|
||||
TODO
|
||||
|
||||
#### [`PowerRenameManager.cpp`](/src/modules/powerrename/lib/PowerRenameManager.cpp)
|
||||
TODO
|
||||
|
||||
#### [`PowerRenameRegEx.cpp`](/src/modules/powerrename/lib/PowerRenameRegEx.cpp)
|
||||
TODO
|
||||
|
||||
#### [`Settings.cpp`](/src/modules/powerrename/lib/Settings.cpp)
|
||||
TODO
|
||||
|
||||
#### [`trace.cpp`](/src/modules/powerrename/lib/trace.cpp)
|
||||
TODO
|
||||
|
||||
#### [`PowerRenameUI.cpp`](/src/modules/powerrename/ui/PowerRenameUI.cpp)
|
||||
TODO
|
||||
17
doc/devdocs/modules/shortcut_guide.md
Normal file
17
doc/devdocs/modules/shortcut_guide.md
Normal file
@@ -0,0 +1,17 @@
|
||||
#### [`dllmain.cpp`](/src/modules/shortcut_guide/dllmain.cpp)
|
||||
Contains DLL boilerplate code.
|
||||
|
||||
#### [`shortcut_guide.cpp`](/src/modules/shortcut_guide/shortcut_guide.cpp)
|
||||
Contains the module interface code. It initializes the settings values and the keyboard event listener.
|
||||
|
||||
#### [`overlay_window.cpp`](/src/modules/shortcut_guide/overlay_window.cpp)
|
||||
Contains the code for loading the SVGs, creating and rendering of the overlay window.
|
||||
|
||||
#### [`keyboard_state.cpp`](/src/modules/shortcut_guide/keyboard_state.cpp)
|
||||
Contains helper methods for checking the current state of the keyboard.
|
||||
|
||||
#### [`target_state.cpp`](/src/modules/shortcut_guide/target_state.cpp)
|
||||
State machine that handles the keyboard events. It’s responsible for deciding when to show the overlay, when to suppress the Start menu (if the overlay is displayed long enough), etc.
|
||||
|
||||
#### [`trace.cpp`](/src/modules/shortcut_guide/trace.cpp)
|
||||
Contains code for telemetry.
|
||||
182
doc/devdocs/readme.md
Normal file
182
doc/devdocs/readme.md
Normal file
@@ -0,0 +1,182 @@
|
||||
# Dev Documentation
|
||||
|
||||
## Rules
|
||||
|
||||
- **Follow the pattern of what you already see in the code.**
|
||||
- [Coding style](style.md).
|
||||
- Try to package new ideas/components into libraries that have nicely defined interfaces.
|
||||
- Package new ideas into classes or refactor existing ideas into a class as you extend.
|
||||
- When adding new classes/methods/changing existing code: add new unit tests or update the existing tests.
|
||||
|
||||
## Github Workflow
|
||||
|
||||
- Before starting to work on a fix/feature, make sure there is an open issue to track the work.
|
||||
- Add the `In progress` label to the issue, if not already present also add a `Cost-Small/Medium/Large` estimate and make sure all appropriate labels are set.
|
||||
- If you are a community contributor, you will not be able to add labels to the issue, in that case just add a comment saying that you started to work on the issue and try to give an estimate for the delivery date.
|
||||
- If the work item has a medium/large cost, using the markdown task list, list each sub item and update the list with a check mark after completing each sub item.
|
||||
- When opening a PR, follow the PR template.
|
||||
- When the PR is approved, let the owner of the PR merge it. For community contributions the reviewer that approved the PR can also merge it.
|
||||
- Use the `Squash and merge` option to merge a PR, if you don't want to squash it because there are logically different commits, use `Rebase and merge`.
|
||||
- We don't close issues automatically when referenced in a PR, so after the PR is merged:
|
||||
- mark the issue(s), that the PR solved, with the `Resolution-Fix-Committed` label, remove the `In progress` label and if the issue is assigned to a project, move the item to the `Done` status.
|
||||
- don't close the issue if it's a bug in the current released version since users tend to not search for closed issues, we will close the resolved issues when a new version is released.
|
||||
- if it's not a code fix that effects the end user, the issue can be closed (for example a fix in the build or a code refactoring and so on).
|
||||
|
||||
## Repository Overview
|
||||
|
||||
General project organization:
|
||||
|
||||
### The [`doc`](/doc) folder
|
||||
|
||||
Documentation for the project.
|
||||
|
||||
### The [`Wiki`](https://github.com/microsoft/PowerToys/wiki)
|
||||
|
||||
The Wiki contains the current specs for the project.
|
||||
|
||||
### The [`installer`](/installer) folder
|
||||
|
||||
Contains the source code of the PowerToys installer.
|
||||
|
||||
### The [`src`](/src) folder
|
||||
|
||||
Contains the source code of the PowerToys runner and of all of the PowerToys modules. **This is where most of the magic happens.**
|
||||
|
||||
### The [`tools`](/tools) folder
|
||||
|
||||
Various tools used by PowerToys. Includes the Visual Studio 2019 project template for new PowerToys.
|
||||
|
||||
## Compiling PowerToys
|
||||
|
||||
### Prerequisites for Compiling PowerToys
|
||||
|
||||
1. Windows 10 April 2018 Update (version 1803) or newer
|
||||
2. Visual Studio Community/Professional/Enterprise 2019
|
||||
3. Run the command below in cmd/terminal to install all the workloads and components for VS.
|
||||
|
||||
```shell
|
||||
cd "%ProgramFiles(x86)%\Microsoft Visual Studio\2019"
|
||||
SET targetFolder="\"
|
||||
IF EXIST Preview\NUL (SET targetFolder=Preview)
|
||||
IF EXIST Enterprise\NUL (SET targetFolder=Enterprise)
|
||||
IF EXIST Professional\NUL (SET targetFolder=Professional)
|
||||
IF EXIST Community\NUL (SET targetFolder=Community)
|
||||
|
||||
ECHO %targetFolder%
|
||||
|
||||
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vs_installer.exe" ^
|
||||
modify --installpath "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\%targetFolder%" ^
|
||||
--add Microsoft.VisualStudio.Workload.NativeDesktop ^
|
||||
--add Microsoft.VisualStudio.Workload.ManagedDesktop ^
|
||||
--add Microsoft.VisualStudio.Workload.Universal ^
|
||||
--add Microsoft.VisualStudio.Component.Windows10SDK.17134 ^
|
||||
--add Microsoft.VisualStudio.ComponentGroup.UWP.VC ^
|
||||
--add Microsoft.VisualStudio.Component.VC.Runtimes.x86.x64.Spectre ^
|
||||
--add Microsoft.VisualStudio.Component.VC.ATL.Spectre
|
||||
```
|
||||
|
||||
### Compiling Source Code
|
||||
|
||||
- Open `powertoys.sln` in Visual Studio, in the `Solutions Configuration` drop-down menu select `Release` or `Debug`, from the `Build` menu choose `Build Solution`.
|
||||
- The PowerToys binaries will be in your repo under `x64\Release`.
|
||||
- If you want to copy the `PowerToys.exe` binary to a different location, you'll also need to copy the `modules` and the `svgs` folders.
|
||||
|
||||
## Building the Installers
|
||||
|
||||
Our installer is two parts, an EXE and an MSI. The EXE contains the MSI and handles more complex install logic.
|
||||
- The EXE installs all prerequisites and installs PowerToys via the MSI. Also has additional features, such as silent installation flags
|
||||
- The MSI installs PowerToys.
|
||||
|
||||
### Prerequisites Building the Installer (.MSI)
|
||||
|
||||
1. Install the [WiX Toolset Visual Studio 2019 Extension](https://marketplace.visualstudio.com/items?itemName=RobMensching.WiXToolset).
|
||||
2. Install the [WiX Toolset build tools](https://wixtoolset.org/releases/).
|
||||
|
||||
### Compiling Installer (.MSI)
|
||||
|
||||
- From the `installer` folder open `PowerToysSetup.sln` in Visual Studio, in the `Solutions Configuration` drop-down menu select `Release`, from the `Build` menu choose `Build Solution`.
|
||||
- The resulting `PowerToysSetup.msi` installer will be available in the `installer\PowerToysSetup\x64\Release\` folder.
|
||||
|
||||
### Compiling Bootstraper Installer (.EXE)
|
||||
|
||||
- MSI Installer needs to be built in release mode
|
||||
- Build `PowerToysBootstrapper` solution (`installer\PowerToysBootstrapper\`)
|
||||
|
||||
#### Supported arguments for EXE installer:
|
||||
|
||||
Head over to the wiki to get the [full list of supported installer arguments][installerArgWiki].
|
||||
|
||||
## Debugging
|
||||
|
||||
The following configuration issue only applies if the user is a member of the Administrators group.
|
||||
|
||||
Some PowerToys modules require being run with the highest permission level if the current user is a member of the Administrators group. The highest permission level is required to be able to perform some actions when an elevated application (e.g. Task Manager) is in the foreground or is the target of an action. Without elevated privileges some PowerToys modules will still work but with some limitations:
|
||||
|
||||
- The `FancyZones` module will be not be able to move an elevated window to a zone.
|
||||
- The `Shortcut Guide` module will not appear if the foreground window belongs to an elevated application.
|
||||
|
||||
To run and debug PowerToys from Visual Studio when the user is a member of the Administrators group, Visual Studio has to be started with elevated privileges. If you want to avoid running Visual Studio with elevated privileges and don't mind the limitations described above, you can do the following: open the `runner` project properties and navigate to the `Linker -> Manifest File` settings, edit the `UAC Execution Level` property and change it from `highestAvailable (level='highestAvailable')` to `asInvoker (/level='asInvoker')`, save the changes.
|
||||
|
||||
## How to create new PowerToys
|
||||
|
||||
See the instructions on [how to install the PowerToys Module project template](/tools/project_template). <br />
|
||||
Specifications for the [PowerToys settings API](/doc/devdocs/settings.md).
|
||||
|
||||
## Implementation details
|
||||
|
||||
### [`Runner`](runner.md)
|
||||
|
||||
The PowerToys Runner contains the project for the PowerToys.exe executable.
|
||||
It's responsible for:
|
||||
|
||||
- Loading the individual PowerToys modules.
|
||||
- Passing registered events to the PowerToys.
|
||||
- Showing a system tray icon to manage the PowerToys.
|
||||
- Bridging between the PowerToys modules and the Settings editor.
|
||||
|
||||

|
||||
|
||||
### [`Interface`](modules/interface.md)
|
||||
|
||||
Definition of the interface used by the [`runner`](/src/runner) to manage the PowerToys. All PowerToys must implement this interface.
|
||||
|
||||
### [`Common`](common.md)
|
||||
|
||||
The common lib, as the name suggests, contains code shared by multiple PowerToys components and modules, e.g. [json parsing](/src/common/json.h) and [IPC primitives](/src/common/two_way_pipe_message_ipc.h).
|
||||
|
||||
### [`Settings`](settings.md)
|
||||
|
||||
WebView project for editing the PowerToys settings.
|
||||
|
||||
The html portion of the project that is shown in the WebView is contained in [`settings-html`](/src/settings/settings-html).
|
||||
Instructions on how build a new version and update this project are in the [Web project for the Settings UI](./settings-web.md).
|
||||
|
||||
While developing, it's possible to connect the WebView to the development server running in localhost by setting the `_DEBUG_WITH_LOCALHOST` flag to `1` and following the instructions near it in `./main.cpp`.
|
||||
|
||||
### [`Settings-web`](settings-web.md)
|
||||
This project generates the web UI shown in the [PowerToys Settings](/src/editor).
|
||||
It's a `ReactJS` project created using [Fluent UI](https://developer.microsoft.com/en-us/fluentui#/).
|
||||
|
||||
## Current modules
|
||||
### [`FancyZones`](modules/fancyzones.md)
|
||||
The FancyZones PowerToy that allows users to create custom zones on the screen, to which the windows will snap when moved.
|
||||
|
||||
### [`PowerRename`](modules/powerrename.md)
|
||||
PowerRename is a Windows Shell Context Menu Extension for advanced bulk renaming using simple search and replace or more powerful regular expression matching.
|
||||
|
||||
### [`Shortcut Guide`](modules/shortcut_guide.md)
|
||||
The Windows Shortcut Guide, displayed when the WinKey is held for some time.
|
||||
|
||||
#### Options
|
||||
|
||||
This module has a setting to serve as an example for each of the currently implemented settings property:
|
||||
|
||||
- BoolToggle property
|
||||
- IntSpinner property
|
||||
- String property
|
||||
- ColorPicker property
|
||||
- CustomAction property
|
||||
|
||||

|
||||
|
||||
[installerArgWiki]: https://github.com/microsoft/PowerToys/wiki/Installer-arguments-for-exe
|
||||
3
doc/devdocs/run-as-admin-detection.md
Normal file
3
doc/devdocs/run-as-admin-detection.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# This file has been moved
|
||||
|
||||
[PowerToys and running as Administrator](https://aka.ms/powertoysDetectedElevatedHelp)
|
||||
36
doc/devdocs/runner.md
Normal file
36
doc/devdocs/runner.md
Normal file
@@ -0,0 +1,36 @@
|
||||
#### [`main.cpp`](/src/runner/main.cpp)
|
||||
Contains the executable starting point, initialization code and the list of known PowerToys. All singletones are also initialized here at the start. Loads all the powertoys by scanning the `./modules` folder and `enable()`s those marked as enabled in `%LOCALAPPDATA%\Microsoft\PowerToys\settings.json` config. Then it runs [a message loop](https://docs.microsoft.com/en-us/windows/win32/winmsg/using-messages-and-message-queues) for the tray UI. Note that this message loop also [handles lowlevel_keyboard_hook events](https://github.com/microsoft/PowerToys/blob/1760af50c8803588cb575167baae0439af38a9c1/src/runner/lowlevel_keyboard_event.cpp#L24).
|
||||
|
||||
#### [`general_settings.cpp`](./general_settings.cpp)
|
||||
#### [`powertoy_module.h`](/src/runner/powertoy_module.h) and [`powertoy_module.cpp`](/src/runner/powertoy_module.cpp)
|
||||
Contains code for initializing and managing the PowerToy modules. `PowertoyModule` is a RAII-style holder for the `PowertoyModuleIface` pointer, which we got by [invoking module DLL's `powertoy_create` function](https://github.com/microsoft/PowerToys/blob/1760af50c8803588cb575167baae0439af38a9c1/src/runner/powertoy_module.cpp#L13-L24).
|
||||
|
||||
#### [`powertoys_events.cpp`](/src/runner/powertoys_events.cpp)
|
||||
Contains code that handles the various events listeners, and forwards those events to the PowerToys modules. You can learn more about the current event architecture [here](/doc/devdocs/shared-hooks.md).
|
||||
|
||||
#### [`lowlevel_keyboard_event.cpp`](/src/runner/lowlevel_keyboard_event.cpp)
|
||||
Contains code for registering the low level keyboard event hook that listens for keyboard events. Please note that `signal_event` is called from the main thread for this event.
|
||||
|
||||
#### [`win_hook_event.cpp`](/src/runner/win_hook_event.cpp)
|
||||
Contains code for registering a Windows event hook through `SetWinEventHook`, that listens for various events raised when a window is interacted with. Please note, that `signal_event` is called from a separate `dispatch_thread_proc` worker thread, so you must provide thread-safety for your `signal_event` if you intend to receive it. This is a subject to change.
|
||||
|
||||
#### [`tray_icon.cpp`](/src/runner/tray_icon.cpp)
|
||||
Contains code for managing the PowerToys tray icon and its menu commands. Note that `dispatch_run_on_main_ui_thread` is used to
|
||||
transfer received json message from the [Settings window](/doc/devdocs/settings.md) to the main thread, since we're communicating with it from [a dedicated thread](https://github.com/microsoft/PowerToys/blob/7357e40d3f54de51176efe54fda6d57028837b8c/src/runner/settings_window.cpp#L267-L271).
|
||||
#### [`settings_window.cpp`](/src/runner/settings_window.cpp)
|
||||
Contains code for starting the PowerToys settings window and communicating with it. Settings window is a separate process, so we're using [Windows pipes](https://docs.microsoft.com/en-us/windows/win32/ipc/pipes) as a transport for json messages.
|
||||
|
||||
#### [`general_settings.cpp`](/src/runner/general_settings.cpp)
|
||||
Contains code for loading, saving and applying the general settings.
|
||||
|
||||
#### [`auto_start_helper.cpp`](/src/runner/auto_start_helper.cpp)
|
||||
Contains helper code for registering and unregistering PowerToys to run when the user logs in.
|
||||
|
||||
#### [`unhandled_exception_handler.cpp`](/src/runner/unhandled_exception_handler.cpp)
|
||||
Contains helper code to get stack traces in builds. Can be used by adding a call to `init_global_error_handlers` in [`WinMain`](./main.cpp).
|
||||
|
||||
#### [`trace.cpp`](/src/runner/trace.cpp)
|
||||
Contains code for telemetry.
|
||||
|
||||
#### [`svgs`](/src/runner/svgs/)
|
||||
Contains the SVG assets used by the PowerToys modules.
|
||||
597
doc/devdocs/settings-reference.md
Normal file
597
doc/devdocs/settings-reference.md
Normal file
@@ -0,0 +1,597 @@
|
||||
# Settings
|
||||
|
||||
While the module interface passes the settings and values thorough a JSON string, **use our helper functions**. In future we might move to a different implementation. All current modules use:
|
||||
* `load_module_settings` to load the settings from the disk.
|
||||
* `PowerToySettings::Settings` class to define module properties and the settings screen.
|
||||
* `PowerToySettings::PowerToyValues` class to parse the JSON passed by the runner.
|
||||
* `save_module_settings` to store the settings on the disk.
|
||||
|
||||
Most functions provide two overloads - one that accepts UINT with a resource ID and one that accepts strings. **Put all strings in the resource file and use the resource ID overload.**
|
||||
|
||||
|
||||
The following documents internal workings of the settings system.
|
||||
|
||||
## Overview
|
||||
|
||||
PowerToys runner provides a generic way for modules to define their settings.
|
||||
|
||||
Each module on startup is responsible for loading its own settings and initializing accordingly. When the user wants to edit settings, the runner will call [`get_config()`](modules/interface.md#get_config) module method. The module must provide a JSON which includes the module name, description but also what settings options are provided.
|
||||
|
||||
When settings from all modules are collected, a separate [settings editor app](/src/settings) is spawned. The editor wraps [an React app](/src/settings-web) and handles the communication with the runner.
|
||||
|
||||
When loaded, the React app receives the JSON passed by the runner. When user saves the settings, the editor passes the new settings values as JSON string to the runner. Runner in turn will call [`set_config()`](modules/interface.md#set_config) for all modules with appropriate JSON. When user initiates a custom action (like the Zone Editor in FancyZones), the runner will call [`call_custom_action()`](modules/interface.md#call_custom_action) providing the action name in a JSON.
|
||||
|
||||
There are C++ helper functions in [/src/common/settings_objects.h](/src/common/settings_objects.h) and [/src/common/settings_helpers.h](/src/common/settings_helpers.h). Those include classes for creating the settings options JSON and ones for parsing the incoming settings JSON.
|
||||
|
||||
### Module settings
|
||||
The value returned by the [`get_config()`](modules/interface.md#get_config) call should provide a JSON object with following fields:
|
||||
* `name` - The name of the PowerToy. Used on the nav panel on the left.
|
||||
* `version` - The settings version. Needs to be set to `"1.0"`.
|
||||
* `description` - Description of the PowerToy module.
|
||||
* `overview_link`, `video_link` - Optional links to the documentation and video preview of the PowerToy module.
|
||||
* `icon_key` - Name of the icon of the PowerToy. The SVGs for the icons are located in [/src/settings-web/src/svg](/src/settings-web/src/svg). They also need to be added in [/settings-web/src/setup_icons.tsx](/settings-web/src/setup_icons.tsx).
|
||||
* `properties` - Optional object that contains the definition of the settings screen.
|
||||
|
||||
The `properties` JSON object defines what settings controls are available to the user. Each key defines one control. The controls have some common properties:
|
||||
* The key in the `properties` which identifies the control.
|
||||
* `editor_type` - Defines the type of the control. Those are listed further.
|
||||
* `order` - Defines the order of the elements on the settings screen.
|
||||
|
||||
Each `editor_type` has its own set of properties.
|
||||
|
||||
Example module JSON (taken from Shortcut Guide):
|
||||
```json
|
||||
{
|
||||
"name": "Shortcut Guide",
|
||||
"version": "1.0",
|
||||
"description": "Shows a help overlay with Windows shortcuts when the Windows key is pressed.",
|
||||
"overview_link": "https://github.com/.../README.md",
|
||||
"icon_key": "pt-shortcut-guide",
|
||||
"properties": {
|
||||
"press_time": {
|
||||
"editor_type": "int_spinner",
|
||||
"order": 1,
|
||||
"display_name": "How long to press the Windows key before showing the Shortcut Guide (ms)",
|
||||
"value": 900,
|
||||
"min": 100,
|
||||
"max": 10000,
|
||||
"step": 100
|
||||
},
|
||||
"overlay_opacity": {
|
||||
"editor_type": "int_spinner",
|
||||
"order": 2,
|
||||
"display_name": "Opacity of the Shortcut Guide's overlay background (%)",
|
||||
"value": 90,
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"step": 1
|
||||
},
|
||||
"theme":{
|
||||
"editor_type": "choice_group",
|
||||
"order": 3,
|
||||
"display_name": "Choose Shortcut Guide overlay color",
|
||||
"value": "system",
|
||||
"options": [ {"key": "system", "text": "System default app mode"},
|
||||
{"key": "light", "text": "Light"},
|
||||
{"key": "dark", "text": "Dark"} ]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
produces this settings screen:
|
||||
|
||||

|
||||
|
||||
### Helper methods
|
||||
|
||||
PowerToys provides [a helper class](/src/common/json.h) to parse and generate JSON strings.
|
||||
|
||||
In [`settings_helpers.h`](/src/common/settings_helpers.h) there are two helper functions: `load_module_settings(powertoy_name)` and `save_general_settings(settings)` for loading and saving the module configuration.
|
||||
|
||||
In [`settings_objects.h`](/src/common/settings_objects.h) there are some helper classes:
|
||||
* `Settings` - for generating JSON with module settings definition.
|
||||
* `PowerToyValues` - for parsing JSON with settings - either loaded from file or from the settings editor.
|
||||
* `CustomActionObject` and `HotkeyObject` - for parsing custom actions and hotkey input specific JSON.
|
||||
|
||||
### General settings
|
||||
General settings control the PowerToys runner and decide which modules are enabled and which are not. The general settings screen is special - while modules provide the definition of the settings controls, the available settings on the general screen are hardcoded.
|
||||
|
||||
General settings has following properties:
|
||||
* `enabled` - Enabled/disabled status of each PowerToy.
|
||||
* `startup` - Should PowerToys start at user logon.
|
||||
* `theme` - Settings editor theme - `light`, `dark` or `system`.
|
||||
* `system_theme` - Current Windows theme - `light` or `dark`.
|
||||
* `powertoys_version` - The version of the PowerToys.
|
||||
|
||||
This JSON:
|
||||
```json
|
||||
{
|
||||
"enabled": {
|
||||
"FancyZones": true,
|
||||
"PowerRename": true,
|
||||
"Shortcut Guide": true
|
||||
},
|
||||
"startup": true,
|
||||
"theme": "light",
|
||||
"system_theme": "dark",
|
||||
"powertoys_version": "0.14.2.0"
|
||||
}
|
||||
```
|
||||
Produces this general settings screen:
|
||||
|
||||

|
||||
|
||||
## Putting it all together
|
||||
The runner combines general settings and each module settings into a single JSON that is passed to the settings editor. Example combined settings look like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"general": {
|
||||
"enabled": {
|
||||
"FancyZones": true,
|
||||
"PowerRename": true,
|
||||
"Shortcut Guide": true
|
||||
},
|
||||
"startup": true,
|
||||
"theme": "light",
|
||||
"system_theme": "dark",
|
||||
"powertoys_version": "0.14.2.0"
|
||||
},
|
||||
"powertoys": {
|
||||
"FancyZones": { ... },
|
||||
"PowerRename": { ... },
|
||||
"Shortcut Guide":{
|
||||
"name": "Shortcut Guide",
|
||||
"version": "1.0",
|
||||
"description": "Shows a help overlay with Windows shortcuts when the Windows key is pressed.",
|
||||
"overview_link": "https://github.com/.../README.md",
|
||||
"icon_key": "pt-shortcut-guide",
|
||||
"properties": { ... }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## C++ helpers
|
||||
While you can generate and parse JSON yourself there are helper methods provided.
|
||||
|
||||
### Loading settings
|
||||
When a PowerToy module is created, it should load its configuration. This can be done by calling
|
||||
```c++
|
||||
json::JsonObject PTSettingsHelper::load_module_settings(std::wstring_view powertoy_name);
|
||||
```
|
||||
declared in [`settings_helpers.h`](/src/common/settings_helpers.h). The function will return an `json::JsonObject` object containing the module settings.
|
||||
|
||||
Another option is using [`PowerToySettings::PowerToyValues`](/src/common/settings_objects.h#L67) class. A static method
|
||||
```c++
|
||||
PowerToyValues PowerToyValues::load_from_settings_file(std::wstring_view powertoy_name);
|
||||
```
|
||||
will load and parse the settings. You can also use
|
||||
```c++
|
||||
PowerToyValues PowerToyValues::from_json_string(std::wstring_view json);
|
||||
```
|
||||
to parse JSON string - for example when implementing [`set_config()`](modules/interface.md#set_config). The returned `PowerToyValues` object has helper methods that return `std::optional` with values, for example:
|
||||
```c++
|
||||
auto settings = PowerToyValues::load_from_settings_file(L"some_powertoy");
|
||||
std::optional<std::wstring> str_prop = settings.get_string_value(L"some_string_property");
|
||||
auto int_prop = settings.get_int_value(L"some_int_property");
|
||||
```
|
||||
|
||||
### Generating settings screen
|
||||
The [`PowerToySettings::Settings`](/src/common/settings_objects.h) can be used to generate settings:
|
||||
```c++
|
||||
// Need to get strings from the resource file.
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
|
||||
auto hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
||||
PowerToysSettings::Settings settings(hinstance, L"example_powertoy");
|
||||
settings.set_description(L"Example powertoy.");
|
||||
settings.set_overview_link(L"https://example.com");
|
||||
settings.set_icon_key(L"pt-example");
|
||||
settings.add_string(L"string_val", L"Example string label", L"example value");
|
||||
settings.add_int_spinner(L"int_val", L"Example int label", 0, 0, 100, 10);
|
||||
```
|
||||
You can then use `std::wstring serialize()` or `bool serialize_to_buffer(wchar_t* buffer, int* buffer_size)` methods to generate output JSON string.
|
||||
|
||||
### Saving settings
|
||||
Use
|
||||
```c++
|
||||
void PTSettingsHelper::save_module_settings(std::wstring_view powertoy_name, json::JsonObject& settings);
|
||||
```
|
||||
declared in [`settings_helpers.h`](/src/common/settings_helpers.h).
|
||||
|
||||
## Module settings elements
|
||||
|
||||
### Bool toggle
|
||||
```c++
|
||||
add_bool_toggle(name, description, value)
|
||||
```
|
||||
A simple on-off toggle. Parameters:
|
||||
* `name` - Key for the element in the JSON.
|
||||
* `description` - String or resource ID of the text displayed to the user.
|
||||
* `value` - Initial state of the toggle (`true` - on, `false` - off).
|
||||
|
||||
This C++:
|
||||
```c++
|
||||
settings.add_bool_toggle(L"bool_name", L"description", true);
|
||||
```
|
||||
produces this settings element:
|
||||
|
||||

|
||||
|
||||
and this generated JSON:
|
||||
```json
|
||||
{
|
||||
"properties": {
|
||||
"bool_name": {
|
||||
"editor_type": "bool_toggle",
|
||||
"order": autoincremented_number,
|
||||
"display_name": "description",
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The toggle value is stored as bool:
|
||||
```c++
|
||||
std::optional<bool> bool_value = settings.get_bool_value(L"bool_name");
|
||||
```
|
||||
|
||||
### Int Spinner
|
||||
```c++
|
||||
add_int_spinner(name, description, value, min, max, step)
|
||||
```
|
||||
Numeric input with dials to increment and decrement the value. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - String or resource ID of the text displayed to the user.
|
||||
* `value` - Initial control value.
|
||||
* `min`, `max` - Minimum and maximum values for the input. User cannot use dials to move beyond those values, if a value out of range is inserted using the keyboard, it will get clamped to the allowed range.
|
||||
* `step` - How much the dials change the value.
|
||||
|
||||
This C++:
|
||||
```c++
|
||||
settings.add_int_spinner(L"int_spinner_name", L"description", 50, -100, 100, 10);
|
||||
```
|
||||
produces this settings element:
|
||||
|
||||

|
||||
|
||||
and this generated JSON:
|
||||
```json
|
||||
{
|
||||
"properties": {
|
||||
"int_spinner_name": {
|
||||
"editor_type": "int_spinner",
|
||||
"order": autoincremented_number,
|
||||
"display_name": "description",
|
||||
"value": 50,
|
||||
"min": -100,
|
||||
"max": 100,
|
||||
"step": 10
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The spinner value is stored as int:
|
||||
```c++
|
||||
std::optional<int> int_value = settings.get_int_value(L"int_spinner_name");
|
||||
```
|
||||
|
||||
### String
|
||||
```c++
|
||||
add_string(name, description, value)
|
||||
```
|
||||
Single line text input. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - String or resource ID of the text displayed to the user.
|
||||
* `value` - Default value for the input.
|
||||
|
||||
This C++:
|
||||
```c++
|
||||
settings.add_string(L"string_name", L"description", L"value");
|
||||
```
|
||||
produces this settings element:
|
||||
|
||||

|
||||
|
||||
and this generated JSON:
|
||||
```json
|
||||
{
|
||||
"properties": {
|
||||
"string_name": {
|
||||
"editor_type": "string_text",
|
||||
"order": autoincremented_number,
|
||||
"display_name": "description",
|
||||
"value": "value"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The input value is stored as `std::wstring`:
|
||||
```c++
|
||||
std::optional<std::wstring> string_value = settings.get_string_value(L"string_name");
|
||||
```
|
||||
|
||||
### Multiline string
|
||||
```c++
|
||||
add_multiline_string(name, description, value)
|
||||
```
|
||||
Multiline text input. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - String or resource ID of the text displayed to the user.
|
||||
* `value` - Default value for the input. Can have multiple lines.
|
||||
|
||||
This C++:
|
||||
```c++
|
||||
settings.add_multiline_string(L"multiline_name", L"description", L"multiline1\nmultiline2");
|
||||
```
|
||||
produces this settings element:
|
||||
|
||||

|
||||
|
||||
and this generated JSON:
|
||||
```json
|
||||
{
|
||||
"properties": {
|
||||
"multiline_name": {
|
||||
"editor_type": "string_text",
|
||||
"multiline": true,
|
||||
"order": autoincremented_number,
|
||||
"display_name": "description",
|
||||
"value": "multiline1\nmultiline2"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The input value is stored as string:
|
||||
```c++
|
||||
std::optional<std::wstring> value = settings.get_string_value(L"multiline_name");
|
||||
```
|
||||
|
||||
### Color picker
|
||||
```c++
|
||||
add_color_picker(name, description, value)
|
||||
```
|
||||
|
||||
Allows user to pick a color. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - String or resource ID of the text displayed to the user.
|
||||
* `value` - Initial color, as a string in `"#RRGGBB"` format.
|
||||
|
||||
This C++:
|
||||
```c++
|
||||
settings.add_color_picker(L"colorpicker_name", L"description", L"#102040");
|
||||
```
|
||||
produces this settings element:
|
||||
|
||||

|
||||
|
||||
and this generated JSON:
|
||||
```json
|
||||
{
|
||||
"properties": {
|
||||
"colorpicker_name": {
|
||||
"editor_type": "color_picker",
|
||||
"order": autoincremented_number,
|
||||
"display_name": "description",
|
||||
"value": "#102040"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The color picker value is stored as `std::wstring`:
|
||||
```c++
|
||||
std::optional<std::wstring> value = settings.get_string_value(L"colorpicker_name");
|
||||
```
|
||||
|
||||
### Hotkey
|
||||
```c++
|
||||
settings.add_hotkey(name, description, hotkey)
|
||||
```
|
||||
Input for capturing hotkeys. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - String or resource ID of the text displayed to the user.
|
||||
* `hotkey` - Instance of `PowerToysSettings::HotkeyObject` class.
|
||||
|
||||
You can create `PowerToysSettings::HotkeyObject` object either by using helper `from_settings` static method or by providing JSON object to `from_json` static method:
|
||||
|
||||
The `PowerToysSettings::HotkeyObject::from_settings` take following parameters:
|
||||
* `win_pressed` - Is the WinKey pressed.
|
||||
* `ctrl_pressed` - Is the Ctrl key pressed.
|
||||
* `alt_pressed` - Is the Alt key pressed.
|
||||
* `shift_pressed` - Is the Shift key pressed.
|
||||
* `vk_code` - The [virtual key-code](https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes) of the key.
|
||||
|
||||
The displayed key is deduced from the `vk_code` using the users keyboard layout and language settings.
|
||||
|
||||
Similar parameters can be passed using the `from_json` static method:
|
||||
```c++
|
||||
json::JsonObject json;
|
||||
json.SetNamedValue(L"win", json::value(win_pressed));
|
||||
json.SetNamedValue(L"ctrl", json::value(ctrl_pressed));
|
||||
json.SetNamedValue(L"alt", json::value(alt_pressed));
|
||||
json.SetNamedValue(L"shift", json::value(shift_pressed));
|
||||
json.SetNamedValue(L"code", json::value(vk_code));
|
||||
json.SetNamedValue(L"key", json::value(L"string with key name"));
|
||||
auto hotkey = PowerToysSettings::HotkeyObject::from_json(json);
|
||||
```
|
||||
|
||||
|
||||
This C++:
|
||||
```c++
|
||||
settings.add_hotkey(L"hotkey_name",
|
||||
L"description",
|
||||
PowerToysSettings::HotkeyObject::from_settings(true, true, true, true, VK_F5));
|
||||
```
|
||||
produces this settings element:
|
||||
|
||||

|
||||
|
||||
and this generated JSON (`114` is the value of `VK_F5`):
|
||||
```json
|
||||
{
|
||||
"properties": {
|
||||
"hotkey_name": {
|
||||
"editor_type": "hotkey",
|
||||
"order": autoincremented_number,
|
||||
"display_name": "description",
|
||||
"value": {
|
||||
"win": true,
|
||||
"ctrl": true,
|
||||
"alt": true,
|
||||
"shift": true,
|
||||
"code": 114,
|
||||
"key": "F5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The hotkey value is returned as JSON, with the same format as `from_json` method uses. You can use `HotkeyObject` class to parse this JSON, since it offers some helper methods. A typical example of registering a hotkey:
|
||||
```c++
|
||||
std::optional<json::JsonObject> value = settings.get_json(L"hotkey_name");
|
||||
if (value) {
|
||||
auto hotkey = PowerToysSettings::HotkeyObject::from_json(*value);
|
||||
RegisterHotKey(hwnd, 1, hotkey.get_modifiers(), hotkey.get_code());
|
||||
}
|
||||
```
|
||||
|
||||
### Choice group
|
||||
```c++
|
||||
add_choice_group(name, description, value, vector<pair<wstring, wstring>> keys_and_texts)
|
||||
add_choice_group(name, description, value, vector<pair<wstring, UINT>> keys_and_texts)
|
||||
```
|
||||
|
||||
A radio buttons group. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - String or resource ID of the text displayed to the user.
|
||||
* `value` - Key selected by default.
|
||||
* `keys_and_text` - Vector of radio buttons definitions: key and the displayed label. The texts can either be strings or resource IDs.
|
||||
|
||||
This C++:
|
||||
```c++
|
||||
settings.add_choice_group(L"choice_group_name", L"description", L"val1", { { L"val1", L"value-1" },
|
||||
{ L"val2", L"value-2" },
|
||||
{ L"val3", L"value-3" } });
|
||||
```
|
||||
produces this settings element:
|
||||
|
||||

|
||||
|
||||
and this generated JSON:
|
||||
```json
|
||||
{
|
||||
"properties": {
|
||||
"choice_group_name": {
|
||||
"editor_type": "choice_group",
|
||||
"order": autoincremented_number,
|
||||
"display_name": "description",
|
||||
"value": "val1",
|
||||
"options": [ {"key": "val1", "text": "value-1"},
|
||||
{"key": "val2", "text": "value-2"},
|
||||
{"key": "val3", "text": "value-3"} ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The chosen button value is stored as a string with the key of the button selected by the user:
|
||||
```c++
|
||||
std::optional<std::wstring> value = settings.get_string_value(L"choice_group_name");
|
||||
```
|
||||
|
||||
### Dropdown
|
||||
```c++
|
||||
add_dropdown(name, description, value, vector<pair<wstring, wstring>> keys_and_texts)
|
||||
add_dropdown(name, description, value, vector<pair<wstring, UINT>> keys_and_texts)
|
||||
```
|
||||
|
||||
A dropdown. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - String or resource ID of the text displayed to the user.
|
||||
* `value` - Key selected by default.
|
||||
* `keys_and_text` - Vector of the options definitions: key and the displayed label. The texts can either be strings or resource IDs.
|
||||
|
||||
This C++:
|
||||
```c++
|
||||
settings.add_dropdown(L"dropdown_name", L"description", L"val2", { { L"val1", L"value-1" },
|
||||
{ L"val2", L"value-2" },
|
||||
{ L"val3", L"value-3" } });
|
||||
```
|
||||
produces this settings element:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
and this generated JSON:
|
||||
```json
|
||||
{
|
||||
"properties": {
|
||||
"dropdown_name": {
|
||||
"editor_type": "dropdown",
|
||||
"order": autoincremented_number,
|
||||
"display_name": "description",
|
||||
"value": "val1",
|
||||
"options": [ {"key": "val1", "text": "value-1"},
|
||||
{"key": "val2", "text": "value-2"},
|
||||
{"key": "val3", "text": "value-3"} ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The chosen value is stored as a string with the key of the option selected by the user:
|
||||
```c++
|
||||
std::optional<std::wstring> value = settings.get_string_value(L"dropdown_name");
|
||||
```
|
||||
### Custom action
|
||||
|
||||
```c++
|
||||
add_custom_action(name, description, button_text, ext_description)
|
||||
```
|
||||
|
||||
Adds a button with a description. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - String or resource ID of the text displayed to the user.
|
||||
* `button_text` - String or resource ID for the button label.
|
||||
* `ext_description` - String or resource ID for the extended description.
|
||||
|
||||
This C++:
|
||||
```c++
|
||||
settings.add_custom_action(L"custom_action_name", L"description", L"button_text", L"ext_description");
|
||||
```
|
||||
produces this settings element:
|
||||
|
||||

|
||||
|
||||
and this generated JSON:
|
||||
```json
|
||||
{
|
||||
"properties": {
|
||||
"custom_action_name": {
|
||||
"editor_type": "custom_action",
|
||||
"order": autoincremented_number,
|
||||
"display_name": "description",
|
||||
"button_text": "button_text",
|
||||
"value": "ext_description"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When the button is pressed, the `call_custom_action` method of the module will be called, with JSON containing the name of the action. In our example:
|
||||
```json
|
||||
{
|
||||
"action_name":"custom_action_name",
|
||||
"value":"ext_description"
|
||||
}
|
||||
```
|
||||
@@ -1,10 +1,3 @@
|
||||
# Web project for the Settings UI
|
||||
|
||||
## Introduction
|
||||
|
||||
This project generates the web UI shown in the [PowerToys Settings](/src/editor).
|
||||
It's a `ReactJS` project created using [UI Fabric](https://developer.microsoft.com/en-us/fabric#/).
|
||||
|
||||
## Build Commands
|
||||
|
||||
Here are the commands to build and test this project:
|
||||
@@ -22,9 +15,11 @@ npm run start
|
||||
npm run build
|
||||
```
|
||||
|
||||
**Note:** you will need to rebuild the settings project to pick up the changes
|
||||
|
||||
## Updating the icons
|
||||
|
||||
Icons inside [`src/icons/`](./src/icons/) were generated from the [Office UI Fabric Icons subset generation tool.](https://uifabricicons.azurewebsites.net/)
|
||||
Icons inside [`src/icons/`](/src/settings-web/src/icons/) were generated from the [Office UI Fabric Icons subset generation tool.](https://uifabricicons.azurewebsites.net/)
|
||||
|
||||
In case the subset needs to be changed, additional steps are needed to include the icon font in the built `dist/bundle.js`:
|
||||
- Copy the inline font data taken from [`src/icons/css/fabric-icons-inline.css`](src/icons/css/fabric-icons-inline.css) and place it in the `fontFace` `src` value in [`src/icons/src/fabric-icons.ts`](src/icons/src/fabric-icons.ts).
|
||||
@@ -37,44 +32,44 @@ SVG icons, including the icons for each PowerToy listed in the Settings, are con
|
||||
|
||||
The project structure is based on the [`UI Fabric` scaffold](https://developer.microsoft.com/en-us/fabric#/get-started/web#option-1-quick-start) obtained by initializing it with `npm init uifabric`.
|
||||
|
||||
#### [index.html](./index.html)
|
||||
#### [index.html](/src/settings-web/index.html)
|
||||
The HTML entry-point of the project.
|
||||
Loads the `ReactJS` distribution script.
|
||||
Defines JavaScript functions to receive and send messages to the [PowerToys Settings](/src/editor) window.
|
||||
|
||||
#### [src/index.tsx](./src/index.tsx)
|
||||
#### [src/index.tsx](/src/settings-web/src/index.tsx)
|
||||
Main `ReactJS` entrypoint, initializing the `ReactDOM`.
|
||||
|
||||
#### [src/setup_icons.tsx](./src/setup_icons.tsx)
|
||||
#### [src/setup_icons.tsx](/src/settings-web/src/setup_icons.tsx)
|
||||
Defines the `setup_powertoys_icons` function that registers the icons to be used in the components.
|
||||
|
||||
#### [src/components/](./src/components/)
|
||||
#### [src/components/](/src/settings-web/src/components/)
|
||||
Contains the `ReactJS` components, including the Settings controls for each type of setting.
|
||||
|
||||
#### [src/components/App.tsx](./src/components/App.tsx)
|
||||
#### [src/components/App.tsx](/src/settings-web/src/components/App.tsx)
|
||||
Defines the main App component, containing the UI layout, navigation menu, dialogs and main load/save logic.
|
||||
|
||||
#### [src/components/GeneralSettings.tsx](./src/components/GeneralSettings.tsx)
|
||||
#### [src/components/GeneralSettings.tsx](/src/settings-web/src/components/GeneralSettings.tsx)
|
||||
Defines the PowerToys General Settings component, including logic to construct the object sent to PowerToys to change the General settings.
|
||||
|
||||
#### [src/components/CustomSettingsScreen.tsx](./src/components/CustomSettingsScreen.tsx)
|
||||
#### [src/components/ModuleSettings.tsx](/src/settings-web/src/components/ModuleSettings.tsx)
|
||||
Defines the component that generates the settings screen for a PowerToy depending on its settings definition.
|
||||
|
||||
#### [src/components/BaseSettingsControl.tsx](./src/components/BaseSettingsControl.tsx)
|
||||
#### [src/components/BaseSettingsControl.tsx](/src/settings-web/src/components/BaseSettingsControl.tsx)
|
||||
Defines the base class for a Settings control.
|
||||
|
||||
#### [src/css/layout.css](./src/css/layout.css)
|
||||
#### [src/css/layout.css](/src/settings-web/src/css/layout.css)
|
||||
General layout styles.
|
||||
|
||||
#### [src/icons/](./src/icons/)
|
||||
#### [src/icons/](/src/settings-web/src/icons/)
|
||||
Icons generated from the [Office UI Fabric Icons subset generation tool.](https://uifabricicons.azurewebsites.net/)
|
||||
|
||||
#### [src/svg/](./src/svg/)
|
||||
#### [src/svg/](/src/settings-web/src/svg/)
|
||||
SVG icon assets.
|
||||
|
||||
## Creating a new settings control
|
||||
|
||||
The [`BaseSettingsControl` class](./src/components/BaseSettingsControl.tsx) can be extended to create a new Settings control type.
|
||||
The [`BaseSettingsControl` class](/src/settings-web/src/components/BaseSettingsControl.tsx) can be extended to create a new Settings control type.
|
||||
|
||||
```tsx
|
||||
export class BaseSettingsControl extends React.Component <any, any> {
|
||||
@@ -92,7 +87,7 @@ export class BaseSettingsControl extends React.Component <any, any> {
|
||||
A settings control overrides the `get_value` function to return the value to be used for the Setting the control is representing.
|
||||
It will use the `parent_on_change` property to signal that the user made some changes to the settings.
|
||||
|
||||
Here's the [`StringTextSettingsControl`](./src/components/StringTextSettingsControl.tsx) component to serve as an example:
|
||||
Here's the [`StringTextSettingsControl`](/src/settings-web/src/components/StringTextSettingsControl.tsx) component to serve as an example:
|
||||
|
||||
```tsx
|
||||
export class StringTextSettingsControl extends BaseSettingsControl {
|
||||
@@ -153,15 +148,15 @@ Each settings property has a `editor_type` field that's used to differentiate be
|
||||
}
|
||||
```
|
||||
|
||||
A new Settings control component can be added to [`src/components/`](./src/components/).
|
||||
To render the new Settings control, its `editor_type` and component instance need to be added to the [`CustomSettingsScreen` component render()](./src/components/CustomSettingsScreen.tsx):
|
||||
A new Settings control component can be added to [`src/components/`](/src/settings-web/src/components/).
|
||||
To render the new Settings control, its `editor_type` and component instance need to be added to the [`ModuleSettings` component render()](/src/settings-web/src/components/ModuleSettings.tsx):
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import {StringTextSettingsControl} from './StringTextSettingsControl';
|
||||
|
||||
...
|
||||
|
||||
export class CustomSettingsScreen extends React.Component <any, any> {
|
||||
export class ModuleSettings extends React.Component <any, any> {
|
||||
references: any;
|
||||
parent_on_change: Function;
|
||||
...
|
||||
287
doc/devdocs/settings.md
Normal file
287
doc/devdocs/settings.md
Normal file
@@ -0,0 +1,287 @@
|
||||
# Settings
|
||||
|
||||
## Overview
|
||||
|
||||
PowerToys provides a common framework for settings. It can be used to save and load settings on disk, and provides a user interface for changing the options.
|
||||
|
||||
## Initialization
|
||||
When a PowerToy module is created, it should load its configuration using [`PowerToyValues`](/src/common/settings_objects.h) class. The class provides static `load_from_settings_file` method which takes one parameter - the PowerToy module name. The `PowerToyValues` class provides methods to extract values. The method return `std::optional` - it is possible, that the method will return `std::nullopt` in which case you must use defaults.
|
||||
```c++
|
||||
class ExamplePowertoy : public PowertoyModuleIface
|
||||
{
|
||||
public:
|
||||
ExamplePowertoy()
|
||||
{
|
||||
auto settings = PowerToySettings::PowerToyValues::load_from_settings_file(L"Example Powertoy");
|
||||
// See if value is set, otherwise keep the default value
|
||||
if (auto int_value = settings.get_int_value(L"int_setting"))
|
||||
{
|
||||
m_int_setting = *int_value;
|
||||
}
|
||||
if (auto string_value = setting.get_string_value("string_setting"))
|
||||
{
|
||||
m_string_setting = *string_value;
|
||||
}
|
||||
}
|
||||
// ...
|
||||
private:
|
||||
// Settings and their default values
|
||||
int m_int_setting = 10;
|
||||
std::wstring m_string_setting = L"default";
|
||||
}
|
||||
```
|
||||
|
||||
## Settings screen
|
||||
When users starts the settings screen, the runner will call the [`get_config()`](modules/interface.md) method. The interface expects the method to fill provided buffer. Use the [`Settings`](/src/common/settings_objects.h) class to construct proper response with proper format. The class has helper method to set description and links fields, it also provides a way to define the content of the settings screen. Keep all the strings in the resource file and provide the resource IDs to the methods.
|
||||
```c++
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase; // Needed to get strings from the resource file
|
||||
|
||||
bool ExamplePowertoy::get_config(wchar_t* buffer, int* buffer_size)
|
||||
{
|
||||
PowerToySettings::Settings settings(reinterpret_cast<HINSTANCE>(&__ImageBase), L"Example Powertoy");
|
||||
// Set PowerToy description
|
||||
settings.set_description(IDS_POWERTOY_DESCRIPTION);
|
||||
settings.set_icon_key("pt_icon_key");
|
||||
settings.set_overview_link(IDS_POWERTOY_OVERVIEW_LINK);
|
||||
settings.set_video_link(IDS_POWERTOY_OVERVIEW_LINK);
|
||||
|
||||
// Add int and string settings, provide current values:
|
||||
settings.add_int_spinner(L"int_setting", IDS_INT_SETTING_DESCRIPTION, m_int_setting, 0, 100, 10);
|
||||
settings.add_string(L"string_setting", IDS_STRING_SETTING_DESCRIPTION, m_string_setting);
|
||||
|
||||
// Use the build-in machinery to return the configuration:
|
||||
return settings.serialize_to_buffer(buffer, buffer_size);
|
||||
}
|
||||
```
|
||||
The list of all the available settings elements and their description is [further in this doc](#available-settings-elements). New PowerToy icons need to be [added to the `settings-web` project](https://github.com/microsoft/PowerToys/blob/master/doc/devdocs/settings-web.md#updating-the-icons).
|
||||
|
||||
## User changes settings
|
||||
When user closes the settings screen, the runner will call the [`get_config()`](modules/interface.md) method. Use [`PowerToyValues`](/src/common/settings_objects.h) class static `from_json_string` method to parse the settings. After that, the code is similar to loading the settings from disk:
|
||||
```c++
|
||||
void ExamplePowertoy::set_config(const wchar_t* config)
|
||||
{
|
||||
auto settings = PowerToySettings::PowerToyValues::from_json_string(config);
|
||||
// See if value is set update the values
|
||||
if (auto int_value = settings.get_int_value(L"int_setting"))
|
||||
{
|
||||
m_int_setting = *int_value;
|
||||
}
|
||||
if (auto string_value = setting.get_string_value("string_setting"))
|
||||
{
|
||||
m_string_setting = *string_value;
|
||||
}
|
||||
// Save the new settings to disk
|
||||
settings.save_to_settings_file();
|
||||
}
|
||||
```
|
||||
|
||||
## Detailed reference
|
||||
For a detailed reference of how the settings are implemented in the runner and in the settings editor, consult [this detailed guide](settings-reference.md).
|
||||
|
||||
# Available settings elements
|
||||
|
||||
## Bool toggle
|
||||
<table><tr><td align="center">
|
||||
<img src="../images/settings/bool_toggle.png" width="80%">
|
||||
</td></tr></table>
|
||||
|
||||
```c++
|
||||
settings.add_bool_toggle(name, description, value)
|
||||
```
|
||||
A simple on-off toggle. Parameters:
|
||||
* `name` - Key for the element in the JSON.
|
||||
* `description` - Resource ID of the text displayed to the user.
|
||||
* `value` - Initial state of the toggle (`true` - on, `false` - off).
|
||||
|
||||
The toggle value is stored as bool:
|
||||
```c++
|
||||
std::optional<bool> bool_value = settings.get_bool_value(L"bool_name");
|
||||
```
|
||||
|
||||
## Int Spinner
|
||||
<table><tr><td align="center">
|
||||
<img src="../images/settings/int_spinner.png" width="80%">
|
||||
</td></tr></table>
|
||||
|
||||
```c++
|
||||
settings.add_int_spinner(name, description, value, min, max, step)
|
||||
```
|
||||
Numeric input with dials to increment and decrement the value. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - Resource ID of the text displayed to the user.
|
||||
* `value` - Initial control value.
|
||||
* `min`, `max` - Minimum and maximum values for the input. User cannot use dials to move beyond those values, if a value out of range is inserted using the keyboard, it will get clamped to the allowed range.
|
||||
* `step` - How much the dials change the value.
|
||||
|
||||
The spinner value is stored as int:
|
||||
```c++
|
||||
std::optional<int> int_value = settings.get_int_value(L"int_spinner_name");
|
||||
```
|
||||
|
||||
## String
|
||||
<table><tr><td align="center">
|
||||
<img src="../images/settings/string.png" width="80%">
|
||||
</td></tr></table>
|
||||
|
||||
```c++
|
||||
settings.add_string(name, description, value)
|
||||
```
|
||||
Single line text input. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - Resource ID of the text displayed to the user.
|
||||
* `value` - Default value for the input.
|
||||
|
||||
The input value is stored as `std::wstring`:
|
||||
```c++
|
||||
std::optional<std::wstring> string_value = settings.get_string_value(L"string_name");
|
||||
```
|
||||
|
||||
## Multiline string
|
||||
<table><tr><td align="center">
|
||||
<img src="../images/settings/multiline.png" width="80%">
|
||||
</td></tr></table>
|
||||
|
||||
```c++
|
||||
settings.add_multiline_string(name, description, value)
|
||||
```
|
||||
Multiline text input. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - Resource ID of the text displayed to the user.
|
||||
* `value` - Default value for the input. Can have multiple lines.
|
||||
|
||||
The input value is stored as string:
|
||||
```c++
|
||||
std::optional<std::wstring> value = settings.get_string_value(L"multiline_name");
|
||||
```
|
||||
|
||||
## Color picker
|
||||
<table><tr><td align="center">
|
||||
<img src="../images/settings/color_picker.png" width="80%">
|
||||
</td></tr></table>
|
||||
|
||||
```c++
|
||||
settings.add_color_picker(name, description, value)
|
||||
```
|
||||
|
||||
Allows user to pick a color. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - Resource ID of the text displayed to the user.
|
||||
* `value` - Initial color, as a string in `"#RRGGBB"` format.
|
||||
|
||||
The color picker value is stored as `std::wstring` as `#RRGGBB`:
|
||||
```c++
|
||||
std::optional<std::wstring> value = settings.get_string_value(L"colorpicker_name");
|
||||
```
|
||||
|
||||
## Hotkey
|
||||
<table><tr><td align="center">
|
||||
<img src="../images/settings/hotkey.png" width="80%">
|
||||
</td></tr></table>
|
||||
|
||||
```c++
|
||||
settings.add_hotkey(name, description, hotkey)
|
||||
```
|
||||
Input for capturing hotkeys. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - Resource ID of the text displayed to the user.
|
||||
* `hotkey` - Instance of `PowerToysSettings::HotkeyObject` class.
|
||||
|
||||
You can create `PowerToysSettings::HotkeyObject` object either by using helper `from_settings` static method or by providing a JSON object to `from_json` static method.
|
||||
|
||||
The `PowerToysSettings::HotkeyObject::from_settings` take following parameters:
|
||||
* `win_pressed` - Is the WinKey pressed.
|
||||
* `ctrl_pressed` - Is the Ctrl key pressed.
|
||||
* `alt_pressed` - Is the Alt key pressed.
|
||||
* `shift_pressed` - Is the Shift key pressed.
|
||||
* `vk_code` - The [virtual key-code](https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes) of the key.
|
||||
|
||||
The displayed key is deduced from the `vk_code` using the users keyboard layout and language settings.
|
||||
|
||||
The hotkey value is returned as JSON, which can be used with the `from_json` method to create a `HotkeyObject` object. A typical example of registering a hotkey:
|
||||
```c++
|
||||
std::optional<json::JsonObject> value = settings.get_json(L"hotkey_name");
|
||||
if (value) {
|
||||
auto hotkey = PowerToysSettings::HotkeyObject::from_json(*value);
|
||||
RegisterHotKey(hwnd, 1, hotkey.get_modifiers(), hotkey.get_code());
|
||||
}
|
||||
```
|
||||
|
||||
## Choice group
|
||||
<table><tr><td align="center">
|
||||
<img src="../images/settings/choice_group.png" width="80%">
|
||||
</td></tr></table>
|
||||
|
||||
```c++
|
||||
add_choice_group(name, description, value, vector<pair<wstring, UINT>> keys_and_texts)
|
||||
```
|
||||
A radio buttons group. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - Resource ID of the text displayed to the user.
|
||||
* `value` - Key selected by default.
|
||||
* `keys_and_text` - Vector of radio buttons definitions: key and the displayed label.
|
||||
|
||||
|
||||
The chosen button value is stored as a string with the key of the button selected by the user:
|
||||
```c++
|
||||
std::optional<std::wstring> value = settings.get_string_value(L"choice_group_name");
|
||||
```
|
||||
|
||||
## Dropdown
|
||||
<table>
|
||||
<tr><td align="center">
|
||||
<img src="../images/settings/dropdown_1.png" width="80%">
|
||||
</td></tr>
|
||||
<tr><td align="center">
|
||||
<img src="../images/settings/dropdown_2.png" width="80%">
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
```c++
|
||||
add_dropdown(name, description, value, vector<pair<wstring, UINT>> keys_and_texts)
|
||||
```
|
||||
|
||||
A dropdown. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - Resource ID of the text displayed to the user.
|
||||
* `value` - Key selected by default.
|
||||
* `keys_and_text` - Vector of the options definitions: key and the displayed label.
|
||||
|
||||
The chosen value is stored as a string with the key of the option selected by the user:
|
||||
```c++
|
||||
std::optional<std::wstring> value = settings.get_string_value(L"dropdown_name");
|
||||
```
|
||||
## Custom action
|
||||
<table><tr><td align="center">
|
||||
<img src="../images/settings/custom_action.png" width="80%">
|
||||
</td></tr></table>
|
||||
|
||||
```c++
|
||||
add_custom_action(name, description, button_text, ext_description)
|
||||
```
|
||||
|
||||
Adds a button with a description. Parameters:
|
||||
* `name` - Key for element in the JSON.
|
||||
* `description` - Resource ID of the text displayed to the user.
|
||||
* `button_text` - Resource ID for the button label.
|
||||
* `ext_description` - Resource ID for the extended description.
|
||||
|
||||
When the button is pressed, the `call_custom_action` method of the module will be called, with JSON containing the name of the action. Parse it using `PowerToysSettings::CustomActionObject`:
|
||||
```c++
|
||||
void ExamplePowertoy::call_custom_action(const wchar_t* action) override
|
||||
{
|
||||
auto action_object = PowerToysSettings::CustomActionObject::from_json_string(action);
|
||||
auto name = action_object.get_name(); // same value as the 'name' parameter
|
||||
// .. do stuff ..
|
||||
}
|
||||
```
|
||||
|
||||
# File organization
|
||||
|
||||
### [main.cpp](/src/settings/main.cpp)
|
||||
Contains the main executable code, initializing and managing the Window containing the WebView and communication with the main PowerToys executable.
|
||||
|
||||
### [StreamURIResolverFromFile.cpp](/src/settings/StreamURIResolverFromFile.cpp)
|
||||
Defines a class implementing `IUriToStreamResolver`. Allows the WebView to navigate to filesystem files in this Win32 project.
|
||||
|
||||
### [settings-html/](/src/settings/settings-html/)
|
||||
Contains the assets file from building the [Web project for the Settings UI](/src/settings/settings-html). It will be loaded by the WebView.
|
||||
15
doc/devdocs/settingsv2/communication-with-modules.md
Normal file
15
doc/devdocs/settingsv2/communication-with-modules.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Communication with modules
|
||||
|
||||
## Through runner
|
||||
- The settings process communicates changes in the UI to most modules using the runner through delegates.
|
||||
- More details on this are mentioned in [`runner-ipc.md`](settingsv2/runner-ipc.md).
|
||||
|
||||
## PT Run
|
||||
- Any changes to the UI are saved by the settings process in the `settings.json` file located within the `/Local/Microsoft/PowerToys/Launcher/` folder.
|
||||
- PT Run watches for any changes within this file and updates it's general settings or propagates the information to the plugins, depending on the type of information.
|
||||
Eg: The maximum number of results drop down updates the maximum number of rows in the results list which updates the general settings of PT Run whereas the drive detection checkbox details are dispatched to the indexer plugin.
|
||||
|
||||
## Keyboard Manager
|
||||
- The Settings process and keyboard manager share access to a common `default.json` file which contains information about the remapped keys and shortcuts.
|
||||
- To ensure that there is no contention while both processes try to access the common file, there is a named file mutex.
|
||||
- The settings process expects the keyboard manager process to create the `default.json` file if it does not exist. It does not create the file in case it is not present.
|
||||
12
doc/devdocs/settingsv2/compatibility-legacy-settings.md
Normal file
12
doc/devdocs/settingsv2/compatibility-legacy-settings.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Compatibility with legacy settings and runner
|
||||
The following must be kept in mind regarding compatibility with settings v1 and runner.
|
||||
|
||||
### 1. Folder Naming structure
|
||||
- Each of the modules has a folder within the `Local/Microsoft/PowerToys` directory which contains the module configurations within the `settings.json` file. The name of this folder must be the same across settingsv1 and settingsv2.
|
||||
- The name of the settings folder for each powertoy is the same as the `ModuleName`. It is set within each of the viewModel files. This name must not be changed to ensure that the user configurations for each of the powertoys rolls over on update.
|
||||
|
||||
### 2. Communication with runner
|
||||
- The status of each of the modules is communicated with the runner in the form of a json object. The names of all the powerToys is set in the [`EnableModules.cs`](src/core/Microsoft.PowerToys.Settings.UI.Library/EnabledModules.cs) file. The `JsonPropertyName` must not be changed to ensure that the information is dispatched properly to all the modules by the runner.
|
||||
|
||||
### ImageResizer anomaly
|
||||
All the powertoys have the same folder name as well as JsonPropertyName to communicate information with the runner. However that is not the case with ImageResizer. The folder name is `ImageResizer` whereas the JsonPropertyName is `Image Resizer`(Note the additional space). This should not be changed to ensure backward compatibility as well as proper functioning of the module.
|
||||
46
doc/devdocs/settingsv2/hotkeycontrol.md
Normal file
46
doc/devdocs/settingsv2/hotkeycontrol.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Custom HotKey Control
|
||||
|
||||
The Settings project provides a custom hotkey control which consumes key presses. This control can be used to set the hotkey of any PowerToy.
|
||||
|
||||
## HotKey Control in FancyZones
|
||||

|
||||
|
||||
## Hotkey related files
|
||||
|
||||
#### [`HotkeySettingsControlHook.cs`](/src/core/Microsoft.PowerToys.Settings.UI.Library/HotkeySettingsControlHook.cs)
|
||||
|
||||
- This function initializes and starts the [`keyboardHook`](src/common/interop/KeyboardHook.cpp) for the hotkey control.
|
||||
|
||||
```csharp
|
||||
public HotkeySettingsControlHook(KeyEvent keyDown, KeyEvent keyUp, IsActive isActive, FilterAccessibleKeyboardEvents filterAccessibleKeyboardEvents)
|
||||
{
|
||||
_keyDown = keyDown;
|
||||
_keyUp = keyUp;
|
||||
_isActive = isActive;
|
||||
_filterKeyboardEvent = filterAccessibleKeyboardEvents;
|
||||
_hook = new KeyboardHook(HotkeySettingsHookCallback, IsActive, FilterKeyboardEvents);
|
||||
_hook.Start();
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### [`HotkeySettingsControl.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI/HotkeySettingsControl.xaml.cs)
|
||||
|
||||
- The function of this class is to update the state of the keys being pressed within the custom control. This information is stored in `internalSettings`.
|
||||
|
||||
- It provides the following callbacks to the `HotKeySettingsControlHook`:
|
||||
|
||||
- `KeyUp`: Resets the key state in `internalSettings` when a key is released.
|
||||
- `KeyDown`: Updates the user facing text of the hotkey control as soon as a key is pressed.
|
||||
- `isActive`: Sets the current status of the keyboard hook.
|
||||
- `FilterAccessibleKeyboardEvents`: This function is used to ignore the `Tab` and `Shift+Tab` key presses to meet the accessibility requirements.
|
||||
|
||||
#### [`HotkeySettings.cs`](/src/core/Microsoft.PowerToys.Settings.UI.Library/HotkeySettings.cs)
|
||||
|
||||
- Contains the structure of a HotKey where it is represented as a combination of one of the modifier keys (`Alt`, `Shift`, `Win` and `Ctrl`) and a non-modifier key.
|
||||
|
||||
#### Note
|
||||
- The control displays all key presses to the user (except Tab and Shift+Tab which move focus out of the control). However, when the focus is being lost from the control, the `lastValidHotkeySettings` is set as the user facing text.
|
||||
|
||||
|
||||
|
||||
17
doc/devdocs/settingsv2/project-overview.md
Normal file
17
doc/devdocs/settingsv2/project-overview.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Overview
|
||||
`Settingsv2` is WPF .net core desktop application. It uses the `WindowsXamlHost` control from the Windows Community Toolkit to host UWP controls from `WinUI3` library. More details about WinUI can be found [here](https://microsoft.github.io/microsoft-ui-xaml/about.html#what-is-it).
|
||||
|
||||
## Settings V2 Project structure
|
||||
The Settings project is a XAML island based project which
|
||||
follows the [MVVM architectural pattern][MVVM] where the graphical user interface is separated from the view models.
|
||||
|
||||
#### [UI Components:](/src/core/Microsoft.PowerToys.Settings.UI)
|
||||
The Settings.UI project contains the xaml files for each of the UI components. It also contains the Hotkey logic for the settings control.
|
||||
|
||||
#### [Viewmodels:](/src/core/Microsoft.PowerToys.Settings.UI.Library)
|
||||
The Settings.UI.Library project contains the data that is to be rendered by the UI components.
|
||||
|
||||
#### [Settings Runner:](/src/core/Microsoft.PowerToys.Settings.UI.Runner)
|
||||
The function of the settings runner project is to communicate all changes that the user makes in the user interface, to the runner so that it can be dispatched and reflected in all the modules.
|
||||
|
||||
[MVVM]: https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvm
|
||||
12
doc/devdocs/settingsv2/readme.md
Normal file
12
doc/devdocs/settingsv2/readme.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Table of Contents
|
||||
1. [Settings overview](/doc/devdocs/settingsv2/project-overview.md)
|
||||
2. [UI Architecture](/doc/devdocs/settingsv2/ui-architecture.md)
|
||||
3. [ViewModels](/doc/devdocs/settingsv2/viewmodels.md)
|
||||
4. Data flow
|
||||
- [Inter-Process Communication with runner](/doc/devdocs/settingsv2/runner-ipc.md)
|
||||
- [Communication with modules](/doc/devdocs/settingsv2/communication-with-modules.md)
|
||||
5. [Settings Utilities](/doc/devdocs/settingsv2/settings-utilities.md)
|
||||
6. [Custom Hotkey control and keyboard hook handling](hotkeycontrol.md)
|
||||
7. [Compatibility with legacy settings and runner](/doc/devdocs/settingsv2/compatibility-legacy-settings.md)
|
||||
8. [XAML Island tweaks](/doc/devdocs/settingsv2/xaml-island-tweaks.md)
|
||||
9. [Telemetry](/doc/devdocs/settingsv2/telemetry.md)
|
||||
46
doc/devdocs/settingsv2/runner-ipc.md
Normal file
46
doc/devdocs/settingsv2/runner-ipc.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Inter-Process Communication with Runner
|
||||
|
||||
The Settings v2 process uses two way IPC to communicate with the runner process.
|
||||
|
||||
## Initialization
|
||||
- On the settings' side, the two way IPC delegates are contained with the [`ShellPage.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI/Views/ShellPage.xaml.cs) file. The delegates are static and the views for all the powerToys send the ipc information to the viewmodels as `ShellPage.DefaultSndMSGCallBack`.
|
||||
- These delegates are initialized within the [`Mainwindow.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml.cs) file in the `Settings.Runner` project.
|
||||
|
||||
|
||||
## Types of IPC delegates
|
||||
- There are three types of delegates for the settings to communicate with the runner:
|
||||
1. `SendDefaultMessage` - This is used by all the viewmodels to communicate changes in the UI to the runner so that the information can be dispatched to the modules.
|
||||
2. `RestartAsAdmin`
|
||||
3. `CheckForUpdates`
|
||||
|
||||
## Sending information to runner
|
||||
- The settings process communicates with the runner by using the delegates defined within the [`ShellPage.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI/Views/ShellPage.xaml.cs) file.
|
||||
- Depending on the type of object sending the information, the json is created accordingly.
|
||||
- If any information has been modified by the user in the GeneralSettings page, then the json file sent to the runner has the name set to `general`, whereas if any information has been modified by the user in any powertoy related settings page, the name of the json file being communicated with the runner is set to `powertoy`.
|
||||
|
||||
## Receiving information from runner
|
||||
- The `ShellPage`object has a `IPCResponseHandleList` which is a list of functions which handle IPC responses.
|
||||
|
||||
```csharp
|
||||
// receive IPC Message
|
||||
Program.IPCMessageReceivedCallback = (string msg) =>
|
||||
{
|
||||
if (ShellPage.ShellHandler.IPCResponseHandleList != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
JsonObject json = JsonObject.Parse(msg);
|
||||
foreach (Action<JsonObject> handle in ShellPage.ShellHandler.IPCResponseHandleList)
|
||||
{
|
||||
handle(json);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
- Whenever any information is sent from the runner each of the functions in the handle list perform their action on that json object.
|
||||
- One example of where information sent from the runner is being processed by the settings is in [`GeneralPage.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI/Views/GeneralPage.xaml.cs) when the user clicks the check for updates button. The information displayed after, such as the user has the latest version installed is a result of this handle.
|
||||
13
doc/devdocs/settingsv2/settings-utilities.md
Normal file
13
doc/devdocs/settingsv2/settings-utilities.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Settings Utilities
|
||||
|
||||
- Abstractions for each of the file/folder related operations are present in [`SettingsUtils.cs`](src/core/Microsoft.PowerToys.Settings.UI.Library/SettingsUtils.cs).
|
||||
- To reduce contention between the settings process and runner while trying to access the `settings.json` file of any powertoy, the settings process tries to access the file only when it needs to load the information for the first time. However, there is still no mechanism in place which ensures that both the settings and runner processes do not access the information simultaneously leading to `IOExceptions`.
|
||||
|
||||
## Utilities
|
||||
|
||||
### `GetSettings<T>(powertoy, filename)`
|
||||
|
||||
- The GetSettings function tries to read the file in the powertoy settings folder and creates a new file with default configurations if it does not exist.
|
||||
- Ideally this function should only be called by the [`SettingsRepository`](src/core/Microsoft.PowerToys.Settings.UI.Library/SettingsRepository`1.cs) which would be accessed only when a powertoy settings object is being loaded for the first time.
|
||||
- The reason behind ensuring that it is not accessed elsewhere is to avoid contention with the runner during file access.
|
||||
- Each of the objects which are deserialized using this function must implement the `ISettingsConfig` interface.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user