diff --git a/res/layout/keybox_data_pref.xml b/res/layout/keybox_data_pref.xml
index 6848b9a4..622cd331 100644
--- a/res/layout/keybox_data_pref.xml
+++ b/res/layout/keybox_data_pref.xml
@@ -1,10 +1,35 @@
-
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:clipToPadding="false"
+ android:baselineAligned="false">
+
+
+
+
+
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+ android:maxLines="5"
+ android:ellipsize="end" />
diff --git a/res/raw-night/lottie_gesture_screenshot.json b/res/raw-night/lottie_gesture_screenshot.json
new file mode 100644
index 00000000..08632357
--- /dev/null
+++ b/res/raw-night/lottie_gesture_screenshot.json
@@ -0,0 +1 @@
+{"v":"5.12.2","fr":60,"ip":1,"op":353,"w":382,"h":224,"nm":"Screenshot gesture_Dark","ddd":0,"assets":[{"id":"comp_0","nm":"Pre-comp 3","fr":60,"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Pre-comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[302.812,145.5,0],"ix":2,"l":2},"a":{"a":0,"k":[228.313,78.75,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"w":382,"h":224,"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Pre-comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[227.812,146,0],"ix":2,"l":2},"a":{"a":0,"k":[228.313,78.75,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"w":382,"h":224,"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"Pre-comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[302.812,78,0],"ix":2,"l":2},"a":{"a":0,"k":[228.313,78.75,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"w":382,"h":224,"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"Pre-comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[227.812,78.25,0],"ix":2,"l":2},"a":{"a":0,"k":[228.313,78.75,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"w":382,"h":224,"ip":0,"op":400,"st":0,"ct":1,"bm":0}]},{"id":"comp_1","nm":"Pre-comp 2","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 23","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[229.219,76.281,0],"ix":2,"l":2},"a":{"a":0,"k":[33.5,-35.25,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[33.5,-32.25],[33.5,-38.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.941176470588,0.949019607843,0.949019607843,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 22","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[226.281,79.906,0],"ix":2,"l":2},"a":{"a":0,"k":[33.5,-35.25,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[33.5,-32.25],[33.5,-38.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.941176470588,0.949019607843,0.949019607843,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Pre-comp 3","refId":"comp_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":118,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":139,"s":[50]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[60]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[265,113,0],"ix":2,"l":2},"a":{"a":0,"k":[265,113,0],"ix":1,"l":2},"s":{"a":0,"k":[99,99,100],"ix":6,"l":2}},"ao":0,"w":382,"h":224,"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 21","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[298.692,193.388,0],"ix":2,"l":2},"a":{"a":0,"k":[81.853,-81.147,0],"ix":1,"l":2},"s":{"a":0,"k":[130,130,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[9.705,9.705],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235309077,0.188235309077,0.20000001496,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[81.853,-81.147],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 20","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[231.308,193.388,0],"ix":2,"l":2},"a":{"a":0,"k":[81.853,-81.147,0],"ix":1,"l":2},"s":{"a":0,"k":[130,130,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[9.705,9.705],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235309077,0.188235309077,0.20000001496,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[81.853,-81.147],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 19","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[301.103,29.888,0],"ix":2,"l":2},"a":{"a":0,"k":[81.853,-81.147,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[9.705,9.705],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235309077,0.188235309077,0.20000001496,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[81.853,-81.147],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 18","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[289.269,29.888,0],"ix":2,"l":2},"a":{"a":0,"k":[81.853,-81.147,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[9.705,9.705],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235309077,0.188235309077,0.20000001496,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[81.853,-81.147],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 17","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277.436,29.888,0],"ix":2,"l":2},"a":{"a":0,"k":[81.853,-81.147,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[9.705,9.705],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235309077,0.188235309077,0.20000001496,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[81.853,-81.147],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 16","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[265.603,29.888,0],"ix":2,"l":2},"a":{"a":0,"k":[81.853,-81.147,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[9.705,9.705],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235309077,0.188235309077,0.20000001496,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[81.853,-81.147],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 15","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[237.829,29.888,0],"ix":2,"l":2},"a":{"a":0,"k":[48.829,-82.044,0],"ix":1,"l":2},"s":{"a":0,"k":[84.827,105.728,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[29.658,10.912],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.84313731474,0.098039223166,0.129411764706,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[48.829,-82.044],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":3,"nm":"Null 1","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[264.5,90,0],"to":[0,12,0],"ti":[0,-12,0]},{"t":101,"s":[264.5,162,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19,19,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":414,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Shape Layer 12","parent":9,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[121.053,-0.877,0],"ix":2,"l":2},"a":{"a":0,"k":[-2,-12,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":22,"s":[507.053,507.053,100]},{"t":29,"s":[421.053,421.053,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.843137015548,0.098038998772,0.1294119891,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":106,"st":-20,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Shape Layer 11","parent":9,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1.316,-42.982,0],"ix":2,"l":2},"a":{"a":0,"k":[-2,-12,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":22,"s":[507.053,507.053,100]},{"t":29,"s":[421.053,421.053,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.843137015548,0.098038998772,0.1294119891,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":106,"st":-20,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Shape Layer 10","parent":9,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-118.421,-0.877,0],"ix":2,"l":2},"a":{"a":0,"k":[-2,-12,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":22,"s":[507.053,507.053,100]},{"t":29,"s":[421.053,421.053,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.843137015548,0.098038998772,0.1294119891,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":106,"st":-20,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Shape Layer 14","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":106,"s":[264.692,119.514,0],"to":[0.052,-1.254,0],"ti":[-0.052,1.254,0]},{"t":127,"s":[265.005,111.991,0]}],"ix":2,"l":2},"a":{"a":0,"k":[73.442,-14.236,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":106,"s":[100,100,100]},{"t":127,"s":[90,90,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[41.627,-45.296],[41.504,-44.704],[-41.75,-44.704],[-41.627,-45.296]],"c":true}]},{"t":101,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[41.627,-45.296],[41.258,30.296],[-41.996,30.296],[-41.627,-45.296]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"rd","nm":"Round Corners 1","r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":106,"s":[4]},{"t":127,"s":[0]}],"ix":1},"ix":2,"mn":"ADBE Vector Filter - RC","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235309077,0.188235309077,0.20000001496,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[73.627,-6.704],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":29,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"4","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[264.817,112.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.026,0],[0,0],[0,4.954],[0,0],[-5.026,0],[0,0],[0,-4.954],[0,0]],"o":[[0,0],[-5.026,0],[0,0],[0,-4.954],[0,0],[5.026,0],[0,0],[0,4.954]],"v":[[34.628,95.607],[-34.628,95.607],[-43.693,86.605],[-43.693,-86.605],[-34.628,-95.607],[34.628,-95.607],[43.693,-86.605],[43.693,86.605]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235297799,0.188235297799,0.20000000298,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector (Stroke)","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":416,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"3","tt":2,"tp":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[264.755,112.023,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.158,0],[0,0],[0,7.122],[0,0],[-7.158,0],[0,0],[0,-7.122],[0,0]],"o":[[0,0],[-7.158,0],[0,0],[0,-7.122],[0,0],[7.158,0],[0,0],[0,7.122]],"v":[[34.628,99.5],[-34.628,99.5],[-47.587,86.605],[-47.587,-86.605],[-34.628,-99.5],[34.628,-99.5],[47.587,-86.605],[47.587,86.605]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235297799,0.188235297799,0.20000000298,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector (Stroke)","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":416,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"5","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[117.005,112.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.026,0],[0,0],[0,4.954],[0,0],[-5.026,0],[0,0],[0,-4.954],[0,0]],"o":[[0,0],[-5.026,0],[0,0],[0,-4.954],[0,0],[5.026,0],[0,0],[0,4.954]],"v":[[34.628,95.607],[-34.628,95.607],[-43.693,86.605],[-43.693,-86.605],[-34.628,-95.607],[34.628,-95.607],[43.693,-86.605],[43.693,86.605]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235297799,0.188235297799,0.20000000298,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector (Stroke)","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":150,"op":475,"st":59,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Shape Layer 9","tt":1,"tp":16,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.127,"y":1},"o":{"x":0.167,"y":0},"t":150,"s":[87.972,180.675,0],"to":[-5.083,0,0],"ti":[5.083,0,0]},{"t":190,"s":[57.472,180.675,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-73.528,-0.325,0],"ix":1,"l":2},"s":{"a":0,"k":[23,23,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[87.943,191.35],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":14,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235309077,0.188235309077,0.20000001496,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-73.528,-0.325],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":150,"op":471,"st":59,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Shape Layer 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.127,"y":1},"o":{"x":0.333,"y":0},"t":50,"s":[116.972,112.175,0],"to":[-4.833,11.417,0],"ti":[4.833,-11.417,0]},{"t":91,"s":[87.972,180.675,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-73.528,-0.325,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.127,0.127,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":50,"s":[100,101.045,100]},{"t":91,"s":[23,23,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[87.943,191.35],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.127],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":50,"s":[8]},{"t":91,"s":[14]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235309077,0.188235309077,0.20000001496,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-73.528,-0.325],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":50,"op":150,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":3,"nm":"Null 1","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.316,"y":1},"o":{"x":0.615,"y":0},"t":22,"s":[117.5,90,0],"to":[0,7.333,0],"ti":[0,-7.333,0]},{"t":50,"s":[117.5,134,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19,19,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":414,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Shape Layer 6","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[121.053,-0.877,0],"ix":2,"l":2},"a":{"a":0,"k":[-2,-12,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":22,"s":[507.053,507.053,100]},{"t":29,"s":[421.053,421.053,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.843137015548,0.098038998772,0.1294119891,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":50,"st":-20,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Shape Layer 5","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1.316,-42.982,0],"ix":2,"l":2},"a":{"a":0,"k":[-2,-12,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":22,"s":[507.053,507.053,100]},{"t":29,"s":[421.053,421.053,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.843137015548,0.098038998772,0.1294119891,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":50,"st":-20,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"Shape Layer 4","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-118.421,-0.877,0],"ix":2,"l":2},"a":{"a":0,"k":[-2,-12,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":22,"s":[507.053,507.053,100]},{"t":29,"s":[421.053,421.053,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.843137015548,0.098038998772,0.1294119891,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":50,"st":-20,"ct":1,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":"1","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[117.005,112.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.026,0],[0,0],[0,4.954],[0,0],[-5.026,0],[0,0],[0,-4.954],[0,0]],"o":[[0,0],[-5.026,0],[0,0],[0,-4.954],[0,0],[5.026,0],[0,0],[0,4.954]],"v":[[34.628,95.607],[-34.628,95.607],[-43.693,86.605],[-43.693,-86.605],[-34.628,-95.607],[34.628,-95.607],[43.693,-86.605],[43.693,86.605]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235297799,0.188235297799,0.20000000298,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector (Stroke)","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":416,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"2","tt":2,"tp":23,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[117.005,112.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.158,0],[0,0],[0,7.122],[0,0],[-7.158,0],[0,0],[0,-7.122],[0,0]],"o":[[0,0],[-7.158,0],[0,0],[0,-7.122],[0,0],[7.158,0],[0,0],[0,7.122]],"v":[[34.628,99.5],[-34.628,99.5],[-47.587,86.605],[-47.587,-86.605],[-34.628,-99.5],[34.628,-99.5],[47.587,-86.605],[47.587,86.605]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235297799,0.188235297799,0.20000000298,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector (Stroke)","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":416,"st":0,"ct":1,"bm":0}],"markers":[],"props":{}}
diff --git a/res/raw-night/nt_power_off_verify.json b/res/raw-night/nt_power_off_verify.json
new file mode 100644
index 00000000..24ac0b22
--- /dev/null
+++ b/res/raw-night/nt_power_off_verify.json
@@ -0,0 +1 @@
+{"nm":"Dark","ddd":0,"h":278,"w":366,"meta":{"g":"LottieFiles Figma v67"},"layers":[{"ty":4,"nm":"bar","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[17,1.5],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[17,1.5],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[17,1.5],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[17,1.5],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[17,1.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[17,1.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[17,1.5],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[17,1.5],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[17,1.5],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[17,1.5],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[17,1.5],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[17,1.5],"t":408},{"s":[17,1.5],"t":456}]},"s":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":408},{"s":[100,100],"t":456}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,245.5],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,245.5],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,245.5],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,245.5],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,245.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,245.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,245.5],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,245.5],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,245.5],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,245.5],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,245.5],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[183,245.5],"t":408},{"s":[183,245.5],"t":456}]},"r":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":408},{"s":[0],"t":456}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}],"t":408},{"s":[{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}],"t":456}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5687,0.5647,0.5804],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5687,0.5647,0.5804],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5687,0.5647,0.5804],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5687,0.5647,0.5804],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5687,0.5647,0.5804],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5687,0.5647,0.5804],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5687,0.5647,0.5804],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5687,0.5647,0.5804],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5687,0.5647,0.5804],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5687,0.5647,0.5804],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5687,0.5647,0.5804],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0.5687,0.5647,0.5804],"t":408},{"s":[0.5687,0.5647,0.5804],"t":456}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}}],"ind":1},{"ty":0,"nm":"Frame 427322354","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":true,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[55,115],"t":408},{"s":[55,115],"t":456}]},"s":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":408},{"s":[100,100],"t":456}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,139],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,139],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,139],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,139],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,139],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,139],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,139],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,139],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,139],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,139],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[183,139],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[183,139],"t":408},{"s":[183,139],"t":456}]},"r":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":408},{"s":[0],"t":456}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"masksProperties":[{"nm":"","inv":false,"mode":"a","x":{"a":0,"k":0},"o":{"a":0,"k":100},"pt":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":408},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":456}]}}],"w":366,"h":278,"refId":"1","ind":2}],"v":"5.7.0","fr":60,"op":408.06,"ip":0,"assets":[{"nm":"[Asset] Frame 427322354","id":"1","layers":[{"ty":0,"nm":"Frame 427322356","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":396.06},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[35,39],"t":408},{"s":[35,39],"t":456}]},"s":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":396.06},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":408},{"s":[100,100],"t":456}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,111],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,111],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,111],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,111],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,111],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,111],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,111],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,111],"t":396.06},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[55,111],"t":408},{"s":[55,111],"t":456}]},"r":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396.06},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":408},{"s":[0],"t":456}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396.06},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"w":366,"h":278,"refId":"2","ind":1},{"ty":4,"nm":"Vector (Stroke)","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[55,115],"t":408},{"s":[55,115],"t":456}]},"s":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":408},{"s":[100,100],"t":456}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[55,115],"t":408},{"s":[55,115],"t":456}]},"r":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":408},{"s":[0],"t":456}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}],"t":408},{"s":[{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}],"t":456}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}],"t":408},{"s":[{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}],"t":456}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0.1942,0.1942,0.1942],"t":408},{"s":[0.1942,0.1942,0.1942],"t":456}]},"r":2,"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}}],"ind":2},{"ty":4,"nm":"Subtract","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2.5,1.25],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2.5,1.25],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2.5,1.25],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2.5,1.25],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2.5,1.25],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2.5,1.25],"t":276},{"s":[2.5,1.25],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,53.25],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,53.25],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,53.25],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,53.25],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,53.25],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,53.25],"t":276},{"s":[55,53.25],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[1.38,0],[0,-1.38],[0,0],[-0.83,0],[0,-0.83]],"o":[[0,0],[0,-1.38],[-1.38,0],[0,0],[0,-0.83],[0.83,0],[0,0]],"v":[[4,2.5],[5,2.5],[2.5,0],[0,2.5],[1,2.5],[2.5,1],[4,2.5]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[1.38,0],[0,-1.38],[0,0],[-0.83,0],[0,-0.83]],"o":[[0,0],[0,-1.38],[-1.38,0],[0,0],[0,-0.83],[0.83,0],[0,0]],"v":[[4,2.5],[5,2.5],[2.5,0],[0,2.5],[1,2.5],[2.5,1],[4,2.5]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[1.38,0],[0,-1.38],[0,0],[-0.83,0],[0,-0.83]],"o":[[0,0],[0,-1.38],[-1.38,0],[0,0],[0,-0.83],[0.83,0],[0,0]],"v":[[4,2.5],[5,2.5],[2.5,0],[0,2.5],[1,2.5],[2.5,1],[4,2.5]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[1.38,0],[0,-1.38],[0,0],[-0.83,0],[0,-0.83]],"o":[[0,0],[0,-1.38],[-1.38,0],[0,0],[0,-0.83],[0.83,0],[0,0]],"v":[[4,2.5],[5,2.5],[2.5,0],[0,2.5],[1,2.5],[2.5,1],[4,2.5]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[1.38,0],[0,-1.38],[0,0],[-0.83,0],[0,-0.83]],"o":[[0,0],[0,-1.38],[-1.38,0],[0,0],[0,-0.83],[0.83,0],[0,0]],"v":[[4,2.5],[5,2.5],[2.5,0],[0,2.5],[1,2.5],[2.5,1],[4,2.5]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[1.38,0],[0,-1.38],[0,0],[-0.83,0],[0,-0.83]],"o":[[0,0],[0,-1.38],[-1.38,0],[0,0],[0,-0.83],[0.83,0],[0,0]],"v":[[4,2.5],[5,2.5],[2.5,0],[0,2.5],[1,2.5],[2.5,1],[4,2.5]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[1.38,0],[0,-1.38],[0,0],[-0.83,0],[0,-0.83]],"o":[[0,0],[0,-1.38],[-1.38,0],[0,0],[0,-0.83],[0.83,0],[0,0]],"v":[[4,2.5],[5,2.5],[2.5,0],[0,2.5],[1,2.5],[2.5,1],[4,2.5]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[1.38,0],[0,-1.38],[0,0],[-0.83,0],[0,-0.83]],"o":[[0,0],[0,-1.38],[-1.38,0],[0,0],[0,-0.83],[0.83,0],[0,0]],"v":[[4,2.5],[5,2.5],[2.5,0],[0,2.5],[1,2.5],[2.5,1],[4,2.5]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":276},{"s":[0.8922,0.8922,0.8922],"t":396}]},"r":2,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":3},{"ty":4,"nm":"Line 2 (Stroke)","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":276},{"s":[0.5,0.5],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,55],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,55],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,55],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,55],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,55],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,55],"t":276},{"s":[57,55],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[-90],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[-90],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[-90],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[-90],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[-90],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[-90],"t":276},{"s":[-90],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,1],[0,1],[0,0],[1,0],[1,1]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,1],[0,1],[0,0],[1,0],[1,1]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,1],[0,1],[0,0],[1,0],[1,1]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,1],[0,1],[0,0],[1,0],[1,1]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,1],[0,1],[0,0],[1,0],[1,1]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,1],[0,1],[0,0],[1,0],[1,1]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,1],[0,1],[0,0],[1,0],[1,1]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,1],[0,1],[0,0],[1,0],[1,1]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":276},{"s":[0.8922,0.8922,0.8922],"t":396}]},"r":2,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":4},{"ty":4,"nm":"Line 1 (Stroke)","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":276},{"s":[0.5,0.5],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[53,55],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[53,55],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[53,55],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[53,55],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[53,55],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[53,55],"t":276},{"s":[53,55],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,0],[1,1],[0,1],[0,0],[1,0]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,0],[1,1],[0,1],[0,0],[1,0]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,0],[1,1],[0,1],[0,0],[1,0]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,0],[1,1],[0,1],[0,0],[1,0]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,0],[1,1],[0,1],[0,0],[1,0]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,0],[1,1],[0,1],[0,0],[1,0]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,0],[1,1],[0,1],[0,0],[1,0]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,0],[1,1],[0,1],[0,0],[1,0]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":276},{"s":[0.8922,0.8922,0.8922],"t":396}]},"r":2,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":5},{"ty":4,"nm":"Rectangle 4979","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[4,3.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[4,3.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[4,3.5],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[4,3.5],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[4,3.5],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[4,3.5],"t":276},{"s":[4,3.5],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55.5,59.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55.5,59.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55.5,59.5],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55.5,59.5],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55.5,59.5],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55.5,59.5],"t":276},{"s":[55.5,59.5],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.4714285714285715],[0,0],[0.48125000000000007,0],[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0]],"o":[[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0],[0,-0.4714285714285715],[0,0],[0.48125000000000007,0]],"v":[[7,0.8571428571428572],[7,5.142857142857143],[6.125,6],[0.875,6],[0,5.142857142857143],[0,0.8571428571428572],[0.875,0],[6.125,0]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.4714285714285715],[0,0],[0.48125000000000007,0],[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0]],"o":[[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0],[0,-0.4714285714285715],[0,0],[0.48125000000000007,0]],"v":[[7,0.8571428571428572],[7,5.142857142857143],[6.125,6],[0.875,6],[0,5.142857142857143],[0,0.8571428571428572],[0.875,0],[6.125,0]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.4714285714285715],[0,0],[0.48125000000000007,0],[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0]],"o":[[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0],[0,-0.4714285714285715],[0,0],[0.48125000000000007,0]],"v":[[7,0.8571428571428572],[7,5.142857142857143],[6.125,6],[0.875,6],[0,5.142857142857143],[0,0.8571428571428572],[0.875,0],[6.125,0]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.4714285714285715],[0,0],[0.48125000000000007,0],[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0]],"o":[[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0],[0,-0.4714285714285715],[0,0],[0.48125000000000007,0]],"v":[[7,0.8571428571428572],[7,5.142857142857143],[6.125,6],[0.875,6],[0,5.142857142857143],[0,0.8571428571428572],[0.875,0],[6.125,0]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.4714285714285715],[0,0],[0.48125000000000007,0],[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0]],"o":[[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0],[0,-0.4714285714285715],[0,0],[0.48125000000000007,0]],"v":[[7,0.8571428571428572],[7,5.142857142857143],[6.125,6],[0.875,6],[0,5.142857142857143],[0,0.8571428571428572],[0.875,0],[6.125,0]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.4714285714285715],[0,0],[0.48125000000000007,0],[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0]],"o":[[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0],[0,-0.4714285714285715],[0,0],[0.48125000000000007,0]],"v":[[7,0.8571428571428572],[7,5.142857142857143],[6.125,6],[0.875,6],[0,5.142857142857143],[0,0.8571428571428572],[0.875,0],[6.125,0]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-0.4714285714285715],[0,0],[0.48125000000000007,0],[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0]],"o":[[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0],[0,-0.4714285714285715],[0,0],[0.48125000000000007,0]],"v":[[7,0.8571428571428572],[7,5.142857142857143],[6.125,6],[0.875,6],[0,5.142857142857143],[0,0.8571428571428572],[0.875,0],[6.125,0]]}],"t":276},{"s":[{"c":true,"i":[[0,-0.4714285714285715],[0,0],[0.48125000000000007,0],[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0]],"o":[[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0],[0,-0.4714285714285715],[0,0],[0.48125000000000007,0]],"v":[[7,0.8571428571428572],[7,5.142857142857143],[6.125,6],[0.875,6],[0,5.142857142857143],[0,0.8571428571428572],[0.875,0],[6.125,0]]}],"t":396}]}},{"ty":"st","bm":0,"hd":false,"nm":"","lc":1,"lj":1,"ml":1,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]},"w":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1],"t":276},{"s":[1],"t":396}]},"c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8922,0.8922,0.8922],"t":276},{"s":[0.8922,0.8922,0.8922],"t":396}]}}],"ind":6},{"ty":4,"nm":"Rectangle 160","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,0.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,0.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,32],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,32],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,32],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,32],"t":276},{"s":[2,32],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[25,106.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[25,106.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[25,138],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[25,138],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[25,138],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[25,138],"t":276},{"s":[25,138],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[20],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[20],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[20],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,1],[0,1],[0,0]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,1],[0,1],[0,0]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,1],[0,1],[0,0]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,64],[0,64],[0,0]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,64],[0,64],[0,0]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,64],[0,64],[0,0]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,64],[0,64],[0,0]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,64],[0,64],[0,0]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1,1,1],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1,1,1],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1,1,1],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1,1,1],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1,1,1],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1,1,1],"t":276},{"s":[1,1,1],"t":396}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":7},{"ty":0,"nm":"Group 1","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":396},{"s":[33,33],"t":456.06}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":396},{"s":[100,100],"t":456.06}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":396},{"s":[55,138],"t":456.06}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"w":366,"h":278,"refId":"3","ind":8},{"ty":4,"nm":"Rectangle 161","sr":1,"st":0,"op":409.06,"ip":174,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,0.5],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,30],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,30],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,30],"t":276},{"s":[2,30],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[27.5,168],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,168],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,168],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,168],"t":276},{"s":[57,168],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[90],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[90],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[90],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[90],"t":276},{"s":[90],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[20],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[20],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,1],[0,1],[0,0]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,1],[0,1],[0,0]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,60],[0,60],[0,0]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,60],[0,60],[0,0]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,60],[0,60],[0,0]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,60],[0,60],[0,0]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1,1,1],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1,1,1],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1,1,1],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1,1,1],"t":276},{"s":[1,1,1],"t":396}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":9},{"ty":4,"nm":"Shutting down...","sr":1,"st":0,"op":409.06,"ip":276,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[38.5,6],"t":276},{"s":[38.5,6],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55.5,115],"t":276},{"s":[55.5,115],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0.39,0.17],[0.22,0.3],[0.03,0.41],[0,0],[-0.16,-0.18],[-0.25,-0.09],[-0.28,0],[-0.26,0.11],[-0.15,0.2],[0,0.26],[0.13,0.15],[0.22,0.09],[0.26,0.07],[0,0],[0.33,0.31],[0,0.48],[-0.22,0.31],[-0.38,0.17],[-0.47,0],[-0.37,-0.17],[-0.21,-0.29],[-0.01,-0.37],[0,0],[0.3,0.19],[0.43,0],[0.24,-0.1],[0.13,-0.18],[0,-0.23],[-0.16,-0.16],[-0.21,-0.09],[-0.18,-0.05],[0,0],[-0.23,-0.09],[-0.21,-0.15],[-0.14,-0.23],[0,-0.34],[0.21,-0.32],[0.39,-0.19],[0.56,0]],"o":[[-0.52,0],[-0.38,-0.17],[-0.22,-0.31],[0,0],[0.03,0.27],[0.16,0.18],[0.25,0.08],[0.33,0],[0.26,-0.11],[0.15,-0.2],[0,-0.23],[-0.13,-0.15],[-0.22,-0.09],[0,0],[-0.59,-0.17],[-0.33,-0.31],[0,-0.41],[0.22,-0.31],[0.38,-0.17],[0.48,0],[0.37,0.17],[0.21,0.29],[0,0],[-0.04,-0.35],[-0.3,-0.2],[-0.31,0],[-0.23,0.1],[-0.13,0.18],[0,0.25],[0.16,0.15],[0.22,0.08],[0,0],[0.2,0.05],[0.24,0.09],[0.21,0.15],[0.14,0.23],[0,0.4],[-0.21,0.32],[-0.39,0.19],[0,0]],"v":[[3.21,10.13],[1.84,9.87],[0.94,9.17],[0.57,8.1],[1.52,8.1],[1.8,8.77],[2.41,9.17],[3.21,9.3],[4.09,9.14],[4.72,8.68],[4.95,8],[4.75,7.43],[4.22,7.07],[3.51,6.82],[2.63,6.57],[1.26,5.86],[0.77,4.67],[1.1,3.6],[2,2.88],[3.27,2.63],[4.54,2.88],[5.41,3.57],[5.75,4.56],[4.84,4.56],[4.34,3.74],[3.24,3.45],[2.42,3.6],[1.87,4.02],[1.67,4.63],[1.91,5.24],[2.47,5.61],[3.06,5.81],[3.79,6.01],[4.43,6.22],[5.11,6.59],[5.64,7.16],[5.85,8.02],[5.54,9.09],[4.64,9.85],[3.21,10.13]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0.39,0.17],[0.22,0.3],[0.03,0.41],[0,0],[-0.16,-0.18],[-0.25,-0.09],[-0.28,0],[-0.26,0.11],[-0.15,0.2],[0,0.26],[0.13,0.15],[0.22,0.09],[0.26,0.07],[0,0],[0.33,0.31],[0,0.48],[-0.22,0.31],[-0.38,0.17],[-0.47,0],[-0.37,-0.17],[-0.21,-0.29],[-0.01,-0.37],[0,0],[0.3,0.19],[0.43,0],[0.24,-0.1],[0.13,-0.18],[0,-0.23],[-0.16,-0.16],[-0.21,-0.09],[-0.18,-0.05],[0,0],[-0.23,-0.09],[-0.21,-0.15],[-0.14,-0.23],[0,-0.34],[0.21,-0.32],[0.39,-0.19],[0.56,0]],"o":[[-0.52,0],[-0.38,-0.17],[-0.22,-0.31],[0,0],[0.03,0.27],[0.16,0.18],[0.25,0.08],[0.33,0],[0.26,-0.11],[0.15,-0.2],[0,-0.23],[-0.13,-0.15],[-0.22,-0.09],[0,0],[-0.59,-0.17],[-0.33,-0.31],[0,-0.41],[0.22,-0.31],[0.38,-0.17],[0.48,0],[0.37,0.17],[0.21,0.29],[0,0],[-0.04,-0.35],[-0.3,-0.2],[-0.31,0],[-0.23,0.1],[-0.13,0.18],[0,0.25],[0.16,0.15],[0.22,0.08],[0,0],[0.2,0.05],[0.24,0.09],[0.21,0.15],[0.14,0.23],[0,0.4],[-0.21,0.32],[-0.39,0.19],[0,0]],"v":[[3.21,10.13],[1.84,9.87],[0.94,9.17],[0.57,8.1],[1.52,8.1],[1.8,8.77],[2.41,9.17],[3.21,9.3],[4.09,9.14],[4.72,8.68],[4.95,8],[4.75,7.43],[4.22,7.07],[3.51,6.82],[2.63,6.57],[1.26,5.86],[0.77,4.67],[1.1,3.6],[2,2.88],[3.27,2.63],[4.54,2.88],[5.41,3.57],[5.75,4.56],[4.84,4.56],[4.34,3.74],[3.24,3.45],[2.42,3.6],[1.87,4.02],[1.67,4.63],[1.91,5.24],[2.47,5.61],[3.06,5.81],[3.79,6.01],[4.43,6.22],[5.11,6.59],[5.64,7.16],[5.85,8.02],[5.54,9.09],[4.64,9.85],[3.21,10.13]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0.39,0.17],[0.22,0.3],[0.03,0.41],[0,0],[-0.16,-0.18],[-0.25,-0.09],[-0.28,0],[-0.26,0.11],[-0.15,0.2],[0,0.26],[0.13,0.15],[0.22,0.09],[0.26,0.07],[0,0],[0.33,0.31],[0,0.48],[-0.22,0.31],[-0.38,0.17],[-0.47,0],[-0.37,-0.17],[-0.21,-0.29],[-0.01,-0.37],[0,0],[0.3,0.19],[0.43,0],[0.24,-0.1],[0.13,-0.18],[0,-0.23],[-0.16,-0.16],[-0.21,-0.09],[-0.18,-0.05],[0,0],[-0.23,-0.09],[-0.21,-0.15],[-0.14,-0.23],[0,-0.34],[0.21,-0.32],[0.39,-0.19],[0.56,0]],"o":[[-0.52,0],[-0.38,-0.17],[-0.22,-0.31],[0,0],[0.03,0.27],[0.16,0.18],[0.25,0.08],[0.33,0],[0.26,-0.11],[0.15,-0.2],[0,-0.23],[-0.13,-0.15],[-0.22,-0.09],[0,0],[-0.59,-0.17],[-0.33,-0.31],[0,-0.41],[0.22,-0.31],[0.38,-0.17],[0.48,0],[0.37,0.17],[0.21,0.29],[0,0],[-0.04,-0.35],[-0.3,-0.2],[-0.31,0],[-0.23,0.1],[-0.13,0.18],[0,0.25],[0.16,0.15],[0.22,0.08],[0,0],[0.2,0.05],[0.24,0.09],[0.21,0.15],[0.14,0.23],[0,0.4],[-0.21,0.32],[-0.39,0.19],[0,0]],"v":[[3.21,10.13],[1.84,9.87],[0.94,9.17],[0.57,8.1],[1.52,8.1],[1.8,8.77],[2.41,9.17],[3.21,9.3],[4.09,9.14],[4.72,8.68],[4.95,8],[4.75,7.43],[4.22,7.07],[3.51,6.82],[2.63,6.57],[1.26,5.86],[0.77,4.67],[1.1,3.6],[2,2.88],[3.27,2.63],[4.54,2.88],[5.41,3.57],[5.75,4.56],[4.84,4.56],[4.34,3.74],[3.24,3.45],[2.42,3.6],[1.87,4.02],[1.67,4.63],[1.91,5.24],[2.47,5.61],[3.06,5.81],[3.79,6.01],[4.43,6.22],[5.11,6.59],[5.64,7.16],[5.85,8.02],[5.54,9.09],[4.64,9.85],[3.21,10.13]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.31,0.21],[-0.41,0],[-0.28,-0.15],[-0.15,-0.31],[0,-0.46],[0,0],[0,0],[0,0],[0.22,0.24],[0.38,0],[0.21,-0.11],[0.12,-0.22],[0,-0.31]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.17,-0.5],[0.31,-0.21],[0.37,0],[0.28,0.15],[0.16,0.3],[0,0],[0,0],[0,0],[0,-0.42],[-0.22,-0.24],[-0.26,0],[-0.21,0.11],[-0.12,0.22],[0,0]],"v":[[8.07,6.73],[8.07,10],[7.19,10],[7.19,2.72],[8.07,2.72],[8.07,5.86],[7.92,5.86],[8.62,4.79],[9.71,4.47],[10.67,4.7],[11.32,5.39],[11.56,6.53],[11.56,10],[10.67,10],[10.67,6.61],[10.34,5.62],[9.44,5.26],[8.74,5.43],[8.25,5.93],[8.07,6.73]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.31,0.21],[-0.41,0],[-0.28,-0.15],[-0.15,-0.31],[0,-0.46],[0,0],[0,0],[0,0],[0.22,0.24],[0.38,0],[0.21,-0.11],[0.12,-0.22],[0,-0.31]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.17,-0.5],[0.31,-0.21],[0.37,0],[0.28,0.15],[0.16,0.3],[0,0],[0,0],[0,0],[0,-0.42],[-0.22,-0.24],[-0.26,0],[-0.21,0.11],[-0.12,0.22],[0,0]],"v":[[8.07,6.73],[8.07,10],[7.19,10],[7.19,2.72],[8.07,2.72],[8.07,5.86],[7.92,5.86],[8.62,4.79],[9.71,4.47],[10.67,4.7],[11.32,5.39],[11.56,6.53],[11.56,10],[10.67,10],[10.67,6.61],[10.34,5.62],[9.44,5.26],[8.74,5.43],[8.25,5.93],[8.07,6.73]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0.28,0.15],[0.16,0.31],[0,0.46],[0,0],[0,0],[0,0],[-0.22,-0.24],[-0.38,0],[-0.21,0.11],[-0.12,0.22],[0,0.31],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.31,-0.21],[0.4,0]],"o":[[-0.37,0],[-0.28,-0.15],[-0.15,-0.31],[0,0],[0,0],[0,0],[0,0.42],[0.22,0.24],[0.26,0],[0.21,-0.11],[0.12,-0.22],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.17,0.51],[-0.31,0.21],[0,0]],"v":[[14.96,10.07],[13.98,9.84],[13.34,9.16],[13.11,8.01],[13.11,4.54],[13.98,4.54],[13.98,7.93],[14.32,8.92],[15.22,9.28],[15.92,9.11],[16.41,8.61],[16.59,7.81],[16.59,4.54],[17.48,4.54],[17.48,10],[16.63,10],[16.63,8.68],[16.74,8.68],[16.02,9.76],[14.96,10.07]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0.28,0.15],[0.16,0.31],[0,0.46],[0,0],[0,0],[0,0],[-0.22,-0.24],[-0.38,0],[-0.21,0.11],[-0.12,0.22],[0,0.31],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.31,-0.21],[0.4,0]],"o":[[-0.37,0],[-0.28,-0.15],[-0.15,-0.31],[0,0],[0,0],[0,0],[0,0.42],[0.22,0.24],[0.26,0],[0.21,-0.11],[0.12,-0.22],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.17,0.51],[-0.31,0.21],[0,0]],"v":[[14.96,10.07],[13.98,9.84],[13.34,9.16],[13.11,8.01],[13.11,4.54],[13.98,4.54],[13.98,7.93],[14.32,8.92],[15.22,9.28],[15.92,9.11],[16.41,8.61],[16.59,7.81],[16.59,4.54],[17.48,4.54],[17.48,10],[16.63,10],[16.63,8.68],[16.74,8.68],[16.02,9.76],[14.96,10.07]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[21.17,4.54],[21.17,5.29],[18.35,5.29],[18.35,4.54],[21.17,4.54]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[21.17,4.54],[21.17,5.29],[18.35,5.29],[18.35,4.54],[21.17,4.54]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[-0.1,-0.11],[-0.23,0],[-0.08,0.01],[-0.07,0.01],[0,0],[0.12,-0.02],[0.11,0],[0.26,0.25],[0,0.45],[0,0]],"o":[[0,0],[0,0],[0,0.24],[0.1,0.11],[0.06,0],[0.09,-0.01],[0,0],[-0.09,0.03],[-0.11,0.02],[-0.47,0],[-0.26,-0.25],[0,0],[0,0]],"v":[[19.17,3.24],[20.05,3.24],[20.05,8.58],[20.2,9.12],[20.69,9.29],[20.9,9.27],[21.14,9.23],[21.32,9.97],[21.01,10.04],[20.67,10.07],[19.57,9.7],[19.17,8.65],[19.17,3.24]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[-0.1,-0.11],[-0.23,0],[-0.08,0.01],[-0.07,0.01],[0,0],[0.12,-0.02],[0.11,0],[0.26,0.25],[0,0.45],[0,0]],"o":[[0,0],[0,0],[0,0.24],[0.1,0.11],[0.06,0],[0.09,-0.01],[0,0],[-0.09,0.03],[-0.11,0.02],[-0.47,0],[-0.26,-0.25],[0,0],[0,0]],"v":[[19.17,3.24],[20.05,3.24],[20.05,8.58],[20.2,9.12],[20.69,9.29],[20.9,9.27],[21.14,9.23],[21.32,9.97],[21.01,10.04],[20.67,10.07],[19.57,9.7],[19.17,8.65],[19.17,3.24]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[24.2,4.54],[24.2,5.29],[21.38,5.29],[21.38,4.54],[24.2,4.54]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[24.2,4.54],[24.2,5.29],[21.38,5.29],[21.38,4.54],[24.2,4.54]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[-0.1,-0.11],[-0.23,0],[-0.08,0.01],[-0.07,0.01],[0,0],[0.12,-0.02],[0.11,0],[0.26,0.25],[0,0.45],[0,0]],"o":[[0,0],[0,0],[0,0.24],[0.1,0.11],[0.06,0],[0.09,-0.01],[0,0],[-0.09,0.03],[-0.11,0.02],[-0.47,0],[-0.26,-0.25],[0,0],[0,0]],"v":[[22.2,3.24],[23.08,3.24],[23.08,8.58],[23.22,9.12],[23.72,9.29],[23.93,9.27],[24.17,9.23],[24.35,9.97],[24.04,10.04],[23.7,10.07],[22.59,9.7],[22.2,8.65],[22.2,3.24]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[-0.1,-0.11],[-0.23,0],[-0.08,0.01],[-0.07,0.01],[0,0],[0.12,-0.02],[0.11,0],[0.26,0.25],[0,0.45],[0,0]],"o":[[0,0],[0,0],[0,0.24],[0.1,0.11],[0.06,0],[0.09,-0.01],[0,0],[-0.09,0.03],[-0.11,0.02],[-0.47,0],[-0.26,-0.25],[0,0],[0,0]],"v":[[22.2,3.24],[23.08,3.24],[23.08,8.58],[23.22,9.12],[23.72,9.29],[23.93,9.27],[24.17,9.23],[24.35,9.97],[24.04,10.04],[23.7,10.07],[22.59,9.7],[22.2,8.65],[22.2,3.24]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[25.32,10],[25.32,4.54],[26.2,4.54],[26.2,10],[25.32,10]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[25.32,10],[25.32,4.54],[26.2,4.54],[26.2,10],[25.32,10]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0.12,0.11],[0,0.16],[-0.12,0.11],[-0.17,0],[-0.12,-0.11],[0,-0.16],[0.12,-0.11],[0.17,0]],"o":[[-0.17,0],[-0.12,-0.11],[0,-0.16],[0.12,-0.11],[0.17,0],[0.12,0.11],[0,0.16],[-0.12,0.11],[0,0]],"v":[[25.77,3.65],[25.34,3.48],[25.16,3.07],[25.34,2.66],[25.77,2.49],[26.2,2.66],[26.38,3.07],[26.2,3.48],[25.77,3.65]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0.12,0.11],[0,0.16],[-0.12,0.11],[-0.17,0],[-0.12,-0.11],[0,-0.16],[0.12,-0.11],[0.17,0]],"o":[[-0.17,0],[-0.12,-0.11],[0,-0.16],[0.12,-0.11],[0.17,0],[0.12,0.11],[0,0.16],[-0.12,0.11],[0,0]],"v":[[25.77,3.65],[25.34,3.48],[25.16,3.07],[25.34,2.66],[25.77,2.49],[26.2,2.66],[26.38,3.07],[26.2,3.48],[25.77,3.65]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.31,0.21],[-0.41,0],[-0.28,-0.15],[-0.15,-0.31],[0,-0.46],[0,0],[0,0],[0,0],[0.22,0.24],[0.38,0],[0.21,-0.11],[0.12,-0.22],[0,-0.31]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.17,-0.5],[0.31,-0.21],[0.37,0],[0.28,0.15],[0.16,0.3],[0,0],[0,0],[0,0],[0,-0.42],[-0.22,-0.24],[-0.26,0],[-0.21,0.11],[-0.12,0.22],[0,0]],"v":[[28.62,6.73],[28.62,10],[27.74,10],[27.74,4.54],[28.59,4.54],[28.59,5.86],[28.47,5.86],[29.18,4.79],[30.26,4.47],[31.23,4.7],[31.88,5.39],[32.11,6.53],[32.11,10],[31.23,10],[31.23,6.61],[30.9,5.62],[30,5.26],[29.3,5.43],[28.8,5.93],[28.62,6.73]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.31,0.21],[-0.41,0],[-0.28,-0.15],[-0.15,-0.31],[0,-0.46],[0,0],[0,0],[0,0],[0.22,0.24],[0.38,0],[0.21,-0.11],[0.12,-0.22],[0,-0.31]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.17,-0.5],[0.31,-0.21],[0.37,0],[0.28,0.15],[0.16,0.3],[0,0],[0,0],[0,0],[0,-0.42],[-0.22,-0.24],[-0.26,0],[-0.21,0.11],[-0.12,0.22],[0,0]],"v":[[28.62,6.73],[28.62,10],[27.74,10],[27.74,4.54],[28.59,4.54],[28.59,5.86],[28.47,5.86],[29.18,4.79],[30.26,4.47],[31.23,4.7],[31.88,5.39],[32.11,6.53],[32.11,10],[31.23,10],[31.23,6.61],[30.9,5.62],[30,5.26],[29.3,5.43],[28.8,5.93],[28.62,6.73]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0.3,0.1],[0.2,0.17],[0.11,0.2],[0,0],[-0.11,-0.13],[-0.2,-0.09],[-0.32,0],[-0.28,0.21],[0,0.45],[0,0],[0,0],[0.11,-0.14],[0.21,-0.11],[0.35,0],[0.35,0.21],[0.2,0.4],[0,0.57],[-0.2,0.41],[-0.35,0.23],[-0.45,0],[-0.21,-0.12],[-0.11,-0.15],[-0.06,-0.1],[0,0],[0,0],[0,0],[0,0],[0.21,-0.3],[0.36,-0.14],[0.44,0]],"o":[[-0.4,0],[-0.29,-0.1],[-0.2,-0.17],[0,0],[0.08,0.1],[0.12,0.13],[0.2,0.09],[0.44,0],[0.28,-0.21],[0,0],[0,0],[-0.06,0.1],[-0.11,0.14],[-0.21,0.11],[-0.44,0],[-0.35,-0.21],[-0.2,-0.4],[0,-0.56],[0.2,-0.42],[0.35,-0.23],[0.35,0],[0.21,0.11],[0.11,0.15],[0,0],[0,0],[0,0],[0,0],[0,0.47],[-0.21,0.3],[-0.36,0.14],[0,0]],"v":[[35.86,12.16],[34.81,12],[34.08,11.6],[33.62,11.04],[34.33,10.59],[34.62,10.93],[35.09,11.25],[35.86,11.39],[36.94,11.08],[37.36,10.09],[37.36,9],[37.28,9],[37.02,9.37],[36.53,9.75],[35.69,9.91],[34.52,9.6],[33.69,8.7],[33.39,7.25],[33.69,5.78],[34.51,4.81],[35.71,4.47],[36.55,4.65],[37.04,5.04],[37.3,5.42],[37.39,5.42],[37.39,4.54],[38.24,4.54],[38.24,10.14],[37.92,11.29],[37.07,11.95],[35.86,12.16]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0.3,0.1],[0.2,0.17],[0.11,0.2],[0,0],[-0.11,-0.13],[-0.2,-0.09],[-0.32,0],[-0.28,0.21],[0,0.45],[0,0],[0,0],[0.11,-0.14],[0.21,-0.11],[0.35,0],[0.35,0.21],[0.2,0.4],[0,0.57],[-0.2,0.41],[-0.35,0.23],[-0.45,0],[-0.21,-0.12],[-0.11,-0.15],[-0.06,-0.1],[0,0],[0,0],[0,0],[0,0],[0.21,-0.3],[0.36,-0.14],[0.44,0]],"o":[[-0.4,0],[-0.29,-0.1],[-0.2,-0.17],[0,0],[0.08,0.1],[0.12,0.13],[0.2,0.09],[0.44,0],[0.28,-0.21],[0,0],[0,0],[-0.06,0.1],[-0.11,0.14],[-0.21,0.11],[-0.44,0],[-0.35,-0.21],[-0.2,-0.4],[0,-0.56],[0.2,-0.42],[0.35,-0.23],[0.35,0],[0.21,0.11],[0.11,0.15],[0,0],[0,0],[0,0],[0,0],[0,0.47],[-0.21,0.3],[-0.36,0.14],[0,0]],"v":[[35.86,12.16],[34.81,12],[34.08,11.6],[33.62,11.04],[34.33,10.59],[34.62,10.93],[35.09,11.25],[35.86,11.39],[36.94,11.08],[37.36,10.09],[37.36,9],[37.28,9],[37.02,9.37],[36.53,9.75],[35.69,9.91],[34.52,9.6],[33.69,8.7],[33.39,7.25],[33.69,5.78],[34.51,4.81],[35.71,4.47],[36.55,4.65],[37.04,5.04],[37.3,5.42],[37.39,5.42],[37.39,4.54],[38.24,4.54],[38.24,10.14],[37.92,11.29],[37.07,11.95],[35.86,12.16]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[-0.23,0.15],[-0.12,0.28],[0,0.4],[0.12,0.29],[0.23,0.17],[0.34,0],[0.23,-0.18],[0.12,-0.3],[0,-0.36],[-0.12,-0.29],[-0.23,-0.16],[-0.34,0]],"o":[[0.33,0],[0.23,-0.15],[0.12,-0.29],[0,-0.39],[-0.11,-0.3],[-0.23,-0.17],[-0.34,0],[-0.23,0.18],[-0.11,0.3],[0,0.37],[0.12,0.29],[0.23,0.16],[0,0]],"v":[[35.84,9.13],[36.68,8.91],[37.2,8.25],[37.37,7.23],[37.2,6.21],[36.68,5.51],[35.84,5.26],[34.98,5.53],[34.45,6.24],[34.28,7.23],[34.46,8.22],[34.98,8.89],[35.84,9.13]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[-0.23,0.15],[-0.12,0.28],[0,0.4],[0.12,0.29],[0.23,0.17],[0.34,0],[0.23,-0.18],[0.12,-0.3],[0,-0.36],[-0.12,-0.29],[-0.23,-0.16],[-0.34,0]],"o":[[0.33,0],[0.23,-0.15],[0.12,-0.29],[0,-0.39],[-0.11,-0.3],[-0.23,-0.17],[-0.34,0],[-0.23,0.18],[-0.11,0.3],[0,0.37],[0.12,0.29],[0.23,0.16],[0,0]],"v":[[35.84,9.13],[36.68,8.91],[37.2,8.25],[37.37,7.23],[37.2,6.21],[36.68,5.51],[35.84,5.26],[34.98,5.53],[34.45,6.24],[34.28,7.23],[34.46,8.22],[34.98,8.89],[35.84,9.13]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0.35,0.23],[0.2,0.42],[0,0.58],[-0.2,0.42],[-0.35,0.23],[-0.45,0],[-0.21,-0.12],[-0.11,-0.15],[-0.06,-0.1],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.12,-0.15],[0.21,-0.12],[0.35,0]],"o":[[-0.45,0],[-0.35,-0.23],[-0.2,-0.42],[0,-0.58],[0.2,-0.42],[0.35,-0.23],[0.35,0],[0.21,0.12],[0.11,0.15],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.06,0.1],[-0.11,0.15],[-0.21,0.12],[0,0]],"v":[[44.64,10.12],[43.44,9.77],[42.63,8.79],[42.33,7.29],[42.63,5.79],[43.45,4.81],[44.65,4.47],[45.49,4.65],[45.97,5.05],[46.23,5.42],[46.3,5.42],[46.3,2.72],[47.18,2.72],[47.18,10],[46.33,10],[46.33,9.16],[46.23,9.16],[45.97,9.54],[45.48,9.94],[44.64,10.12]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0.35,0.23],[0.2,0.42],[0,0.58],[-0.2,0.42],[-0.35,0.23],[-0.45,0],[-0.21,-0.12],[-0.11,-0.15],[-0.06,-0.1],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.12,-0.15],[0.21,-0.12],[0.35,0]],"o":[[-0.45,0],[-0.35,-0.23],[-0.2,-0.42],[0,-0.58],[0.2,-0.42],[0.35,-0.23],[0.35,0],[0.21,0.12],[0.11,0.15],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.06,0.1],[-0.11,0.15],[-0.21,0.12],[0,0]],"v":[[44.64,10.12],[43.44,9.77],[42.63,8.79],[42.33,7.29],[42.63,5.79],[43.45,4.81],[44.65,4.47],[45.49,4.65],[45.97,5.05],[46.23,5.42],[46.3,5.42],[46.3,2.72],[47.18,2.72],[47.18,10],[46.33,10],[46.33,9.16],[46.23,9.16],[45.97,9.54],[45.48,9.94],[44.64,10.12]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[-0.23,0.17],[-0.12,0.31],[0,0.4],[0.12,0.3],[0.23,0.17],[0.34,0],[0.23,-0.18],[0.11,-0.31],[0,-0.38],[-0.11,-0.31],[-0.23,-0.19],[-0.34,0]],"o":[[0.33,0],[0.23,-0.18],[0.12,-0.31],[0,-0.4],[-0.11,-0.3],[-0.23,-0.17],[-0.35,0],[-0.23,0.18],[-0.11,0.3],[0,0.38],[0.12,0.31],[0.23,0.18],[0,0]],"v":[[44.78,9.33],[45.62,9.07],[46.13,8.34],[46.31,7.28],[46.13,6.22],[45.62,5.51],[44.78,5.26],[43.91,5.53],[43.4,6.25],[43.23,7.28],[43.4,8.32],[43.92,9.06],[44.78,9.33]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[-0.23,0.17],[-0.12,0.31],[0,0.4],[0.12,0.3],[0.23,0.17],[0.34,0],[0.23,-0.18],[0.11,-0.31],[0,-0.38],[-0.11,-0.31],[-0.23,-0.19],[-0.34,0]],"o":[[0.33,0],[0.23,-0.18],[0.12,-0.31],[0,-0.4],[-0.11,-0.3],[-0.23,-0.17],[-0.35,0],[-0.23,0.18],[-0.11,0.3],[0,0.38],[0.12,0.31],[0.23,0.18],[0,0]],"v":[[44.78,9.33],[45.62,9.07],[46.13,8.34],[46.31,7.28],[46.13,6.22],[45.62,5.51],[44.78,5.26],[43.91,5.53],[43.4,6.25],[43.23,7.28],[43.4,8.32],[43.92,9.06],[44.78,9.33]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0.37,0.23],[0.21,0.42],[0,0.56],[-0.21,0.42],[-0.37,0.23],[-0.49,0],[-0.37,-0.23],[-0.21,-0.43],[0,-0.57],[0.21,-0.42],[0.37,-0.23],[0.5,0]],"o":[[-0.49,0],[-0.37,-0.23],[-0.21,-0.42],[0,-0.57],[0.21,-0.43],[0.37,-0.23],[0.5,0],[0.37,0.23],[0.21,0.42],[0,0.56],[-0.21,0.42],[-0.37,0.23],[0,0]],"v":[[50.94,10.12],[49.64,9.77],[48.77,8.78],[48.46,7.3],[48.77,5.82],[49.64,4.82],[50.94,4.47],[52.25,4.82],[53.13,5.82],[53.44,7.3],[53.13,8.78],[52.25,9.77],[50.94,10.12]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0.37,0.23],[0.21,0.42],[0,0.56],[-0.21,0.42],[-0.37,0.23],[-0.49,0],[-0.37,-0.23],[-0.21,-0.43],[0,-0.57],[0.21,-0.42],[0.37,-0.23],[0.5,0]],"o":[[-0.49,0],[-0.37,-0.23],[-0.21,-0.42],[0,-0.57],[0.21,-0.43],[0.37,-0.23],[0.5,0],[0.37,0.23],[0.21,0.42],[0,0.56],[-0.21,0.42],[-0.37,0.23],[0,0]],"v":[[50.94,10.12],[49.64,9.77],[48.77,8.78],[48.46,7.3],[48.77,5.82],[49.64,4.82],[50.94,4.47],[52.25,4.82],[53.13,5.82],[53.44,7.3],[53.13,8.78],[52.25,9.77],[50.94,10.12]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[-0.24,0.19],[-0.11,0.31],[0,0.36],[0.11,0.31],[0.24,0.19],[0.37,0],[0.23,-0.19],[0.11,-0.31],[0,-0.36],[-0.11,-0.31],[-0.23,-0.19],[-0.36,0]],"o":[[0.37,0],[0.24,-0.19],[0.11,-0.31],[0,-0.36],[-0.11,-0.31],[-0.24,-0.19],[-0.36,0],[-0.23,0.19],[-0.11,0.31],[0,0.36],[0.11,0.31],[0.23,0.19],[0,0]],"v":[[50.94,9.33],[51.85,9.05],[52.38,8.31],[52.55,7.3],[52.38,6.3],[51.85,5.55],[50.94,5.26],[50.04,5.55],[49.52,6.29],[49.35,7.3],[49.52,8.31],[50.04,9.05],[50.94,9.33]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[-0.24,0.19],[-0.11,0.31],[0,0.36],[0.11,0.31],[0.24,0.19],[0.37,0],[0.23,-0.19],[0.11,-0.31],[0,-0.36],[-0.11,-0.31],[-0.23,-0.19],[-0.36,0]],"o":[[0.37,0],[0.24,-0.19],[0.11,-0.31],[0,-0.36],[-0.11,-0.31],[-0.24,-0.19],[-0.36,0],[-0.23,0.19],[-0.11,0.31],[0,0.36],[0.11,0.31],[0.23,0.19],[0,0]],"v":[[50.94,9.33],[51.85,9.05],[52.38,8.31],[52.55,7.3],[52.38,6.3],[51.85,5.55],[50.94,5.26],[50.04,5.55],[49.52,6.29],[49.35,7.3],[49.52,8.31],[50.04,9.05],[50.94,9.33]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[-0.1,-0.41],[-0.1,-0.52],[0,0],[-0.1,0.41],[-0.09,0.35],[0,0],[0,0],[0,0],[-0.1,-0.41],[-0.1,-0.51],[0,0],[-0.1,0.41],[-0.09,0.34],[0,0],[0,0],[0,0],[0,0],[0,0],[0.07,0.26],[0.07,0.27],[0.07,0.28],[0,0],[0.07,-0.28],[0.07,-0.26],[0.07,-0.24],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0.09,0.33],[0.1,0.41],[0,0],[0.1,-0.5],[0.1,-0.41],[0,0],[0,0],[0,0],[0.09,0.34],[0.1,0.41],[0,0],[0.1,-0.5],[0.1,-0.41],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.07,-0.25],[-0.07,-0.26],[-0.07,-0.27],[0,0],[-0.07,0.28],[-0.07,0.27],[-0.07,0.26],[0,0],[0,0],[0,0]],"v":[[55.76,10],[54.1,4.54],[55.03,4.54],[55.7,6.92],[55.99,8.03],[56.3,9.43],[56.15,9.43],[56.45,8.06],[56.74,6.92],[57.39,4.54],[58.33,4.54],[58.97,6.92],[59.26,8.05],[59.56,9.43],[59.4,9.43],[59.71,8.06],[60,6.92],[60.67,4.54],[61.6,4.54],[59.95,10],[59.07,10],[58.36,7.53],[58.15,6.76],[57.95,5.96],[57.75,5.13],[57.95,5.13],[57.75,5.96],[57.55,6.77],[57.34,7.53],[56.63,10],[55.76,10]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[-0.1,-0.41],[-0.1,-0.52],[0,0],[-0.1,0.41],[-0.09,0.35],[0,0],[0,0],[0,0],[-0.1,-0.41],[-0.1,-0.51],[0,0],[-0.1,0.41],[-0.09,0.34],[0,0],[0,0],[0,0],[0,0],[0,0],[0.07,0.26],[0.07,0.27],[0.07,0.28],[0,0],[0.07,-0.28],[0.07,-0.26],[0.07,-0.24],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0.09,0.33],[0.1,0.41],[0,0],[0.1,-0.5],[0.1,-0.41],[0,0],[0,0],[0,0],[0.09,0.34],[0.1,0.41],[0,0],[0.1,-0.5],[0.1,-0.41],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.07,-0.25],[-0.07,-0.26],[-0.07,-0.27],[0,0],[-0.07,0.28],[-0.07,0.27],[-0.07,0.26],[0,0],[0,0],[0,0]],"v":[[55.76,10],[54.1,4.54],[55.03,4.54],[55.7,6.92],[55.99,8.03],[56.3,9.43],[56.15,9.43],[56.45,8.06],[56.74,6.92],[57.39,4.54],[58.33,4.54],[58.97,6.92],[59.26,8.05],[59.56,9.43],[59.4,9.43],[59.71,8.06],[60,6.92],[60.67,4.54],[61.6,4.54],[59.95,10],[59.07,10],[58.36,7.53],[58.15,6.76],[57.95,5.96],[57.75,5.13],[57.95,5.13],[57.75,5.96],[57.55,6.77],[57.34,7.53],[56.63,10],[55.76,10]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.31,0.21],[-0.41,0],[-0.28,-0.15],[-0.15,-0.31],[0,-0.46],[0,0],[0,0],[0,0],[0.22,0.24],[0.38,0],[0.21,-0.11],[0.12,-0.22],[0,-0.31]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.17,-0.5],[0.31,-0.21],[0.37,0],[0.28,0.15],[0.16,0.3],[0,0],[0,0],[0,0],[0,-0.42],[-0.22,-0.24],[-0.26,0],[-0.21,0.11],[-0.12,0.22],[0,0]],"v":[[63.59,6.73],[63.59,10],[62.71,10],[62.71,4.54],[63.56,4.54],[63.56,5.86],[63.44,5.86],[64.15,4.79],[65.23,4.47],[66.2,4.7],[66.85,5.39],[67.08,6.53],[67.08,10],[66.2,10],[66.2,6.61],[65.87,5.62],[64.97,5.26],[64.27,5.43],[63.77,5.93],[63.59,6.73]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.31,0.21],[-0.41,0],[-0.28,-0.15],[-0.15,-0.31],[0,-0.46],[0,0],[0,0],[0,0],[0.22,0.24],[0.38,0],[0.21,-0.11],[0.12,-0.22],[0,-0.31]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.17,-0.5],[0.31,-0.21],[0.37,0],[0.28,0.15],[0.16,0.3],[0,0],[0,0],[0,0],[0,-0.42],[-0.22,-0.24],[-0.26,0],[-0.21,0.11],[-0.12,0.22],[0,0]],"v":[[63.59,6.73],[63.59,10],[62.71,10],[62.71,4.54],[63.56,4.54],[63.56,5.86],[63.44,5.86],[64.15,4.79],[65.23,4.47],[66.2,4.7],[66.85,5.39],[67.08,6.53],[67.08,10],[66.2,10],[66.2,6.61],[65.87,5.62],[64.97,5.26],[64.27,5.43],[63.77,5.93],[63.59,6.73]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0.13,0.13],[0,0.18],[-0.13,0.13],[-0.18,0],[-0.13,-0.13],[0,-0.18],[0.13,-0.13],[0.18,0]],"o":[[-0.18,0],[-0.13,-0.13],[0,-0.18],[0.13,-0.13],[0.18,0],[0.13,0.13],[0,0.18],[-0.13,0.13],[0,0]],"v":[[69.29,10.06],[68.82,9.87],[68.63,9.4],[68.82,8.94],[69.29,8.75],[69.76,8.94],[69.95,9.4],[69.76,9.87],[69.29,10.06]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0.13,0.13],[0,0.18],[-0.13,0.13],[-0.18,0],[-0.13,-0.13],[0,-0.18],[0.13,-0.13],[0.18,0]],"o":[[-0.18,0],[-0.13,-0.13],[0,-0.18],[0.13,-0.13],[0.18,0],[0.13,0.13],[0,0.18],[-0.13,0.13],[0,0]],"v":[[69.29,10.06],[68.82,9.87],[68.63,9.4],[68.82,8.94],[69.29,8.75],[69.76,8.94],[69.95,9.4],[69.76,9.87],[69.29,10.06]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0.13,0.13],[0,0.18],[-0.13,0.13],[-0.18,0],[-0.13,-0.13],[0,-0.18],[0.13,-0.13],[0.18,0]],"o":[[-0.18,0],[-0.13,-0.13],[0,-0.18],[0.13,-0.13],[0.18,0],[0.13,0.13],[0,0.18],[-0.13,0.13],[0,0]],"v":[[72.17,10.06],[71.7,9.87],[71.51,9.4],[71.7,8.94],[72.17,8.75],[72.64,8.94],[72.83,9.4],[72.64,9.87],[72.17,10.06]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0.13,0.13],[0,0.18],[-0.13,0.13],[-0.18,0],[-0.13,-0.13],[0,-0.18],[0.13,-0.13],[0.18,0]],"o":[[-0.18,0],[-0.13,-0.13],[0,-0.18],[0.13,-0.13],[0.18,0],[0.13,0.13],[0,0.18],[-0.13,0.13],[0,0]],"v":[[72.17,10.06],[71.7,9.87],[71.51,9.4],[71.7,8.94],[72.17,8.75],[72.64,8.94],[72.83,9.4],[72.64,9.87],[72.17,10.06]]}],"t":396}]}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[],"o":[],"v":[]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0.13,0.13],[0,0.18],[-0.13,0.13],[-0.18,0],[-0.13,-0.13],[0,-0.18],[0.13,-0.13],[0.18,0]],"o":[[-0.18,0],[-0.13,-0.13],[0,-0.18],[0.13,-0.13],[0.18,0],[0.13,0.13],[0,0.18],[-0.13,0.13],[0,0]],"v":[[75.05,10.06],[74.58,9.87],[74.39,9.4],[74.58,8.94],[75.05,8.75],[75.52,8.94],[75.71,9.4],[75.52,9.87],[75.05,10.06]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0.13,0.13],[0,0.18],[-0.13,0.13],[-0.18,0],[-0.13,-0.13],[0,-0.18],[0.13,-0.13],[0.18,0]],"o":[[-0.18,0],[-0.13,-0.13],[0,-0.18],[0.13,-0.13],[0.18,0],[0.13,0.13],[0,0.18],[-0.13,0.13],[0,0]],"v":[[75.05,10.06],[74.58,9.87],[74.39,9.4],[74.58,8.94],[75.05,8.75],[75.52,8.94],[75.71,9.4],[75.52,9.87],[75.05,10.06]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1,1,1],"t":276},{"s":[1,1,1],"t":396}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":10},{"ty":4,"nm":"Frame 427322354 Bg","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[55,115],"t":408},{"s":[55,115],"t":456}]},"s":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":408},{"s":[100,100],"t":456}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,115],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[55,115],"t":408},{"s":[55,115],"t":456}]},"r":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":408},{"s":[0],"t":456}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":408},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":456}]}}],"ind":11}]},{"nm":"[Asset] Frame 427322356","id":"2","layers":[{"ty":4,"nm":"Ellipse 21629","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[13,13],"t":408},{"s":[13,13],"t":456}]},"s":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":408},{"s":[100,100],"t":456}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[51,51],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[51,51],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[51,51],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[51,51],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[51,51],"t":408},{"s":[51,51],"t":456}]},"r":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":408},{"s":[0],"t":456}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396.06},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":408},{"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":456}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0.2824,0.2824,0.2824],"t":408},{"s":[0.2824,0.2824,0.2824],"t":456}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}}],"ind":1},{"ty":4,"nm":"Ellipse 21628","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[13,13],"t":408},{"s":[13,13],"t":456}]},"s":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":408},{"s":[100,100],"t":456}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[19,51],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[19,51],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[19,51],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[19,51],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[19,51],"t":408},{"s":[19,51],"t":456}]},"r":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":408},{"s":[0],"t":456}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396.06},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":408},{"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":456}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.3765,0.3765,0.3765],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.3765,0.3765,0.3765],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0.2824,0.2824,0.2824],"t":408},{"s":[0.2824,0.2824,0.2824],"t":456}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}}],"ind":2},{"ty":4,"nm":"Ellipse 21627","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[13,13],"t":408},{"s":[13,13],"t":456}]},"s":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":408},{"s":[100,100],"t":456}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[51,19],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[51,19],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[51,19],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[51,19],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[51,19],"t":408},{"s":[51,19],"t":456}]},"r":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":408},{"s":[0],"t":456}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396.06},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":408},{"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":456}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0.2824,0.2824,0.2824],"t":408},{"s":[0.2824,0.2824,0.2824],"t":456}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}}],"ind":3},{"ty":4,"nm":"Ellipse 21626","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[13,13],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[13,13],"t":408},{"s":[13,13],"t":456}]},"s":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":408},{"s":[100,100],"t":456}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[19,19],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[19,19],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[19,19],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[19,19],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[19,19],"t":408},{"s":[19,19],"t":456}]},"r":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":408},{"s":[0],"t":456}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396.06},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":408},{"s":[{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}],"t":456}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8432,0.0981,0.1295],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8432,0.0981,0.1295],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8432,0.0981,0.1295],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.8432,0.0981,0.1295],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0.8432,0.0981,0.1295],"t":408},{"s":[0.8432,0.0981,0.1295],"t":456}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}}],"ind":4},{"ty":4,"nm":"Rectangle 156","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[35,39],"t":408},{"s":[35,39],"t":456}]},"s":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":408},{"s":[100,100],"t":456}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[35,39],"t":408},{"s":[35,39],"t":456}]},"r":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":408},{"s":[0],"t":456}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396.06},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-2.94],[0,0],[2.94,0],[0,0],[0,2.94],[0,0],[-2.94,0],[0,0]],"o":[[0,0],[0,2.94],[0,0],[-2.94,0],[0,0],[0,-2.94],[0,0],[2.94,0]],"v":[[70,5.32],[70,72.68],[64.68,78],[5.32,78],[0,72.68],[0,5.32],[5.32,0],[64.68,0]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-2.94],[0,0],[2.94,0],[0,0],[0,2.94],[0,0],[-2.94,0],[0,0]],"o":[[0,0],[0,2.94],[0,0],[-2.94,0],[0,0],[0,-2.94],[0,0],[2.94,0]],"v":[[70,5.32],[70,72.68],[64.68,78],[5.32,78],[0,72.68],[0,5.32],[5.32,0],[64.68,0]]}],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-2.94],[0,0],[2.94,0],[0,0],[0,2.94],[0,0],[-2.94,0],[0,0]],"o":[[0,0],[0,2.94],[0,0],[-2.94,0],[0,0],[0,-2.94],[0,0],[2.94,0]],"v":[[70,5.32],[70,72.68],[64.68,78],[5.32,78],[0,72.68],[0,5.32],[5.32,0],[64.68,0]]}],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,-2.94],[0,0],[2.94,0],[0,0],[0,2.94],[0,0],[-2.94,0],[0,0]],"o":[[0,0],[0,2.94],[0,0],[-2.94,0],[0,0],[0,-2.94],[0,0],[2.94,0]],"v":[[70,5.32],[70,72.68],[64.68,78],[5.32,78],[0,72.68],[0,5.32],[5.32,0],[64.68,0]]}],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,-2.94],[0,0],[2.94,0],[0,0],[0,2.94],[0,0],[-2.94,0],[0,0]],"o":[[0,0],[0,2.94],[0,0],[-2.94,0],[0,0],[0,-2.94],[0,0],[2.94,0]],"v":[[70,5.32],[70,72.68],[64.68,78],[5.32,78],[0,72.68],[0,5.32],[5.32,0],[64.68,0]]}],"t":408},{"s":[{"c":true,"i":[[0,-2.94],[0,0],[2.94,0],[0,0],[0,2.94],[0,0],[-2.94,0],[0,0]],"o":[[0,0],[0,2.94],[0,0],[-2.94,0],[0,0],[0,-2.94],[0,0],[2.94,0]],"v":[[70,5.32],[70,72.68],[64.68,78],[5.32,78],[0,72.68],[0,5.32],[5.32,0],[64.68,0]]}],"t":456}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.1942,0.1942,0.1942],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0.1942,0.1942,0.1942],"t":408},{"s":[0.1942,0.1942,0.1942],"t":456}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}}],"ind":5},{"ty":4,"nm":"Frame 427322356 Bg","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[35,39],"t":408},{"s":[35,39],"t":456}]},"s":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100,100],"t":408},{"s":[100,100],"t":456}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[35,39],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[35,39],"t":408},{"s":[35,39],"t":456}]},"r":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0],"t":408},{"s":[0],"t":456}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396.06},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[70,0],[70,78],[0,78],[0,0]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[70,0],[70,78],[0,78],[0,0]]}],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[70,0],[70,78],[0,78],[0,0]]}],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[70,0],[70,78],[0,78],[0,0]]}],"t":72},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[70,0],[70,78],[0,78],[0,0]]}],"t":408},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[70,0],[70,78],[0,78],[0,0]]}],"t":456}]}}],"ind":6}]},{"nm":"[Asset] Group 1","id":"3","layers":[{"ty":4,"nm":"Ellipse 581","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,3],"t":276},{"s":[63,3],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":1},{"ty":4,"nm":"Ellipse 582","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,3],"t":276},{"s":[33,3],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":2},{"ty":4,"nm":"Ellipse 588","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,33],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,33],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,33],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,33],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,33],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,33],"t":276},{"s":[3,33],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":3},{"ty":4,"nm":"Ellipse 587","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":276},{"s":[33,33],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":4},{"ty":4,"nm":"Ellipse 586","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,33],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,33],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,33],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,33],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,33],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,33],"t":276},{"s":[63,33],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":5},{"ty":4,"nm":"Ellipse 585","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,63],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,63],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,63],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,63],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,63],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,63],"t":276},{"s":[63,63],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":6},{"ty":4,"nm":"Ellipse 584","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,63],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,63],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,63],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,63],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,63],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,63],"t":276},{"s":[33,63],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":7},{"ty":4,"nm":"Ellipse 583","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,63],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,63],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,63],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,63],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,63],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,63],"t":276},{"s":[3,63],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":8},{"ty":4,"nm":"Ellipse 572","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100,100],"t":276},{"s":[100,100],"t":396}]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"s":[0],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"s":[100],"t":396}]}}],"ind":9}]}]}
\ No newline at end of file
diff --git a/res/raw/lottie_gesture_screenshot.json b/res/raw/lottie_gesture_screenshot.json
new file mode 100644
index 00000000..a38003d4
--- /dev/null
+++ b/res/raw/lottie_gesture_screenshot.json
@@ -0,0 +1 @@
+{"v":"5.12.2","fr":60,"ip":1,"op":353,"w":382,"h":224,"nm":"Screenshot gesture_Light","ddd":0,"assets":[{"id":"comp_0","nm":"Pre-comp 4","fr":60,"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Pre-comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[302.812,145.5,0],"ix":2,"l":2},"a":{"a":0,"k":[228.313,78.75,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"w":382,"h":224,"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Pre-comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[227.812,146,0],"ix":2,"l":2},"a":{"a":0,"k":[228.313,78.75,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"w":382,"h":224,"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"Pre-comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[302.812,78,0],"ix":2,"l":2},"a":{"a":0,"k":[228.313,78.75,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"w":382,"h":224,"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"Pre-comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[227.812,78.25,0],"ix":2,"l":2},"a":{"a":0,"k":[228.313,78.75,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"w":382,"h":224,"ip":0,"op":400,"st":0,"ct":1,"bm":0}]},{"id":"comp_1","nm":"Pre-comp 2","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 23","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[229.219,76.281,0],"ix":2,"l":2},"a":{"a":0,"k":[33.5,-35.25,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[33.5,-32.25],[33.5,-38.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.105882352941,0.105882352941,0.113725490196,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 22","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[226.281,79.906,0],"ix":2,"l":2},"a":{"a":0,"k":[33.5,-35.25,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[33.5,-32.25],[33.5,-38.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.105882352941,0.105882352941,0.113725490196,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Pre-comp 4","refId":"comp_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":118,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":139,"s":[50]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[60]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[265,113,0],"ix":2,"l":2},"a":{"a":0,"k":[265,113,0],"ix":1,"l":2},"s":{"a":0,"k":[99,99,100],"ix":6,"l":2}},"ao":0,"w":382,"h":224,"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 21","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[298.692,193.388,0],"ix":2,"l":2},"a":{"a":0,"k":[81.853,-81.147,0],"ix":1,"l":2},"s":{"a":0,"k":[130,130,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[9.705,9.705],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.780392156863,0.776470588235,0.792156862745,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[81.853,-81.147],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 20","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[231.308,193.388,0],"ix":2,"l":2},"a":{"a":0,"k":[81.853,-81.147,0],"ix":1,"l":2},"s":{"a":0,"k":[130,130,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[9.705,9.705],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.780392156863,0.776470588235,0.792156862745,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[81.853,-81.147],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 19","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[301.103,29.888,0],"ix":2,"l":2},"a":{"a":0,"k":[81.853,-81.147,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[9.705,9.705],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.780392156863,0.776470588235,0.792156862745,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[81.853,-81.147],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 18","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[289.269,29.888,0],"ix":2,"l":2},"a":{"a":0,"k":[81.853,-81.147,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[9.705,9.705],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.780392156863,0.776470588235,0.792156862745,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[81.853,-81.147],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 17","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[277.436,29.888,0],"ix":2,"l":2},"a":{"a":0,"k":[81.853,-81.147,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[9.705,9.705],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.780392156863,0.776470588235,0.792156862745,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[81.853,-81.147],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 16","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[265.603,29.888,0],"ix":2,"l":2},"a":{"a":0,"k":[81.853,-81.147,0],"ix":1,"l":2},"s":{"a":0,"k":[90,90,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[9.705,9.705],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.780392156863,0.776470588235,0.792156862745,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[81.853,-81.147],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 15","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":112,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":133,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[237.829,29.888,0],"ix":2,"l":2},"a":{"a":0,"k":[48.829,-82.044,0],"ix":1,"l":2},"s":{"a":0,"k":[84.827,105.728,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[29.658,10.912],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.881463982077,0.881463982077,0.881463982077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.84313731474,0.098039223166,0.129411764706,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[48.829,-82.044],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":3,"nm":"Null 1","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[264.5,90,0],"to":[0,12,0],"ti":[0,-12,0]},{"t":101,"s":[264.5,162,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19,19,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":414,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Shape Layer 12","parent":9,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[121.053,-0.877,0],"ix":2,"l":2},"a":{"a":0,"k":[-2,-12,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":22,"s":[507.053,507.053,100]},{"t":29,"s":[421.053,421.053,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.843137015548,0.098038998772,0.1294119891,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":106,"st":-20,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Shape Layer 11","parent":9,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1.316,-42.982,0],"ix":2,"l":2},"a":{"a":0,"k":[-2,-12,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":22,"s":[507.053,507.053,100]},{"t":29,"s":[421.053,421.053,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.843137015548,0.098038998772,0.1294119891,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":106,"st":-20,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Shape Layer 10","parent":9,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-118.421,-0.877,0],"ix":2,"l":2},"a":{"a":0,"k":[-2,-12,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":22,"s":[507.053,507.053,100]},{"t":29,"s":[421.053,421.053,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.843137015548,0.098038998772,0.1294119891,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":106,"st":-20,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Shape Layer 14","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":225,"s":[100]},{"t":235,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":106,"s":[264.692,119.514,0],"to":[0.052,-1.254,0],"ti":[-0.052,1.254,0]},{"t":127,"s":[265.005,111.991,0]}],"ix":2,"l":2},"a":{"a":0,"k":[73.442,-14.236,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":106,"s":[100,100,100]},{"t":127,"s":[90,90,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[41.627,-45.296],[41.504,-44.704],[-41.75,-44.704],[-41.627,-45.296]],"c":true}]},{"t":101,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[41.627,-45.296],[41.258,30.296],[-41.996,30.296],[-41.627,-45.296]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"rd","nm":"Round Corners 1","r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":106,"s":[4]},{"t":127,"s":[0]}],"ix":1},"ix":2,"mn":"ADBE Vector Filter - RC","hd":false},{"ty":"fl","c":{"a":0,"k":[0.780392156863,0.776470588235,0.792156862745,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[73.627,-6.704],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":29,"op":400,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"4","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[264.817,112.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.026,0],[0,0],[0,4.954],[0,0],[-5.026,0],[0,0],[0,-4.954],[0,0]],"o":[[0,0],[-5.026,0],[0,0],[0,-4.954],[0,0],[5.026,0],[0,0],[0,4.954]],"v":[[34.628,95.607],[-34.628,95.607],[-43.693,86.605],[-43.693,-86.605],[-34.628,-95.607],[34.628,-95.607],[43.693,-86.605],[43.693,86.605]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235297799,0.188235297799,0.20000000298,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector (Stroke)","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":416,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"3","tt":2,"tp":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[264.755,112.023,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.158,0],[0,0],[0,7.122],[0,0],[-7.158,0],[0,0],[0,-7.122],[0,0]],"o":[[0,0],[-7.158,0],[0,0],[0,-7.122],[0,0],[7.158,0],[0,0],[0,7.122]],"v":[[34.628,99.5],[-34.628,99.5],[-47.587,86.605],[-47.587,-86.605],[-34.628,-99.5],[34.628,-99.5],[47.587,-86.605],[47.587,86.605]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.780392156863,0.776470588235,0.792156862745,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector (Stroke)","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":416,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"5","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[117.005,112.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.026,0],[0,0],[0,4.954],[0,0],[-5.026,0],[0,0],[0,-4.954],[0,0]],"o":[[0,0],[-5.026,0],[0,0],[0,-4.954],[0,0],[5.026,0],[0,0],[0,4.954]],"v":[[34.628,95.607],[-34.628,95.607],[-43.693,86.605],[-43.693,-86.605],[-34.628,-95.607],[34.628,-95.607],[43.693,-86.605],[43.693,86.605]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235297799,0.188235297799,0.20000000298,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector (Stroke)","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":150,"op":475,"st":59,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Shape Layer 9","tt":1,"tp":16,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.127,"y":1},"o":{"x":0.167,"y":0},"t":150,"s":[87.972,180.675,0],"to":[-5.083,0,0],"ti":[5.083,0,0]},{"t":190,"s":[57.472,180.675,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-73.528,-0.325,0],"ix":1,"l":2},"s":{"a":0,"k":[23,23,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[87.943,191.35],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":14,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.780392156863,0.776470588235,0.792156862745,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-73.528,-0.325],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":150,"op":471,"st":59,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Shape Layer 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.127,"y":1},"o":{"x":0.333,"y":0},"t":50,"s":[116.972,112.175,0],"to":[-4.833,11.417,0],"ti":[4.833,-11.417,0]},{"t":91,"s":[87.972,180.675,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-73.528,-0.325,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.127,0.127,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":50,"s":[100,101.045,100]},{"t":91,"s":[23,23,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[87.943,191.35],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.127],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":50,"s":[8]},{"t":91,"s":[14]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.780392156863,0.776470588235,0.792156862745,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-73.528,-0.325],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":50,"op":150,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":3,"nm":"Null 1","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.316,"y":1},"o":{"x":0.615,"y":0},"t":22,"s":[117.5,90,0],"to":[0,7.333,0],"ti":[0,-7.333,0]},{"t":50,"s":[117.5,134,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19,19,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":414,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Shape Layer 6","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[121.053,-0.877,0],"ix":2,"l":2},"a":{"a":0,"k":[-2,-12,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":22,"s":[507.053,507.053,100]},{"t":29,"s":[421.053,421.053,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.843137015548,0.098038998772,0.1294119891,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":50,"st":-20,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Shape Layer 5","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1.316,-42.982,0],"ix":2,"l":2},"a":{"a":0,"k":[-2,-12,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":22,"s":[507.053,507.053,100]},{"t":29,"s":[421.053,421.053,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.843137015548,0.098038998772,0.1294119891,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":50,"st":-20,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"Shape Layer 4","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-118.421,-0.877,0],"ix":2,"l":2},"a":{"a":0,"k":[-2,-12,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":22,"s":[507.053,507.053,100]},{"t":29,"s":[421.053,421.053,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.843137015548,0.098038998772,0.1294119891,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":50,"st":-20,"ct":1,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":"1","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[117.005,112.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.026,0],[0,0],[0,4.954],[0,0],[-5.026,0],[0,0],[0,-4.954],[0,0]],"o":[[0,0],[-5.026,0],[0,0],[0,-4.954],[0,0],[5.026,0],[0,0],[0,4.954]],"v":[[34.628,95.607],[-34.628,95.607],[-43.693,86.605],[-43.693,-86.605],[-34.628,-95.607],[34.628,-95.607],[43.693,-86.605],[43.693,86.605]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.188235297799,0.188235297799,0.20000000298,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector (Stroke)","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":416,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"2","tt":2,"tp":23,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[117.005,112.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.158,0],[0,0],[0,7.122],[0,0],[-7.158,0],[0,0],[0,-7.122],[0,0]],"o":[[0,0],[-7.158,0],[0,0],[0,-7.122],[0,0],[7.158,0],[0,0],[0,7.122]],"v":[[34.628,99.5],[-34.628,99.5],[-47.587,86.605],[-47.587,-86.605],[-34.628,-99.5],[34.628,-99.5],[47.587,-86.605],[47.587,86.605]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.780392156863,0.776470588235,0.792156862745,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector (Stroke)","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":416,"st":0,"ct":1,"bm":0}],"markers":[],"props":{}}
diff --git a/res/raw/nt_power_off_verify.json b/res/raw/nt_power_off_verify.json
new file mode 100644
index 00000000..1049a581
--- /dev/null
+++ b/res/raw/nt_power_off_verify.json
@@ -0,0 +1 @@
+{"nm":"Flow 4","ddd":0,"h":278,"w":366,"meta":{"g":"LottieFiles Figma v70"},"layers":[{"ty":4,"nm":"bar","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[17,1.5]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[183,245.5]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,-0.83],[0,0],[0.83,0],[0,0],[0,0.83],[0,0],[-0.83,0],[0,0]],"o":[[0,0],[0,0.83],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0.83,0]],"v":[[34,1.5],[34,1.5],[32.5,3],[1.5,3],[0,1.5],[0,1.5],[1.5,0],[32.5,0]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":0,"k":[0.5687,0.5647,0.5804]},"r":1,"o":{"a":0,"k":100}}],"ind":1},{"ty":0,"nm":"Frame 427322354","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":true,"ao":0,"ks":{"a":{"a":0,"k":[55,115]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[183,139]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}},"masksProperties":[{"nm":"","inv":false,"mode":"a","x":{"a":0,"k":0},"o":{"a":0,"k":100},"pt":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":408},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}],"t":456}]}}],"w":366,"h":278,"refId":"1","ind":2}],"v":"5.7.0","fr":60,"op":408.06,"ip":0,"assets":[{"nm":"[Asset] Frame 427322354","id":"1","layers":[{"ty":0,"nm":"Frame 427322356","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[35,39]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[55,111]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"w":366,"h":278,"refId":"2","ind":1},{"ty":4,"nm":"Vector (Stroke)","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[55,115]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[55,115]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,0],[0,5.73],[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0]],"o":[[0,0],[5.81,0],[0,0],[0,-5.73],[0,0],[-5.81,0],[0,0],[0,5.73],[0,0]],"v":[[14.98,225.5],[95.02,225.5],[105.5,215.1],[105.5,14.9],[95.02,4.5],[14.98,4.5],[4.5,14.9],[4.5,215.1],[14.98,225.5]]}}},{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,0],[0,8.23],[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0]],"o":[[0,0],[8.27,0],[0,0],[0,-8.23],[0,0],[-8.27,0],[0,0],[0,8.23],[0,0]],"v":[[14.98,230],[95.02,230],[110,215.1],[110,14.9],[95.02,0],[14.98,0],[0,14.9],[0,215.1],[14.98,230]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":0,"k":[0.7844,0.7844,0.7844]},"r":2,"o":{"a":0,"k":100}}],"ind":2},{"ty":4,"nm":"Subtract","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2.5,1.25],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2.5,1.25],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2.5,1.25],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2.5,1.25],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2.5,1.25],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2.5,1.25],"t":276},{"s":[2.5,1.25],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,53.25],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,53.25],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,53.25],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,53.25],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,53.25],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,53.25],"t":276},{"s":[55,53.25],"t":396}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,0],[1.38,0],[0,-1.38],[0,0],[-0.83,0],[0,-0.83]],"o":[[0,0],[0,-1.38],[-1.38,0],[0,0],[0,-0.83],[0.83,0],[0,0]],"v":[[4,2.5],[5,2.5],[2.5,0],[0,2.5],[1,2.5],[2.5,1],[4,2.5]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":2,"o":{"a":0,"k":100}}],"ind":3},{"ty":4,"nm":"Line 2 (Stroke)","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":276},{"s":[0.5,0.5],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,55],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,55],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,55],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,55],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,55],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,55],"t":276},{"s":[57,55],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[-90],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[-90],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[-90],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[-90],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[-90],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[-90],"t":276},{"s":[-90],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,1],[0,1],[0,0],[1,0],[1,1]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":2,"o":{"a":0,"k":100}}],"ind":4},{"ty":4,"nm":"Line 1 (Stroke)","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5,0.5],"t":276},{"s":[0.5,0.5],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[53,55],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[53,55],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[53,55],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[53,55],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[53,55],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[53,55],"t":276},{"s":[53,55],"t":396}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1,0],[1,1],[0,1],[0,0],[1,0]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":2,"o":{"a":0,"k":100}}],"ind":5},{"ty":4,"nm":"Rectangle 4979","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[4,3.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[4,3.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[4,3.5],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[4,3.5],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[4,3.5],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[4,3.5],"t":276},{"s":[4,3.5],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55.5,59.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55.5,59.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55.5,59.5],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55.5,59.5],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55.5,59.5],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55.5,59.5],"t":276},{"s":[55.5,59.5],"t":396}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,-0.4714285714285715],[0,0],[0.48125000000000007,0],[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0]],"o":[[0,0],[0,0.4714285714285715],[0,0],[-0.48125000000000007,0],[0,0],[0,-0.4714285714285715],[0,0],[0.48125000000000007,0]],"v":[[7,0.8571428571428572],[7,5.142857142857143],[6.125,6],[0.875,6],[0,5.142857142857143],[0,0.8571428571428572],[0.875,0],[6.125,0]]}}},{"ty":"st","bm":0,"hd":false,"nm":"","lc":1,"lj":1,"ml":1,"o":{"a":0,"k":100},"w":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[1],"t":276},{"s":[1],"t":396}]},"c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]}}],"ind":6},{"ty":4,"nm":"Rectangle 160","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,0.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,0.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,32],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,32],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,32],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,32],"t":276},{"s":[2,32],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[25,106.5],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[25,106.5],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[25,138],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[25,138],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[25,138],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[25,138],"t":276},{"s":[25,138],"t":396}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[20],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[20],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[20],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,1],[0,1],[0,0]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,1],[0,1],[0,0]]}],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,1],[0,1],[0,0]]}],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,64],[0,64],[0,0]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,64],[0,64],[0,0]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,64],[0,64],[0,0]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,64],[0,64],[0,0]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,64],[0,64],[0,0]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0,0,0],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0,0,0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0,0,0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0,0,0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0,0,0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0,0,0],"t":276},{"s":[0,0,0],"t":396}]},"r":1,"o":{"a":0,"k":100}}],"ind":7},{"ty":0,"nm":"Group 1","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":396},{"s":[33,33],"t":456.06}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[55,138],"t":396},{"s":[55,138],"t":456.06}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"w":366,"h":278,"refId":"3","ind":8},{"ty":4,"nm":"Rectangle 161","sr":1,"st":0,"op":409.06,"ip":174,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,0.5],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,30],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,30],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[2,30],"t":276},{"s":[2,30],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[27.5,168],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,168],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,168],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[57,168],"t":276},{"s":[57,168],"t":396}]},"r":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[90],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[90],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[90],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[90],"t":276},{"s":[90],"t":396}]},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[20],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[20],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,1],[0,1],[0,0]]}],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,1],[0,1],[0,0]]}],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,60],[0,60],[0,0]]}],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,60],[0,60],[0,0]]}],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,60],[0,60],[0,0]]}],"t":276},{"s":[{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4,0],[4,60],[0,60],[0,0]]}],"t":396}]}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0,0,0],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0,0,0],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0,0,0],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0,0,0],"t":276},{"s":[0,0,0],"t":396}]},"r":1,"o":{"a":0,"k":100}}],"ind":9},{"ty":4,"nm":"Frame 427322354 Bg","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[55,115]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[55,115]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110,0],[110,230],[0,230],[0,0]]}}}],"ind":10}]},{"nm":"[Asset] Frame 427322356","id":"2","layers":[{"ty":4,"nm":"Ellipse 21629","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[13,13]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[51,51]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":0,"k":[0.2824,0.2824,0.2824]},"r":1,"o":{"a":0,"k":100}}],"ind":1},{"ty":4,"nm":"Ellipse 21628","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[13,13]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[19,51]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.3765,0.3765,0.3765],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.3765,0.3765,0.3765],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.2824,0.2824,0.2824],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[0.2824,0.2824,0.2824],"t":408},{"s":[0.2824,0.2824,0.2824],"t":456}]},"r":1,"o":{"a":0,"k":100}}],"ind":2},{"ty":4,"nm":"Ellipse 21627","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[13,13]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[51,19]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":0,"k":[0.2824,0.2824,0.2824]},"r":1,"o":{"a":0,"k":100}}],"ind":3},{"ty":4,"nm":"Ellipse 21626","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[13,13]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[19,19]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[7.18,0],[0,7.18],[-7.18,0],[0,-7.18]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0],[0,0]],"v":[[26,13],[13,26],[0,13],[13,0],[26,13]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":0,"k":[0.8432,0.0981,0.1295]},"r":1,"o":{"a":0,"k":100}}],"ind":4},{"ty":4,"nm":"Rectangle 156","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[35,39]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[35,39]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,-2.94],[0,0],[2.94,0],[0,0],[0,2.94],[0,0],[-2.94,0],[0,0]],"o":[[0,0],[0,2.94],[0,0],[-2.94,0],[0,0],[0,-2.94],[0,0],[2.94,0]],"v":[[70,5.32],[70,72.68],[64.68,78],[5.32,78],[0,72.68],[0,5.32],[5.32,0],[64.68,0]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":0,"k":[0.1942,0.1942,0.1942]},"r":1,"o":{"a":0,"k":100}}],"ind":5},{"ty":4,"nm":"Frame 427322356 Bg","sr":1,"st":0,"op":409.06,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[35,39]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[35,39]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":48},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":54},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":72},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":174.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":240.06},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0],"t":396},{"o":{"x":0,"y":0},"i":{"x":1,"y":1},"s":[100],"t":408},{"s":[100],"t":456}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[70,0],[70,78],[0,78],[0,0]]}}}],"ind":6}]},{"nm":"[Asset] Group 1","id":"3","layers":[{"ty":4,"nm":"Ellipse 581","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,3],"t":276},{"s":[63,3],"t":396}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":0,"k":100}}],"ind":1},{"ty":4,"nm":"Ellipse 582","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,3],"t":276},{"s":[33,3],"t":396}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":0,"k":100}}],"ind":2},{"ty":4,"nm":"Ellipse 588","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,33],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,33],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,33],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,33],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,33],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,33],"t":276},{"s":[3,33],"t":396}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":0,"k":100}}],"ind":3},{"ty":4,"nm":"Ellipse 587","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,33],"t":276},{"s":[33,33],"t":396}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":0,"k":100}}],"ind":4},{"ty":4,"nm":"Ellipse 586","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,33],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,33],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,33],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,33],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,33],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,33],"t":276},{"s":[63,33],"t":396}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":0,"k":100}}],"ind":5},{"ty":4,"nm":"Ellipse 585","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,63],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,63],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,63],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,63],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,63],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[63,63],"t":276},{"s":[63,63],"t":396}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":0,"k":100}}],"ind":6},{"ty":4,"nm":"Ellipse 584","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,63],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,63],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,63],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,63],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,63],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[33,63],"t":276},{"s":[33,63],"t":396}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":0,"k":100}}],"ind":7},{"ty":4,"nm":"Ellipse 583","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,63],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,63],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,63],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,63],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,63],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,63],"t":276},{"s":[3,63],"t":396}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":0,"k":100}}],"ind":8},{"ty":4,"nm":"Ellipse 572","sr":1,"st":0,"op":409.06,"ip":108,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[3,3],"t":276},{"s":[3,3],"t":396}]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":276},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[100],"t":396},{"s":[0],"t":456.06}]}},"shapes":[{"ty":"sh","bm":0,"hd":false,"nm":"","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.66,0],[0,1.66],[-1.66,0],[0,-1.66]],"o":[[0,1.66],[-1.66,0],[0,-1.66],[1.66,0],[0,0]],"v":[[6,3],[3,6],[0,3],[3,0],[6,3]]}}},{"ty":"fl","bm":0,"hd":false,"nm":"","c":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,0],"t":0},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":108},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":156},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":174},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":192},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":240},{"o":{"x":0.33,"y":1},"i":{"x":0.68,"y":1},"s":[0.5726,0.5726,0.5726],"t":276},{"s":[0.5726,0.5726,0.5726],"t":396}]},"r":1,"o":{"a":0,"k":100}}],"ind":9}]}]}
\ No newline at end of file
diff --git a/res/values-zh-rCN/custom_strings.xml b/res/values-zh-rCN/custom_strings.xml
index 9a3d7869..da65c996 100644
--- a/res/values-zh-rCN/custom_strings.xml
+++ b/res/values-zh-rCN/custom_strings.xml
@@ -15,13 +15,153 @@
limitations under the License.
-->
+
+
+ 新的快速设置亮度滑条样式
+ 圆形
+ 圆角方形
+ 方形
+
+
+ 关机验证会保护你的设备不会在遗失后立刻被他人关机, 增加你找回它的可能性。你只会在锁屏时尝试关机会被要求输入你的锁屏密码
+ 当你的设备锁定时,你需要验证你的密码来关机/重启
+ 关机验证
+
+
+ 锁屏充电时间
+ 显示距离充满剩余的时间
+
+
+ 通知透明
+ 在通知后方使用透明背景
+
+
+ 三指下滑
+ 使用三根手指下滑执行一些操作
+ 三指长按
+ 使用三根手指点按并下滑进行区域截图
+ 禁用电源+音量下键
+ 禁用使用电源+音量键进行截图的功能
+
+
+ 声音
+ 锁屏音效
+ 解锁音效
+
+
+ 息屏壁纸
+ 当息屏显示启用时显示壁纸
+
+
+ 弹出显示
+ 在一个浮动的小窗口中打开程序
+ 手势
+ 全局手势
+ 通过从屏幕下方角落向中心滑动来使用浮动窗口启动任意应用
+ 管理固定的应用
+ 自定义在菜单中显示的应用
+ 显示更多应用
+ Add more quarter circles in gesture menu
+ 当全局手势启用时,数字助理手势将被禁用
+ 迷你窗口
+ 自动静音
+ 当应用切换至迷你小窗时自动静音
+ 应用在切换回浮动模式时自动取消静音
+ 非窗口区域
+ 单击操作
+ 双击操作
+ 切换至迷你小窗
+ 关闭浮动窗口
+ 无动作
+ 从通知启动
+ 打开通知(竖屏)
+ 在竖屏下使用浮动窗口打开通知
+ 打开通知(横屏)
+ 在横屏下使用浮动窗口打开通知
+ 黑名单应用
+ 在打开来自这些程序的通知时不使用浮动窗口
+
+
+ 防止意外唤醒
+ 使用距离传感器防止意外唤醒
+
+
+ 使用新的快速设置
+ 一些功能可能无法在新的快速设置下工作
+ 快速设置重构
+
+
+ 系统
+ Pixel props
+ 对来自Google应用伪装为最新的Pixel设备
+ 存储加密
+ 声明设备的存储加密状态为加密
+ 特定应用
+ Google app
+ 将设备伪装为最新的Pixel以启用Pixel独占功能
+ Play商店
+ 将设备伪装为最新的Pixel设备
+ Google相册
+ 将设备伪装为Pixel XL
+ Snapchat
+ 将设备伪装为Pixel XL来修复可能存在的问题
+ Keybox覆盖
+ 加载一个自定义的Keybox.xml文件
+ 自定义Keybox已加载,删除以清除
+ 清除Keybox
+ 不是一个xml文件,请选择一个有效的Keybox.xml
+ 无效的Keybox.xml: 缺少必要的条目
+ keybx已加载
+ Keybox已清楚
+
+
+ 禁用投屏确认
+
+
+ USB设置
+ 选择通过USB连接设备时的默认行为
+
+
+ 禁用指纹锁定
+ 在30秒后或多次解锁失败时仍然保持指纹解锁可用
+
+
+ 为VPN禁用
+ 当连接至VPN时自动禁用私人DNS\n将会在断开VPN后自动恢复
+
+
+ 逐渐增加铃声音量
+ 开始音量
+ 增加至最大音量的时间
+
+
+ 每次连接都使用随机的MAC (默认值)
+ 为每个网络使用不同的MAC
+ 使用设备MAC
+
+
+ 降低屏幕刷新率
+ 当省电模式启用时将屏幕刷新率降低至60hz
+
+
+ 无限制录屏
+ 移除单个屏幕录制的15GiB文件大小限制\n可能导致非常大的录制文件输出
+
+
+ 根据时间表自动启用极暗
+ 禁用
+
+
+ 长按搜索
+ 按住home键或小白条以使用你的屏幕内容进行搜索
+
状态栏图标自定义颜色
启用状态栏图标自定义颜色功能
状态栏图标颜色设置
自定义状态栏图标的显示颜色
-
+
状态栏歌词
在状态栏显示歌词 (需应用支持)
歌词选项
@@ -47,8 +187,33 @@
在新的虚线背景和简单的箭头样式之间切换
+ 状态栏进度条
+ 状态栏进度条设置
正在运行部件
在状态栏中显示正在进行的活动 (如下载) 的进度指示器
+ 进度条透明度
+ 调整进度条部件的透明度
+ 小型进度指示器
+ 在进度条中使用小型的环形指示器
+ 显示媒体进度
+ "在状态栏中显示媒体播放进度
+
+ "状态栏进度条将实时显示当前正在进行的媒体播放和上传/下载进度显示
+
+ - 🎵 显示媒体播放进度:
+ • 当音乐或视频正在播放时显示播放进度
+ • 点击可以打开播放控制(上一首/下一首音乐)
+ • 双击以切换播放/暂停
+ • 向左/向右滑动以切换至上一首/下一首曲目
+ • 长按可打开正在播放媒体的应用
+
+ - 📥 显示下载/上传进度:
+ • 显示当前正在进行的上传/下载进度
+ • 当没有检测到活跃的传输活动时自动隐藏
+ • 点击以打开正在进行传输的应用
+
+ 状态栏进度条将自动在媒体和下载进度中切换以确保您能获取最需要的信息"
+
岛屿通知
@@ -372,9 +537,9 @@
电源模式
- 启用每个应用的伪装
- 在 PixelProps 中启用每个应用程序的伪装选项
- 选择每个应用程序的 JSON 属性文件
+ 对特定应用的伪装
+ 在 PixelProps 中启用针对特定应用程序的伪装选项
+ 选择用于这些应用的 JSON 属性文件
选择用于伪装游戏的 JSON 文件
@@ -416,8 +581,8 @@
应用
- 音量声音触觉
- 调整音量时启用声音反馈
+ 音量触觉
+ 调整音量时启用震动反馈
可展开的音量条
展开音量条,而不是从底部显示
媒体输出图标
@@ -500,10 +665,10 @@
设置网络和互联网连接
设置连接的设备
添加、配对蓝牙并配置设备连接
- risingOS 个性化
+ RisingOS 个性化
更改图标、主题等
重置设置
- 这将会重置当前用户大部分的 risingOS 设置为默认值。您要继续吗?
+ 这将会重置当前用户大部分的 RisingOS 设置为默认值。您要继续吗?
搜索
@@ -534,8 +699,8 @@
注意:虽然绕过某些限制可能会带来便利,但也可能导致潜在的隐私风险
- risingOS
- risingOS 版本
+ RisingOS
+ RisingOS 版本
构建类型
由维护者
#官方
@@ -627,20 +792,20 @@
底部
探索功能
-
- 关于 risingOS
+
+ 关于 RisingOS
设备
-
- 分享 risingOS
- 让更多人了解 risingOS
- 查看 #risingOS Android 的全部内容 @ https://rising.net/
- 分享 risingOS
+
+ 分享 RisingOS
+ 让更多人了解 RisingOS
+ 查看 #RisingOS Android 的全部内容 @ https://rising.net/
+ 分享 RisingOS
-
+
GitHub
我们热爱开源,来看看我们的代码吧
- risingOS 社区
+ RisingOS 社区
我们有 TG 群。加入我们!
更新频道
在 Telegram 上获取更新通知
@@ -653,10 +818,10 @@
我们十分推荐这些服务器提供商
-
+
支持我们
捐赠以支持开发
- risingOS 团队
+ RisingOS 团队
捐赠支持服务器托管,网站正常运行时间和整体管理
@@ -1223,8 +1388,8 @@
运行中服务快捷方式
设置快捷方式
-
- risingOS 法律信息
+
+ RisingOS 法律信息
亮度滑块
@@ -1758,7 +1923,7 @@
在状态栏左侧或右侧显示自定义 Logo
Logo 位置
Logo 样式
- risingOS
+ RisingOS
Android
阿迪达斯
外星人
diff --git a/res/values/custom_arrays.xml b/res/values/custom_arrays.xml
index 9b38a46c..76708f5e 100644
--- a/res/values/custom_arrays.xml
+++ b/res/values/custom_arrays.xml
@@ -15,6 +15,100 @@
limitations under the License.
-->
+
+
+ - @string/default_value
+ - @string/quick_settings_tile_shape_circle
+ - @string/quick_settings_tile_shape_rounded_square
+ - @string/quick_settings_tile_shape_square
+
+
+
+ - 0
+ - 1
+ - 2
+ - 3
+
+
+
+
+ - Default
+ - Amazon Fire
+ - Asus Zenfone Max
+ - Essential PH-1
+ - HTC M8
+ - Huawei
+ - Hyper OS
+ - Iqoo
+ - LG G3
+ - Minecraft door
+ - MIUI 10
+ - MIUI 11
+ - Nextbit
+ - Nokia X
+ - Old School IOS
+ - One UI
+ - OOS 14
+ - Razer Phone
+ - Soong
+ - Windows Device
+ - Windows Error
+
+
+
+ - /product/media/audio/ui/Lock.ogg
+ - /product/media/audio/ui/Amazon_Fire_Lock.ogg
+ - /product/media/audio/ui/Asus_Zenfone_Max_Lock.ogg
+ - /product/media/audio/ui/Essential_PH-1_Lock.ogg
+ - /product/media/audio/ui/HTC_M8_Lock.ogg
+ - /product/media/audio/ui/Huawei_Lock.ogg
+ - /product/media/audio/ui/Hyper_OS_Lock.ogg
+ - /product/media/audio/ui/Iqoo_Lock.ogg
+ - /product/media/audio/ui/LG_G3_Lock.ogg
+ - /product/media/audio/ui/Minecraft_Door_Lock.ogg
+ - /product/media/audio/ui/MIUI_10_Lock.ogg
+ - /product/media/audio/ui/MIUI_11_Lock.ogg
+ - /product/media/audio/ui/Nextbit_Lock.ogg
+ - /product/media/audio/ui/Nokia_X_Lock.ogg
+ - /product/media/audio/ui/Old_School_IOS_Lock.ogg
+ - /product/media/audio/ui/One_UI_Lock.ogg
+ - /product/media/audio/ui/OOS_14_Lock.ogg
+ - /product/media/audio/ui/Razer_Phone_Lock.ogg
+ - /product/media/audio/ui/Soong_Lock.ogg
+ - /product/media/audio/ui/Windows_Device_Lock.ogg
+ - /product/media/audio/ui/Windows_Error_Lock.ogg
+
+
+
+ - /product/media/audio/ui/Unlock.ogg
+ - /product/media/audio/ui/Amazon_Fire_Unlock.ogg
+ - /product/media/audio/ui/Asus_Zenfone_Max_Unlock.ogg
+ - /product/media/audio/ui/Essential_PH-1_Unlock.ogg
+ - /product/media/audio/ui/HTC_M8_Unlock.ogg
+ - /product/media/audio/ui/Huawei_Unlock.ogg
+ - /product/media/audio/ui/Hyper_OS_Unlock.ogg
+ - /product/media/audio/ui/Iqoo_Unlock.ogg
+ - /product/media/audio/ui/LG_G3_Unlock.ogg
+ - /product/media/audio/ui/Minecraft_Door_Unlock.ogg
+ - /product/media/audio/ui/MIUI_10_Unlock.ogg
+ - /product/media/audio/ui/MIUI_11_Unlock.ogg
+ - /product/media/audio/ui/Nextbit_Unlock.ogg
+ - /product/media/audio/ui/Nokia_X_Unlock.ogg
+ - /product/media/audio/ui/Old_School_IOS_Unlock.ogg
+ - /product/media/audio/ui/One_UI_Unlock.ogg
+ - /product/media/audio/ui/OOS_14_Unlock.ogg
+ - /product/media/audio/ui/Razer_Phone_Unlock.ogg
+ - /product/media/audio/ui/Soong_Unlock.ogg
+ - /product/media/audio/ui/Windows_Device_Unlock.ogg
+ - /product/media/audio/ui/Windows_Error_Unlock.ogg
+
+
+
+
+
+
+
+
- @string/pop_up_view_action_enter_pinned
@@ -176,12 +270,14 @@
- @string/color_default
- @string/pie_system_animation_style
- @string/scale_system_animation_style
+ - @string/slide_system_animation_style
- 0
- 1
- 2
+ - 3
@@ -191,6 +287,7 @@
- @string/powermenu_style2
- @string/powermenu_style3
- @string/powermenu_style4
+ - @string/powermenu_style5
@@ -199,6 +296,7 @@
- 2
- 3
- 4
+ - 5
@@ -892,7 +990,7 @@
-
+
- @string/hardware_keys_action_nothing
- @string/hardware_keys_action_menu
- @string/hardware_keys_action_app_switch
@@ -914,7 +1012,7 @@
- @string/hardware_keys_action_ringer_modes
-
+
- 0
- 1
- 2
diff --git a/res/values/custom_strings.xml b/res/values/custom_strings.xml
index 1bc45868..0d3ecff9 100644
--- a/res/values/custom_strings.xml
+++ b/res/values/custom_strings.xml
@@ -15,6 +15,50 @@
limitations under the License.
-->
+
+ New QS Brightness slider shape
+ Circle
+ Rounded square
+ Square
+
+
+ Power off verification protects your device by preventing others from turning it off immediately after it\'s lost, increasing the chances of recovery. You only need to enter your lock screen password when powering off or restarting the phone from the lock screen.
+ When your device is locked, you\'ll need to use your password to power off or restart.
+ Power off verify
+
+
+ Lock screen charging time
+ Display the remaining time for charging to finish
+
+
+ Notification row transparency
+ Show translucent quicksettings notifications
+
+
+ Three finger swipe
+ Swipe down with three fingers to perform actions.
+ Three finger long press
+ Press and hold with three fingers and then swipe down to take an area screenshot.
+ Disable power button & volume down button
+ Disable the function of taking a screenshot by pressing and holding the power button and the volume down button.
+
+
+ Small landscape notifications
+ Shows notifications smaller in width in notification panel in landscape mode just as AOSP intended
+
+
+ Audio
+ Lock sound
+ Unlock sound
+
+
+ Keyguard affordance single tap
+ Toggle keyguard affordances with a single tap
+
+
+ AOD wallpaper
+ Show wallpaper when aod on
+
No installed apps support current settings
No apps found matching \"%1$s\"
@@ -85,8 +129,16 @@
Spoof the Google Photos app as a Pixel XL
Snapchat
Spoof Snapchat as a Pixel XL to fix possible chat issues
- Select keybox XML to spoof
- Select keybox XML used for key attestation spoofing for all apps system wide. Click the delete button in order to reset the keybox data values used by the system.
+ Keybox attestation override
+ Load a custom keybox XML to override device key attestation
+ Custom keybox XML loaded. Delete to clear.
+ Clear keybox data
+ Not an XML file. Choose a valid keybox XML.
+ Invalid keybox XML: required fields missing
+ Keybox loaded
+ Keybox cleared
+ Private Keybox spoof
+ Spoof the private key only if you have a valid Keybox for proper Strong Integrity.
Screen Off AOD
@@ -271,8 +323,9 @@
Power Menu Style
Cyberpunk
Duoline
- IOS
- Layers
+ Fluid (Transparent)
+ IOS
+ Layers
QS Header clock style
@@ -317,6 +370,12 @@
Minimal lockscreen notification style
Peek display location
Peek display (bottom) top margin
+ Vertical offset
+ Adjust the vertical position of peek display notifications
+ Always visible
+ Keep peek display notifications visible until manually dismissed
+ Auto dismiss timeout
+ Time in seconds before peek display notifications automatically disappear
Colours
@@ -2442,6 +2501,7 @@
System animation style
Android P
Scale
+ Slide
Select Apps to Spoof
diff --git a/res/xml/power_off_verify.xml b/res/xml/power_off_verify.xml
new file mode 100644
index 00000000..c547ef52
--- /dev/null
+++ b/res/xml/power_off_verify.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
diff --git a/res/xml/pulse_settings.xml b/res/xml/pulse_settings.xml
index c2ceb800..46403116 100644
--- a/res/xml/pulse_settings.xml
+++ b/res/xml/pulse_settings.xml
@@ -103,6 +103,7 @@
android:defaultValue="14"
android:max="30"
settings:min="1"
+ settings:interval="1"
settings:units="@string/unit_pixels"
android:dependency="pulse_fading_bars_category"
lineage:position="top"/>
@@ -123,6 +124,7 @@
android:defaultValue="4"
android:max="8"
settings:min="4"
+ settings:interval="1"
settings:units="@string/unit_pixels"
android:dependency="pulse_fading_bars_category"/>
@@ -132,6 +134,7 @@
android:defaultValue="1"
android:max="4"
settings:min="0"
+ settings:interval="1"
settings:units="@string/unit_pixels"
android:dependency="pulse_fading_bars_category"/>
@@ -141,6 +144,7 @@
android:defaultValue="4"
android:max="6"
settings:min="2"
+ settings:interval="1"
android:dependency="pulse_fading_bars_category"
lineage:position="bottom"/>
@@ -163,6 +167,7 @@
android:defaultValue="200"
android:max="255"
settings:min="0"
+ settings:interval="1"
android:dependency="pulse_2"/>
diff --git a/res/xml/rising_settings_extras.xml b/res/xml/rising_settings_extras.xml
index 9eab6e5e..e6300fe5 100644
--- a/res/xml/rising_settings_extras.xml
+++ b/res/xml/rising_settings_extras.xml
@@ -20,20 +20,13 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:title="@string/extras_toolbox_title">
-
-
+ app:position="top" />
@@ -67,28 +67,13 @@
android:key="three_finger_gestures"
android:title="@string/three_finger_gestures_title">
-
-
-
-
-
+
diff --git a/res/xml/rising_settings_lockscreen.xml b/res/xml/rising_settings_lockscreen.xml
index 3595eab6..ccf48389 100644
--- a/res/xml/rising_settings_lockscreen.xml
+++ b/res/xml/rising_settings_lockscreen.xml
@@ -43,6 +43,12 @@
lineage:position="top"
/>
+
+
+
+
+
+
+
+ lineage:position="bottom" />
diff --git a/res/xml/rising_settings_navigation.xml b/res/xml/rising_settings_navigation.xml
index dc996b29..554cb20f 100644
--- a/res/xml/rising_settings_navigation.xml
+++ b/res/xml/rising_settings_navigation.xml
@@ -42,8 +42,8 @@
android:key="key_back_long_press_action"
android:dialogTitle="@string/navbar_back_long_press_title"
android:title="@string/navbar_back_long_press_title"
- android:entries="@array/hardware_keys_action_entries"
- android:entryValues="@array/hardware_keys_action_values"
+ android:entries="@array/gesture_actions_entries"
+ android:entryValues="@array/gesture_actions_values"
android:summary="%s"
android:defaultValue="0"
lineage:isLineageSettings="true"
@@ -53,8 +53,8 @@
android:key="key_home_long_press_action"
android:dialogTitle="@string/navbar_home_long_press_title"
android:title="@string/navbar_home_long_press_title"
- android:entries="@array/hardware_keys_action_entries"
- android:entryValues="@array/hardware_keys_action_values"
+ android:entries="@array/gesture_actions_entries"
+ android:entryValues="@array/gesture_actions_values"
android:summary="%s"
android:defaultValue="0"
lineage:isLineageSettings="true" />
@@ -63,8 +63,8 @@
android:key="key_home_double_tap_action"
android:dialogTitle="@string/navbar_home_double_tap_title"
android:title="@string/navbar_home_double_tap_title"
- android:entries="@array/hardware_keys_action_entries"
- android:entryValues="@array/hardware_keys_action_values"
+ android:entries="@array/gesture_actions_entries"
+ android:entryValues="@array/gesture_actions_values"
android:summary="%s"
android:defaultValue="0"
lineage:isLineageSettings="true" />
@@ -73,8 +73,8 @@
android:key="key_app_switch_long_press_action"
android:dialogTitle="@string/navbar_app_switch_long_press_title"
android:title="@string/navbar_app_switch_long_press_title"
- android:entries="@array/hardware_keys_action_entries"
- android:entryValues="@array/hardware_keys_action_values"
+ android:entries="@array/gesture_actions_entries"
+ android:entryValues="@array/gesture_actions_values"
android:summary="%s"
android:defaultValue="0"
lineage:isLineageSettings="true" />
@@ -83,8 +83,8 @@
android:key="key_edge_long_swipe_action"
android:dialogTitle="@string/navbar_edge_long_swipe_title"
android:title="@string/navbar_edge_long_swipe_title"
- android:entries="@array/hardware_keys_action_entries"
- android:entryValues="@array/hardware_keys_action_values"
+ android:entries="@array/gesture_actions_entries"
+ android:entryValues="@array/gesture_actions_values"
android:summary="%s"
android:defaultValue="0"
lineage:isLineageSettings="true"
diff --git a/res/xml/rising_settings_notification.xml b/res/xml/rising_settings_notification.xml
index 86639e5d..a4781c37 100644
--- a/res/xml/rising_settings_notification.xml
+++ b/res/xml/rising_settings_notification.xml
@@ -29,7 +29,14 @@
android:title="@string/notification_sound_vib_screen_on_title"
android:summary="@string/notification_sound_vib_screen_on_summary"
android:defaultValue="true"
- lineage:position="solo" />
+ lineage:position="top" />
+
+
+
+
+
+
+
+
+
+
diff --git a/res/xml/rising_settings_qs.xml b/res/xml/rising_settings_qs.xml
index 3e80df22..d645f73b 100644
--- a/res/xml/rising_settings_qs.xml
+++ b/res/xml/rising_settings_qs.xml
@@ -32,7 +32,16 @@
android:title="@string/qs_refactor_title"
android:summary="@string/qs_refactor_summary"
android:defaultValue="true"
- lineage:position="solo" />
+ lineage:position="top" />
+
+
diff --git a/res/xml/rising_settings_spoof.xml b/res/xml/rising_settings_spoof.xml
index a8a1f665..af5fe4ce 100644
--- a/res/xml/rising_settings_spoof.xml
+++ b/res/xml/rising_settings_spoof.xml
@@ -27,16 +27,20 @@
+ android:title="@string/keybox_data_title" />
+
+
+ android:defaultValue="true" />
-
+ android:defaultValue="false" />-->
+
+
+
+
+
+
+
+
+
@@ -82,6 +105,14 @@
android:summary="%s"
android:defaultValue="0" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/com/rising/settings/PersonalizationSettingsController.kt b/src/com/rising/settings/PersonalizationSettingsController.kt
index 01441824..67eac8fa 100644
--- a/src/com/rising/settings/PersonalizationSettingsController.kt
+++ b/src/com/rising/settings/PersonalizationSettingsController.kt
@@ -28,6 +28,9 @@ import com.android.settingslib.widget.LayoutPreference
class PersonalizationSettingsController(context: Context) : AbstractPreferenceController(context) {
+ // Cache for findViewById results to improve performance
+ private val viewCache = mutableMapOf()
+
override fun displayPreference(screen: PreferenceScreen) {
super.displayPreference(screen)
screen.findPreference(KEY_PERSONALIZATIONS)?.let { personalizationPref ->
@@ -51,9 +54,19 @@ class PersonalizationSettingsController(context: Context) : AbstractPreferenceCo
R.id.clock_face to "com.android.settings.Settings\$PersonalizationsClockFacesActivity",
R.id.whats_new to "com.rising.settings.fragments.about.ChangelogActivity"
)
+
personalizationsClickMap.forEach { (viewId, activityName) ->
- preference.findViewById(viewId)?.setOnClickListener {
- mContext.startActivity(createIntent(activityName))
+ // Use cached findViewById to improve performance
+ val view = viewCache.getOrPut(viewId) {
+ preference.findViewById(viewId)
+ }
+ view?.setOnClickListener {
+ try {
+ mContext.startActivity(createIntent(activityName))
+ } catch (e: Exception) {
+ // Graceful error handling for missing activities
+ android.util.Log.w("PersonalizationController", "Failed to start activity: $activityName", e)
+ }
}
}
}
diff --git a/src/com/rising/settings/PersonalizationsFragment.java b/src/com/rising/settings/PersonalizationsFragment.java
deleted file mode 100644
index b552d97b..00000000
--- a/src/com/rising/settings/PersonalizationsFragment.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2023 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.rising.settings;
-
-import android.content.Context;
-import android.os.Bundle;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PersonalizationsFragment extends DashboardFragment {
-
- public static final String CATEGORY_KEY = "com.android.settings.category.ia.personalizations";
-
- private static final String LOG_TAG = "Personalization";
-
- @Override
- protected int getPreferenceScreenResId() {
- return R.xml.rising_dashboard;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- @Override
- public int getHelpResource() {
- return R.string.help_uri_about;
- }
-
- @Override
- public void onStart() {
- super.onStart();
- }
-
- @Override
- protected String getLogTag() {
- return LOG_TAG;
- }
-
- @Override
- protected List createPreferenceControllers(Context context) {
- return buildPreferenceControllers(context, this /* fragment */, getSettingsLifecycle());
- }
-
- private static List buildPreferenceControllers(
- Context context, PersonalizationsFragment fragment, Lifecycle lifecycle) {
- final List controllers = new ArrayList<>();
- controllers.add(new PersonalizationSettingsController(context));
- return controllers;
- }
-
- /**
- * For Search.
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_dashboard) {
- @Override
- public List createPreferenceControllers(
- Context context) {
- return buildPreferenceControllers(context, null /* fragment */,
- null /* lifecycle */);
- }
- };
- }
diff --git a/src/com/rising/settings/PersonalizationsFragment.kt b/src/com/rising/settings/PersonalizationsFragment.kt
new file mode 100644
index 00000000..695be40b
--- /dev/null
+++ b/src/com/rising/settings/PersonalizationsFragment.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings
+
+import android.content.Context
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.dashboard.DashboardFragment
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.core.AbstractPreferenceController
+import com.android.settingslib.core.lifecycle.Lifecycle
+
+class PersonalizationsFragment : DashboardFragment() {
+
+ companion object {
+ const val CATEGORY_KEY = "com.android.settings.category.ia.personalizations"
+ private const val LOG_TAG = "Personalization"
+
+ /**
+ * For Search.
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_dashboard) {
+ override fun createPreferenceControllers(context: Context): List {
+ return buildPreferenceControllers(context, null, null)
+ }
+ }
+
+ private fun buildPreferenceControllers(
+ context: Context,
+ fragment: PersonalizationsFragment?,
+ lifecycle: Lifecycle?
+ ): List {
+ val controllers = ArrayList()
+ controllers.add(PersonalizationSettingsController(context))
+ return controllers
+ }
+ }
+
+ override fun getPreferenceScreenResId(): Int {
+ return R.xml.rising_dashboard
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+
+ override fun getHelpResource(): Int {
+ return R.string.help_uri_about
+ }
+
+ override fun onStart() {
+ super.onStart()
+ }
+
+ override fun getLogTag(): String {
+ return LOG_TAG
+ }
+
+ override fun createPreferenceControllers(context: Context): List {
+ return buildPreferenceControllers(context, this, settingsLifecycle)
+ }
+}
diff --git a/src/com/rising/settings/TopLevelSettingsPreferenceController.java b/src/com/rising/settings/TopLevelSettingsPreferenceController.kt
similarity index 57%
rename from src/com/rising/settings/TopLevelSettingsPreferenceController.java
rename to src/com/rising/settings/TopLevelSettingsPreferenceController.kt
index 39530937..9458cd94 100644
--- a/src/com/rising/settings/TopLevelSettingsPreferenceController.java
+++ b/src/com/rising/settings/TopLevelSettingsPreferenceController.kt
@@ -14,22 +14,17 @@
* limitations under the License.
*/
-package com.rising.settings;
+package com.rising.settings
-import android.content.Context;
+import android.content.Context
+import com.android.settings.core.BasePreferenceController
-import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
+class TopLevelSettingsPreferenceController(
+ context: Context,
+ preferenceKey: String
+) : BasePreferenceController(context, preferenceKey) {
-public class TopLevelSettingsPreferenceController extends BasePreferenceController {
-
- public TopLevelSettingsPreferenceController(Context context,
- String preferenceKey) {
- super(context, preferenceKey);
- }
-
- @Override
- public int getAvailabilityStatus() {
- return AVAILABLE;
+ override fun getAvailabilityStatus(): Int {
+ return AVAILABLE
}
}
diff --git a/src/com/rising/settings/fragments/Assistant.java b/src/com/rising/settings/fragments/Assistant.java
deleted file mode 100644
index 35b02cf8..00000000
--- a/src/com/rising/settings/fragments/Assistant.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.net.Uri;
-import android.provider.Settings;
-import android.text.InputType;
-import android.text.TextUtils;
-import android.widget.EditText;
-
-import androidx.appcompat.app.AlertDialog;
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceClickListener;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.List;
-
-@SearchIndexable
-public class Assistant extends SettingsPreferenceFragment {
-
- private static final String TAG = "Assistant";
-
- private static final String KEY_AI_ASSISTANT_GEMINI_KEY = "ai_assistant_gemini_key";
-
- private Preference mAiAssistantKeyPreference;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.rising_settings_ai_assistant);
- mAiAssistantKeyPreference = findPreference(KEY_AI_ASSISTANT_GEMINI_KEY);
- if (mAiAssistantKeyPreference != null) {
- String currentKey = Settings.System.getString(getContext().getContentResolver(), KEY_AI_ASSISTANT_GEMINI_KEY);
- mAiAssistantKeyPreference.setSummary(TextUtils.isEmpty(currentKey) ? getString(R.string.ai_assistant_gemini_key_summary) : currentKey);
- mAiAssistantKeyPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- showApiKeyDialog();
- return true;
- }
- });
- }
-
- Preference mWikiLink = findPreference("wiki_link_assistant");
- if (mWikiLink != null) {
- mWikiLink.setOnPreferenceClickListener(preference -> {
- Uri uri = Uri.parse("https://github.com/RisingOS-Revived/risingOS_wiki/blob/fifteen/assistant/Risa/README.md");
- Intent intent = new Intent(Intent.ACTION_VIEW, uri);
- startActivity(intent);
- return true;
- });
- }
- }
-
- private void showApiKeyDialog() {
- AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
- builder.setTitle(R.string.ai_assistant_gemini_key_dialog_title);
-
- final EditText input = new EditText(getContext());
- input.setInputType(InputType.TYPE_CLASS_TEXT);
-
- String currentKey = Settings.System.getString(getContext().getContentResolver(), KEY_AI_ASSISTANT_GEMINI_KEY);
- if (!TextUtils.isEmpty(currentKey)) {
- input.setText(currentKey);
- input.setSelection(currentKey.length());
- }
-
- builder.setView(input);
- builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- String newApiKey = input.getText().toString();
- if (!TextUtils.isEmpty(newApiKey)) {
- Settings.System.putString(getContext().getContentResolver(), KEY_AI_ASSISTANT_GEMINI_KEY, newApiKey);
- mAiAssistantKeyPreference.setSummary(newApiKey);
- }
- }
- });
- builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.cancel();
- }
- });
-
- builder.show();
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_ai_assistant) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/Assistant.kt b/src/com/rising/settings/fragments/Assistant.kt
new file mode 100644
index 00000000..6b8bb0db
--- /dev/null
+++ b/src/com/rising/settings/fragments/Assistant.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class Assistant : OptimizedSettingsFragment() {
+
+ companion object {
+ const val TAG = "Assistant"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_ai_assistant) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context).toMutableList()
+ return keys
+ }
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.rising_settings_ai_assistant)
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/Backup.java b/src/com/rising/settings/fragments/Backup.java
deleted file mode 100644
index 8977461a..00000000
--- a/src/com/rising/settings/fragments/Backup.java
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.SystemProperties;
-import android.preference.PreferenceManager;
-import android.provider.Settings;
-import android.util.Log;
-import android.widget.Toast;
-
-import androidx.activity.result.ActivityResultLauncher;
-import androidx.activity.result.contract.ActivityResultContracts;
-import androidx.core.content.FileProvider;
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-import com.android.settings.preferences.ui.AdaptiveListPreference;
-import com.android.settings.preferences.CustomSeekBarPreference;
-import com.android.settings.preferences.GlobalSettingSwitchPreference;
-import com.android.settings.preferences.RisingSystemSettingListPreference;
-import com.android.settings.preferences.SystemPropertyListPreference;
-import com.android.settings.preferences.SecureSettingListPreference;
-import com.android.settings.preferences.SecureSettingSwitchPreference;
-import com.android.settings.preferences.SystemSettingListPreference;
-import com.android.settings.preferences.SystemSettingSeekBarPreference;
-import com.android.settings.preferences.SystemSettingSwitchPreference;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-@SearchIndexable
-public class Backup extends SettingsPreferenceFragment {
-
- private static final String TAG = "Backup";
- private static final String BACKUP_PERSONALIZATION_SETTINGS = "backup_personalization_settings";
- private static final String RESTORE_PERSONALIZATION_SETTINGS = "restore_personalization_settings";
- private static final String UPLOAD_BACKUP_TO_DRIVE = "upload_backup_to_drive";
- private static final String DOWNLOAD_BACKUP_FROM_DRIVE = "download_backup_from_drive";
-
- private ActivityResultLauncher backupLauncher;
- private ActivityResultLauncher restoreLauncher;
- private ActivityResultLauncher uploadLauncher;
- private ActivityResultLauncher downloadLauncher;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.rising_settings_backup);
-
- final PreferenceScreen prefScreen = getPreferenceScreen();
- Context mContext = getActivity().getApplicationContext();
-
- // Initialize ActivityResultLaunchers for file selection
- backupLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
- if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
- Uri uri = result.getData().getData();
- if (uri != null) {
- Log.d(TAG, "Backup URI: " + uri.toString());
- backupSettings(mContext, uri);
- } else {
- Log.e(TAG, "Backup URI is null");
- }
- } else {
- Log.e(TAG, "Backup activity result not OK or data is null");
- }
- });
-
- restoreLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
- if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
- Uri uri = result.getData().getData();
- if (uri != null) {
- Log.d(TAG, "Restore URI: " + uri.toString());
- restoreSettings(mContext, uri);
- } else {
- Log.e(TAG, "Restore URI is null");
- }
- } else {
- Log.e(TAG, "Restore activity result not OK or data is null");
- }
- });
-
- // Initialize ActivityResultLaunchers for file selection
- uploadLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
- if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
- Uri uri = result.getData().getData();
- if (uri != null) {
- Log.d(TAG, "Selected file URI: " + uri.toString());
- uploadFileToDrive(mContext, uri);
- } else {
- Log.e(TAG, "Selected file URI is null");
- }
- } else {
- Log.e(TAG, "Upload activity result not OK or data is null");
- }
- });
-
- downloadLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
- if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
- Uri uri = result.getData().getData();
- if (uri != null) {
- Log.d(TAG, "Download URI: " + uri.toString());
- restoreSettings(mContext, uri);
- } else {
- Log.e(TAG, "Download URI is null");
- }
- } else {
- Log.e(TAG, "Download activity result not OK or data is null");
- }
- });
-
- // Backup settings
- Preference backupPref = findPreference(BACKUP_PERSONALIZATION_SETTINGS);
- if (backupPref != null) {
- backupPref.setOnPreferenceClickListener(preference -> {
- Log.d(TAG, "Backup option clicked");
- chooseFileLocationForBackup();
- return true;
- });
- }
-
- // Restore settings
- Preference restorePref = findPreference(RESTORE_PERSONALIZATION_SETTINGS);
- if (restorePref != null) {
- restorePref.setOnPreferenceClickListener(preference -> {
- Log.d(TAG, "Restore option clicked");
- chooseFileForRestore();
- return true;
- });
- }
-
- // Upload backup to Google Drive
- Preference uploadToDrivePref = findPreference(UPLOAD_BACKUP_TO_DRIVE);
- uploadToDrivePref.setOnPreferenceClickListener(preference -> {
- Log.d(TAG, "Upload to Drive option clicked");
- chooseFileForUpload();
- return true;
- });
-
- // Download backup from Google Drive
- Preference downloadFromDrivePref = findPreference(DOWNLOAD_BACKUP_FROM_DRIVE);
- downloadFromDrivePref.setOnPreferenceClickListener(preference -> {
- Log.d(TAG, "Download from Drive option clicked");
- downloadBackupFromDrive();
- return true;
- });
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- private void chooseFileLocationForBackup() {
- Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
- intent.setType("application/json");
- intent.putExtra(Intent.EXTRA_TITLE, "personalization_settings_backup.json");
- Log.d(TAG, "Launching file picker for backup");
- backupLauncher.launch(intent);
- }
-
- private void chooseFileForRestore() {
- Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
- intent.setType("application/json");
- Log.d(TAG, "Launching file picker for restore");
- restoreLauncher.launch(intent);
- }
-
- private void chooseFileForUpload() {
- Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
- intent.setType("application/json");
- Log.d(TAG, "Launching file picker for upload");
- uploadLauncher.launch(intent);
- }
-
- private void uploadFileToDrive(Context context, Uri fileUri) {
- try {
- context.getContentResolver().takePersistableUriPermission(fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- Intent uploadIntent = new Intent(Intent.ACTION_SEND);
- uploadIntent.setType("application/json");
- uploadIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
- uploadIntent.setPackage("com.google.android.apps.docs");
- uploadIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK);
- if (uploadIntent.resolveActivity(context.getPackageManager()) != null) {
- context.startActivity(uploadIntent);
- } else {
- Toast.makeText(context, "Google Drive app not installed.", Toast.LENGTH_SHORT).show();
- }
- } catch (Exception e) {
- Log.e(TAG, "Failed to upload file to Google Drive: " + e.getMessage(), e);
- Toast.makeText(context, "Failed to upload file to Google Drive.", Toast.LENGTH_SHORT).show();
- }
- }
-
- private void downloadBackupFromDrive() {
- Intent downloadIntent = new Intent(Intent.ACTION_GET_CONTENT);
- downloadIntent.setType("application/json");
- downloadIntent.addCategory(Intent.CATEGORY_OPENABLE);
- downloadIntent.setPackage("com.google.android.apps.docs");
-
- if (downloadIntent.resolveActivity(getContext().getPackageManager()) != null) {
- downloadLauncher.launch(downloadIntent);
- } else {
- Toast.makeText(getContext(), "Google Drive app not installed.", Toast.LENGTH_SHORT).show();
- }
- }
-
- private void backupSettings(Context context, Uri uri) {
- try {
- JSONObject json = new JSONObject();
-
- // Back up System settings
- backupSettingsProvider(json, Settings.System.class, context.getContentResolver());
-
- // Back up Secure settings
- backupSettingsProvider(json, Settings.Secure.class, context.getContentResolver());
-
- // Back up Global settings
- backupSettingsProvider(json, Settings.Global.class, context.getContentResolver());
-
- // Write the JSON object to the backup file
- try (OutputStream outputStream = context.getContentResolver().openOutputStream(uri)) {
- if (outputStream != null) {
- outputStream.write(json.toString().getBytes(StandardCharsets.UTF_8));
- // Save the backup locally
- File backupFile = new File(context.getCacheDir(), "personalization_settings_backup.json");
- try (OutputStream os = new FileOutputStream(backupFile)) {
- os.write(json.toString().getBytes(StandardCharsets.UTF_8));
- }
- Toast.makeText(getActivity(), "Personalization settings backed up successfully!", Toast.LENGTH_SHORT).show();
- }
- }
- } catch (IOException | JSONException e) {
- e.printStackTrace();
- Toast.makeText(getActivity(), "Failed to backup settings", Toast.LENGTH_SHORT).show();
- }
- }
-
- private void backupSettingsProvider(JSONObject json, Class> settingsClass, ContentResolver resolver) throws JSONException {
- try {
- // Determine which Settings class we're working with
- Uri uri;
- String methodName;
-
- if (settingsClass == Settings.System.class) {
- uri = Settings.System.CONTENT_URI;
- methodName = "System";
- } else if (settingsClass == Settings.Secure.class) {
- uri = Settings.Secure.CONTENT_URI;
- methodName = "Secure";
- } else if (settingsClass == Settings.Global.class) {
- uri = Settings.Global.CONTENT_URI;
- methodName = "Global";
- } else {
- return; // Unsupported settings type
- }
-
- // Query all settings from this provider
- Cursor cursor = resolver.query(uri, null, null, null, null);
- if (cursor != null) {
- // Create a JSON object for this settings type
- JSONObject settingsJson = new JSONObject();
-
- // Get column indices
- int nameIndex = cursor.getColumnIndex("name");
- int valueIndex = cursor.getColumnIndex("value");
-
- // Extract all settings
- while (cursor.moveToNext()) {
- String name = cursor.getString(nameIndex);
- String value = cursor.getString(valueIndex);
-
- if (name != null && value != null) {
- settingsJson.put(name, value);
- }
- }
-
- cursor.close();
-
- // Add this settings type to the main JSON object
- json.put(methodName, settingsJson);
- }
- } catch (Exception e) {
- Log.e(TAG, "Error backing up " + settingsClass.getSimpleName() + " settings", e);
- }
- }
-
- private void restoreSettings(Context context, Uri uri) {
- try (InputStream inputStream = context.getContentResolver().openInputStream(uri)) {
- if (inputStream != null) {
- StringBuilder builder = new StringBuilder();
- int ch;
- while ((ch = inputStream.read()) != -1) {
- builder.append((char) ch);
- }
-
- JSONObject json = new JSONObject(builder.toString());
- ContentResolver resolver = context.getContentResolver();
-
- // Restore System settings
- if (json.has("System")) {
- restoreSettingsProvider(json.getJSONObject("System"), Settings.System.class, resolver);
- }
-
- // Restore Secure settings
- if (json.has("Secure")) {
- restoreSettingsProvider(json.getJSONObject("Secure"), Settings.Secure.class, resolver);
- }
-
- // Restore Global settings
- if (json.has("Global")) {
- restoreSettingsProvider(json.getJSONObject("Global"), Settings.Global.class, resolver);
- }
-
- // Force refresh settings
- context.getContentResolver().notifyChange(Settings.System.CONTENT_URI, null);
- context.getContentResolver().notifyChange(Settings.Secure.CONTENT_URI, null);
- context.getContentResolver().notifyChange(Settings.Global.CONTENT_URI, null);
-
- Toast.makeText(getActivity(), "Personalization settings restored successfully!", Toast.LENGTH_SHORT).show();
- }
- } catch (IOException | JSONException e) {
- e.printStackTrace();
- Toast.makeText(getActivity(), "Failed to restore settings", Toast.LENGTH_SHORT).show();
- }
- }
-
- private void restoreSettingsProvider(JSONObject settingsJson, Class> settingsClass, ContentResolver resolver) throws JSONException {
- try {
- Iterator keys = settingsJson.keys();
-
- while (keys.hasNext()) {
- String key = keys.next();
- String value = settingsJson.getString(key);
-
- if (settingsClass == Settings.System.class) {
- Settings.System.putString(resolver, key, value);
- } else if (settingsClass == Settings.Secure.class) {
- Settings.Secure.putString(resolver, key, value);
- } else if (settingsClass == Settings.Global.class) {
- Settings.Global.putString(resolver, key, value);
- }
- }
- } catch (Exception e) {
- Log.e(TAG, "Error restoring " + settingsClass.getSimpleName() + " settings", e);
- }
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_backup) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/Backup.kt b/src/com/rising/settings/fragments/Backup.kt
new file mode 100644
index 00000000..eb324b5e
--- /dev/null
+++ b/src/com/rising/settings/fragments/Backup.kt
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.app.Activity
+import android.content.Context
+import android.content.ContentResolver
+import android.content.Intent
+import android.database.Cursor
+import android.net.Uri
+import android.os.Bundle
+import android.provider.Settings
+import android.util.Log
+import android.widget.Toast
+import androidx.activity.result.ActivityResultLauncher
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.SettingsPreferenceFragment
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+import org.json.JSONException
+import org.json.JSONObject
+import java.io.File
+import java.io.FileOutputStream
+import java.io.IOException
+import java.io.InputStream
+import java.io.OutputStream
+import java.nio.charset.StandardCharsets
+
+@SearchIndexable
+class Backup : SettingsPreferenceFragment() {
+
+ companion object {
+ private const val TAG = "Backup"
+ private const val BACKUP_PERSONALIZATION_SETTINGS = "backup_personalization_settings"
+ private const val RESTORE_PERSONALIZATION_SETTINGS = "restore_personalization_settings"
+ private const val UPLOAD_BACKUP_TO_DRIVE = "upload_backup_to_drive"
+ private const val DOWNLOAD_BACKUP_FROM_DRIVE = "download_backup_from_drive"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_backup) {
+ override fun getNonIndexableKeys(context: Context): List {
+ return super.getNonIndexableKeys(context)
+ }
+ }
+ }
+
+ private lateinit var backupLauncher: ActivityResultLauncher
+ private lateinit var restoreLauncher: ActivityResultLauncher
+ private lateinit var uploadLauncher: ActivityResultLauncher
+ private lateinit var downloadLauncher: ActivityResultLauncher
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.rising_settings_backup)
+
+ val prefScreen: PreferenceScreen = preferenceScreen
+ val mContext: Context = requireActivity().applicationContext
+
+ // Initialize ActivityResultLaunchers for file selection
+ backupLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+ if (result.resultCode == Activity.RESULT_OK && result.data != null) {
+ val uri = result.data?.data
+ if (uri != null) {
+ Log.d(TAG, "Backup URI: $uri")
+ backupSettings(mContext, uri)
+ } else {
+ Log.e(TAG, "Backup URI is null")
+ }
+ } else {
+ Log.e(TAG, "Backup activity result not OK or data is null")
+ }
+ }
+
+ restoreLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+ if (result.resultCode == Activity.RESULT_OK && result.data != null) {
+ val uri = result.data?.data
+ if (uri != null) {
+ Log.d(TAG, "Restore URI: $uri")
+ restoreSettings(mContext, uri)
+ } else {
+ Log.e(TAG, "Restore URI is null")
+ }
+ } else {
+ Log.e(TAG, "Restore activity result not OK or data is null")
+ }
+ }
+
+ // Initialize ActivityResultLaunchers for file selection
+ uploadLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+ if (result.resultCode == Activity.RESULT_OK && result.data != null) {
+ val uri = result.data?.data
+ if (uri != null) {
+ Log.d(TAG, "Selected file URI: $uri")
+ uploadFileToDrive(mContext, uri)
+ } else {
+ Log.e(TAG, "Selected file URI is null")
+ }
+ } else {
+ Log.e(TAG, "Upload activity result not OK or data is null")
+ }
+ }
+
+ downloadLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+ if (result.resultCode == Activity.RESULT_OK && result.data != null) {
+ val uri = result.data?.data
+ if (uri != null) {
+ Log.d(TAG, "Download URI: $uri")
+ restoreSettings(mContext, uri)
+ } else {
+ Log.e(TAG, "Download URI is null")
+ }
+ } else {
+ Log.e(TAG, "Download activity result not OK or data is null")
+ }
+ }
+
+ // Backup settings
+ val backupPref: Preference? = findPreference(BACKUP_PERSONALIZATION_SETTINGS)
+ backupPref?.setOnPreferenceClickListener {
+ Log.d(TAG, "Backup option clicked")
+ chooseFileLocationForBackup()
+ true
+ }
+
+ // Restore settings
+ val restorePref: Preference? = findPreference(RESTORE_PERSONALIZATION_SETTINGS)
+ restorePref?.setOnPreferenceClickListener {
+ Log.d(TAG, "Restore option clicked")
+ chooseFileForRestore()
+ true
+ }
+
+ // Upload backup to Google Drive
+ val uploadToDrivePref: Preference? = findPreference(UPLOAD_BACKUP_TO_DRIVE)
+ uploadToDrivePref?.setOnPreferenceClickListener {
+ Log.d(TAG, "Upload to Drive option clicked")
+ chooseFileForUpload()
+ true
+ }
+
+ // Download backup from Google Drive
+ val downloadFromDrivePref: Preference? = findPreference(DOWNLOAD_BACKUP_FROM_DRIVE)
+ downloadFromDrivePref?.setOnPreferenceClickListener {
+ Log.d(TAG, "Download from Drive option clicked")
+ downloadBackupFromDrive()
+ true
+ }
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+
+ private fun chooseFileLocationForBackup() {
+ val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
+ type = "application/json"
+ putExtra(Intent.EXTRA_TITLE, "personalization_settings_backup.json")
+ }
+ Log.d(TAG, "Launching file picker for backup")
+ backupLauncher.launch(intent)
+ }
+
+ private fun chooseFileForRestore() {
+ val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
+ type = "application/json"
+ }
+ Log.d(TAG, "Launching file picker for restore")
+ restoreLauncher.launch(intent)
+ }
+
+ private fun chooseFileForUpload() {
+ val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
+ type = "application/json"
+ }
+ Log.d(TAG, "Launching file picker for upload")
+ uploadLauncher.launch(intent)
+ }
+
+ private fun uploadFileToDrive(context: Context, fileUri: Uri) {
+ try {
+ context.contentResolver.takePersistableUriPermission(
+ fileUri,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ )
+ val uploadIntent = Intent(Intent.ACTION_SEND).apply {
+ type = "application/json"
+ putExtra(Intent.EXTRA_STREAM, fileUri)
+ setPackage("com.google.android.apps.docs")
+ addFlags(
+ Intent.FLAG_GRANT_READ_URI_PERMISSION or
+ Intent.FLAG_GRANT_WRITE_URI_PERMISSION or
+ Intent.FLAG_ACTIVITY_NEW_TASK
+ )
+ }
+ if (uploadIntent.resolveActivity(context.packageManager) != null) {
+ context.startActivity(uploadIntent)
+ } else {
+ Toast.makeText(context, "Google Drive app not installed.", Toast.LENGTH_SHORT).show()
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, "Failed to upload file to Google Drive: ${e.message}", e)
+ Toast.makeText(context, "Failed to upload file to Google Drive.", Toast.LENGTH_SHORT).show()
+ }
+ }
+
+ private fun downloadBackupFromDrive() {
+ val downloadIntent = Intent(Intent.ACTION_GET_CONTENT).apply {
+ type = "application/json"
+ addCategory(Intent.CATEGORY_OPENABLE)
+ setPackage("com.google.android.apps.docs")
+ }
+
+ if (downloadIntent.resolveActivity(requireContext().packageManager) != null) {
+ downloadLauncher.launch(downloadIntent)
+ } else {
+ Toast.makeText(requireContext(), "Google Drive app not installed.", Toast.LENGTH_SHORT).show()
+ }
+ }
+
+ private fun backupSettings(context: Context, uri: Uri) {
+ try {
+ val json = JSONObject()
+
+ // Back up System settings
+ backupSettingsProvider(json, Settings.System::class.java, context.contentResolver)
+
+ // Back up Secure settings
+ backupSettingsProvider(json, Settings.Secure::class.java, context.contentResolver)
+
+ // Back up Global settings
+ backupSettingsProvider(json, Settings.Global::class.java, context.contentResolver)
+
+ // Write the JSON object to the backup file
+ context.contentResolver.openOutputStream(uri)?.use { outputStream ->
+ outputStream.write(json.toString().toByteArray(StandardCharsets.UTF_8))
+
+ // Save the backup locally
+ val backupFile = File(context.cacheDir, "personalization_settings_backup.json")
+ FileOutputStream(backupFile).use { os ->
+ os.write(json.toString().toByteArray(StandardCharsets.UTF_8))
+ }
+ Toast.makeText(requireActivity(), "Personalization settings backed up successfully!", Toast.LENGTH_SHORT).show()
+ }
+ } catch (e: IOException) {
+ e.printStackTrace()
+ Toast.makeText(requireActivity(), "Failed to backup settings", Toast.LENGTH_SHORT).show()
+ } catch (e: JSONException) {
+ e.printStackTrace()
+ Toast.makeText(requireActivity(), "Failed to backup settings", Toast.LENGTH_SHORT).show()
+ }
+ }
+
+ @Throws(JSONException::class)
+ private fun backupSettingsProvider(json: JSONObject, settingsClass: Class<*>, resolver: ContentResolver) {
+ try {
+ // Determine which Settings class we're working with
+ val (uri, methodName) = when (settingsClass) {
+ Settings.System::class.java -> Settings.System.CONTENT_URI to "System"
+ Settings.Secure::class.java -> Settings.Secure.CONTENT_URI to "Secure"
+ Settings.Global::class.java -> Settings.Global.CONTENT_URI to "Global"
+ else -> return // Unsupported settings type
+ }
+
+ // Query all settings from this provider
+ resolver.query(uri, null, null, null, null)?.use { cursor ->
+ // Create a JSON object for this settings type
+ val settingsJson = JSONObject()
+
+ // Get column indices
+ val nameIndex = cursor.getColumnIndex("name")
+ val valueIndex = cursor.getColumnIndex("value")
+
+ // Extract all settings
+ while (cursor.moveToNext()) {
+ val name = cursor.getString(nameIndex)
+ val value = cursor.getString(valueIndex)
+
+ if (name != null && value != null) {
+ settingsJson.put(name, value)
+ }
+ }
+
+ // Add this settings type to the main JSON object
+ json.put(methodName, settingsJson)
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, "Error backing up ${settingsClass.simpleName} settings", e)
+ }
+ }
+
+ private fun restoreSettings(context: Context, uri: Uri) {
+ try {
+ context.contentResolver.openInputStream(uri)?.use { inputStream ->
+ val builder = StringBuilder()
+ var ch: Int
+ while (inputStream.read().also { ch = it } != -1) {
+ builder.append(ch.toChar())
+ }
+
+ val json = JSONObject(builder.toString())
+ val resolver = context.contentResolver
+
+ // Restore System settings
+ if (json.has("System")) {
+ restoreSettingsProvider(json.getJSONObject("System"), Settings.System::class.java, resolver)
+ }
+
+ // Restore Secure settings
+ if (json.has("Secure")) {
+ restoreSettingsProvider(json.getJSONObject("Secure"), Settings.Secure::class.java, resolver)
+ }
+
+ // Restore Global settings
+ if (json.has("Global")) {
+ restoreSettingsProvider(json.getJSONObject("Global"), Settings.Global::class.java, resolver)
+ }
+
+ // Force refresh settings
+ context.contentResolver.notifyChange(Settings.System.CONTENT_URI, null)
+ context.contentResolver.notifyChange(Settings.Secure.CONTENT_URI, null)
+ context.contentResolver.notifyChange(Settings.Global.CONTENT_URI, null)
+
+ Toast.makeText(requireActivity(), "Personalization settings restored successfully!", Toast.LENGTH_SHORT).show()
+ }
+ } catch (e: IOException) {
+ e.printStackTrace()
+ Toast.makeText(requireActivity(), "Failed to restore settings", Toast.LENGTH_SHORT).show()
+ } catch (e: JSONException) {
+ e.printStackTrace()
+ Toast.makeText(requireActivity(), "Failed to restore settings", Toast.LENGTH_SHORT).show()
+ }
+ }
+
+ @Throws(JSONException::class)
+ private fun restoreSettingsProvider(settingsJson: JSONObject, settingsClass: Class<*>, resolver: ContentResolver) {
+ try {
+ val keys = settingsJson.keys()
+
+ while (keys.hasNext()) {
+ val key = keys.next()
+ val value = settingsJson.getString(key)
+
+ when (settingsClass) {
+ Settings.System::class.java -> Settings.System.putString(resolver, key, value)
+ Settings.Secure::class.java -> Settings.Secure.putString(resolver, key, value)
+ Settings.Global::class.java -> Settings.Global.putString(resolver, key, value)
+ }
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, "Error restoring ${settingsClass.simpleName} settings", e)
+ }
+ }
+}
diff --git a/src/com/rising/settings/fragments/BootAnimationSettings.java b/src/com/rising/settings/fragments/BootAnimationSettings.java
deleted file mode 100644
index d5e1a5b5..00000000
--- a/src/com/rising/settings/fragments/BootAnimationSettings.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2024 risingOS
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.SystemProperties;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.util.Log;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-import androidx.documentfile.provider.DocumentFile;
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.Indexable;
-import com.android.settingslib.search.SearchIndexable;
-import com.android.settings.preferences.BootAnimationPreviewPreference;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-@SearchIndexable
-public class BootAnimationSettings extends SettingsPreferenceFragment implements OnPreferenceChangeListener {
-
- private static final String BOOTANIMATION_STYLE_KEY = "persist.sys.bootanimation_style";
- private static final String TAG = "BootAnimationSettings";
- private static final int REQUEST_CODE_PICK_ZIP = 1001;
- private static final String CUSTOM_BOOTANIMATION_FILE = "/data/misc/bootanim/bootanimation.zip";
-
- private static final String[] PRODUCT_BOOT_ANIMATION_FILES = {
- "/product/media/bootanimation_rising.zip",
- "/product/media/bootanimation_cyberpunk.zip",
- "/product/media/bootanimation_google.zip",
- "/product/media/bootanimation_google_monet.zip",
- "/product/media/bootanimation_valorant.zip"
- };
-
- private ListPreference mBootAnimationStyle;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.rising_settings_bootanimation);
-
- mBootAnimationStyle = (ListPreference) findPreference(BOOTANIMATION_STYLE_KEY);
- if (mBootAnimationStyle != null) {
- mBootAnimationStyle.setOnPreferenceChangeListener(this);
-
- // Set the current value from the system property
- int currentStyle = SystemProperties.getInt(BOOTANIMATION_STYLE_KEY, 0);
- mBootAnimationStyle.setValue(String.valueOf(currentStyle));
- updateBootAnimationPreview();
- }
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (preference == mBootAnimationStyle) {
- int style = Integer.parseInt((String) newValue);
- if (style == 5) { // Custom option selected
- launchFilePicker();
- return false; // Return false to prevent immediate property update
- } else {
- copyProductFile(style);
- return true;
- }
- }
- return false;
- }
-
- private void launchFilePicker() {
- Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
- intent.addCategory(Intent.CATEGORY_OPENABLE);
- intent.setType("application/zip");
- startActivityForResult(intent, REQUEST_CODE_PICK_ZIP);
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == REQUEST_CODE_PICK_ZIP && resultCode == Activity.RESULT_OK && data != null) {
- Uri uri = data.getData();
- if (uri != null) {
- handleSelectedFile(uri);
- }
- }
- }
-
- private void handleSelectedFile(Uri uri) {
- try {
- // Copy the selected file to the custom bootanimation location
- InputStream inputStream = getContext().getContentResolver().openInputStream(uri);
- File customBootAnimation = new File(CUSTOM_BOOTANIMATION_FILE);
- // Ensure the directory exists
- customBootAnimation.getParentFile().mkdirs();
- try (OutputStream outputStream = new FileOutputStream(customBootAnimation)) {
- byte[] buffer = new byte[1024];
- int length;
- while ((length = inputStream.read(buffer)) > 0) {
- outputStream.write(buffer, 0, length);
- }
- }
- inputStream.close();
- // Update system property to use custom bootanimation
- SystemProperties.set(BOOTANIMATION_STYLE_KEY, "5"); // Custom option value
- updateBootAnimationPreview();
- // Force the preference to update to the custom option
- mBootAnimationStyle.setValue("5"); // Set to the custom option
- Toast.makeText(getContext(), R.string.boot_animation_applied, Toast.LENGTH_SHORT).show();
- } catch (Exception e) {
- Log.e(TAG, "Error copying custom bootanimation", e);
- }
- }
-
- private void copyProductFile(int style) {
- try {
- if (style < 0 || style >= PRODUCT_BOOT_ANIMATION_FILES.length) {
- Log.e(TAG, "Invalid style index");
- return;
- }
- String productFilePath = PRODUCT_BOOT_ANIMATION_FILES[style];
- File productFile = new File(productFilePath);
- if (!productFile.exists()) {
- Log.e(TAG, "Product file does not exist: " + productFilePath);
- return;
- }
- InputStream inputStream = new FileInputStream(productFile);
- File customBootAnimation = new File(CUSTOM_BOOTANIMATION_FILE);
- customBootAnimation.getParentFile().mkdirs();
- try (OutputStream outputStream = new FileOutputStream(customBootAnimation)) {
- byte[] buffer = new byte[1024];
- int length;
- while ((length = inputStream.read(buffer)) > 0) {
- outputStream.write(buffer, 0, length);
- }
- }
- inputStream.close();
- SystemProperties.set(BOOTANIMATION_STYLE_KEY, String.valueOf(style));
- updateBootAnimationPreview();
- mBootAnimationStyle.setValue(String.valueOf(style));
- Toast.makeText(getContext(), R.string.boot_animation_applied, Toast.LENGTH_SHORT).show();
- } catch (Exception e) {
- Log.e(TAG, "Error copying product bootanimation", e);
- }
- }
-
- private void updateBootAnimationPreview() {
- BootAnimationPreviewPreference previewPreference = (BootAnimationPreviewPreference) findPreference("bootanimation_preview");
- if (previewPreference != null) {
- previewPreference.loadBootAnimationPreview();
- }
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider() {
- @Override
- public List getXmlResourcesToIndex(Context context,
- boolean enabled) {
- ArrayList result =
- new ArrayList<>();
-
- SearchIndexableResource sir = new SearchIndexableResource(context);
- sir.xmlResId = R.xml.rising_settings_bootanimation;
- result.add(sir);
- return result;
- }
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/BootAnimationSettings.kt b/src/com/rising/settings/fragments/BootAnimationSettings.kt
new file mode 100644
index 00000000..dd64d35b
--- /dev/null
+++ b/src/com/rising/settings/fragments/BootAnimationSettings.kt
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2024 risingOS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import android.os.Environment
+import android.os.SystemProperties
+import android.provider.SearchIndexableResource
+import android.provider.Settings
+import android.util.Log
+import android.widget.ImageView
+import android.widget.Toast
+
+import androidx.documentfile.provider.DocumentFile
+import androidx.preference.ListPreference
+import androidx.preference.Preference
+import androidx.preference.Preference.OnPreferenceChangeListener
+import androidx.preference.PreferenceScreen
+
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.SettingsPreferenceFragment
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.Indexable
+import com.android.settingslib.search.SearchIndexable
+import com.android.settings.preferences.BootAnimationPreviewPreference
+
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileOutputStream
+import java.io.InputStream
+import java.io.OutputStream
+import java.util.ArrayList
+import java.util.concurrent.Future
+import java.lang.ref.WeakReference
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Executors
+import java.util.concurrent.ConcurrentHashMap
+
+@SearchIndexable
+class BootAnimationSettings : SettingsPreferenceFragment(), OnPreferenceChangeListener {
+
+ private var mBootAnimationStyle: ListPreference? = null
+
+ // Background executor for file operations
+ private var mFileExecutor: ExecutorService? = null
+
+ // Cache for file existence checks
+ private val mFileExistenceCache: MutableMap = ConcurrentHashMap()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.rising_settings_bootanimation)
+
+ // Initialize background executor
+ mFileExecutor = Executors.newSingleThreadExecutor()
+
+ mBootAnimationStyle = findPreference(BOOTANIMATION_STYLE_KEY)?.apply {
+ setOnPreferenceChangeListener(this@BootAnimationSettings)
+
+ // Set the current value from the system property
+ val currentStyle = SystemProperties.getInt(BOOTANIMATION_STYLE_KEY, 0)
+ value = currentStyle.toString()
+ updateBootAnimationPreview()
+ }
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ if (preference == mBootAnimationStyle) {
+ val style = (newValue as String).toInt()
+ if (style == 5) { // Custom option selected
+ launchFilePicker()
+ return false // Return false to prevent immediate property update
+ } else {
+ copyProductFile(style)
+ return true
+ }
+ }
+ return false
+ }
+
+ private fun launchFilePicker() {
+ val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
+ addCategory(Intent.CATEGORY_OPENABLE)
+ type = "application/zip"
+ }
+ startActivityForResult(intent, REQUEST_CODE_PICK_ZIP)
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ if (requestCode == REQUEST_CODE_PICK_ZIP && resultCode == Activity.RESULT_OK && data != null) {
+ val uri = data.data
+ if (uri != null) {
+ handleSelectedFile(uri)
+ }
+ }
+ }
+
+ private fun handleSelectedFile(uri: Uri) {
+ // Perform file operations in background to avoid blocking UI
+ performCopyOperation(uri, 5, true)
+ }
+
+ private fun copyProductFile(style: Int) {
+ // Validate input
+ if (style < 0 || style >= PRODUCT_BOOT_ANIMATION_FILES.size) {
+ Log.e(TAG, "Invalid style index")
+ return
+ }
+
+ val productFilePath = PRODUCT_BOOT_ANIMATION_FILES[style]
+
+ // Check cache first
+ var fileExists = mFileExistenceCache[productFilePath]
+ if (fileExists == null) {
+ fileExists = File(productFilePath).exists()
+ mFileExistenceCache[productFilePath] = fileExists
+ }
+
+ if (!fileExists) {
+ Log.e(TAG, "Product file does not exist: $productFilePath")
+ return
+ }
+
+ // Perform file operations in background
+ performCopyOperation(productFilePath, style, false)
+ }
+
+ private fun updateBootAnimationPreview() {
+ val previewPreference = findPreference("bootanimation_preview")
+ previewPreference?.loadBootAnimationPreview()
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+
+ /**
+ * Modern ExecutorService-based file copy operation replacing deprecated AsyncTask
+ */
+ private fun performCopyOperation(source: Any, style: Int, isCustomFile: Boolean) {
+ mFileExecutor?.execute {
+ val success = performFileCopy(source)
+
+ // Update UI on main thread
+ activity?.runOnUiThread {
+ if (!isAdded) return@runOnUiThread
+
+ if (success) {
+ SystemProperties.set(BOOTANIMATION_STYLE_KEY, style.toString())
+ updateBootAnimationPreview()
+ mBootAnimationStyle?.value = style.toString()
+ Toast.makeText(context, R.string.boot_animation_applied, Toast.LENGTH_SHORT).show()
+ } else {
+ Toast.makeText(context, "Failed to apply boot animation", Toast.LENGTH_LONG).show()
+ }
+ }
+ }
+ }
+
+ /**
+ * Perform the actual file copy operation in background thread
+ */
+ private fun performFileCopy(source: Any): Boolean {
+ return try {
+ val inputStream: InputStream? = when (source) {
+ is Uri -> context?.contentResolver?.openInputStream(source)
+ is String -> FileInputStream(File(source))
+ else -> null
+ }
+
+ if (inputStream == null) {
+ Log.e(TAG, "Failed to open input stream")
+ return false
+ }
+
+ val customBootAnimation = File(CUSTOM_BOOTANIMATION_FILE)
+ customBootAnimation.parentFile?.mkdirs()
+
+ FileOutputStream(customBootAnimation).use { outputStream ->
+ val buffer = ByteArray(8192) // Larger buffer for better performance
+ var length: Int
+ while (inputStream.read(buffer).also { length = it } > 0) {
+ outputStream.write(buffer, 0, length)
+ }
+ outputStream.flush()
+ }
+ inputStream.close()
+
+ true
+ } catch (e: Exception) {
+ Log.e(TAG, "Error copying bootanimation: ${e.message}", e)
+ false
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ // Cleanup executor and cache
+ mFileExecutor?.let { executor ->
+ if (!executor.isShutdown) {
+ executor.shutdown()
+ }
+ }
+ mFileExistenceCache.clear()
+ }
+
+ override fun onDetach() {
+ super.onDetach()
+ // Additional cleanup
+ mFileExistenceCache.clear()
+ }
+
+ companion object {
+ private const val BOOTANIMATION_STYLE_KEY = "persist.sys.bootanimation_style"
+ private const val TAG = "BootAnimationSettings"
+ private const val REQUEST_CODE_PICK_ZIP = 1001
+ private const val CUSTOM_BOOTANIMATION_FILE = "/data/misc/bootanim/bootanimation.zip"
+
+ private val PRODUCT_BOOT_ANIMATION_FILES = arrayOf(
+ "/product/media/bootanimation_rising.zip",
+ "/product/media/bootanimation_cyberpunk.zip",
+ "/product/media/bootanimation_google.zip",
+ "/product/media/bootanimation_google_monet.zip",
+ "/product/media/bootanimation_valorant.zip"
+ )
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider() {
+ override fun getXmlResourcesToIndex(context: Context, enabled: Boolean): List {
+ val result = ArrayList()
+ val sir = SearchIndexableResource(context).apply {
+ xmlResId = R.xml.rising_settings_bootanimation
+ }
+ result.add(sir)
+ return result
+ }
+
+ override fun getNonIndexableKeys(context: Context): List {
+ return super.getNonIndexableKeys(context)
+ }
+ }
+ }
+}
diff --git a/src/com/rising/settings/fragments/BrightnessSlider.java b/src/com/rising/settings/fragments/BrightnessSlider.java
deleted file mode 100644
index e2ed429a..00000000
--- a/src/com/rising/settings/fragments/BrightnessSlider.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2021 AospExtended ROM Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- package com.rising.settings.fragments;
-
- import android.content.ContentResolver;
- import android.content.Context;
- import android.content.res.Resources;
- import android.content.pm.PackageManager;
- import android.graphics.drawable.AnimationDrawable;
- import android.graphics.drawable.Drawable;
- import android.os.Bundle;
- import android.os.UserHandle;
- import android.provider.SearchIndexableResource;
- import android.provider.Settings;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.Gravity;
- import android.view.ViewGroup;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.FrameLayout;
- import android.widget.TextView;
- import android.text.TextUtils;
- import androidx.preference.PreferenceViewHolder;
- import android.view.ViewGroup.LayoutParams;
-
- import androidx.annotation.NonNull;
- import androidx.annotation.Nullable;
- import androidx.recyclerview.widget.GridLayoutManager;
- import androidx.recyclerview.widget.RecyclerView.ViewHolder;
- import androidx.recyclerview.widget.RecyclerView;
- import androidx.preference.Preference;
- import androidx.preference.Preference.OnPreferenceChangeListener;
- import androidx.preference.PreferenceScreen;
-
- import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
- import com.android.settings.R;
- import com.android.settings.search.BaseSearchIndexProvider;
- import com.android.settingslib.search.Indexable;
- import com.android.settings.SettingsPreferenceFragment;
-
- import com.bumptech.glide.Glide;
-
- import com.android.internal.util.android.ThemeUtils;
-
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Arrays;
-
- import org.json.JSONObject;
- import org.json.JSONException;
-
- public class BrightnessSlider extends SettingsPreferenceFragment {
-
- private RecyclerView mRecyclerView;
- private ThemeUtils mThemeUtils;
- private String mCategory = "android.theme.customization.brightness_slider";
-
- private List mPkgs;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getActivity().setTitle(R.string.theme_customization_brightness_slider_title);
-
- mThemeUtils = ThemeUtils.getInstance(getActivity());
- mPkgs = mThemeUtils.getOverlayPackagesForCategory(mCategory, "com.android.systemui");
- }
-
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(
- R.layout.item_view, container, false);
-
- mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
- GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 1);
- mRecyclerView.setLayoutManager(gridLayoutManager);
- Adapter mAdapter = new Adapter(getActivity());
- mRecyclerView.setAdapter(mAdapter);
-
- return view;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.VIEW_UNKNOWN;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- }
-
- public class Adapter extends RecyclerView.Adapter {
- Context context;
- String mSelectedPkg;
- String mAppliedPkg;
-
- public Adapter(Context context) {
- this.context = context;
- }
-
- @Override
- public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.brightness_slider_option, parent, false);
- CustomViewHolder vh = new CustomViewHolder(v);
- return vh;
- }
-
- @Override
- public void onBindViewHolder(CustomViewHolder holder, final int position) {
- String navPkg = mPkgs.get(position);
-
- String currentPackageName = mThemeUtils.getOverlayInfos(mCategory, "com.android.systemui").stream()
- .filter(info -> info.isEnabled())
- .map(info -> info.packageName)
- .findFirst()
- .orElse("com.android.systemui");
-
- holder.name.setText("com.android.systemui".equals(navPkg) ? "Default" : getLabel(holder.name.getContext(), navPkg));
-
- holder.name.setTextSize(24);
-
- if (currentPackageName.equals(navPkg)) {
- mAppliedPkg = navPkg;
- if (mSelectedPkg == null) {
- mSelectedPkg = navPkg;
- }
- }
-
- holder.itemView.setActivated(navPkg == mSelectedPkg);
- holder.itemView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- updateActivatedStatus(mSelectedPkg, false);
- updateActivatedStatus(navPkg, true);
- mSelectedPkg = navPkg;
- enableOverlays(position);
- }
- });
- }
-
- @Override
- public int getItemCount() {
- return mPkgs.size();
- }
-
- public class CustomViewHolder extends RecyclerView.ViewHolder {
- TextView name;
- public CustomViewHolder(View itemView) {
- super(itemView);
- name = (TextView) itemView.findViewById(R.id.option_label);
- }
- }
-
- private void updateActivatedStatus(String pkg, boolean isActivated) {
- int index = mPkgs.indexOf(pkg);
- if (index < 0) {
- return;
- }
- RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(index);
- if (holder != null && holder.itemView != null) {
- holder.itemView.setActivated(isActivated);
- }
- }
- }
-
- public Drawable getDrawable(Context context, String pkg, String drawableName) {
- try {
- PackageManager pm = context.getPackageManager();
- Resources res = pm.getResourcesForApplication(pkg);
- int resId = res.getIdentifier(drawableName, "drawable", pkg);
- return res.getDrawable(resId);
- }
- catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public String getLabel(Context context, String pkg) {
- PackageManager pm = context.getPackageManager();
- try {
- return pm.getApplicationInfo(pkg, 0)
- .loadLabel(pm).toString();
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return pkg;
- }
-
- public void enableOverlays(int position) {
- mThemeUtils.setOverlayEnabled(mCategory, mPkgs.get(position), "com.android.systemui");
- }
- }
diff --git a/src/com/rising/settings/fragments/BrightnessSlider.kt b/src/com/rising/settings/fragments/BrightnessSlider.kt
new file mode 100644
index 00000000..f04723f5
--- /dev/null
+++ b/src/com/rising/settings/fragments/BrightnessSlider.kt
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2021 AospExtended ROM Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.content.pm.PackageManager
+import android.content.res.Resources
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.annotation.NonNull
+import androidx.annotation.Nullable
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent
+import com.android.internal.util.android.ThemeUtils
+import com.android.settings.R
+
+class BrightnessSlider : OptimizedSettingsFragment() {
+
+ private var mRecyclerView: RecyclerView? = null
+ override var mThemeUtils: ThemeUtils? = null
+ private val mCategory = "android.theme.customization.brightness_slider"
+
+ private var mPkgs: List? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ activity?.setTitle(R.string.theme_customization_brightness_slider_title)
+
+ val context = getSafeContext()
+ if (context != null) {
+ mThemeUtils = ThemeUtils.getInstance(context)
+ }
+ mThemeUtils?.let { themeUtils ->
+ mPkgs = themeUtils.getOverlayPackagesForCategory(mCategory, "com.android.systemui")
+ }
+ }
+
+ override fun onCreateView(@NonNull inflater: LayoutInflater, @Nullable container: ViewGroup?,
+ @Nullable savedInstanceState: Bundle?): View {
+ val view = inflater.inflate(R.layout.item_view, container, false)
+
+ mRecyclerView = view.findViewById(R.id.recycler_view)
+ val gridLayoutManager = GridLayoutManager(activity, 1)
+ mRecyclerView?.layoutManager = gridLayoutManager
+ val mAdapter = Adapter(activity)
+ mRecyclerView?.adapter = mAdapter
+
+ return view
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsEvent.VIEW_UNKNOWN
+ }
+
+ override fun onResume() {
+ super.onResume()
+ }
+
+ inner class Adapter(private val context: Context?) : RecyclerView.Adapter() {
+ private var mSelectedPkg: String? = null
+ private var mAppliedPkg: String? = null
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
+ val v = LayoutInflater.from(parent.context).inflate(R.layout.brightness_slider_option, parent, false)
+ return CustomViewHolder(v)
+ }
+
+ override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
+ val pkgs = mPkgs ?: return
+ val navPkg = pkgs[position]
+
+ val currentPackageName = mThemeUtils?.getOverlayInfos(mCategory, "com.android.systemui")
+ ?.filter { it.isEnabled }
+ ?.map { it.packageName }
+ ?.firstOrNull() ?: "com.android.systemui"
+
+ holder.name.text = if ("com.android.systemui" == navPkg) "Default" else getLabel(holder.name.context, navPkg)
+ holder.name.textSize = 24f
+
+ if (currentPackageName == navPkg) {
+ mAppliedPkg = navPkg
+ if (mSelectedPkg == null) {
+ mSelectedPkg = navPkg
+ }
+ }
+
+ holder.itemView.isActivated = navPkg == mSelectedPkg
+ holder.itemView.setOnClickListener {
+ updateActivatedStatus(mSelectedPkg, false)
+ updateActivatedStatus(navPkg, true)
+ mSelectedPkg = navPkg
+ enableOverlays(position)
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return mPkgs?.size ?: 0
+ }
+
+ inner class CustomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val name: TextView = itemView.findViewById(R.id.option_label)
+ }
+
+ private fun updateActivatedStatus(pkg: String?, isActivated: Boolean) {
+ val pkgs = mPkgs ?: return
+ val index = pkgs.indexOf(pkg)
+ if (index < 0) {
+ return
+ }
+ val holder = mRecyclerView?.findViewHolderForAdapterPosition(index)
+ holder?.itemView?.isActivated = isActivated
+ }
+ }
+
+ private fun getDrawable(context: Context, pkg: String, drawableName: String): Drawable? {
+ return try {
+ val pm = context.packageManager
+ val res = pm.getResourcesForApplication(pkg)
+ val resId = res.getIdentifier(drawableName, "drawable", pkg)
+ res.getDrawable(resId)
+ } catch (e: PackageManager.NameNotFoundException) {
+ // Handle silently - package not found
+ null
+ }
+ }
+
+ private fun getLabel(context: Context, pkg: String): String {
+ val pm = context.packageManager
+ return try {
+ pm.getApplicationInfo(pkg, 0).loadLabel(pm).toString()
+ } catch (e: PackageManager.NameNotFoundException) {
+ // Handle silently - package not found
+ pkg
+ }
+ }
+
+ private fun enableOverlays(position: Int) {
+ val pkgs = mPkgs
+ if (mThemeUtils != null && pkgs != null && position < pkgs.size) {
+ mThemeUtils?.setOverlayEnabled(mCategory, pkgs[position], "com.android.systemui")
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ mThemeUtils = null
+ mPkgs = null
+ }
+}
diff --git a/src/com/rising/settings/fragments/Extras.java b/src/com/rising/settings/fragments/Extras.java
deleted file mode 100644
index 2e673db8..00000000
--- a/src/com/rising/settings/fragments/Extras.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.content.Context;
-import android.os.Bundle;
-
-import androidx.preference.Preference;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.List;
-
-@SearchIndexable
-public class Extras extends SettingsPreferenceFragment {
-
- private static final String TAG = "Extras";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.rising_settings_extras);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_extras) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/Extras.kt b/src/com/rising/settings/fragments/Extras.kt
new file mode 100644
index 00000000..48176eab
--- /dev/null
+++ b/src/com/rising/settings/fragments/Extras.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class Extras : OptimizedSettingsFragment() {
+
+ companion object {
+ const val TAG = "Extras"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_extras) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context).toMutableList()
+ return keys
+ }
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.rising_settings_extras)
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/Gestures.java b/src/com/rising/settings/fragments/Gestures.java
deleted file mode 100644
index f0232051..00000000
--- a/src/com/rising/settings/fragments/Gestures.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.SystemProperties;
-import android.util.Log;
-import android.provider.Settings;
-
-import androidx.preference.Preference;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.List;
-
-@SearchIndexable
-public class Gestures extends SettingsPreferenceFragment {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.rising_settings_gestures);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_gestures) {
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/Gestures.kt b/src/com/rising/settings/fragments/Gestures.kt
new file mode 100644
index 00000000..c85941fd
--- /dev/null
+++ b/src/com/rising/settings/fragments/Gestures.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class Gestures : OptimizedSettingsFragment() {
+
+ companion object {
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_gestures) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context).toMutableList()
+ return keys
+ }
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.rising_settings_gestures)
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/IslandSettings.java b/src/com/rising/settings/fragments/IslandSettings.java
deleted file mode 100644
index 9f9f3aef..00000000
--- a/src/com/rising/settings/fragments/IslandSettings.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2019-2024 The Evolution X Project
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package com.rising.settings.fragments;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Bundle;
-
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.List;
-
-@SearchIndexable
-public class IslandSettings extends SettingsPreferenceFragment implements
- Preference.OnPreferenceChangeListener {
-
- private static final String TAG = "IslandSettings";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.island_settings);
-
- final Context context = getContext();
- final ContentResolver resolver = context.getContentResolver();
- final PreferenceScreen prefScreen = getPreferenceScreen();
- final Resources resources = context.getResources();
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- final Context context = getContext();
- final ContentResolver resolver = context.getContentResolver();
- return false;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.VIEW_UNKNOWN;
- }
-
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.island_settings) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
- final Resources resources = context.getResources();
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/IslandSettings.kt b/src/com/rising/settings/fragments/IslandSettings.kt
new file mode 100644
index 00000000..06c9daca
--- /dev/null
+++ b/src/com/rising/settings/fragments/IslandSettings.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019-2024 The Evolution X Project
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.rising.settings.fragments
+
+import android.content.ContentResolver
+import android.content.Context
+import android.content.res.Resources
+import android.os.Bundle
+
+import androidx.preference.Preference
+import androidx.preference.Preference.OnPreferenceChangeListener
+import androidx.preference.PreferenceCategory
+import androidx.preference.PreferenceScreen
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent
+import com.android.settings.R
+import com.android.settings.search.BaseSearchIndexProvider
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class IslandSettings : OptimizedSettingsFragment(), Preference.OnPreferenceChangeListener {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.island_settings)
+
+ val context = getSafeContext() ?: return
+ val resolver = context.contentResolver
+ val prefScreen = preferenceScreen
+ val resources = context.resources
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ val context = getSafeContext() ?: return false
+ val resolver = context.contentResolver
+ return false
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsEvent.VIEW_UNKNOWN
+ }
+
+ companion object {
+ private const val TAG = "IslandSettings"
+
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.island_settings) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context)
+ val resources = context.resources
+ return keys
+ }
+ }
+ }
+}
diff --git a/src/com/rising/settings/fragments/LockScreen.java b/src/com/rising/settings/fragments/LockScreen.java
deleted file mode 100644
index 07d4c7af..00000000
--- a/src/com/rising/settings/fragments/LockScreen.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.hardware.fingerprint.FingerprintManager;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.text.TextUtils;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.internal.util.android.OmniJawsClient;
-import com.android.internal.util.android.Utils;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.List;
-
-import lineageos.providers.LineageSettings;
-
-import com.android.settings.preferences.ui.PreferenceUtils;
-
-import com.android.settings.utils.SystemRestartUtils;
-
-@SearchIndexable
-public class LockScreen extends SettingsPreferenceFragment
- implements Preference.OnPreferenceChangeListener {
-
- public static final String TAG = "LockScreen";
-
- private static final String LOCKSCREEN_INTERFACE_CATEGORY = "lockscreen_interface_category";
- private static final String LOCKSCREEN_GESTURES_CATEGORY = "lockscreen_gestures_category";
- private static final String LOCKSCREEN_FP_CATEGORY = "lockscreen_fp_category";
- private static final String LOCKSCREEN_UDFPS_CATEGORY = "lockscreen_udfps_category";
- private static final String KEY_RIPPLE_EFFECT = "enable_ripple_effect";
- private static final String KEY_WEATHER = "lockscreen_weather_enabled";
- private static final String KEY_UDFPS_ANIMATIONS = "udfps_recognizing_animation_preview";
- private static final String KEY_UDFPS_ICONS = "udfps_icon_picker";
- private static final String SCREEN_OFF_UDFPS_ENABLED = "screen_off_udfps_enabled";
- private static final String KEY_FP_SUCCESS = "fp_success_vibrate";
- private static final String KEY_FP_FAIL = "fp_error_vibrate";
-
- private Preference mUdfpsIcons;
- private Preference mUdfpsAnimation;
- private Preference mRippleEffect;
- private Preference mWeather;
- private Preference mScreenOffUdfps;
- private Preference mFpSuccess;
- private Preference mFpFail;
-
- private OmniJawsClient mWeatherClient;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.rising_settings_lockscreen);
-
- PreferenceCategory udfpsCategory = (PreferenceCategory) findPreference(LOCKSCREEN_UDFPS_CATEGORY);
- PreferenceCategory fpCategory = (PreferenceCategory) findPreference(LOCKSCREEN_FP_CATEGORY);
-
- FingerprintManager mFingerprintManager = (FingerprintManager)
- getActivity().getSystemService(Context.FINGERPRINT_SERVICE);
- mUdfpsIcons = (Preference) findPreference(KEY_UDFPS_ICONS);
- mUdfpsAnimation = (Preference) findPreference(KEY_UDFPS_ANIMATIONS);
- mRippleEffect = (Preference) findPreference(KEY_RIPPLE_EFFECT);
- mScreenOffUdfps = (Preference) findPreference(SCREEN_OFF_UDFPS_ENABLED);
- mFpSuccess = (Preference) findPreference(KEY_FP_SUCCESS);
- mFpFail = (Preference) findPreference(KEY_FP_FAIL);
-
- if (mFingerprintManager == null || !mFingerprintManager.isHardwareDetected()) {
- if (udfpsCategory != null) {
- if (mUdfpsAnimation != null) udfpsCategory.removePreference(mUdfpsAnimation);
- if (mUdfpsIcons != null) udfpsCategory.removePreference(mUdfpsIcons);
- if (mScreenOffUdfps != null) udfpsCategory.removePreference(mScreenOffUdfps);
- }
- if (fpCategory != null) {
- if (mRippleEffect != null) fpCategory.removePreference(mRippleEffect);
- if (mFpSuccess != null) fpCategory.removePreference(mFpSuccess);
- if (mFpFail != null) fpCategory.removePreference(mFpFail);
- }
- } else {
- final boolean udfpsAnimationInstalled = Utils.isPackageInstalled(getContext(), "com.crdroid.udfps.animations");
- final boolean udfpsIconsInstalled = Utils.isPackageInstalled(getContext(), "com.crdroid.udfps.icons");
- if (!udfpsAnimationInstalled && udfpsCategory != null && mUdfpsAnimation != null) {
- udfpsCategory.removePreference(mUdfpsAnimation);
- }
- if (!udfpsIconsInstalled && udfpsCategory != null && mUdfpsIcons != null) {
- udfpsCategory.removePreference(mUdfpsIcons);
- }
- if (!udfpsAnimationInstalled && !udfpsIconsInstalled && udfpsCategory != null && mScreenOffUdfps != null) {
- udfpsCategory.removePreference(mScreenOffUdfps);
- }
- }
-
- mWeather = (Preference) findPreference(KEY_WEATHER);
- if (mWeather != null) {
- mWeather.setOnPreferenceChangeListener(this);
- }
- mWeatherClient = new OmniJawsClient(getContext());
- updateWeatherSettings();
-
- PreferenceScreen screen = getPreferenceScreen();
- PreferenceUtils.hideEmptyCategory(udfpsCategory, screen);
- PreferenceUtils.hideEmptyCategory(fpCategory, screen);
- com.android.settingslib.widget.LayoutPreference lockHighlightPref = screen.findPreference("lockscreen_highlight_dashboard");
- if (lockHighlightPref != null) {
- java.util.Map lockHighlightClickMap = new java.util.HashMap<>();
- lockHighlightClickMap.put(R.id.lockscreen_widgets_tile, "PersonalizationsWidgetsActivity");
- lockHighlightClickMap.put(R.id.peek_display_tile, "PersonalizationsPDActivity");
- lockHighlightClickMap.put(R.id.aod_tile, "PersonalizationsAODActivity");
- lockHighlightClickMap.put(R.id.dw_tile, "PersonalizationsDWActivity");
- com.android.settings.utils.HighlightPrefUtils.Companion.setupHighlightPref(getContext(), lockHighlightPref, lockHighlightClickMap);
- }
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- String key = preference.getKey();
-
- if (KEY_WEATHER.equals(key)) {
- // Restart SystemUI when weather preference changes
- SystemRestartUtils.restartSystemUI(getContext());
- return true;
- }
-
- return false;
- }
-
- private void updateWeatherSettings() {
- if (mWeatherClient == null || mWeather == null) return;
-
- boolean weatherEnabled = mWeatherClient.isOmniJawsEnabled();
- mWeather.setEnabled(weatherEnabled);
- mWeather.setSummary(weatherEnabled ? R.string.lockscreen_weather_summary :
- R.string.lockscreen_weather_enabled_info);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- updateWeatherSettings();
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_lockscreen) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- FingerprintManager mFingerprintManager = (FingerprintManager)
- context.getSystemService(Context.FINGERPRINT_SERVICE);
- if (mFingerprintManager == null || !mFingerprintManager.isHardwareDetected()) {
- keys.add(KEY_UDFPS_ANIMATIONS);
- keys.add(KEY_UDFPS_ICONS);
- keys.add(KEY_RIPPLE_EFFECT);
- keys.add(SCREEN_OFF_UDFPS_ENABLED);
- } else {
- if (!Utils.isPackageInstalled(context, "com.crdroid.udfps.animations")) {
- keys.add(KEY_UDFPS_ANIMATIONS);
- }
- if (!Utils.isPackageInstalled(context, "com.crdroid.udfps.icons")) {
- keys.add(KEY_UDFPS_ICONS);
- }
- Resources resources = context.getResources();
- boolean screenOffUdfpsAvailable = resources.getBoolean(
- com.android.internal.R.bool.config_supportScreenOffUdfps) ||
- !TextUtils.isEmpty(resources.getString(
- com.android.internal.R.string.config_dozeUdfpsLongPressSensorType));
- if (!screenOffUdfpsAvailable)
- keys.add(SCREEN_OFF_UDFPS_ENABLED);
- }
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/LockScreen.kt b/src/com/rising/settings/fragments/LockScreen.kt
new file mode 100644
index 00000000..ff228947
--- /dev/null
+++ b/src/com/rising/settings/fragments/LockScreen.kt
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.ContentResolver
+import android.content.Context
+import android.content.res.Resources
+import android.hardware.fingerprint.FingerprintManager
+import android.os.Bundle
+import android.provider.Settings
+import android.text.TextUtils
+import android.util.Log
+import androidx.preference.Preference
+import androidx.preference.PreferenceCategory
+import androidx.preference.PreferenceScreen
+import com.android.internal.logging.nano.MetricsProto
+import com.android.internal.util.android.OmniJawsClient
+import com.android.internal.util.android.Utils
+import com.android.settings.R
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+import com.android.settings.preferences.ui.PreferenceUtils
+import com.android.settings.utils.SystemRestartUtils
+import kotlin.math.abs
+
+@SearchIndexable
+class LockScreen : OptimizedSettingsFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ const val TAG = "LockScreen"
+
+ private const val LOCKSCREEN_INTERFACE_CATEGORY = "lockscreen_interface_category"
+ private const val LOCKSCREEN_GESTURES_CATEGORY = "lockscreen_gestures_category"
+ private const val LOCKSCREEN_FP_CATEGORY = "lockscreen_fp_category"
+ private const val LOCKSCREEN_UDFPS_CATEGORY = "lockscreen_udfps_category"
+ private const val KEY_RIPPLE_EFFECT = "enable_ripple_effect"
+ private const val KEY_WEATHER = "lockscreen_weather_enabled"
+ private const val KEY_UDFPS_ANIMATIONS = "udfps_recognizing_animation_preview"
+ private const val KEY_UDFPS_ICONS = "udfps_icon_picker"
+ private const val SCREEN_OFF_UDFPS_ENABLED = "screen_off_udfps_enabled"
+ private const val KEY_FP_SUCCESS = "fp_success_vibrate"
+ private const val KEY_FP_FAIL = "fp_error_vibrate"
+
+ // Now Bar settings keys
+ private const val KEY_NOW_BAR_ENABLED = "keyguard_now_bar_enabled"
+ private const val KEY_NOW_BAR_MARGIN_BOTTOM = "nowbar_margin_bottom"
+ private const val DEFAULT_NOW_BAR_MARGIN = 18
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_lockscreen) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context).toMutableList()
+
+ val fingerprintManager = context.getSystemService(Context.FINGERPRINT_SERVICE) as? FingerprintManager
+ if (fingerprintManager == null || !fingerprintManager.isHardwareDetected) {
+ keys.add(KEY_UDFPS_ANIMATIONS)
+ keys.add(KEY_UDFPS_ICONS)
+ keys.add(KEY_RIPPLE_EFFECT)
+ keys.add(SCREEN_OFF_UDFPS_ENABLED)
+ } else {
+ if (!Utils.isPackageInstalled(context, "com.crdroid.udfps.animations")) {
+ keys.add(KEY_UDFPS_ANIMATIONS)
+ }
+ if (!Utils.isPackageInstalled(context, "com.crdroid.udfps.icons")) {
+ keys.add(KEY_UDFPS_ICONS)
+ }
+ val resources = context.resources
+ val screenOffUdfpsAvailable = resources.getBoolean(
+ com.android.internal.R.bool.config_supportScreenOffUdfps) ||
+ !TextUtils.isEmpty(resources.getString(
+ com.android.internal.R.string.config_dozeUdfpsLongPressSensorType))
+ if (!screenOffUdfpsAvailable) {
+ keys.add(SCREEN_OFF_UDFPS_ENABLED)
+ }
+ }
+ return keys
+ }
+ }
+ }
+
+ private var mUdfpsIcons: Preference? = null
+ private var mUdfpsAnimation: Preference? = null
+ private var mRippleEffect: Preference? = null
+ private var mWeather: Preference? = null
+ private var mScreenOffUdfps: Preference? = null
+ private var mFpSuccess: Preference? = null
+ private var mFpFail: Preference? = null
+
+ // Now Bar preferences and position management
+ private var mNowBarEnabled: Preference? = null
+ private var mNowBarMargin: com.android.settings.preferences.SystemSettingSeekBarPreference? = null
+ private var mLastValidNowBarMargin = DEFAULT_NOW_BAR_MARGIN
+
+ private var mWeatherClient: OmniJawsClient? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.rising_settings_lockscreen)
+
+ val udfpsCategory = findPreference(LOCKSCREEN_UDFPS_CATEGORY)
+ val fpCategory = findPreference(LOCKSCREEN_FP_CATEGORY)
+
+ // Use safe context access and cached preferences
+ val context = getSafeContext()
+ val fingerprintManager = context?.getSystemService(Context.FINGERPRINT_SERVICE) as? FingerprintManager
+
+ mUdfpsIcons = findCachedPreference(KEY_UDFPS_ICONS)
+ mUdfpsAnimation = findCachedPreference(KEY_UDFPS_ANIMATIONS)
+ mRippleEffect = findCachedPreference(KEY_RIPPLE_EFFECT)
+ mScreenOffUdfps = findCachedPreference(SCREEN_OFF_UDFPS_ENABLED)
+ mFpSuccess = findCachedPreference(KEY_FP_SUCCESS)
+ mFpFail = findCachedPreference(KEY_FP_FAIL)
+
+ // Initialize Now Bar preferences
+ mNowBarEnabled = findCachedPreference(KEY_NOW_BAR_ENABLED)
+ mNowBarMargin = findCachedPreference(KEY_NOW_BAR_MARGIN_BOTTOM)
+
+ // Initialize Now Bar position management
+ initializeNowBarPosition()
+
+ if (fingerprintManager == null || !fingerprintManager.isHardwareDetected) {
+ udfpsCategory?.let { category ->
+ mUdfpsAnimation?.let { category.removePreference(it) }
+ mUdfpsIcons?.let { category.removePreference(it) }
+ mScreenOffUdfps?.let { category.removePreference(it) }
+ }
+ fpCategory?.let { category ->
+ mRippleEffect?.let { category.removePreference(it) }
+ mFpSuccess?.let { category.removePreference(it) }
+ mFpFail?.let { category.removePreference(it) }
+ }
+ } else {
+ // Cache package installation checks to avoid repeated calls
+ val udfpsAnimationInstalled = if (isOperationCached("udfps_anim_installed")) {
+ getCachedOperation("udfps_anim_installed") ?: false
+ } else {
+ val installed = Utils.isPackageInstalled(context, "com.crdroid.udfps.animations")
+ cacheOperation("udfps_anim_installed", installed)
+ installed
+ }
+
+ val udfpsIconsInstalled = if (isOperationCached("udfps_icons_installed")) {
+ getCachedOperation("udfps_icons_installed") ?: false
+ } else {
+ val installed = Utils.isPackageInstalled(context, "com.crdroid.udfps.icons")
+ cacheOperation("udfps_icons_installed", installed)
+ installed
+ }
+
+ if (!udfpsAnimationInstalled) {
+ udfpsCategory?.let { category ->
+ mUdfpsAnimation?.let { category.removePreference(it) }
+ }
+ }
+ if (!udfpsIconsInstalled) {
+ udfpsCategory?.let { category ->
+ mUdfpsIcons?.let { category.removePreference(it) }
+ }
+ }
+ if (!udfpsAnimationInstalled && !udfpsIconsInstalled) {
+ udfpsCategory?.let { category ->
+ mScreenOffUdfps?.let { category.removePreference(it) }
+ }
+ }
+ }
+
+ mWeather = findCachedPreference(KEY_WEATHER)?.apply {
+ onPreferenceChangeListener = this@LockScreen
+ }
+
+ // Set up Now Bar preference listeners
+ mNowBarEnabled?.onPreferenceChangeListener = this
+ mNowBarMargin?.onPreferenceChangeListener = this
+
+ // Initialize weather client with null check
+ context?.let {
+ mWeatherClient = OmniJawsClient(it)
+ updateWeatherSettings()
+ }
+
+ val screen = preferenceScreen
+ screen?.let {
+ PreferenceUtils.hideEmptyCategory(udfpsCategory, it)
+ PreferenceUtils.hideEmptyCategory(fpCategory, it)
+
+ val lockHighlightPref = it.findPreference("lockscreen_highlight_dashboard")
+ if (lockHighlightPref != null && context != null) {
+ val lockHighlightClickMap = mapOf(
+ R.id.lockscreen_widgets_tile to "PersonalizationsWidgetsActivity",
+ R.id.peek_display_tile to "PersonalizationsPDActivity",
+ R.id.aod_tile to "PersonalizationsAODActivity",
+ R.id.dw_tile to "PersonalizationsDWActivity"
+ )
+ com.android.settings.utils.HighlightPrefUtils.setupHighlightPref(context, lockHighlightPref, lockHighlightClickMap)
+ }
+ }
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
+ val key = preference.key
+
+ return when (key) {
+ KEY_WEATHER -> {
+ // Restart SystemUI when weather preference changes
+ getSafeContext()?.let { context ->
+ SystemRestartUtils.restartSystemUI(context)
+ }
+ true
+ }
+ KEY_NOW_BAR_ENABLED -> {
+ // Handle Now Bar enable/disable
+ val enabled = newValue as Boolean
+ handleNowBarEnabledChange(enabled)
+ true
+ }
+ KEY_NOW_BAR_MARGIN_BOTTOM -> {
+ // Handle Now Bar margin changes with position stability
+ val newMargin = newValue as Int
+ handleNowBarMarginChange(newMargin)
+ }
+ else -> false
+ }
+ }
+
+ private fun updateWeatherSettings() {
+ val weatherClient = mWeatherClient
+ val weather = mWeather
+ if (weatherClient == null || weather == null) return
+
+ val weatherEnabled = weatherClient.isOmniJawsEnabled
+ weather.isEnabled = weatherEnabled
+ weather.setSummary(if (weatherEnabled) R.string.lockscreen_weather_summary else R.string.lockscreen_weather_enabled_info)
+ }
+
+ override fun onResume() {
+ super.onResume()
+ // Use safe method to update weather settings
+ if (isFragmentReady()) {
+ updateWeatherSettings()
+ // Check and restore Now Bar position to prevent drift
+ checkAndRestoreNowBarPosition()
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ // Cleanup weather client
+ mWeatherClient = null
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+
+ /**
+ * Initialize Now Bar position management
+ */
+ private fun initializeNowBarPosition() {
+ val context = getSafeContext() ?: return
+ val nowBarMargin = mNowBarMargin ?: return
+
+ val resolver = context.contentResolver
+
+ // Load cached position
+ val currentMargin = Settings.System.getInt(resolver,
+ KEY_NOW_BAR_MARGIN_BOTTOM, DEFAULT_NOW_BAR_MARGIN)
+ mLastValidNowBarMargin = currentMargin
+ }
+
+ /**
+ * Handle Now Bar enabled/disabled changes
+ */
+ private fun handleNowBarEnabledChange(enabled: Boolean) {
+ val context = getSafeContext() ?: return
+
+ // Restart SystemUI when Now Bar is enabled/disabled to apply changes
+ postDelayedSafe(100) {
+ SystemRestartUtils.restartSystemUI(context)
+ }
+ }
+
+ /**
+ * Handle Now Bar margin changes with position stability
+ */
+ private fun handleNowBarMarginChange(newMargin: Int): Boolean {
+ val context = getSafeContext() ?: return false
+
+ // Validate margin range (0-210 as defined in XML)
+ val validMargin = newMargin.coerceIn(0, 210)
+
+ // Cache the new valid position
+ mLastValidNowBarMargin = validMargin
+
+ // Apply the setting with stability
+ val resolver = context.contentResolver
+ Settings.System.putInt(resolver, KEY_NOW_BAR_MARGIN_BOTTOM, validMargin)
+
+ // Notify SystemUI of the change with a slight delay for stability
+ postDelayedSafe(50) {
+ resolver.notifyChange(Settings.System.getUriFor(KEY_NOW_BAR_MARGIN_BOTTOM), null)
+ }
+
+ return true
+ }
+
+ /**
+ * Check and restore Now Bar position to prevent drift after idle periods
+ * This is the key method to fix the position drift issue
+ */
+ private fun checkAndRestoreNowBarPosition() {
+ val nowBarMargin = mNowBarMargin ?: return
+ val context = getSafeContext() ?: return
+
+ val resolver = context.contentResolver
+
+ // Check if Now Bar is enabled
+ val nowBarEnabled = Settings.System.getInt(resolver,
+ KEY_NOW_BAR_ENABLED, 0) == 1
+
+ if (!nowBarEnabled) {
+ return // No need to check position if Now Bar is disabled
+ }
+
+ val currentMargin = Settings.System.getInt(resolver,
+ KEY_NOW_BAR_MARGIN_BOTTOM, DEFAULT_NOW_BAR_MARGIN)
+
+ // Check if position has drifted (tolerance of 2 units)
+ if (abs(currentMargin - mLastValidNowBarMargin) > 2) {
+ // Position has drifted - restore stable position
+ postDelayedSafe(100) {
+ Settings.System.putInt(resolver, KEY_NOW_BAR_MARGIN_BOTTOM, mLastValidNowBarMargin)
+ nowBarMargin.setValue(mLastValidNowBarMargin)
+
+ // Notify SystemUI of the position correction
+ resolver.notifyChange(Settings.System.getUriFor(KEY_NOW_BAR_MARGIN_BOTTOM), null)
+
+ Log.d(TAG, "Now Bar position drift detected and corrected: $currentMargin -> $mLastValidNowBarMargin")
+ }
+ } else {
+ // Position is stable - update cache
+ mLastValidNowBarMargin = currentMargin
+ }
+ }
+}
diff --git a/src/com/rising/settings/fragments/MonetSettings.java b/src/com/rising/settings/fragments/MonetSettings.java
deleted file mode 100644
index 77273f26..00000000
--- a/src/com/rising/settings/fragments/MonetSettings.java
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Copyright (C) 2021-2024 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import com.android.settings.preferences.colorpicker.ColorPickerPreference;
-import com.android.settings.preferences.CustomSeekBarPreference;
-import com.android.settings.preferences.SecureSettingListPreference;
-import com.android.settings.preferences.SecureSettingSwitchPreference;
-
-import java.lang.CharSequence;
-
-import lineageos.providers.LineageSettings;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-@SearchIndexable
-public class MonetSettings extends DashboardFragment implements
- OnPreferenceChangeListener {
-
- private static final String TAG = "MonetSettings";
- private static final String OVERLAY_CATEGORY_ACCENT_COLOR =
- "android.theme.customization.accent_color";
- private static final String OVERLAY_CATEGORY_SYSTEM_PALETTE =
- "android.theme.customization.system_palette";
- private static final String OVERLAY_CATEGORY_THEME_STYLE =
- "android.theme.customization.theme_style";
- private static final String OVERLAY_CATEGORY_BG_COLOR =
- "android.theme.customization.bg_color";
- private static final String OVERLAY_COLOR_SOURCE =
- "android.theme.customization.color_source";
- private static final String OVERLAY_COLOR_BOTH =
- "android.theme.customization.color_both";
- private static final String OVERLAY_LUMINANCE_FACTOR =
- "android.theme.customization.luminance_factor";
- private static final String OVERLAY_CHROMA_FACTOR =
- "android.theme.customization.chroma_factor";
- private static final String OVERLAY_WHOLE_PALETTE =
- "android.theme.customization.whole_palette";
- private static final String OVERLAY_TINT_BACKGROUND =
- "android.theme.customization.tint_background";
- private static final String COLOR_SOURCE_PRESET = "preset";
- private static final String COLOR_SOURCE_HOME = "home_wallpaper";
- private static final String COLOR_SOURCE_LOCK = "lock_wallpaper";
- private static final String TIMESTAMP_FIELD = "_applied_timestamp";
-
- private static final String PREF_THEME_STYLE = "theme_style";
- private static final String PREF_COLOR_SOURCE = "color_source";
- private static final String PREF_ACCENT_COLOR = "accent_color";
- private static final String PREF_ACCENT_BACKGROUND = "accent_background";
- private static final String PREF_BG_COLOR = "bg_color";
- private static final String PREF_LUMINANCE_FACTOR = "luminance_factor";
- private static final String PREF_CHROMA_FACTOR = "chroma_factor";
- private static final String PREF_WHOLE_PALETTE = "whole_palette";
- private static final String PREF_TINT_BACKGROUND = "tint_background";
-
- private static final int DEFAULT_COLOR = 0xFF1b6ef3;
-
- private SecureSettingListPreference mThemeStylePref;
- private SecureSettingListPreference mColorSourcePref;
- private ColorPickerPreference mAccentColorPref;
- private SecureSettingSwitchPreference mAccentBackgroundPref;
- private ColorPickerPreference mBgColorPref;
- private CustomSeekBarPreference mLuminancePref;
- private CustomSeekBarPreference mChromaPref;
- private SecureSettingSwitchPreference mWholePalettePref;
- private SecureSettingSwitchPreference mTintBackgroundPref;
-
- private int mAccentColorValue;
- private int mBgColorValue;
-
- private SharedPreferences mSharedPreferences;
-
- @Override
- protected int getPreferenceScreenResId() {
- return R.xml.monet_engine;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- mThemeStylePref = findPreference(PREF_THEME_STYLE);
- mColorSourcePref = findPreference(PREF_COLOR_SOURCE);
- mAccentColorPref = findPreference(PREF_ACCENT_COLOR);
- mAccentBackgroundPref = findPreference(PREF_ACCENT_BACKGROUND);
- mBgColorPref = findPreference(PREF_BG_COLOR);
- mLuminancePref = findPreference(PREF_LUMINANCE_FACTOR);
- mChromaPref = findPreference(PREF_CHROMA_FACTOR);
- mWholePalettePref = findPreference(PREF_WHOLE_PALETTE);
- mTintBackgroundPref = findPreference(PREF_TINT_BACKGROUND);
- mSharedPreferences = getActivity().getSharedPreferences(TAG, Context.MODE_PRIVATE);
-
- updatePreferences();
-
- mThemeStylePref.setOnPreferenceChangeListener(this);
- mColorSourcePref.setOnPreferenceChangeListener(this);
- mAccentColorPref.setOnPreferenceChangeListener(this);
- mAccentBackgroundPref.setOnPreferenceChangeListener(this);
- mBgColorPref.setOnPreferenceChangeListener(this);
- mLuminancePref.setOnPreferenceChangeListener(this);
- mChromaPref.setOnPreferenceChangeListener(this);
- mWholePalettePref.setOnPreferenceChangeListener(this);
- mTintBackgroundPref.setOnPreferenceChangeListener(this);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- updatePreferences();
- }
-
- private void updatePreferences() {
- final String overlayPackageJson = Settings.Secure.getStringForUser(
- getActivity().getContentResolver(),
- Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
- UserHandle.USER_CURRENT);
- if (overlayPackageJson != null && !overlayPackageJson.isEmpty()) {
- try {
- final JSONObject object = new JSONObject(overlayPackageJson);
- final String style = object.optString(OVERLAY_CATEGORY_THEME_STYLE, "TONAL_SPOT");
- final String source = object.optString(OVERLAY_COLOR_SOURCE, COLOR_SOURCE_HOME);
- String color;
- if (object.has(OVERLAY_CATEGORY_SYSTEM_PALETTE)) {
- color = object.optString(OVERLAY_CATEGORY_SYSTEM_PALETTE);
- mAccentColorValue = ColorPickerPreference.convertToColorInt(color);
- } else {
- mAccentColorValue = mSharedPreferences.getInt(PREF_ACCENT_COLOR, DEFAULT_COLOR);
- color = ColorPickerPreference.convertToRGB(mAccentColorValue).replace("#", "");
- }
- boolean hasBGColor = object.has(OVERLAY_CATEGORY_BG_COLOR);
- mAccentBackgroundPref.setChecked(mSharedPreferences.getBoolean(PREF_ACCENT_BACKGROUND, hasBGColor));
- if (hasBGColor) {
- mBgColorValue = object.optInt(OVERLAY_CATEGORY_BG_COLOR);
- } else {
- mBgColorValue = mSharedPreferences.getInt(PREF_BG_COLOR, DEFAULT_COLOR);
- }
- boolean both;
- if (object.has(OVERLAY_COLOR_BOTH)) {
- both = object.optInt(OVERLAY_COLOR_BOTH) == 1;
- } else {
- both = false;
- }
- final boolean wholePalette = object.optInt(OVERLAY_WHOLE_PALETTE, 0) == 1;
- final boolean tintBG = object.optInt(OVERLAY_TINT_BACKGROUND, 0) == 1;
- final float lumin = (float) object.optDouble(OVERLAY_LUMINANCE_FACTOR, 1d);
- final float chroma = (float) object.optDouble(OVERLAY_CHROMA_FACTOR, 1d);
- // style handling
- boolean styleUpdated = false;
- if (style != null && !style.isEmpty()) {
- for (CharSequence value : mThemeStylePref.getEntryValues()) {
- if (value.toString().equals(style)) {
- styleUpdated = true;
- break;
- }
- }
- if (styleUpdated) {
- updateListByValue(mThemeStylePref, style);
- }
- }
- if (!styleUpdated) {
- updateListByValue(mThemeStylePref,
- mThemeStylePref.getEntryValues()[0].toString());
- }
- // color handling
- final String sourceVal = (source == null || source.isEmpty() ||
- (source.equals(COLOR_SOURCE_HOME) && both)) ? "both" : source;
- updateListByValue(mColorSourcePref, sourceVal);
- updateAccentEnablement(sourceVal);
- // Set preview color irrespective it is enabled
- if (color != null && !color.isEmpty()) {
- mAccentColorPref.setNewPreviewColor(mAccentColorValue);
- }
- mBgColorPref.setNewPreviewColor(mBgColorValue);
- // etc
- int luminV = 0;
- if (lumin > 1d) luminV = Math.round((lumin - 1f) * 100f);
- else if (lumin < 1d) luminV = -1 * Math.round((1f - lumin) * 100f);
- mLuminancePref.setValue(luminV);
- int chromaV = 0;
- if (chroma > 1d) chromaV = Math.round((chroma - 1f) * 100f);
- else if (chroma < 1d) chromaV = -1 * Math.round((1f - chroma) * 100f);
- mChromaPref.setValue(chromaV);
- mWholePalettePref.setChecked(wholePalette);
- mTintBackgroundPref.setChecked(tintBG);
- } catch (JSONException | IllegalArgumentException ignored) {}
- } else {
- // reflect default values in every preference
- mThemeStylePref.setValueIndex(0);
- mColorSourcePref.setValueIndex(0);
- mLuminancePref.setValue(0);
- mChromaPref.setValue(0);
- mAccentBackgroundPref.setChecked(false);
- mWholePalettePref.setChecked(false);
- mTintBackgroundPref.setChecked(false);
- updateAccentEnablement("both");
- }
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- final ContentResolver resolver = getActivity().getContentResolver();
- if (preference == mThemeStylePref) {
- String value = (String) newValue;
- setStyleValue(value);
- updateListByValue(mThemeStylePref, value, false);
- return true;
- } else if (preference == mColorSourcePref) {
- String value = (String) newValue;
- setSourceValue(value);
- updateListByValue(mColorSourcePref, value, false);
- updateAccentEnablement(value);
- return true;
- } else if (preference == mAccentColorPref) {
- mAccentColorValue = (Integer) newValue;
- mSharedPreferences.edit().putInt(PREF_ACCENT_COLOR, mAccentColorValue).apply();
- setColorValue();
- return true;
- } else if (preference == mAccentBackgroundPref) {
- boolean value = (Boolean) newValue;
- mAccentBackgroundPref.setChecked(value);
- mSharedPreferences.edit().putBoolean(PREF_ACCENT_BACKGROUND, value).apply();
- setBgColorValue();
- return true;
- } else if (preference == mBgColorPref) {
- mBgColorValue = (Integer) newValue;
- mSharedPreferences.edit().putInt(PREF_BG_COLOR, mBgColorValue).apply();
- setBgColorValue();
- return true;
- } else if (preference == mLuminancePref) {
- int value = (Integer) newValue;
- setLuminanceValue(value);
- return true;
- } else if (preference == mChromaPref) {
- int value = (Integer) newValue;
- setChromaValue(value);
- return true;
- } else if (preference == mWholePalettePref) {
- boolean value = (Boolean) newValue;
- setWholePaletteValue(value);
- return true;
- } else if (preference == mTintBackgroundPref) {
- boolean value = (Boolean) newValue;
- setTintBackgroundValue(value);
- return true;
- }
- return false;
- }
-
- private void updateListByValue(SecureSettingListPreference pref, String value) {
- updateListByValue(pref, value, true);
- }
-
- private void updateListByValue(SecureSettingListPreference pref, String value, boolean set) {
- if (set) pref.setValue(value);
- final int index = pref.findIndexOfValue(value);
- pref.setSummary(pref.getEntries()[index]);
- }
-
- private void updateAccentEnablement(String source) {
- final boolean shouldEnable = source != null && source.equals(COLOR_SOURCE_PRESET);
- mAccentColorPref.setEnabled(shouldEnable);
- mAccentBackgroundPref.setEnabled(shouldEnable);
- setColorValue();
- setBgColorValue();
- }
-
- private JSONObject getSettingsJson() throws JSONException {
- final String overlayPackageJson = Settings.Secure.getStringForUser(
- getActivity().getContentResolver(),
- Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
- UserHandle.USER_CURRENT);
- JSONObject object;
- if (overlayPackageJson == null || overlayPackageJson.isEmpty())
- return new JSONObject();
- return new JSONObject(overlayPackageJson);
- }
-
- private void putSettingsJson(JSONObject object) {
- Settings.Secure.putStringForUser(
- getActivity().getContentResolver(),
- Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
- object.toString(), UserHandle.USER_CURRENT);
- }
-
- private void setStyleValue(String style) {
- try {
- JSONObject object = getSettingsJson();
- object.putOpt(OVERLAY_CATEGORY_THEME_STYLE, style);
- putSettingsJson(object);
- } catch (JSONException | IllegalArgumentException ignored) {}
- }
-
- private void setSourceValue(String source) {
- try {
- JSONObject object = getSettingsJson();
- if (source.equals("both")) {
- object.putOpt(OVERLAY_COLOR_BOTH, 1);
- object.putOpt(OVERLAY_COLOR_SOURCE, COLOR_SOURCE_HOME);
- } else {
- object.remove(OVERLAY_COLOR_BOTH);
- object.putOpt(OVERLAY_COLOR_SOURCE, source);
- }
- object.putOpt(TIMESTAMP_FIELD, System.currentTimeMillis());
- if (!source.equals(COLOR_SOURCE_PRESET)) {
- object.remove(OVERLAY_CATEGORY_ACCENT_COLOR);
- object.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE);
- }
- putSettingsJson(object);
- } catch (JSONException | IllegalArgumentException ignored) {}
- }
-
- private void setColorValue() {
- try {
- JSONObject object = getSettingsJson();
-
- if (mColorSourcePref.getValue().equals(COLOR_SOURCE_PRESET)) {
- final String rgbColor = ColorPickerPreference.convertToRGB(mAccentColorValue).replace("#", "");
- object.putOpt(OVERLAY_CATEGORY_ACCENT_COLOR, rgbColor);
- object.putOpt(OVERLAY_CATEGORY_SYSTEM_PALETTE, rgbColor);
- } else {
- object.remove(OVERLAY_CATEGORY_ACCENT_COLOR);
- object.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE);
- }
- putSettingsJson(object);
- } catch (JSONException | IllegalArgumentException ignored) {}
- }
-
- private void setBgColorValue() {
- try {
- JSONObject object = getSettingsJson();
- if (mColorSourcePref.getValue().equals(COLOR_SOURCE_PRESET) && mAccentBackgroundPref.isChecked()) {
- object.putOpt(OVERLAY_CATEGORY_BG_COLOR, mBgColorValue);
- } else {
- object.remove(OVERLAY_CATEGORY_BG_COLOR);
- }
- putSettingsJson(object);
- } catch (JSONException | IllegalArgumentException ignored) {}
- }
-
- private void setLuminanceValue(int lumin) {
- try {
- JSONObject object = getSettingsJson();
- if (lumin == 0)
- object.remove(OVERLAY_LUMINANCE_FACTOR);
- else
- object.putOpt(OVERLAY_LUMINANCE_FACTOR, 1d + ((double) lumin / 100d));
- putSettingsJson(object);
- } catch (JSONException | IllegalArgumentException ignored) {}
- }
-
- private void setChromaValue(int chroma) {
- try {
- JSONObject object = getSettingsJson();
- if (chroma == 0)
- object.remove(OVERLAY_CHROMA_FACTOR);
- else
- object.putOpt(OVERLAY_CHROMA_FACTOR, 1d + ((double) chroma / 100d));
- putSettingsJson(object);
- } catch (JSONException | IllegalArgumentException ignored) {}
- }
-
- private void setWholePaletteValue(boolean whole) {
- try {
- JSONObject object = getSettingsJson();
- if (!whole) object.remove(OVERLAY_WHOLE_PALETTE);
- else object.putOpt(OVERLAY_WHOLE_PALETTE, 1);
- putSettingsJson(object);
- } catch (JSONException | IllegalArgumentException ignored) {}
- }
-
- private void setTintBackgroundValue(boolean tint) {
- try {
- JSONObject object = getSettingsJson();
- if (!tint) object.remove(OVERLAY_TINT_BACKGROUND);
- else object.putOpt(OVERLAY_TINT_BACKGROUND, 1);
- putSettingsJson(object);
- } catch (JSONException | IllegalArgumentException ignored) {}
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- @Override
- protected String getLogTag() {
- return TAG;
- }
-
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.monet_engine);
-}
diff --git a/src/com/rising/settings/fragments/MonetSettings.kt b/src/com/rising/settings/fragments/MonetSettings.kt
new file mode 100644
index 00000000..f39c0c84
--- /dev/null
+++ b/src/com/rising/settings/fragments/MonetSettings.kt
@@ -0,0 +1,519 @@
+/*
+ * Copyright (C) 2021-2024 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.ContentResolver
+import android.content.Context
+import android.content.SharedPreferences
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.Settings
+import androidx.preference.Preference
+import androidx.preference.Preference.OnPreferenceChangeListener
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.dashboard.DashboardFragment
+import com.android.settings.preferences.CustomSeekBarPreference
+import com.android.settings.preferences.SecureSettingListPreference
+import com.android.settings.preferences.SecureSettingSwitchPreference
+import com.android.settings.preferences.colorpicker.ColorPickerPreference
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+import org.json.JSONException
+import org.json.JSONObject
+import java.lang.ref.WeakReference
+import java.util.concurrent.ConcurrentHashMap
+
+@SearchIndexable
+class MonetSettings : DashboardFragment(), OnPreferenceChangeListener {
+
+ override fun getLogTag(): String {
+ return TAG
+ }
+
+ companion object {
+ private const val TAG = "MonetSettings"
+ private const val OVERLAY_CATEGORY_ACCENT_COLOR = "android.theme.customization.accent_color"
+ private const val OVERLAY_CATEGORY_SYSTEM_PALETTE = "android.theme.customization.system_palette"
+ private const val OVERLAY_CATEGORY_THEME_STYLE = "android.theme.customization.theme_style"
+ private const val OVERLAY_CATEGORY_BG_COLOR = "android.theme.customization.bg_color"
+ private const val OVERLAY_COLOR_SOURCE = "android.theme.customization.color_source"
+ private const val OVERLAY_COLOR_BOTH = "android.theme.customization.color_both"
+ private const val OVERLAY_LUMINANCE_FACTOR = "android.theme.customization.luminance_factor"
+ private const val OVERLAY_CHROMA_FACTOR = "android.theme.customization.chroma_factor"
+ private const val OVERLAY_WHOLE_PALETTE = "android.theme.customization.whole_palette"
+ private const val OVERLAY_TINT_BACKGROUND = "android.theme.customization.tint_background"
+ private const val COLOR_SOURCE_PRESET = "preset"
+ private const val COLOR_SOURCE_HOME = "home_wallpaper"
+ private const val COLOR_SOURCE_LOCK = "lock_wallpaper"
+ private const val TIMESTAMP_FIELD = "_applied_timestamp"
+
+ private const val PREF_THEME_STYLE = "theme_style"
+ private const val PREF_COLOR_SOURCE = "color_source"
+ private const val PREF_ACCENT_COLOR = "accent_color"
+ private const val PREF_ACCENT_BACKGROUND = "accent_background"
+ private const val PREF_BG_COLOR = "bg_color"
+ private const val PREF_LUMINANCE_FACTOR = "luminance_factor"
+ private const val PREF_CHROMA_FACTOR = "chroma_factor"
+ private const val PREF_WHOLE_PALETTE = "whole_palette"
+ private const val PREF_TINT_BACKGROUND = "tint_background"
+
+ private const val DEFAULT_COLOR = 0xFF1b6ef3.toInt()
+
+ // JSON cache timeout constant
+ private const val JSON_CACHE_TIMEOUT = 1000L // 1 second cache
+
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = BaseSearchIndexProvider(R.xml.monet_engine)
+ }
+
+ private var mThemeStylePref: SecureSettingListPreference? = null
+ private var mColorSourcePref: SecureSettingListPreference? = null
+ private var mAccentColorPref: ColorPickerPreference? = null
+ private var mAccentBackgroundPref: SecureSettingSwitchPreference? = null
+ private var mBgColorPref: ColorPickerPreference? = null
+ private var mLuminancePref: CustomSeekBarPreference? = null
+ private var mChromaPref: CustomSeekBarPreference? = null
+ private var mWholePalettePref: SecureSettingSwitchPreference? = null
+ private var mTintBackgroundPref: SecureSettingSwitchPreference? = null
+
+ private var mAccentColorValue: Int = 0
+ private var mBgColorValue: Int = 0
+
+ private var mSharedPreferences: SharedPreferences? = null
+
+ // Cache for JSON operations to prevent redundant parsing
+ private var mCachedSettingsJson: JSONObject? = null
+ private var mLastJsonUpdateTime: Long = 0
+
+ // Cache for preference states
+ private val mPreferenceCache = ConcurrentHashMap()
+
+ override fun getPreferenceScreenResId(): Int {
+ return R.xml.monet_engine
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ mThemeStylePref = findPreference(PREF_THEME_STYLE)
+ mColorSourcePref = findPreference(PREF_COLOR_SOURCE)
+ mAccentColorPref = findPreference(PREF_ACCENT_COLOR)
+ mAccentBackgroundPref = findPreference(PREF_ACCENT_BACKGROUND)
+ mBgColorPref = findPreference(PREF_BG_COLOR)
+ mLuminancePref = findPreference(PREF_LUMINANCE_FACTOR)
+ mChromaPref = findPreference(PREF_CHROMA_FACTOR)
+ mWholePalettePref = findPreference(PREF_WHOLE_PALETTE)
+ mTintBackgroundPref = findPreference(PREF_TINT_BACKGROUND)
+ mSharedPreferences = activity?.getSharedPreferences(TAG, Context.MODE_PRIVATE)
+
+ updatePreferences()
+
+ mThemeStylePref?.onPreferenceChangeListener = this
+ mColorSourcePref?.onPreferenceChangeListener = this
+ mAccentColorPref?.onPreferenceChangeListener = this
+ mAccentBackgroundPref?.onPreferenceChangeListener = this
+ mBgColorPref?.onPreferenceChangeListener = this
+ mLuminancePref?.onPreferenceChangeListener = this
+ mChromaPref?.onPreferenceChangeListener = this
+ mWholePalettePref?.onPreferenceChangeListener = this
+ mTintBackgroundPref?.onPreferenceChangeListener = this
+ }
+
+ override fun onResume() {
+ super.onResume()
+ // Update preferences on resume
+ updatePreferences()
+ }
+
+ private fun updatePreferences() {
+ val overlayPackageJson = Settings.Secure.getStringForUser(
+ activity?.contentResolver,
+ Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
+ UserHandle.USER_CURRENT)
+
+ if (!overlayPackageJson.isNullOrEmpty()) {
+ try {
+ val obj = JSONObject(overlayPackageJson)
+ val style = obj.optString(OVERLAY_CATEGORY_THEME_STYLE, "TONAL_SPOT")
+ val source = obj.optString(OVERLAY_COLOR_SOURCE, COLOR_SOURCE_HOME)
+
+ val color = if (obj.has(OVERLAY_CATEGORY_SYSTEM_PALETTE)) {
+ val colorStr = obj.optString(OVERLAY_CATEGORY_SYSTEM_PALETTE)
+ mAccentColorValue = ColorPickerPreference.convertToColorInt(colorStr)
+ colorStr
+ } else {
+ mAccentColorValue = mSharedPreferences?.getInt(PREF_ACCENT_COLOR, DEFAULT_COLOR) ?: DEFAULT_COLOR
+ ColorPickerPreference.convertToRGB(mAccentColorValue).replace("#", "")
+ }
+
+ val hasBGColor = obj.has(OVERLAY_CATEGORY_BG_COLOR)
+ mAccentBackgroundPref?.isChecked = mSharedPreferences?.getBoolean(PREF_ACCENT_BACKGROUND, hasBGColor) ?: hasBGColor
+
+ mBgColorValue = if (hasBGColor) {
+ obj.optInt(OVERLAY_CATEGORY_BG_COLOR)
+ } else {
+ mSharedPreferences?.getInt(PREF_BG_COLOR, DEFAULT_COLOR) ?: DEFAULT_COLOR
+ }
+
+ val both = if (obj.has(OVERLAY_COLOR_BOTH)) {
+ obj.optInt(OVERLAY_COLOR_BOTH) == 1
+ } else {
+ false
+ }
+
+ val wholePalette = obj.optInt(OVERLAY_WHOLE_PALETTE, 0) == 1
+ val tintBG = obj.optInt(OVERLAY_TINT_BACKGROUND, 0) == 1
+ val lumin = obj.optDouble(OVERLAY_LUMINANCE_FACTOR, 1.0).toFloat()
+ val chroma = obj.optDouble(OVERLAY_CHROMA_FACTOR, 1.0).toFloat()
+
+ // Style handling
+ var styleUpdated = false
+ if (style.isNotEmpty()) {
+ mThemeStylePref?.entryValues?.forEach { value ->
+ if (value.toString() == style) {
+ styleUpdated = true
+ return@forEach
+ }
+ }
+ if (styleUpdated) {
+ updateListByValue(mThemeStylePref, style)
+ }
+ }
+ if (!styleUpdated) {
+ mThemeStylePref?.entryValues?.get(0)?.toString()?.let { defaultStyle ->
+ updateListByValue(mThemeStylePref, defaultStyle)
+ }
+ }
+
+ // Color handling
+ val sourceVal = if (source.isEmpty() || (source == COLOR_SOURCE_HOME && both)) "both" else source
+ updateListByValue(mColorSourcePref, sourceVal)
+ updateAccentEnablement(sourceVal)
+
+ // Set preview color irrespective it is enabled
+ if (color.isNotEmpty()) {
+ mAccentColorPref?.setNewPreviewColor(mAccentColorValue)
+ }
+ mBgColorPref?.setNewPreviewColor(mBgColorValue)
+
+ // Luminance and chroma
+ val luminV = when {
+ lumin > 1.0 -> Math.round((lumin - 1f) * 100f)
+ lumin < 1.0 -> -1 * Math.round((1f - lumin) * 100f)
+ else -> 0
+ }
+ mLuminancePref?.setValue(luminV)
+
+ val chromaV = when {
+ chroma > 1.0 -> Math.round((chroma - 1f) * 100f)
+ chroma < 1.0 -> -1 * Math.round((1f - chroma) * 100f)
+ else -> 0
+ }
+ mChromaPref?.setValue(chromaV)
+
+ mWholePalettePref?.isChecked = wholePalette
+ mTintBackgroundPref?.isChecked = tintBG
+
+ } catch (e: JSONException) {
+ // Ignored
+ } catch (e: IllegalArgumentException) {
+ // Ignored
+ }
+ } else {
+ // Reflect default values in every preference
+ mThemeStylePref?.setValueIndex(0)
+ mColorSourcePref?.setValueIndex(0)
+ mLuminancePref?.setValue(0)
+ mChromaPref?.setValue(0)
+ mAccentBackgroundPref?.isChecked = false
+ mWholePalettePref?.isChecked = false
+ mTintBackgroundPref?.isChecked = false
+ updateAccentEnablement("both")
+ }
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
+ val resolver = activity?.contentResolver ?: return false
+
+ return when (preference) {
+ mThemeStylePref -> {
+ val value = newValue as String
+ setStyleValue(value)
+ updateListByValue(mThemeStylePref, value, false)
+ true
+ }
+
+ mColorSourcePref -> {
+ val value = newValue as String
+ setSourceValue(value)
+ updateListByValue(mColorSourcePref, value, false)
+ updateAccentEnablement(value)
+ true
+ }
+
+ mAccentColorPref -> {
+ mAccentColorValue = newValue as Int
+ mSharedPreferences?.edit()?.putInt(PREF_ACCENT_COLOR, mAccentColorValue)?.apply()
+ setColorValue()
+ true
+ }
+
+ mAccentBackgroundPref -> {
+ val value = newValue as Boolean
+ mAccentBackgroundPref?.isChecked = value
+ mSharedPreferences?.edit()?.putBoolean(PREF_ACCENT_BACKGROUND, value)?.apply()
+ setBgColorValue()
+ true
+ }
+
+ mBgColorPref -> {
+ mBgColorValue = newValue as Int
+ mSharedPreferences?.edit()?.putInt(PREF_BG_COLOR, mBgColorValue)?.apply()
+ setBgColorValue()
+ true
+ }
+
+ mLuminancePref -> {
+ val value = newValue as Int
+ setLuminanceValue(value)
+ true
+ }
+
+ mChromaPref -> {
+ val value = newValue as Int
+ setChromaValue(value)
+ true
+ }
+
+ mWholePalettePref -> {
+ val value = newValue as Boolean
+ setWholePaletteValue(value)
+ true
+ }
+
+ mTintBackgroundPref -> {
+ val value = newValue as Boolean
+ setTintBackgroundValue(value)
+ true
+ }
+
+ else -> false
+ }
+ }
+
+ private fun updateListByValue(pref: SecureSettingListPreference?, value: String) {
+ updateListByValue(pref, value, true)
+ }
+
+ private fun updateListByValue(pref: SecureSettingListPreference?, value: String, set: Boolean) {
+ if (pref == null) return
+ if (set) pref.value = value
+ val index = pref.findIndexOfValue(value)
+ pref.summary = pref.entries[index]
+ }
+
+ private fun updateAccentEnablement(source: String?) {
+ val shouldEnable = source == COLOR_SOURCE_PRESET
+ mAccentColorPref?.isEnabled = shouldEnable
+ mAccentBackgroundPref?.isEnabled = shouldEnable
+ setColorValue()
+ setBgColorValue()
+ }
+
+ private fun getSettingsJson(): JSONObject {
+ val currentTime = System.currentTimeMillis()
+
+ // Use cached JSON if still valid
+ mCachedSettingsJson?.let { cached ->
+ if ((currentTime - mLastJsonUpdateTime) < JSON_CACHE_TIMEOUT) {
+ return JSONObject(cached.toString()) // Return copy
+ }
+ }
+
+ val overlayPackageJson = Settings.Secure.getStringForUser(
+ activity?.contentResolver,
+ Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
+ UserHandle.USER_CURRENT)
+
+ val obj = if (overlayPackageJson.isNullOrEmpty()) {
+ JSONObject()
+ } else {
+ JSONObject(overlayPackageJson)
+ }
+
+ // Update cache
+ mCachedSettingsJson = JSONObject(obj.toString())
+ mLastJsonUpdateTime = currentTime
+
+ return obj
+ }
+
+ private fun putSettingsJson(obj: JSONObject) {
+ Settings.Secure.putStringForUser(
+ activity?.contentResolver,
+ Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
+ obj.toString(), UserHandle.USER_CURRENT)
+
+ // Update cache
+ try {
+ mCachedSettingsJson = JSONObject(obj.toString())
+ mLastJsonUpdateTime = System.currentTimeMillis()
+ } catch (e: JSONException) {
+ // Clear cache on error
+ mCachedSettingsJson = null
+ }
+ }
+
+ private fun setStyleValue(style: String) {
+ try {
+ val obj = getSettingsJson()
+ obj.putOpt(OVERLAY_CATEGORY_THEME_STYLE, style)
+ putSettingsJson(obj)
+ } catch (e: JSONException) {
+ // Ignored
+ } catch (e: IllegalArgumentException) {
+ // Ignored
+ }
+ }
+
+ private fun setSourceValue(source: String) {
+ try {
+ val obj = getSettingsJson()
+ if (source == "both") {
+ obj.putOpt(OVERLAY_COLOR_BOTH, 1)
+ obj.putOpt(OVERLAY_COLOR_SOURCE, COLOR_SOURCE_HOME)
+ } else {
+ obj.remove(OVERLAY_COLOR_BOTH)
+ obj.putOpt(OVERLAY_COLOR_SOURCE, source)
+ }
+ obj.putOpt(TIMESTAMP_FIELD, System.currentTimeMillis())
+ if (source != COLOR_SOURCE_PRESET) {
+ obj.remove(OVERLAY_CATEGORY_ACCENT_COLOR)
+ obj.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE)
+ }
+ putSettingsJson(obj)
+ } catch (e: JSONException) {
+ // Ignored
+ } catch (e: IllegalArgumentException) {
+ // Ignored
+ }
+ }
+
+ private fun setColorValue() {
+ try {
+ val obj = getSettingsJson()
+
+ if (mColorSourcePref?.value == COLOR_SOURCE_PRESET) {
+ val rgbColor = ColorPickerPreference.convertToRGB(mAccentColorValue).replace("#", "")
+ obj.putOpt(OVERLAY_CATEGORY_ACCENT_COLOR, rgbColor)
+ obj.putOpt(OVERLAY_CATEGORY_SYSTEM_PALETTE, rgbColor)
+ } else {
+ obj.remove(OVERLAY_CATEGORY_ACCENT_COLOR)
+ obj.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE)
+ }
+ putSettingsJson(obj)
+ } catch (e: JSONException) {
+ // Ignored
+ } catch (e: IllegalArgumentException) {
+ // Ignored
+ }
+ }
+
+ private fun setBgColorValue() {
+ try {
+ val obj = getSettingsJson()
+ if (mColorSourcePref?.value == COLOR_SOURCE_PRESET && mAccentBackgroundPref?.isChecked == true) {
+ obj.putOpt(OVERLAY_CATEGORY_BG_COLOR, mBgColorValue)
+ } else {
+ obj.remove(OVERLAY_CATEGORY_BG_COLOR)
+ }
+ putSettingsJson(obj)
+ } catch (e: JSONException) {
+ // Ignored
+ } catch (e: IllegalArgumentException) {
+ // Ignored
+ }
+ }
+
+ private fun setLuminanceValue(lumin: Int) {
+ try {
+ val obj = getSettingsJson()
+ if (lumin == 0) {
+ obj.remove(OVERLAY_LUMINANCE_FACTOR)
+ } else {
+ obj.putOpt(OVERLAY_LUMINANCE_FACTOR, 1.0 + (lumin.toDouble() / 100.0))
+ }
+ putSettingsJson(obj)
+ } catch (e: JSONException) {
+ // Ignored
+ } catch (e: IllegalArgumentException) {
+ // Ignored
+ }
+ }
+
+ private fun setChromaValue(chroma: Int) {
+ try {
+ val obj = getSettingsJson()
+ if (chroma == 0) {
+ obj.remove(OVERLAY_CHROMA_FACTOR)
+ } else {
+ obj.putOpt(OVERLAY_CHROMA_FACTOR, 1.0 + (chroma.toDouble() / 100.0))
+ }
+ putSettingsJson(obj)
+ } catch (e: JSONException) {
+ // Ignored
+ } catch (e: IllegalArgumentException) {
+ // Ignored
+ }
+ }
+
+ private fun setWholePaletteValue(whole: Boolean) {
+ try {
+ val obj = getSettingsJson()
+ if (!whole) {
+ obj.remove(OVERLAY_WHOLE_PALETTE)
+ } else {
+ obj.putOpt(OVERLAY_WHOLE_PALETTE, 1)
+ }
+ putSettingsJson(obj)
+ } catch (e: JSONException) {
+ // Ignored
+ } catch (e: IllegalArgumentException) {
+ // Ignored
+ }
+ }
+
+ private fun setTintBackgroundValue(tint: Boolean) {
+ try {
+ val obj = getSettingsJson()
+ if (!tint) {
+ obj.remove(OVERLAY_TINT_BACKGROUND)
+ } else {
+ obj.putOpt(OVERLAY_TINT_BACKGROUND, 1)
+ }
+ putSettingsJson(obj)
+ } catch (e: JSONException) {
+ // Ignored
+ } catch (e: IllegalArgumentException) {
+ // Ignored
+ }
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/Navigation.java b/src/com/rising/settings/fragments/Navigation.java
deleted file mode 100644
index ac05cc88..00000000
--- a/src/com/rising/settings/fragments/Navigation.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2016-2024 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import com.android.internal.logging.nano.MetricsProto;
-
-@SearchIndexable
-public class Navigation extends SettingsPreferenceFragment {
-
- public static final String TAG = "Navigation";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.rising_settings_navigation);
- }
-
- public static void reset(Context mContext) {
- ContentResolver resolver = mContext.getContentResolver();
- Settings.Secure.putIntForUser(resolver,
- Settings.Secure.NAVBAR_LAYOUT_MODE, 0, UserHandle.USER_CURRENT);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_navigation);
-}
diff --git a/src/com/rising/settings/fragments/Navigation.kt b/src/com/rising/settings/fragments/Navigation.kt
new file mode 100644
index 00000000..087d8c32
--- /dev/null
+++ b/src/com/rising/settings/fragments/Navigation.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016-2024 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.ContentResolver
+import android.content.Context
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.Settings
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class Navigation : OptimizedSettingsFragment() {
+
+ companion object {
+ const val TAG = "Navigation"
+
+ @JvmStatic
+ fun reset(mContext: Context) {
+ val resolver = mContext.contentResolver
+ Settings.Secure.putIntForUser(resolver,
+ Settings.Secure.NAVBAR_LAYOUT_MODE, 0, UserHandle.USER_CURRENT)
+ }
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = BaseSearchIndexProvider(R.xml.rising_settings_navigation)
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.rising_settings_navigation)
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/Notifications.java b/src/com/rising/settings/fragments/Notifications.java
deleted file mode 100644
index 1b3ae730..00000000
--- a/src/com/rising/settings/fragments/Notifications.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.content.Context;
-import android.os.Bundle;
-
-import androidx.preference.Preference;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import com.android.settings.utils.SystemRestartUtils;
-
-import java.util.List;
-
-@SearchIndexable
-public class Notifications extends SettingsPreferenceFragment implements Preference.OnPreferenceChangeListener {
-
- public static final String TAG = "Notifications";
-
- private static final String COMPACT_HUN_KEY = "persist.sys.compact_hun.enabled";
-
- private Preference mCompactHUNPref;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.rising_settings_notification);
- mCompactHUNPref = findPreference(COMPACT_HUN_KEY);
- mCompactHUNPref.setOnPreferenceChangeListener(this);
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (preference == mCompactHUNPref) {
- SystemRestartUtils.showSystemUIRestartDialog(getContext());
- return true;
- }
- return false;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_notification) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/Notifications.kt b/src/com/rising/settings/fragments/Notifications.kt
new file mode 100644
index 00000000..4cc4919d
--- /dev/null
+++ b/src/com/rising/settings/fragments/Notifications.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+import androidx.preference.Preference
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settings.utils.SystemRestartUtils
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class Notifications : OptimizedSettingsFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ const val TAG = "Notifications"
+
+ private const val COMPACT_HUN_KEY = "persist.sys.compact_hun.enabled"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_notification) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context).toMutableList()
+ return keys
+ }
+ }
+ }
+
+ private var mCompactHUNPref: Preference? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.rising_settings_notification)
+ mCompactHUNPref = findCachedPreference(COMPACT_HUN_KEY)
+ mCompactHUNPref?.onPreferenceChangeListener = this
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
+ return when (preference) {
+ mCompactHUNPref -> {
+ val context = getSafeContext()
+ context?.let { SystemRestartUtils.showSystemUIRestartDialog(it) }
+ true
+ }
+ else -> false
+ }
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/OngoingProgressBar.java b/src/com/rising/settings/fragments/OngoingProgressBar.java
deleted file mode 100644
index 66c4c997..00000000
--- a/src/com/rising/settings/fragments/OngoingProgressBar.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.rising.settings.fragments;
-
-import android.content.Context;
-import android.os.Bundle;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.List;
-
-@SearchIndexable
-public class OngoingProgressBar extends SettingsPreferenceFragment {
-
- public static final String TAG = "OngoingProgressBar";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.ongoing_progress_settings);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.ongoing_progress_settings) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/OngoingProgressBar.kt b/src/com/rising/settings/fragments/OngoingProgressBar.kt
new file mode 100644
index 00000000..6f9ac8b6
--- /dev/null
+++ b/src/com/rising/settings/fragments/OngoingProgressBar.kt
@@ -0,0 +1,38 @@
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class OngoingProgressBar : OptimizedSettingsFragment() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.ongoing_progress_settings)
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+
+ companion object {
+ const val TAG = "OngoingProgressBar"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.ongoing_progress_settings) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context)
+ return keys
+ }
+ }
+ }
+}
diff --git a/src/com/rising/settings/fragments/OptimizedSettingsFragment.kt b/src/com/rising/settings/fragments/OptimizedSettingsFragment.kt
new file mode 100644
index 00000000..c0742a14
--- /dev/null
+++ b/src/com/rising/settings/fragments/OptimizedSettingsFragment.kt
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import androidx.preference.Preference
+import com.android.settings.SettingsPreferenceFragment
+import com.android.internal.util.android.ThemeUtils
+import java.lang.ref.WeakReference
+import java.util.concurrent.ConcurrentHashMap
+
+/**
+ * Optimized base class for Settings fragments with performance improvements:
+ * - Memory leak prevention
+ * - Resource caching
+ * - Proper lifecycle management
+ * - Background task handling
+ */
+abstract class OptimizedSettingsFragment : SettingsPreferenceFragment() {
+
+ // Safe handler to prevent memory leaks
+ protected class SafeHandler(fragment: OptimizedSettingsFragment) : Handler(Looper.getMainLooper()) {
+ private val mFragmentRef = WeakReference(fragment)
+
+ override fun handleMessage(msg: android.os.Message) {
+ val fragment = mFragmentRef.get()
+ if (fragment != null && fragment.isAdded) {
+ super.handleMessage(msg)
+ }
+ }
+ }
+
+ protected var mHandler: SafeHandler? = null
+ protected open var mThemeUtils: ThemeUtils? = null
+
+ // Cache for preference states to prevent redundant operations
+ protected val mPreferenceCache = ConcurrentHashMap()
+
+ // Cache for expensive operations
+ protected val mOperationCache = ConcurrentHashMap()
+
+ // Track if fragment is properly initialized
+ private var mIsInitialized = false
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ // Initialize handler with weak reference
+ mHandler = SafeHandler(this)
+
+ // Initialize ThemeUtils with null check
+ activity?.let {
+ mThemeUtils = ThemeUtils.getInstance(it)
+ }
+
+ mIsInitialized = true
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+
+ // Cleanup to prevent memory leaks
+ mHandler?.let {
+ it.removeCallbacksAndMessages(null)
+ mHandler = null
+ }
+
+ mThemeUtils = null
+ mPreferenceCache.clear()
+ mOperationCache.clear()
+ mIsInitialized = false
+ }
+
+ override fun onDetach() {
+ super.onDetach()
+
+ // Additional cleanup
+ mHandler?.removeCallbacksAndMessages(null)
+
+ mPreferenceCache.clear()
+ mOperationCache.clear()
+ }
+
+ /**
+ * Safe method to check if fragment is properly initialized and attached
+ */
+ protected fun isFragmentReady(): Boolean {
+ return mIsInitialized && isAdded && activity != null && activity?.isFinishing == false
+ }
+
+ /**
+ * Safe method to get context with null checks
+ */
+ protected fun getSafeContext(): Context? {
+ return if (!isFragmentReady()) null else context
+ }
+
+ /**
+ * Cached preference lookup to avoid repeated findViewById calls
+ */
+ @Suppress("UNCHECKED_CAST")
+ protected fun findCachedPreference(key: String): T? {
+ var preference = mPreferenceCache[key] as? T
+ if (preference == null) {
+ preference = findPreference(key)
+ if (preference != null) {
+ mPreferenceCache[key] = preference
+ }
+ }
+ return preference
+ }
+
+ /**
+ * Safe method to post delayed tasks with fragment lifecycle checks
+ */
+ protected fun postDelayedSafe(runnable: Runnable, delayMillis: Long) {
+ if (mHandler != null && isFragmentReady()) {
+ mHandler?.postDelayed({
+ if (isFragmentReady()) {
+ runnable.run()
+ }
+ }, delayMillis)
+ }
+ }
+
+ /**
+ * Safe method to post delayed tasks with fragment lifecycle checks (Kotlin lambda version)
+ */
+ protected inline fun postDelayedSafe(delayMillis: Long, crossinline action: () -> Unit) {
+ if (mHandler != null && isFragmentReady()) {
+ mHandler?.postDelayed({
+ if (isFragmentReady()) {
+ action()
+ }
+ }, delayMillis)
+ }
+ }
+
+ /**
+ * Cache expensive operations to prevent redundant execution
+ */
+ protected fun cacheOperation(key: String, result: Any) {
+ mOperationCache[key] = result
+ }
+
+ /**
+ * Get cached operation result
+ */
+ @Suppress("UNCHECKED_CAST")
+ protected fun getCachedOperation(key: String): T? {
+ return mOperationCache[key] as? T
+ }
+
+ /**
+ * Check if operation result is cached
+ */
+ protected fun isOperationCached(key: String): Boolean {
+ return mOperationCache.containsKey(key)
+ }
+
+ /**
+ * Safe ThemeUtils access with lazy initialization
+ */
+ protected fun getSafeThemeUtils(): ThemeUtils? {
+ if (mThemeUtils == null && getSafeContext() != null) {
+ mThemeUtils = ThemeUtils.getInstance(getSafeContext())
+ }
+ return mThemeUtils
+ }
+
+ /**
+ * Optimized overlay operation with caching
+ */
+ protected fun setOverlayEnabledCached(category: String, packageName: String, target: String) {
+ val cacheKey = "$category:$packageName:$target"
+
+ // Check if this operation was already performed
+ if (isOperationCached(cacheKey)) {
+ return
+ }
+
+ val themeUtils = getSafeThemeUtils()
+ if (themeUtils != null) {
+ themeUtils.setOverlayEnabled(category, packageName, target)
+ cacheOperation(cacheKey, true)
+ }
+ }
+
+ /**
+ * Clear operation cache when needed (e.g., on preference changes)
+ */
+ protected fun clearOperationCache() {
+ mOperationCache.clear()
+ }
+
+ /**
+ * Safe method to remove callbacks and messages
+ */
+ protected fun removeCallbacks() {
+ mHandler?.removeCallbacksAndMessages(null)
+ }
+}
diff --git a/src/com/rising/settings/fragments/QuickSettings.java b/src/com/rising/settings/fragments/QuickSettings.java
deleted file mode 100644
index ecba6f43..00000000
--- a/src/com/rising/settings/fragments/QuickSettings.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.app.ActivityManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import com.android.internal.util.android.ThemeUtils;
-
-import com.android.settings.preferences.CustomSeekBarPreference;
-import com.android.settings.preferences.SecureSettingSwitchPreference;
-
-import com.android.settings.utils.SystemRestartUtils;
-
-import java.util.List;
-
-@SearchIndexable
-public class QuickSettings extends SettingsPreferenceFragment implements
- Preference.OnPreferenceChangeListener {
-
- public static final String TAG = "QuickSettings";
-
- private static final String KEY_QS_UI_STYLE = "qs_tile_ui_style";
- private static final String KEY_QS_PANEL_STYLE = "qs_panel_style";
- private static final String KEY_PREF_TILE_ANIM_STYLE = "qs_tile_animation_style";
- private static final String KEY_PREF_TILE_ANIM_DURATION = "qs_tile_animation_duration";
- private static final String KEY_PREF_TILE_ANIM_INTERPOLATOR = "qs_tile_animation_interpolator";
- private static final String KEY_QS_REFACTOR_ENABLED = "qs_refactor_enabled";
-
- private ListPreference mQsUI;
- private ListPreference mQsPanelStyle;
- private ListPreference mTileAnimationStyle;
- private ListPreference mTileAnimationInterpolator;
- private CustomSeekBarPreference mTileAnimationDuration;
- private Preference mSplitShadePref;
- private SecureSettingSwitchPreference mQsRefactorEnabled;
-
- private ThemeUtils mThemeUtils;
-
- private Handler mHandler = new Handler();
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.rising_settings_qs);
-
- final Context mContext = getActivity().getApplicationContext();
-
- mThemeUtils = ThemeUtils.getInstance(getActivity());
-
- mQsUI = (ListPreference) findPreference(KEY_QS_UI_STYLE);
- mQsUI.setOnPreferenceChangeListener(this);
-
- mQsPanelStyle = (ListPreference) findPreference(KEY_QS_PANEL_STYLE);
- mQsPanelStyle.setOnPreferenceChangeListener(this);
-
- mSplitShadePref = (Preference) findPreference("qs_split_shade_enabled");
- mSplitShadePref.setOnPreferenceChangeListener(this);
-
- mQsRefactorEnabled = (SecureSettingSwitchPreference) findPreference(KEY_QS_REFACTOR_ENABLED);
- mQsRefactorEnabled.setOnPreferenceChangeListener(this);
-
- mTileAnimationStyle = (ListPreference) findPreference(KEY_PREF_TILE_ANIM_STYLE);
- mTileAnimationDuration = (CustomSeekBarPreference) findPreference(KEY_PREF_TILE_ANIM_DURATION);
- mTileAnimationInterpolator = (ListPreference) findPreference(KEY_PREF_TILE_ANIM_INTERPOLATOR);
-
- mTileAnimationStyle.setOnPreferenceChangeListener(this);
-
- int tileAnimationStyle = Settings.System.getIntForUser(getActivity().getContentResolver(),
- KEY_PREF_TILE_ANIM_STYLE, 0, UserHandle.USER_CURRENT);
- updateAnimTileStyle(tileAnimationStyle);
-
- checkQSOverlays(mContext);
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- ContentResolver resolver = getActivity().getContentResolver();
-
- if (preference == mQsUI) {
- int value = Integer.parseInt((String) newValue);
- Settings.System.putIntForUser(resolver,
- Settings.System.QS_TILE_UI_STYLE, value, UserHandle.USER_CURRENT);
- updateQsStyle(getActivity());
- checkQSOverlays(getActivity());
- return true;
- } else if (preference == mQsPanelStyle) {
- int value = Integer.parseInt((String) newValue);
- Settings.System.putIntForUser(resolver,
- Settings.System.QS_PANEL_STYLE, value, UserHandle.USER_CURRENT);
- updateQsPanelStyle(getActivity());
- checkQSOverlays(getActivity());
- return true;
- } else if (preference == mTileAnimationStyle) {
- int value = Integer.parseInt((String) newValue);
- updateAnimTileStyle(value);
- return true;
- } else if (preference == mSplitShadePref) {
- int value = (boolean) newValue ? 1 : 0;
- Settings.System.putIntForUser(resolver,
- "qs_split_shade_enabled", value, UserHandle.USER_CURRENT);
- updateSplitShadeEnabled(getActivity());
- return true;
- } else if (preference == mQsRefactorEnabled) {
- // QS Refactor setting changed - restart SystemUI
- SystemRestartUtils.restartSystemUI(getContext());
- return true;
- }
- return false;
- }
-
- private void updateAnimTileStyle(int tileAnimationStyle) {
- mTileAnimationDuration.setEnabled(tileAnimationStyle != 0);
- mTileAnimationInterpolator.setEnabled(tileAnimationStyle != 0);
- }
-
- private void updateSplitShadeEnabled(Context context) {
- ContentResolver resolver = context.getContentResolver();
- boolean splitShadeEnabled = Settings.System.getIntForUser(
- resolver,
- "qs_split_shade_enabled" , 0, UserHandle.USER_CURRENT) != 0;
- String splitShadeStyleCategory = "android.theme.customization.better_qs";
- String overlayThemeTarget = "com.android.systemui";
- String overlayThemePackage = "com.android.system.qs.ui.better_qs";
- if (mThemeUtils == null) {
- mThemeUtils = ThemeUtils.getInstance(context);
- }
- mHandler.postDelayed(() -> {
- mThemeUtils.setOverlayEnabled(splitShadeStyleCategory, overlayThemeTarget, overlayThemeTarget);
- if (splitShadeEnabled) {
- mThemeUtils.setOverlayEnabled(splitShadeStyleCategory, overlayThemePackage, overlayThemeTarget);
- }
- }, 1250);
- }
-
- private void updateQsStyle(Context context) {
- ContentResolver resolver = context.getContentResolver();
-
- boolean isA11Style = Settings.System.getIntForUser(resolver,
- Settings.System.QS_TILE_UI_STYLE , 0, UserHandle.USER_CURRENT) != 0;
-
- String qsUIStyleCategory = "android.theme.customization.qs_ui";
- String overlayThemeTarget = "com.android.systemui";
- String overlayThemePackage = "com.android.system.qs.ui.A11";
-
- if (mThemeUtils == null) {
- mThemeUtils = ThemeUtils.getInstance(context);
- }
-
- // reset all overlays before applying
- mThemeUtils.setOverlayEnabled(qsUIStyleCategory, overlayThemeTarget, overlayThemeTarget);
-
- if (isA11Style) {
- mThemeUtils.setOverlayEnabled(qsUIStyleCategory, overlayThemePackage, overlayThemeTarget);
- }
- }
-
- private void updateQsPanelStyle(Context context) {
- ContentResolver resolver = context.getContentResolver();
-
- int qsPanelStyle = Settings.System.getIntForUser(resolver,
- Settings.System.QS_PANEL_STYLE, 0, UserHandle.USER_CURRENT);
-
- String qsPanelStyleCategory = "android.theme.customization.qs_panel";
- String overlayThemeTarget = "com.android.systemui";
- String overlayThemePackage = "com.android.systemui";
-
- switch (qsPanelStyle) {
- case 1:
- overlayThemePackage = "com.android.system.qs.outline";
- break;
- case 2:
- case 3:
- overlayThemePackage = "com.android.system.qs.twotoneaccent";
- break;
- case 4:
- overlayThemePackage = "com.android.system.qs.shaded";
- break;
- case 5:
- overlayThemePackage = "com.android.system.qs.cyberpunk";
- break;
- case 6:
- overlayThemePackage = "com.android.system.qs.neumorph";
- break;
- case 7:
- overlayThemePackage = "com.android.system.qs.reflected";
- break;
- case 8:
- overlayThemePackage = "com.android.system.qs.surround";
- break;
- case 9:
- overlayThemePackage = "com.android.system.qs.thin";
- break;
- default:
- break;
- }
-
- if (mThemeUtils == null) {
- mThemeUtils = ThemeUtils.getInstance(context);
- }
-
- // reset all overlays before applying
- mThemeUtils.setOverlayEnabled(qsPanelStyleCategory, overlayThemeTarget, overlayThemeTarget);
-
- if (qsPanelStyle > 0) {
- mThemeUtils.setOverlayEnabled(qsPanelStyleCategory, overlayThemePackage, overlayThemeTarget);
- }
- }
-
- private void checkQSOverlays(Context context) {
- ContentResolver resolver = context.getContentResolver();
- int isA11Style = Settings.System.getIntForUser(resolver,
- Settings.System.QS_TILE_UI_STYLE , 0, UserHandle.USER_CURRENT);
- int qsPanelStyle = Settings.System.getIntForUser(resolver,
- Settings.System.QS_PANEL_STYLE , 0, UserHandle.USER_CURRENT);
-
- // Update summaries
- int index = mQsUI.findIndexOfValue(Integer.toString(isA11Style));
- mQsUI.setValue(Integer.toString(isA11Style));
- mQsUI.setSummary(mQsUI.getEntries()[index]);
-
- index = mQsPanelStyle.findIndexOfValue(Integer.toString(qsPanelStyle));
- mQsPanelStyle.setValue(Integer.toString(qsPanelStyle));
- mQsPanelStyle.setSummary(mQsPanelStyle.getEntries()[index]);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_qs) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/QuickSettings.kt b/src/com/rising/settings/fragments/QuickSettings.kt
new file mode 100644
index 00000000..9f56057e
--- /dev/null
+++ b/src/com/rising/settings/fragments/QuickSettings.kt
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.ContentResolver
+import android.content.Context
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.os.UserHandle
+import android.provider.Settings
+import androidx.preference.ListPreference
+import androidx.preference.Preference
+import com.android.internal.logging.nano.MetricsProto
+import com.android.internal.util.android.ThemeUtils
+import com.android.settings.R
+import com.android.settings.SettingsPreferenceFragment
+import com.android.settings.preferences.CustomSeekBarPreference
+import com.android.settings.preferences.SecureSettingSwitchPreference
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settings.utils.SystemRestartUtils
+import com.android.settingslib.search.SearchIndexable
+import java.lang.ref.WeakReference
+
+@SearchIndexable
+class QuickSettings : SettingsPreferenceFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ const val TAG = "QuickSettings"
+
+ private const val KEY_QS_UI_STYLE = "qs_tile_ui_style"
+ private const val KEY_QS_PANEL_STYLE = "qs_panel_style"
+ private const val KEY_PREF_TILE_ANIM_STYLE = "qs_tile_animation_style"
+ private const val KEY_PREF_TILE_ANIM_DURATION = "qs_tile_animation_duration"
+ private const val KEY_PREF_TILE_ANIM_INTERPOLATOR = "qs_tile_animation_interpolator"
+ private const val KEY_QS_REFACTOR_ENABLED = "qs_refactor_enabled"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_qs) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context).toMutableList()
+ return keys
+ }
+ }
+ }
+
+ private var mQsUI: ListPreference? = null
+ private var mQsPanelStyle: ListPreference? = null
+ private var mTileAnimationStyle: ListPreference? = null
+ private var mTileAnimationInterpolator: ListPreference? = null
+ private var mTileAnimationDuration: CustomSeekBarPreference? = null
+ private var mSplitShadePref: Preference? = null
+ private var mQsRefactorEnabled: SecureSettingSwitchPreference? = null
+
+ private var mThemeUtils: ThemeUtils? = null
+
+ // Use WeakReference to prevent memory leaks
+ private class SafeHandler(fragment: QuickSettings) : Handler(Looper.getMainLooper()) {
+ private val mFragmentRef = WeakReference(fragment)
+
+ override fun handleMessage(msg: android.os.Message) {
+ val fragment = mFragmentRef.get()
+ if (fragment != null && fragment.isAdded) {
+ super.handleMessage(msg)
+ }
+ }
+ }
+
+ private var mHandler: SafeHandler? = null
+
+ // Cache for overlay operations to prevent redundant calls
+ private var mLastQsUIStyle: String? = null
+ private var mLastQsPanelStyle: String? = null
+ private var mLastSplitShadeEnabled = false
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.rising_settings_qs)
+
+ val mContext = activity?.applicationContext
+
+ // Initialize handler with weak reference
+ mHandler = SafeHandler(this)
+
+ activity?.let {
+ mThemeUtils = ThemeUtils.getInstance(it)
+ }
+
+ mQsUI = findPreference(KEY_QS_UI_STYLE)?.apply {
+ onPreferenceChangeListener = this@QuickSettings
+ }
+
+ mQsPanelStyle = findPreference(KEY_QS_PANEL_STYLE)?.apply {
+ onPreferenceChangeListener = this@QuickSettings
+ }
+
+ mSplitShadePref = findPreference("qs_split_shade_enabled")?.apply {
+ onPreferenceChangeListener = this@QuickSettings
+ }
+
+ mQsRefactorEnabled = findPreference(KEY_QS_REFACTOR_ENABLED)?.apply {
+ onPreferenceChangeListener = this@QuickSettings
+ }
+
+ mTileAnimationStyle = findPreference(KEY_PREF_TILE_ANIM_STYLE)
+ mTileAnimationDuration = findPreference(KEY_PREF_TILE_ANIM_DURATION)
+ mTileAnimationInterpolator = findPreference(KEY_PREF_TILE_ANIM_INTERPOLATOR)
+
+ mTileAnimationStyle?.onPreferenceChangeListener = this
+
+ val tileAnimationStyle = Settings.System.getIntForUser(activity?.contentResolver,
+ KEY_PREF_TILE_ANIM_STYLE, 0, UserHandle.USER_CURRENT)
+ updateAnimTileStyle(tileAnimationStyle)
+
+ mContext?.let { checkQSOverlays(it) }
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
+ val resolver = activity?.contentResolver ?: return false
+
+ return when (preference) {
+ mQsUI -> {
+ val value = (newValue as String).toInt()
+ Settings.System.putIntForUser(resolver,
+ Settings.System.QS_TILE_UI_STYLE, value, UserHandle.USER_CURRENT)
+ activity?.let { updateQsStyle(it) }
+ activity?.let { checkQSOverlays(it) }
+ true
+ }
+
+ mQsPanelStyle -> {
+ val value = (newValue as String).toInt()
+ Settings.System.putIntForUser(resolver,
+ Settings.System.QS_PANEL_STYLE, value, UserHandle.USER_CURRENT)
+ activity?.let { updateQsPanelStyle(it) }
+ activity?.let { checkQSOverlays(it) }
+ true
+ }
+
+ mTileAnimationStyle -> {
+ val value = (newValue as String).toInt()
+ updateAnimTileStyle(value)
+ true
+ }
+
+ mSplitShadePref -> {
+ val value = if (newValue as Boolean) 1 else 0
+ Settings.System.putIntForUser(resolver,
+ "qs_split_shade_enabled", value, UserHandle.USER_CURRENT)
+ activity?.let { updateSplitShadeEnabled(it) }
+ true
+ }
+
+ mQsRefactorEnabled -> {
+ // QS Refactor setting changed - restart SystemUI
+ context?.let { SystemRestartUtils.restartSystemUI(it) }
+ true
+ }
+
+ else -> false
+ }
+ }
+
+ private fun updateAnimTileStyle(tileAnimationStyle: Int) {
+ mTileAnimationDuration?.isEnabled = tileAnimationStyle != 0
+ mTileAnimationInterpolator?.isEnabled = tileAnimationStyle != 0
+ }
+
+ private fun updateSplitShadeEnabled(context: Context) {
+ val resolver = context.contentResolver
+ val splitShadeEnabled = Settings.System.getIntForUser(
+ resolver,
+ "qs_split_shade_enabled", 0, UserHandle.USER_CURRENT) != 0
+ val splitShadeStyleCategory = "android.theme.customization.better_qs"
+ val overlayThemeTarget = "com.android.systemui"
+ val overlayThemePackage = "com.android.system.qs.ui.better_qs"
+
+ if (mThemeUtils == null) {
+ mThemeUtils = ThemeUtils.getInstance(context)
+ }
+
+ // Optimize: Only apply if state actually changed
+ if (splitShadeEnabled != mLastSplitShadeEnabled) {
+ mLastSplitShadeEnabled = splitShadeEnabled
+ mHandler?.postDelayed({
+ if (isAdded && mThemeUtils != null) {
+ mThemeUtils?.setOverlayEnabled(splitShadeStyleCategory, overlayThemeTarget, overlayThemeTarget)
+ if (splitShadeEnabled) {
+ mThemeUtils?.setOverlayEnabled(splitShadeStyleCategory, overlayThemePackage, overlayThemeTarget)
+ }
+ }
+ }, 1250)
+ }
+ }
+
+ private fun updateQsStyle(context: Context) {
+ val resolver = context.contentResolver
+
+ val isA11Style = Settings.System.getIntForUser(resolver,
+ Settings.System.QS_TILE_UI_STYLE, 0, UserHandle.USER_CURRENT) != 0
+
+ val currentStyle = if (isA11Style) "A11" else "default"
+
+ // Optimize: Only apply if style actually changed
+ if (currentStyle == mLastQsUIStyle) {
+ return
+ }
+ mLastQsUIStyle = currentStyle
+
+ val qsUIStyleCategory = "android.theme.customization.qs_ui"
+ val overlayThemeTarget = "com.android.systemui"
+ val overlayThemePackage = "com.android.system.qs.ui.A11"
+
+ if (mThemeUtils == null) {
+ mThemeUtils = ThemeUtils.getInstance(context)
+ }
+
+ // reset all overlays before applying
+ mThemeUtils?.setOverlayEnabled(qsUIStyleCategory, overlayThemeTarget, overlayThemeTarget)
+
+ if (isA11Style) {
+ mThemeUtils?.setOverlayEnabled(qsUIStyleCategory, overlayThemePackage, overlayThemeTarget)
+ }
+ }
+
+ private fun updateQsPanelStyle(context: Context) {
+ val resolver = context.contentResolver
+
+ val qsPanelStyle = Settings.System.getIntForUser(resolver,
+ Settings.System.QS_PANEL_STYLE, 0, UserHandle.USER_CURRENT)
+
+ val currentPanelStyle = qsPanelStyle.toString()
+
+ // Optimize: Only apply if style actually changed
+ if (currentPanelStyle == mLastQsPanelStyle) {
+ return
+ }
+ mLastQsPanelStyle = currentPanelStyle
+
+ val qsPanelStyleCategory = "android.theme.customization.qs_panel"
+ val overlayThemeTarget = "com.android.systemui"
+ var overlayThemePackage = "com.android.systemui"
+
+ when (qsPanelStyle) {
+ 1 -> overlayThemePackage = "com.android.system.qs.outline"
+ 2, 3 -> overlayThemePackage = "com.android.system.qs.twotoneaccent"
+ 4 -> overlayThemePackage = "com.android.system.qs.shaded"
+ 5 -> overlayThemePackage = "com.android.system.qs.cyberpunk"
+ 6 -> overlayThemePackage = "com.android.system.qs.neumorph"
+ 7 -> overlayThemePackage = "com.android.system.qs.reflected"
+ 8 -> overlayThemePackage = "com.android.system.qs.surround"
+ 9 -> overlayThemePackage = "com.android.system.qs.thin"
+ }
+
+ if (mThemeUtils == null) {
+ mThemeUtils = ThemeUtils.getInstance(context)
+ }
+
+ // reset all overlays before applying
+ mThemeUtils?.setOverlayEnabled(qsPanelStyleCategory, overlayThemeTarget, overlayThemeTarget)
+
+ if (qsPanelStyle > 0) {
+ mThemeUtils?.setOverlayEnabled(qsPanelStyleCategory, overlayThemePackage, overlayThemeTarget)
+ }
+ }
+
+ private fun checkQSOverlays(context: Context) {
+ val resolver = context.contentResolver
+ val isA11Style = Settings.System.getIntForUser(resolver,
+ Settings.System.QS_TILE_UI_STYLE, 0, UserHandle.USER_CURRENT)
+ val qsPanelStyleValue = Settings.System.getIntForUser(resolver,
+ Settings.System.QS_PANEL_STYLE, 0, UserHandle.USER_CURRENT)
+
+ // Update summaries
+ mQsUI?.let { qsUI ->
+ val index = qsUI.findIndexOfValue(isA11Style.toString())
+ if (index >= 0 && index < qsUI.entries.size) {
+ qsUI.value = isA11Style.toString()
+ qsUI.summary = qsUI.entries[index]
+ }
+ }
+
+ mQsPanelStyle?.let { qsPanelStylePref ->
+ val index = qsPanelStylePref.findIndexOfValue(qsPanelStyleValue.toString())
+ if (index >= 0 && index < qsPanelStylePref.entries.size) {
+ qsPanelStylePref.value = qsPanelStyleValue.toString()
+ qsPanelStylePref.summary = qsPanelStylePref.entries[index]
+ }
+ }
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ // Cleanup to prevent memory leaks
+ mHandler?.let {
+ it.removeCallbacksAndMessages(null)
+ mHandler = null
+ }
+ mThemeUtils = null
+ mLastQsUIStyle = null
+ mLastQsPanelStyle = null
+ }
+
+ override fun onDetach() {
+ super.onDetach()
+ // Additional cleanup
+ mHandler?.removeCallbacksAndMessages(null)
+ }
+}
diff --git a/src/com/rising/settings/fragments/QuickSwitch.java b/src/com/rising/settings/fragments/QuickSwitch.java
deleted file mode 100644
index 52899061..00000000
--- a/src/com/rising/settings/fragments/QuickSwitch.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2023 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.rising.settings.fragments;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.os.SystemProperties;
-import android.provider.SearchIndexableResource;
-
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.Utils;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.Indexable;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.android.internal.util.android.SystemRestartUtils;
-
-@SearchIndexable
-public class QuickSwitch extends SettingsPreferenceFragment
- implements Preference.OnPreferenceChangeListener, Indexable {
-
- private static final String TAG = "QuickSwitch";
-
- private static final String QUICKSWITCH_KEY = "persist.sys.default_launcher";
-
- private ListPreference quickSwitchPref;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.quick_switch);
-
- int defaultLauncher = SystemProperties.getInt(QUICKSWITCH_KEY, 0);
- quickSwitchPref = findPreference(QUICKSWITCH_KEY);
- quickSwitchPref.setOnPreferenceChangeListener(this);
- Context context = getContext();
- Resources res = context.getResources();
-
- String[] launcherEntries = res.getStringArray(R.array.quickswitch_launcher_entries);
- String[] launcherValues = res.getStringArray(R.array.quickswitch_launcher_values);
-
- List quickSwitchEntries = new ArrayList<>();
- List quickSwitchValues = new ArrayList<>();
-
- quickSwitchEntries.add(launcherEntries[0]);
- quickSwitchValues.add(launcherValues[0]);
-
- if (SystemProperties.getInt("persist.sys.quickswitch_pixel_shipped", 0) != 0) {
- quickSwitchEntries.add(launcherEntries[1]);
- quickSwitchValues.add(launcherValues[1]);
- }
-
- if (SystemProperties.getInt("persist.sys.quickswitch_lawnchair_shipped", 0) != 0) {
- quickSwitchEntries.add(launcherEntries[2]);
- quickSwitchValues.add(launcherValues[2]);
- }
-
- quickSwitchPref.setEntries(quickSwitchEntries.toArray(new CharSequence[0]));
- quickSwitchPref.setEntryValues(quickSwitchValues.toArray(new CharSequence[0]));
- quickSwitchPref.setValue(String.valueOf(defaultLauncher));
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (preference == quickSwitchPref) {
- SystemRestartUtils.showSystemRestartDialog(getContext());
- return true;
- }
- return false;
- }
-
- public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider() {
- @Override
- public List getXmlResourcesToIndex(Context context,
- boolean enabled) {
- ArrayList result =
- new ArrayList();
-
- SearchIndexableResource sir = new SearchIndexableResource(context);
- sir.xmlResId = R.xml.quick_switch;
- result.add(sir);
- return result;
- }
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/QuickSwitch.kt b/src/com/rising/settings/fragments/QuickSwitch.kt
new file mode 100644
index 00000000..a2e60c09
--- /dev/null
+++ b/src/com/rising/settings/fragments/QuickSwitch.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+import android.os.SystemProperties
+import android.provider.SearchIndexableResource
+import androidx.preference.ListPreference
+import androidx.preference.Preference
+import com.android.internal.logging.nano.MetricsProto
+import com.android.internal.util.android.SystemRestartUtils
+import com.android.settings.R
+import com.android.settings.SettingsPreferenceFragment
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.Indexable
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class QuickSwitch : SettingsPreferenceFragment(), Preference.OnPreferenceChangeListener, Indexable {
+
+ companion object {
+ private const val TAG = "QuickSwitch"
+ private const val QUICKSWITCH_KEY = "persist.sys.default_launcher"
+
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider() {
+ override fun getXmlResourcesToIndex(context: Context, enabled: Boolean): List {
+ val result = ArrayList()
+ val sir = SearchIndexableResource(context).apply {
+ xmlResId = R.xml.quick_switch
+ }
+ result.add(sir)
+ return result
+ }
+
+ override fun getNonIndexableKeys(context: Context): List {
+ return super.getNonIndexableKeys(context)
+ }
+ }
+ }
+
+ private lateinit var quickSwitchPref: ListPreference
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.quick_switch)
+
+ val defaultLauncher = SystemProperties.getInt(QUICKSWITCH_KEY, 0)
+ quickSwitchPref = findPreference(QUICKSWITCH_KEY)!!
+ quickSwitchPref.onPreferenceChangeListener = this
+
+ val context = requireContext()
+ val res = context.resources
+
+ val launcherEntries = res.getStringArray(R.array.quickswitch_launcher_entries)
+ val launcherValues = res.getStringArray(R.array.quickswitch_launcher_values)
+
+ val quickSwitchEntries = mutableListOf()
+ val quickSwitchValues = mutableListOf()
+
+ // Always add the first launcher (default)
+ quickSwitchEntries.add(launcherEntries[0])
+ quickSwitchValues.add(launcherValues[0])
+
+ // Add Pixel launcher if shipped
+ if (SystemProperties.getInt("persist.sys.quickswitch_pixel_shipped", 0) != 0) {
+ quickSwitchEntries.add(launcherEntries[1])
+ quickSwitchValues.add(launcherValues[1])
+ }
+
+ // Add Lawnchair launcher if shipped
+ if (SystemProperties.getInt("persist.sys.quickswitch_lawnchair_shipped", 0) != 0) {
+ quickSwitchEntries.add(launcherEntries[2])
+ quickSwitchValues.add(launcherValues[2])
+ }
+
+ quickSwitchPref.entries = quickSwitchEntries.toTypedArray()
+ quickSwitchPref.entryValues = quickSwitchValues.toTypedArray()
+ quickSwitchPref.value = defaultLauncher.toString()
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
+ return if (preference == quickSwitchPref) {
+ SystemRestartUtils.showSystemRestartDialog(context)
+ true
+ } else {
+ false
+ }
+ }
+}
diff --git a/src/com/rising/settings/fragments/Security.java b/src/com/rising/settings/fragments/Security.java
deleted file mode 100644
index f68f7c71..00000000
--- a/src/com/rising/settings/fragments/Security.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.SystemProperties;
-import android.util.Log;
-import android.provider.Settings;
-
-import androidx.preference.Preference;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import com.android.internal.util.android.SystemRestartUtils;
-
-import java.util.List;
-
-@SearchIndexable
-public class Security extends SettingsPreferenceFragment implements Preference.OnPreferenceChangeListener {
-
- private final static String HIDE_SCREEN_CAPTURE_STATUS_KEY = "hide_screen_capture_status";
- private final static String NO_STORAGE_RESTRICT_KEY = "no_storage_restrict";
- private final static String WINDOW_IGNORE_SECURE_KEY = "window_ignore_secure";
-
- Preference mHideScreenCapturePref;
- Preference mNoStorageRestrictPref;
- Preference mWindowIgnoreSecurePref;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.rising_settings_security);
-
- mHideScreenCapturePref = findPreference(HIDE_SCREEN_CAPTURE_STATUS_KEY);
- mNoStorageRestrictPref = findPreference(NO_STORAGE_RESTRICT_KEY);
- mWindowIgnoreSecurePref = findPreference(WINDOW_IGNORE_SECURE_KEY);
-
- mHideScreenCapturePref.setOnPreferenceChangeListener(this);
- mNoStorageRestrictPref.setOnPreferenceChangeListener(this);
- mWindowIgnoreSecurePref.setOnPreferenceChangeListener(this);
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (preference == mHideScreenCapturePref
- || preference == mNoStorageRestrictPref
- || preference == mWindowIgnoreSecurePref) {
- SystemRestartUtils.showSystemRestartDialog(getContext());
- return true;
- }
- return false;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_security) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/Security.kt b/src/com/rising/settings/fragments/Security.kt
new file mode 100644
index 00000000..873e5758
--- /dev/null
+++ b/src/com/rising/settings/fragments/Security.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+import androidx.preference.Preference
+import com.android.internal.logging.nano.MetricsProto
+import com.android.internal.util.android.SystemRestartUtils
+import com.android.settings.R
+import com.android.settings.SettingsPreferenceFragment
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class Security : SettingsPreferenceFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ private const val HIDE_SCREEN_CAPTURE_STATUS_KEY = "hide_screen_capture_status"
+ private const val NO_STORAGE_RESTRICT_KEY = "no_storage_restrict"
+ private const val WINDOW_IGNORE_SECURE_KEY = "window_ignore_secure"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_security) {
+ override fun getNonIndexableKeys(context: Context): List {
+ return super.getNonIndexableKeys(context)
+ }
+ }
+ }
+
+ private lateinit var mHideScreenCapturePref: Preference
+ private lateinit var mNoStorageRestrictPref: Preference
+ private lateinit var mWindowIgnoreSecurePref: Preference
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.rising_settings_security)
+
+ mHideScreenCapturePref = findPreference(HIDE_SCREEN_CAPTURE_STATUS_KEY)!!
+ mNoStorageRestrictPref = findPreference(NO_STORAGE_RESTRICT_KEY)!!
+ mWindowIgnoreSecurePref = findPreference(WINDOW_IGNORE_SECURE_KEY)!!
+
+ mHideScreenCapturePref.onPreferenceChangeListener = this
+ mNoStorageRestrictPref.onPreferenceChangeListener = this
+ mWindowIgnoreSecurePref.onPreferenceChangeListener = this
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
+ return when (preference) {
+ mHideScreenCapturePref, mNoStorageRestrictPref, mWindowIgnoreSecurePref -> {
+ SystemRestartUtils.showSystemRestartDialog(context)
+ true
+ }
+ else -> false
+ }
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/SmartPowerOff.java b/src/com/rising/settings/fragments/SmartPowerOff.java
deleted file mode 100644
index a0d78e83..00000000
--- a/src/com/rising/settings/fragments/SmartPowerOff.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.app.TimePickerDialog;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.text.format.DateFormat;
-import android.widget.TimePicker;
-
-import androidx.preference.Preference;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.Calendar;
-import java.util.List;
-
-@SearchIndexable
-public class SmartPowerOff extends SettingsPreferenceFragment {
-
- private static final String TAG = "SmartPowerOff";
-
- private static final String REBOOT_TIME_KEY = "smart_power_off_time";
- private static final String REBOOT_TIME_PREFERENCE_KEY = "power_off_time_preference";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.rising_settings_smart_power_off);
-
- Preference timePreference = findPreference(REBOOT_TIME_PREFERENCE_KEY);
- if (timePreference != null) {
- timePreference.setOnPreferenceClickListener(preference -> {
- showTimePicker();
- return true;
- });
- updateRebootTimeSummary(timePreference);
- }
- }
-
- private void showTimePicker() {
- Calendar calendar = Calendar.getInstance();
- int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
- int currentMinute = calendar.get(Calendar.MINUTE);
- int hour = (currentHour + 1) % 24;
- TimePickerDialog timePickerDialog = new TimePickerDialog(getContext(),
- (view, hourOfDay, minute) -> {
- saveRebootTime(hourOfDay, minute);
- },
- hour, currentMinute, DateFormat.is24HourFormat(getContext()));
-
- timePickerDialog.show();
- }
-
- private void saveRebootTime(int hourOfDay, int minute) {
- Calendar currentCalendar = Calendar.getInstance();
- Calendar selectedCalendar = Calendar.getInstance();
- selectedCalendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
- selectedCalendar.set(Calendar.MINUTE, minute);
- selectedCalendar.set(Calendar.SECOND, 0);
- selectedCalendar.set(Calendar.MILLISECOND, 0);
- if (selectedCalendar.getTimeInMillis() <= currentCalendar.getTimeInMillis()) {
- selectedCalendar.add(Calendar.DAY_OF_YEAR, 1);
- }
- String timeValue = String.format("%02d:%02d", selectedCalendar.get(Calendar.HOUR_OF_DAY), selectedCalendar.get(Calendar.MINUTE));
- ContentResolver resolver = getContext().getContentResolver();
- Settings.System.putString(resolver, REBOOT_TIME_KEY, timeValue);
- Preference timePreference = findPreference(REBOOT_TIME_PREFERENCE_KEY);
- if (timePreference != null) {
- updateRebootTimeSummary(timePreference);
- }
- }
-
- private void updateRebootTimeSummary(Preference timePreference) {
- String timeValue = Settings.System.getString(getContext().getContentResolver(), REBOOT_TIME_KEY);
- if (timeValue != null) {
- timePreference.setSummary(getContext().getString(R.string.smart_power_off_desc) + " " + timeValue);
- } else {
- timePreference.setSummary(getContext().getString(R.string.smart_power_off_time_summary));
- }
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_smart_power_off) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/SmartPowerOff.kt b/src/com/rising/settings/fragments/SmartPowerOff.kt
new file mode 100644
index 00000000..8d91d8e8
--- /dev/null
+++ b/src/com/rising/settings/fragments/SmartPowerOff.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class SmartPowerOff : OptimizedSettingsFragment() {
+
+ companion object {
+ const val TAG = "SmartPowerOff"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_smart_power_off) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context).toMutableList()
+ return keys
+ }
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.rising_settings_smart_power_off)
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/Sound.java b/src/com/rising/settings/fragments/Sound.java
deleted file mode 100644
index cfe24e7a..00000000
--- a/src/com/rising/settings/fragments/Sound.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.content.Context;
-import android.os.Bundle;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.List;
-
-@SearchIndexable
-public class Sound extends SettingsPreferenceFragment {
-
- public static final String TAG = "Sound";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.rising_settings_sound);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_sound) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/Sound.kt b/src/com/rising/settings/fragments/Sound.kt
new file mode 100644
index 00000000..cea0558a
--- /dev/null
+++ b/src/com/rising/settings/fragments/Sound.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016-2024 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class Sound : OptimizedSettingsFragment() {
+
+ companion object {
+ const val TAG = "Sound"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_sound) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context).toMutableList()
+ return keys
+ }
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.rising_settings_sound)
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/Spoof.java b/src/com/rising/settings/fragments/Spoof.java
deleted file mode 100644
index 6256c864..00000000
--- a/src/com/rising/settings/fragments/Spoof.java
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.SystemProperties;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.util.Log;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.Toast;
-import android.provider.Settings;
-
-import androidx.activity.result.ActivityResultLauncher;
-import androidx.activity.result.contract.ActivityResultContracts;
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.util.android.SystemRestartUtils;
-import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import com.android.settings.preferences.KeyboxDataPreference;
-import com.android.settings.preferences.SystemPropertySwitchPreference;
-import com.android.settings.utils.DeviceUtils;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-@SearchIndexable
-public class Spoof extends SettingsPreferenceFragment implements
- Preference.OnPreferenceChangeListener {
-
- private static final String TAG = "Spoof";
-
- private static final String KEY_PIF_JSON_FILE_PREFERENCE = "pif_json_file_preference";
- private static final String KEY_SYSTEM_WIDE_CATEGORY = "spoofing_system_wide_category";
- private static final String KEY_UPDATE_JSON_BUTTON = "update_pif_json";
- private static final String SYS_GMS_SPOOF = "persist.sys.pixelprops.gms";
- private static final String SYS_GOOGLE_SPOOF = "persist.sys.pixelprops";
- private static final String SYS_GAMEPROP_SPOOF = "persist.sys.pixelprops.games";
- private static final String SYS_GPHOTOS_SPOOF = "persist.sys.pixelprops.gphotos";
- private static final String SYS_QSB_SPOOF = "persist.sys.pixelprops.qsb";
- private static final String SYS_SNAP_SPOOF = "persist.sys.pixelprops.snap";
- private static final String SYS_VENDING_SPOOF = "persist.sys.pixelprops.vending";
- private static final String SYS_ENABLE_TENSOR_FEATURES = "persist.sys.features.tensor";
- private static final String KEYBOX_DATA_KEY = "keybox_data_setting";
-
- private ActivityResultLauncher mKeyboxFilePickerLauncher;
- private KeyboxDataPreference mKeyboxDataPreference;
- private Preference mPifJsonFilePreference;
- private Preference mUpdateJsonButton;
- private PreferenceCategory mSystemWideCategory;
- private SystemPropertySwitchPreference mGmsSpoof;
- private SystemPropertySwitchPreference mGoogleSpoof;
- private SystemPropertySwitchPreference mGamePropsSpoof;
- private SystemPropertySwitchPreference mGphotosSpoof;
- private SystemPropertySwitchPreference mQsbSpoof;
- private SystemPropertySwitchPreference mSnapSpoof;
- private SystemPropertySwitchPreference mVendingSpoof;
- private SystemPropertySwitchPreference mTensorFeaturesToggle;
- private Preference mWikiLink;
-
- private Handler mHandler;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mHandler = new Handler();
- addPreferencesFromResource(R.xml.rising_settings_spoof);
-
- final Context context = getContext();
- final ContentResolver resolver = context.getContentResolver();
- final PreferenceScreen prefScreen = getPreferenceScreen();
- final Resources resources = context.getResources();
-
- mSystemWideCategory = (PreferenceCategory) findPreference(KEY_SYSTEM_WIDE_CATEGORY);
- mGamePropsSpoof = (SystemPropertySwitchPreference) findPreference(SYS_GAMEPROP_SPOOF);
- mGphotosSpoof = (SystemPropertySwitchPreference) findPreference(SYS_GPHOTOS_SPOOF);
- mGmsSpoof = (SystemPropertySwitchPreference) findPreference(SYS_GMS_SPOOF);
- mGoogleSpoof = (SystemPropertySwitchPreference) findPreference(SYS_GOOGLE_SPOOF);
- mPifJsonFilePreference = findPreference(KEY_PIF_JSON_FILE_PREFERENCE);
- mQsbSpoof = (SystemPropertySwitchPreference) findPreference(SYS_QSB_SPOOF);
- mSnapSpoof = (SystemPropertySwitchPreference) findPreference(SYS_SNAP_SPOOF);
- mVendingSpoof = (SystemPropertySwitchPreference) findPreference(SYS_VENDING_SPOOF);
- mUpdateJsonButton = findPreference(KEY_UPDATE_JSON_BUTTON);
- mTensorFeaturesToggle = (SystemPropertySwitchPreference) findPreference(SYS_ENABLE_TENSOR_FEATURES);
-
- String model = SystemProperties.get("ro.product.model");
- boolean isTensorDevice = model.matches("Pixel [6-9][a-zA-Z ]*");
- boolean isPixelGmsEnabled = SystemProperties.getBoolean(SYS_GMS_SPOOF, true); // Default to Pixel GMS
-
- if (DeviceUtils.isCurrentlySupportedPixel()) {
- mGoogleSpoof.setDefaultValue(false);
- if (isMainlineTensorModel(model)) {
- mSystemWideCategory.removePreference(mGoogleSpoof);
- }
- }
-
- if (isTensorDevice) {
- mSystemWideCategory.removePreference(mTensorFeaturesToggle);
- }
-
- mGmsSpoof.setOnPreferenceChangeListener(this);
- mGoogleSpoof.setOnPreferenceChangeListener(this);
- mGphotosSpoof.setOnPreferenceChangeListener(this);
- mGamePropsSpoof.setOnPreferenceChangeListener(this);
- mQsbSpoof.setOnPreferenceChangeListener(this);
- mSnapSpoof.setOnPreferenceChangeListener(this);
- mVendingSpoof.setOnPreferenceChangeListener(this);
- mTensorFeaturesToggle.setOnPreferenceChangeListener(this);
-
- mKeyboxFilePickerLauncher = registerForActivityResult(
- new ActivityResultContracts.StartActivityForResult(),
- result -> {
- if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
- Uri uri = result.getData().getData();
- Preference pref = findPreference(KEYBOX_DATA_KEY);
- if (pref instanceof KeyboxDataPreference) {
- ((KeyboxDataPreference) pref).handleFileSelected(uri);
- }
- }
- }
- );
-
- mPifJsonFilePreference.setOnPreferenceClickListener(preference -> {
- openFileSelector(10001);
- return true;
- });
-
- mUpdateJsonButton.setOnPreferenceClickListener(preference -> {
- updatePropertiesFromUrl("https://raw.githubusercontent.com/RisingOS-Revived/risingOS_wiki/refs/heads/fifteen/spoofing/PlayIntergrity/pif.json");
- return true;
- });
-
- mWikiLink = findPreference("wiki_link");
- if (mWikiLink != null) {
- mWikiLink.setOnPreferenceClickListener(preference -> {
- Uri uri = Uri.parse("https://github.com/RisingOS-Revived/risingOS_wiki");
- Intent intent = new Intent(Intent.ACTION_VIEW, uri);
- startActivity(intent);
- return true;
- });
- }
-
- Preference showPropertiesPref = findPreference("show_pif_properties");
- if (showPropertiesPref != null) {
- showPropertiesPref.setOnPreferenceClickListener(preference -> {
- showPropertiesDialog();
- return true;
- });
- }
- }
-
- private boolean isMainlineTensorModel(String model) {
- return model.matches("Pixel [8-9][a-zA-Z ]*");
- }
-
- private void openFileSelector(int requestCode) {
- Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
- intent.setType("application/json");
- startActivityForResult(intent, requestCode);
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- mKeyboxDataPreference = findPreference(KEYBOX_DATA_KEY);
- if (mKeyboxDataPreference != null) {
- mKeyboxDataPreference.setFilePickerLauncher(mKeyboxFilePickerLauncher);
- }
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (resultCode == Activity.RESULT_OK && data != null) {
- Uri uri = data.getData();
- if (uri != null) {
- if (requestCode == 10001) {
- loadPifJson(uri);
- }
- }
- }
- }
-
- private void showPropertiesDialog() {
- StringBuilder properties = new StringBuilder();
- try {
- JSONObject jsonObject = new JSONObject();
- String[] keys = {
- "persist.sys.pihooks_ID",
- "persist.sys.pihooks_BRAND",
- "persist.sys.pihooks_DEVICE",
- "persist.sys.pihooks_FINGERPRINT",
- "persist.sys.pihooks_MANUFACTURER",
- "persist.sys.pihooks_MODEL",
- "persist.sys.pihooks_PRODUCT",
- "persist.sys.pihooks_SECURITY_PATCH",
- "persist.sys.pihooks_DEVICE_INITIAL_SDK_INT",
- "persist.sys.pihooks_RELEASE",
- "persist.sys.pihooks_SDK_INT"
- };
- for (String key : keys) {
- String value = SystemProperties.get(key, null);
- if (value != null) {
- String buildKey = key.replace("persist.sys.pihooks_", "");
- jsonObject.put(buildKey, value);
- }
- }
- properties.append(jsonObject.toString(4));
- } catch (JSONException e) {
- Log.e(TAG, "Error creating JSON from properties", e);
- properties.append(getString(R.string.error_loading_properties));
- }
- new AlertDialog.Builder(getContext())
- .setTitle(R.string.show_pif_properties_title)
- .setMessage(properties.toString())
- .setPositiveButton(android.R.string.ok, null)
- .show();
- }
-
- private void updatePropertiesFromUrl(String urlString) {
- new Thread(() -> {
- try {
- URL url = new URL(urlString);
- HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
- try (InputStream inputStream = urlConnection.getInputStream()) {
- String json = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
- Log.d(TAG, "Downloaded JSON data: " + json);
- JSONObject jsonObject = new JSONObject(json);
- String spoofedModel = jsonObject.optString("MODEL", "Unknown model");
- for (Iterator it = jsonObject.keys(); it.hasNext(); ) {
- String key = it.next();
- String value = jsonObject.getString(key);
- Log.d(TAG, "Setting property: persist.sys.pihooks_" + key + " = " + value);
- SystemProperties.set("persist.sys.pihooks_" + key, value);
- }
- mHandler.post(() -> {
- String toastMessage = getString(R.string.toast_spoofing_success, spoofedModel);
- Toast.makeText(getContext(), toastMessage, Toast.LENGTH_LONG).show();
- });
-
- } finally {
- urlConnection.disconnect();
- }
- } catch (Exception e) {
- Log.e(TAG, "Error downloading JSON or setting properties", e);
- mHandler.post(() -> {
- Toast.makeText(getContext(), R.string.toast_spoofing_failure, Toast.LENGTH_LONG).show();
- });
- }
- mHandler.postDelayed(() -> {
- SystemRestartUtils.showSystemRestartDialog(getContext());
- }, 1250);
- }).start();
- }
-
- private void loadPifJson(Uri uri) {
- Log.d(TAG, "Loading PIF JSON from URI: " + uri.toString());
- try (InputStream inputStream = getActivity().getContentResolver().openInputStream(uri)) {
- if (inputStream != null) {
- String json = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
- Log.d(TAG, "PIF JSON data: " + json);
- JSONObject jsonObject = new JSONObject(json);
- for (Iterator it = jsonObject.keys(); it.hasNext(); ) {
- String key = it.next();
- String value = jsonObject.getString(key);
- Log.d(TAG, "Setting PIF property: persist.sys.pihooks_" + key + " = " + value);
- SystemProperties.set("persist.sys.pihooks_" + key, value);
- }
- }
- } catch (Exception e) {
- Log.e(TAG, "Error reading PIF JSON or setting properties", e);
- }
- mHandler.postDelayed(() -> {
- SystemRestartUtils.showSystemRestartDialog(getContext());
- }, 1250);
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- final Context context = getContext();
- final ContentResolver resolver = context.getContentResolver();
- if (preference == mGmsSpoof
- || preference == mGoogleSpoof
- || preference == mGphotosSpoof
- || preference == mGamePropsSpoof
- || preference == mQsbSpoof
- || preference == mSnapSpoof
- || preference == mVendingSpoof) {
- SystemRestartUtils.showSystemRestartDialog(getContext());
- return true;
- }
- if (preference == mTensorFeaturesToggle) {
- boolean enabled = (Boolean) newValue;
- SystemProperties.set(SYS_ENABLE_TENSOR_FEATURES, enabled ? "true" : "false");
- SystemRestartUtils.showSystemRestartDialog(getContext());
- return true;
- }
- return false;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.VIEW_UNKNOWN;
- }
-
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_spoof) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
- final Resources resources = context.getResources();
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/Spoof.kt b/src/com/rising/settings/fragments/Spoof.kt
new file mode 100644
index 00000000..0c7816c0
--- /dev/null
+++ b/src/com/rising/settings/fragments/Spoof.kt
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.app.Activity
+import android.app.ActivityManager
+import android.app.AlertDialog
+import android.content.ContentResolver
+import android.content.Context
+import android.content.Intent
+import android.content.res.Resources
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.os.SystemProperties
+import android.util.Log
+import android.view.View
+import android.widget.Toast
+import androidx.activity.result.ActivityResultLauncher
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.preference.Preference
+import androidx.preference.PreferenceCategory
+import androidx.preference.PreferenceScreen
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent
+import com.android.internal.util.android.SystemRestartUtils
+import com.android.settings.R
+import com.android.settings.SettingsPreferenceFragment
+import com.android.settings.preferences.KeyboxDataPreference
+import com.android.settings.preferences.SystemPropertySwitchPreference
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settings.utils.DeviceUtils
+import com.android.settingslib.search.SearchIndexable
+import org.json.JSONException
+import org.json.JSONObject
+import java.io.InputStream
+import java.net.HttpURLConnection
+import java.net.URL
+import java.nio.charset.StandardCharsets
+
+@SearchIndexable
+class Spoof : SettingsPreferenceFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ private const val TAG = "Spoof"
+
+ private const val KEY_PIF_JSON_FILE_PREFERENCE = "pif_json_file_preference"
+ private const val KEY_SYSTEM_WIDE_CATEGORY = "spoofing_system_wide_category"
+ private const val KEY_UPDATE_JSON_BUTTON = "update_pif_json"
+ private const val SYS_GMS_SPOOF = "persist.sys.pixelprops.gms"
+ private const val SYS_GOOGLE_SPOOF = "persist.sys.pixelprops"
+ private const val SYS_GAMEPROP_SPOOF = "persist.sys.pixelprops.games"
+ private const val SYS_GPHOTOS_SPOOF = "persist.sys.pixelprops.gphotos"
+ private const val SYS_QSB_SPOOF = "persist.sys.pixelprops.qsb"
+ private const val SYS_SNAP_SPOOF = "persist.sys.pixelprops.snap"
+ private const val SYS_TENSOR_SPOOF = "persist.sys.features.tensor"
+ private const val SYS_KEYBOX_CHECK_ENABLED = "persist.sys.keybox.check.enabled"
+ private const val KEYBOX_DATA_KEY = "keybox_data_setting"
+
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_spoof) {
+ override fun getNonIndexableKeys(context: Context): List {
+ return super.getNonIndexableKeys(context)
+ }
+ }
+ }
+
+ private lateinit var mKeyboxFilePickerLauncher: ActivityResultLauncher
+ private var mKeyboxDataPreference: KeyboxDataPreference? = null
+ private var mPifJsonFilePreference: Preference? = null
+ private var mUpdateJsonButton: Preference? = null
+ private var mSystemWideCategory: PreferenceCategory? = null
+ private var mGmsSpoof: SystemPropertySwitchPreference? = null
+ private var mGoogleSpoof: SystemPropertySwitchPreference? = null
+ private var mGamePropsSpoof: SystemPropertySwitchPreference? = null
+ private var mGphotosSpoof: SystemPropertySwitchPreference? = null
+ private var mQsbSpoof: SystemPropertySwitchPreference? = null
+ private var mSnapSpoof: SystemPropertySwitchPreference? = null
+ private var mTensorSpoof: SystemPropertySwitchPreference? = null
+ private var mKeyboxCheckEnabled: SystemPropertySwitchPreference? = null
+ private var mWikiLink: Preference? = null
+
+ private lateinit var mHandler: Handler
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ mHandler = Handler(Looper.getMainLooper())
+ addPreferencesFromResource(R.xml.rising_settings_spoof)
+
+ val context = requireContext()
+ val resolver = context.contentResolver
+ val prefScreen = preferenceScreen
+ val resources = context.resources
+
+ mSystemWideCategory = findPreference(KEY_SYSTEM_WIDE_CATEGORY)
+ mGamePropsSpoof = findPreference(SYS_GAMEPROP_SPOOF)
+ mGphotosSpoof = findPreference(SYS_GPHOTOS_SPOOF)
+ mGmsSpoof = findPreference(SYS_GMS_SPOOF)
+ mGoogleSpoof = findPreference(SYS_GOOGLE_SPOOF)
+ mPifJsonFilePreference = findPreference(KEY_PIF_JSON_FILE_PREFERENCE)
+ mQsbSpoof = findPreference(SYS_QSB_SPOOF)
+ mSnapSpoof = findPreference(SYS_SNAP_SPOOF)
+ mTensorSpoof = findPreference(SYS_TENSOR_SPOOF)
+ mUpdateJsonButton = findPreference(KEY_UPDATE_JSON_BUTTON)
+ mKeyboxCheckEnabled = findPreference(SYS_KEYBOX_CHECK_ENABLED)
+
+ val model = SystemProperties.get("ro.product.model")
+ val isTensorDevice = model.matches(Regex("Pixel (6|7|8|9|10)[a-zA-Z ]*"))
+ val isPixelGmsEnabled = SystemProperties.getBoolean(SYS_GMS_SPOOF, true) // Default to Pixel GMS
+
+ if (DeviceUtils.isCurrentlySupportedPixel()) {
+ mGoogleSpoof?.setDefaultValue(false)
+ if (isMainlineTensorModel(model)) {
+ mGoogleSpoof?.let { mSystemWideCategory?.removePreference(it as Preference) }
+ }
+ }
+
+ if (isTensorDevice) {
+ mTensorSpoof?.let { mSystemWideCategory?.removePreference(it as Preference) }
+ }
+
+ mGmsSpoof?.onPreferenceChangeListener = this
+ mGoogleSpoof?.onPreferenceChangeListener = this
+ mGphotosSpoof?.onPreferenceChangeListener = this
+ mGamePropsSpoof?.onPreferenceChangeListener = this
+ mQsbSpoof?.onPreferenceChangeListener = this
+ mSnapSpoof?.onPreferenceChangeListener = this
+ mTensorSpoof?.onPreferenceChangeListener = this
+ mKeyboxCheckEnabled?.onPreferenceChangeListener = this
+
+ mKeyboxFilePickerLauncher = registerForActivityResult(
+ ActivityResultContracts.StartActivityForResult()
+ ) { result ->
+ if (result.resultCode == Activity.RESULT_OK && result.data != null) {
+ val uri = result.data?.data
+ val pref = findPreference(KEYBOX_DATA_KEY)
+ if (uri != null && pref != null) {
+ pref.handleFileSelected(uri)
+ }
+ }
+ }
+
+ mPifJsonFilePreference?.setOnPreferenceClickListener {
+ openFileSelector(10001)
+ true
+ }
+
+ mUpdateJsonButton?.setOnPreferenceClickListener {
+ updatePropertiesFromUrl("https://raw.githubusercontent.com/RisingOS-Revived/risingOS_wiki/refs/heads/fifteen/spoofing/PlayIntergrity/pif.json")
+ true
+ }
+
+ mWikiLink = findPreference("wiki_link")
+ mWikiLink?.setOnPreferenceClickListener {
+ val uri = Uri.parse("https://github.com/RisingOS-Revived/risingOS_wiki")
+ val intent = Intent(Intent.ACTION_VIEW, uri)
+ startActivity(intent)
+ true
+ }
+
+ val showPropertiesPref = findPreference("show_pif_properties")
+ showPropertiesPref?.setOnPreferenceClickListener {
+ showPropertiesDialog()
+ true
+ }
+ }
+
+ private fun isMainlineTensorModel(model: String): Boolean {
+ return model.matches(Regex("Pixel (8|9|10)[a-zA-Z ]*"))
+ }
+
+ private fun openFileSelector(requestCode: Int) {
+ val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
+ type = "application/json"
+ }
+ @Suppress("DEPRECATION")
+ startActivityForResult(intent, requestCode)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ mKeyboxDataPreference = findPreference(KEYBOX_DATA_KEY)
+ mKeyboxDataPreference?.setFilePickerLauncher(mKeyboxFilePickerLauncher)
+ }
+
+ @Suppress("DEPRECATION")
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ if (resultCode == Activity.RESULT_OK && data != null) {
+ val uri = data.data
+ if (uri != null && requestCode == 10001) {
+ loadPifJson(uri)
+ }
+ }
+ }
+
+ private fun showPropertiesDialog() {
+ val properties = StringBuilder()
+ try {
+ val jsonObject = JSONObject()
+ val keys = arrayOf(
+ "persist.sys.pihooks_ID",
+ "persist.sys.pihooks_BRAND",
+ "persist.sys.pihooks_DEVICE",
+ "persist.sys.pihooks_FINGERPRINT",
+ "persist.sys.pihooks_MANUFACTURER",
+ "persist.sys.pihooks_MODEL",
+ "persist.sys.pihooks_PRODUCT",
+ "persist.sys.pihooks_SECURITY_PATCH",
+ "persist.sys.pihooks_DEVICE_INITIAL_SDK_INT",
+ "persist.sys.pihooks_RELEASE",
+ "persist.sys.pihooks_SDK_INT"
+ )
+
+ for (key in keys) {
+ val value = SystemProperties.get(key, null)
+ if (value != null) {
+ val buildKey = key.replace("persist.sys.pihooks_", "")
+ jsonObject.put(buildKey, value)
+ }
+ }
+ properties.append(jsonObject.toString(4))
+ } catch (e: JSONException) {
+ Log.e(TAG, "Error creating JSON from properties", e)
+ properties.append(getString(R.string.error_loading_properties))
+ }
+
+ AlertDialog.Builder(requireContext())
+ .setTitle(R.string.show_pif_properties_title)
+ .setMessage(properties.toString())
+ .setPositiveButton(android.R.string.ok, null)
+ .show()
+ }
+
+ /**
+ * Kill packages that need to be restarted to pick up new PIF properties
+ */
+ private fun killGMSPackages() {
+ try {
+ val am = requireContext().getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+ val packages = arrayOf(
+ "com.google.android.apps.photos",
+ "com.google.android.gms",
+ "com.google.android.googlequicksearchbox",
+ "com.android.vending",
+ "com.snapchat.android"
+ )
+ for (pkg in packages) {
+ am.javaClass
+ .getMethod("forceStopPackage", String::class.java)
+ .invoke(am, pkg)
+ Log.i(TAG, "$pkg process killed")
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, "Failed to kill packages", e)
+ }
+ }
+
+ private fun updatePropertiesFromUrl(urlString: String) {
+ Thread {
+ try {
+ val url = URL(urlString)
+ val urlConnection = url.openConnection() as HttpURLConnection
+ try {
+ urlConnection.inputStream.use { inputStream ->
+ val json = String(inputStream.readAllBytes(), StandardCharsets.UTF_8)
+ Log.d(TAG, "Downloaded JSON data: $json")
+ val jsonObject = JSONObject(json)
+ val spoofedModel = jsonObject.optString("MODEL", "Unknown model")
+
+ val keys = jsonObject.keys()
+ while (keys.hasNext()) {
+ val key = keys.next()
+ val value = jsonObject.getString(key)
+ Log.d(TAG, "Setting property: persist.sys.pihooks_$key = $value")
+ SystemProperties.set("persist.sys.pihooks_$key", value)
+ }
+
+ mHandler.post {
+ val toastMessage = getString(R.string.toast_spoofing_success, spoofedModel)
+ Toast.makeText(requireContext(), toastMessage, Toast.LENGTH_LONG).show()
+ killGMSPackages()
+ }
+ }
+ } finally {
+ urlConnection.disconnect()
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, "Error downloading JSON or setting properties", e)
+ mHandler.post {
+ Toast.makeText(requireContext(), R.string.toast_spoofing_failure, Toast.LENGTH_LONG).show()
+ }
+ }
+ }.start()
+ }
+
+ private fun loadPifJson(uri: Uri) {
+ Log.d(TAG, "Loading PIF JSON from URI: $uri")
+ try {
+ requireActivity().contentResolver.openInputStream(uri)?.use { inputStream ->
+ val json = String(inputStream.readAllBytes(), StandardCharsets.UTF_8)
+ Log.d(TAG, "PIF JSON data: $json")
+ val jsonObject = JSONObject(json)
+
+ val keys = jsonObject.keys()
+ while (keys.hasNext()) {
+ val key = keys.next()
+ val value = jsonObject.getString(key)
+ Log.d(TAG, "Setting PIF property: persist.sys.pihooks_$key = $value")
+ SystemProperties.set("persist.sys.pihooks_$key", value)
+ }
+ killGMSPackages()
+ Toast.makeText(requireContext(), "PIF JSON loaded and packages refreshed", Toast.LENGTH_SHORT).show()
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, "Error reading PIF JSON or setting properties", e)
+ Toast.makeText(requireContext(), "Error loading PIF JSON", Toast.LENGTH_SHORT).show()
+ }
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ val context = requireContext()
+ val resolver = context.contentResolver
+
+ when (preference) {
+ mGmsSpoof, mGphotosSpoof, mQsbSpoof, mSnapSpoof -> {
+ killGMSPackages()
+ return true
+ }
+ mGoogleSpoof, mGamePropsSpoof -> {
+ SystemRestartUtils.showSystemRestartDialog(requireContext())
+ return true
+ }
+ mTensorSpoof -> {
+ val enabled = newValue as Boolean
+ SystemProperties.set(SYS_TENSOR_SPOOF, if (enabled) "true" else "false")
+ SystemRestartUtils.showSystemRestartDialog(requireContext())
+ return true
+ }
+ mKeyboxCheckEnabled -> {
+ killGMSPackages()
+ return true
+ }
+ }
+ return false
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/StatusBar.java b/src/com/rising/settings/fragments/StatusBar.java
deleted file mode 100644
index 742d6bd0..00000000
--- a/src/com/rising/settings/fragments/StatusBar.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.content.Context;
-import android.os.Bundle;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import com.android.settings.preferences.CustomSeekBarPreference;
-
-import java.util.List;
-
-@SearchIndexable
-public class StatusBar extends SettingsPreferenceFragment {
-
- public static final String TAG = "StatusBar";
-
- private static final String KEY_STATUSBAR_TOP_PADDING = "statusbar_top_padding";
- private static final String KEY_STATUSBAR_LEFT_PADDING = "statusbar_left_padding";
- private static final String KEY_STATUSBAR_RIGHT_PADDING = "statusbar_right_padding";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.rising_settings_status_bar);
-
- CustomSeekBarPreference leftSeekBar = findPreference(KEY_STATUSBAR_LEFT_PADDING);
- int defaultLeftPadding = getResources().getDimensionPixelSize(com.android.internal.R.dimen.status_bar_padding_start);
- leftSeekBar.setDefaultValue(defaultLeftPadding, true);
-
- CustomSeekBarPreference rightSeekBar = findPreference(KEY_STATUSBAR_RIGHT_PADDING);
- int defaultRightPadding = getResources().getDimensionPixelSize(com.android.internal.R.dimen.status_bar_padding_end);
- rightSeekBar.setDefaultValue(defaultRightPadding, true);
-
- CustomSeekBarPreference topSeekbar = findPreference(KEY_STATUSBAR_TOP_PADDING);
- int defaultTopPadding = getResources().getDimensionPixelSize(com.android.internal.R.dimen.status_bar_padding_top);
- topSeekbar.setDefaultValue(defaultTopPadding, true);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_status_bar) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/StatusBar.kt b/src/com/rising/settings/fragments/StatusBar.kt
new file mode 100644
index 00000000..178a28cb
--- /dev/null
+++ b/src/com/rising/settings/fragments/StatusBar.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.preferences.CustomSeekBarPreference
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class StatusBar : OptimizedSettingsFragment() {
+
+ companion object {
+ const val TAG = "StatusBar"
+
+ private const val KEY_STATUSBAR_TOP_PADDING = "statusbar_top_padding"
+ private const val KEY_STATUSBAR_LEFT_PADDING = "statusbar_left_padding"
+ private const val KEY_STATUSBAR_RIGHT_PADDING = "statusbar_right_padding"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_status_bar) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context).toMutableList()
+ return keys
+ }
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.rising_settings_status_bar)
+
+ // Use cached preference lookup for better performance
+ val leftSeekBar = findCachedPreference(KEY_STATUSBAR_LEFT_PADDING)
+ leftSeekBar?.let { seekBar ->
+ resources?.let { res ->
+ val defaultLeftPadding = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_padding_start)
+ seekBar.setDefaultValue(defaultLeftPadding, true)
+ }
+ }
+
+ val rightSeekBar = findCachedPreference(KEY_STATUSBAR_RIGHT_PADDING)
+ rightSeekBar?.let { seekBar ->
+ resources?.let { res ->
+ val defaultRightPadding = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_padding_end)
+ seekBar.setDefaultValue(defaultRightPadding, true)
+ }
+ }
+
+ val topSeekbar = findCachedPreference(KEY_STATUSBAR_TOP_PADDING)
+ topSeekbar?.let { seekBar ->
+ resources?.let { res ->
+ val defaultTopPadding = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_padding_top)
+ seekBar.setDefaultValue(defaultTopPadding, true)
+ }
+ }
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/Themes.java b/src/com/rising/settings/fragments/Themes.java
deleted file mode 100644
index ca65baab..00000000
--- a/src/com/rising/settings/fragments/Themes.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import androidx.preference.Preference;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.utils.SystemRestartUtils;
-import com.android.settingslib.search.SearchIndexable;
-
-import com.android.internal.util.android.ThemeUtils;
-
-import java.util.List;
-
-@SearchIndexable
-public class Themes extends SettingsPreferenceFragment implements
- Preference.OnPreferenceChangeListener {
-
- public static final String TAG = "Themes";
- private static final String KEY_PGB_STYLE = "progress_bar_style";
- private static final String KEY_NOTIF_STYLE = "notification_style";
- private static final String KEY_POWERMENU_STYLE = "powermenu_style";
- private static final String KEY_HIDE_IME_STYLE = "hide_ime_space_style";
-
- private static final String[] POWER_MENU_OVERLAYS = {
- "com.android.theme.powermenu.cyberpunk",
- "com.android.theme.powermenu.duoline",
- "com.android.theme.powermenu.ios",
- "com.android.theme.powermenu.layers"
- };
-
- private static final String[] NOTIF_OVERLAYS = {
- "com.android.theme.notification.cyberpunk",
- "com.android.theme.notification.duoline",
- "com.android.theme.notification.ios",
- "com.android.theme.notification.layers"
- };
-
- private static final String[] PROGRESS_BAR_OVERLAYS = {
- "com.android.theme.progressbar.blocky_thumb",
- "com.android.theme.progressbar.minimal_thumb",
- "com.android.theme.progressbar.outline_thumb",
- "com.android.theme.progressbar.shishu"
- };
-
- private static final String[] HIDE_IME_OVERLAYS = {
- "com.android.system.theme.hide_ime_space_narrow",
- "com.android.system.theme.hide_ime_space_no_space",
- };
-
- private ThemeUtils mThemeUtils;
- private Preference mProgressBarPref;
- private Preference mNotificationStylePref;
- private Preference mPowerMenuStylePref;
- private Preference mHideImePref;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.rising_settings_themes);
- mThemeUtils = ThemeUtils.getInstance(getActivity());
-
- mProgressBarPref = findPreference(KEY_PGB_STYLE);
- mProgressBarPref.setOnPreferenceChangeListener(this);
-
- mNotificationStylePref = findPreference(KEY_NOTIF_STYLE);
- mNotificationStylePref.setOnPreferenceChangeListener(this);
-
- mPowerMenuStylePref = findPreference(KEY_POWERMENU_STYLE);
- mPowerMenuStylePref.setOnPreferenceChangeListener(this);
-
- mHideImePref = findPreference(KEY_HIDE_IME_STYLE);
- mHideImePref.setOnPreferenceChangeListener(this);
-
- com.android.settingslib.widget.LayoutPreference highlightPref = getPreferenceScreen().findPreference("themes_highlight_dashboard");
- if (highlightPref != null) {
- java.util.Map highlightClickMap = new java.util.HashMap<>();
- highlightClickMap.put(R.id.boot_styles_tile, "PersonalizationsBSActivity");
- highlightClickMap.put(R.id.icon_pack_tile, "PersonalizationsIconPackActivity");
- highlightClickMap.put(R.id.settings_tile, "PersonalizationsSettingsUIActivity");
- highlightClickMap.put(R.id.wallpaper_styles_tile, "PersonalizationsWSActivity");
- com.android.settings.utils.HighlightPrefUtils.Companion.setupHighlightPref(getContext(), highlightPref, highlightClickMap);
- }
- }
-
- private void updateStyle(String key, String category, String target,
- int defaultValue, String[] overlayPackages, boolean restartSystemUI) {
- final int style = Settings.System.getIntForUser(
- getContext().getContentResolver(),
- key,
- defaultValue,
- UserHandle.USER_CURRENT
- );
- if (mThemeUtils == null) {
- mThemeUtils = ThemeUtils.getInstance(getContext());
- }
- mThemeUtils.setOverlayEnabled(category, target, target);
- if (style > 0 && style <= overlayPackages.length) {
- mThemeUtils.setOverlayEnabled(category, overlayPackages[style - 1], target);
- }
- if (restartSystemUI) {
- SystemRestartUtils.restartSystemUI(getContext());
- }
- }
-
- private void updatePowerMenuStyle() {
- updateStyle(KEY_POWERMENU_STYLE, "android.theme.customization.powermenu", "com.android.systemui", 0, POWER_MENU_OVERLAYS, false);
- }
-
- private void updateNotifStyle() {
- updateStyle(KEY_NOTIF_STYLE, "android.theme.customization.notification", "com.android.systemui", 0, NOTIF_OVERLAYS, true);
- }
-
- private void updateProgressBarStyle() {
- updateStyle(KEY_PGB_STYLE, "android.theme.customization.progress_bar", "android", 0, PROGRESS_BAR_OVERLAYS, false);
- }
-
- private void updateHideImeSpaceStyle() {
- updateStyle(KEY_HIDE_IME_STYLE, "android.theme.customization.hide_ime_space", "android", 0, HIDE_IME_OVERLAYS, false);
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- int value = Integer.parseInt((String) newValue);
-
- if (preference == mProgressBarPref) {
- Settings.System.putIntForUser(getActivity().getContentResolver(),
- KEY_PGB_STYLE, value, UserHandle.USER_CURRENT);
- updateProgressBarStyle();
- return true;
- } else if (preference == mNotificationStylePref) {
- Settings.System.putIntForUser(getActivity().getContentResolver(),
- KEY_NOTIF_STYLE, value, UserHandle.USER_CURRENT);
- updateNotifStyle();
- return true;
- } else if (preference == mPowerMenuStylePref) {
- Settings.System.putIntForUser(getActivity().getContentResolver(),
- KEY_POWERMENU_STYLE, value, UserHandle.USER_CURRENT);
- updatePowerMenuStyle();
- return true;
- } else if (preference == mHideImePref) {
- Settings.System.putIntForUser(getActivity().getContentResolver(),
- KEY_HIDE_IME_STYLE, value, UserHandle.USER_CURRENT);
- updateHideImeSpaceStyle();
- return true;
- }
- return false;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_themes) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/Themes.kt b/src/com/rising/settings/fragments/Themes.kt
new file mode 100644
index 00000000..42d632dd
--- /dev/null
+++ b/src/com/rising/settings/fragments/Themes.kt
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.Settings
+import androidx.preference.Preference
+import com.android.internal.logging.nano.MetricsProto
+import com.android.internal.util.android.ThemeUtils
+import com.android.settings.R
+import com.android.settings.SettingsPreferenceFragment
+import com.android.settings.preferences.GlobalSettingListPreference
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settings.utils.SystemRestartUtils
+import com.android.settingslib.search.SearchIndexable
+import java.util.concurrent.ConcurrentHashMap
+
+@SearchIndexable
+class Themes : SettingsPreferenceFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ const val TAG = "Themes"
+ private const val KEY_PGB_STYLE = "progress_bar_style"
+ private const val KEY_NOTIF_STYLE = "notification_style"
+ private const val KEY_POWERMENU_STYLE = "powermenu_style"
+ private const val KEY_HIDE_IME_STYLE = "hide_ime_space_style"
+ private const val KEY_LOCK_SOUND = "lock_sound"
+ private const val KEY_UNLOCK_SOUND = "unlock_sound"
+
+ private val POWER_MENU_OVERLAYS = arrayOf(
+ "com.android.theme.powermenu.cyberpunk",
+ "com.android.theme.powermenu.duoline",
+ "com.android.theme.powermenu.ios",
+ "com.android.theme.powermenu.layers"
+ )
+
+ private val NOTIF_OVERLAYS = arrayOf(
+ "com.android.theme.notification.cyberpunk",
+ "com.android.theme.notification.duoline",
+ "com.android.theme.powermenu.fluid",
+ "com.android.theme.notification.ios",
+ "com.android.theme.notification.layers"
+ )
+
+ private val PROGRESS_BAR_OVERLAYS = arrayOf(
+ "com.android.theme.progressbar.blocky_thumb",
+ "com.android.theme.progressbar.minimal_thumb",
+ "com.android.theme.progressbar.outline_thumb",
+ "com.android.theme.progressbar.shishu"
+ )
+
+ private val HIDE_IME_OVERLAYS = arrayOf(
+ "com.android.system.theme.hide_ime_space_narrow",
+ "com.android.system.theme.hide_ime_space_no_space"
+ )
+
+ // Cache keys
+ private const val CACHE_KEY_PROGRESS_BAR = "progress_bar_style"
+ private const val CACHE_KEY_NOTIFICATION = "notification_style"
+ private const val CACHE_KEY_POWER_MENU = "powermenu_style"
+ private const val CACHE_KEY_HIDE_IME = "hide_ime_style"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_themes) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context).toMutableList()
+ return keys
+ }
+ }
+ }
+
+ private var mThemeUtils: ThemeUtils? = null
+ private var mProgressBarPref: Preference? = null
+ private var mNotificationStylePref: Preference? = null
+ private var mPowerMenuStylePref: Preference? = null
+ private var mHideImePref: Preference? = null
+ private var mLockSound: GlobalSettingListPreference? = null
+ private var mUnlockSound: GlobalSettingListPreference? = null
+
+ // Cache for style states to prevent redundant operations
+ private val mStyleCache = ConcurrentHashMap()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.rising_settings_themes)
+
+ // Initialize ThemeUtils with null check
+ activity?.let { activity ->
+ mThemeUtils = ThemeUtils.getInstance(activity)
+ }
+
+ mProgressBarPref = findPreference(KEY_PGB_STYLE)
+ mProgressBarPref?.onPreferenceChangeListener = this
+
+ mNotificationStylePref = findPreference(KEY_NOTIF_STYLE)
+ mNotificationStylePref?.onPreferenceChangeListener = this
+
+ mPowerMenuStylePref = findPreference(KEY_POWERMENU_STYLE)
+ mPowerMenuStylePref?.onPreferenceChangeListener = this
+
+ mHideImePref = findPreference(KEY_HIDE_IME_STYLE)
+ mHideImePref?.onPreferenceChangeListener = this
+
+ mLockSound = findPreference(KEY_LOCK_SOUND)
+ mLockSound?.onPreferenceChangeListener = this
+ mUnlockSound = findPreference(KEY_UNLOCK_SOUND)
+ mUnlockSound?.onPreferenceChangeListener = this
+
+ // Initialize highlight preferences with null checks
+ preferenceScreen?.let { screen ->
+ val highlightPref = screen.findPreference("themes_highlight_dashboard")
+ highlightPref?.let { pref ->
+ context?.let { ctx ->
+ val highlightClickMap = hashMapOf().apply {
+ put(R.id.boot_styles_tile, "PersonalizationsBSActivity")
+ put(R.id.icon_pack_tile, "PersonalizationsIconPackActivity")
+ put(R.id.settings_tile, "PersonalizationsSettingsUIActivity")
+ put(R.id.wallpaper_styles_tile, "PersonalizationsWSActivity")
+ }
+ com.android.settings.utils.HighlightPrefUtils.setupHighlightPref(ctx, pref, highlightClickMap)
+ }
+ }
+ }
+ }
+
+ private fun updateStyle(key: String, category: String, target: String,
+ defaultValue: Int, overlayPackages: Array, restartSystemUI: Boolean) {
+ val style = Settings.System.getIntForUser(
+ context?.contentResolver,
+ key,
+ defaultValue,
+ UserHandle.USER_CURRENT
+ )
+
+ // Check cache to avoid redundant operations
+ val cachedStyle = mStyleCache[key]
+ if (cachedStyle != null && cachedStyle == style) {
+ return // Style hasn't changed, skip update
+ }
+
+ // Update cache
+ mStyleCache[key] = style
+
+ if (mThemeUtils == null && context != null) {
+ mThemeUtils = ThemeUtils.getInstance(context)
+ }
+
+ mThemeUtils?.let { themeUtils ->
+ themeUtils.setOverlayEnabled(category, target, target)
+ if (style > 0 && style <= overlayPackages.size) {
+ themeUtils.setOverlayEnabled(category, overlayPackages[style - 1], target)
+ }
+ }
+
+ if (restartSystemUI) {
+ context?.let { SystemRestartUtils.restartSystemUI(it) }
+ }
+ }
+
+ private fun updatePowerMenuStyle() {
+ updateStyle(KEY_POWERMENU_STYLE, "android.theme.customization.powermenu", "com.android.systemui", 0, POWER_MENU_OVERLAYS, false)
+ }
+
+ private fun updateNotifStyle() {
+ updateStyle(KEY_NOTIF_STYLE, "android.theme.customization.notification", "com.android.systemui", 0, NOTIF_OVERLAYS, true)
+ }
+
+ private fun updateProgressBarStyle() {
+ updateStyle(KEY_PGB_STYLE, "android.theme.customization.progress_bar", "android", 0, PROGRESS_BAR_OVERLAYS, false)
+ }
+
+ private fun updateHideImeSpaceStyle() {
+ updateStyle(KEY_HIDE_IME_STYLE, "android.theme.customization.hide_ime_space", "android", 0, HIDE_IME_OVERLAYS, false)
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
+ return when (preference) {
+ mLockSound, mUnlockSound -> {
+ context?.let { SystemRestartUtils.showSystemUIRestartDialog(it) }
+ true
+ }
+
+ mProgressBarPref -> {
+ val value = (newValue as String).toInt()
+ Settings.System.putIntForUser(activity?.contentResolver,
+ KEY_PGB_STYLE, value, UserHandle.USER_CURRENT)
+ updateProgressBarStyle()
+ true
+ }
+
+ mNotificationStylePref -> {
+ val value = (newValue as String).toInt()
+ Settings.System.putIntForUser(activity?.contentResolver,
+ KEY_NOTIF_STYLE, value, UserHandle.USER_CURRENT)
+ updateNotifStyle()
+ true
+ }
+
+ mPowerMenuStylePref -> {
+ val value = (newValue as String).toInt()
+ Settings.System.putIntForUser(activity?.contentResolver,
+ KEY_POWERMENU_STYLE, value, UserHandle.USER_CURRENT)
+ updatePowerMenuStyle()
+ true
+ }
+
+ mHideImePref -> {
+ val value = (newValue as String).toInt()
+ Settings.System.putIntForUser(activity?.contentResolver,
+ KEY_HIDE_IME_STYLE, value, UserHandle.USER_CURRENT)
+ updateHideImeSpaceStyle()
+ true
+ }
+
+ else -> false
+ }
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ // Clear cache and cleanup resources
+ mStyleCache.clear()
+ mThemeUtils = null
+ }
+
+ override fun onDetach() {
+ super.onDetach()
+ // Additional cleanup
+ mStyleCache.clear()
+ }
+}
diff --git a/src/com/rising/settings/fragments/Toolbox.java b/src/com/rising/settings/fragments/Toolbox.java
deleted file mode 100644
index 908d7fa7..00000000
--- a/src/com/rising/settings/fragments/Toolbox.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.content.Context;
-import android.os.Bundle;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.List;
-
-@SearchIndexable
-public class Toolbox extends SettingsPreferenceFragment {
-
- public static final String TAG = "Toolbox";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.rising_settings_toolbox);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_toolbox) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/Toolbox.kt b/src/com/rising/settings/fragments/Toolbox.kt
new file mode 100644
index 00000000..6f38fe4c
--- /dev/null
+++ b/src/com/rising/settings/fragments/Toolbox.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class Toolbox : OptimizedSettingsFragment() {
+
+ companion object {
+ const val TAG = "Toolbox"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_toolbox) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context).toMutableList()
+ return keys
+ }
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.rising_settings_toolbox)
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/Wallpaper.java b/src/com/rising/settings/fragments/Wallpaper.java
deleted file mode 100644
index a4a85231..00000000
--- a/src/com/rising/settings/fragments/Wallpaper.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.content.Context;
-import android.os.Bundle;
-
-import androidx.preference.Preference;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import com.android.settings.preferences.CustomSeekBarPreference;
-
-import java.util.List;
-
-import com.android.settings.utils.SystemRestartUtils;
-
-@SearchIndexable
-public class Wallpaper extends SettingsPreferenceFragment
- implements Preference.OnPreferenceChangeListener {
-
- public static final String TAG = "Wallpaper";
-
- private Preference mBlurWpPref;
- private Preference mBlurWpStylePref;
- private Preference mDimPref;
- private Preference mDimLvlPref;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.rising_settings_wallpaper);
- mBlurWpPref = findPreference("persist.sys.wallpaper.blur_enabled");
- mBlurWpPref.setOnPreferenceChangeListener(this);
- mBlurWpStylePref = findPreference("persist.sys.wallpaper.blur_type");
- mBlurWpStylePref.setOnPreferenceChangeListener(this);
- mDimPref = findPreference("persist.sys.wallpaper.dim_enabled");
- mDimPref.setOnPreferenceChangeListener(this);
- mDimLvlPref = findPreference("persist.sys.wallpaper.dim_level");
- mDimLvlPref.setOnPreferenceChangeListener(this);
- }
-
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (preference == mBlurWpPref
- || preference == mBlurWpStylePref
- || preference == mDimPref
- || preference == mDimLvlPref) {
- if (preference == mDimLvlPref) {
- android.os.SystemProperties.set("persist.sys.wallpaper.dim_level", newValue.toString());
- }
- SystemRestartUtils.showSystemUIRestartDialog(getContext());
- return true;
- }
- return false;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_wallpaper) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/Wallpaper.kt b/src/com/rising/settings/fragments/Wallpaper.kt
new file mode 100644
index 00000000..f47403ca
--- /dev/null
+++ b/src/com/rising/settings/fragments/Wallpaper.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.content.Context
+import android.os.Bundle
+import android.os.SystemProperties
+import androidx.preference.Preference
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settings.utils.SystemRestartUtils
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class Wallpaper : OptimizedSettingsFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ const val TAG = "Wallpaper"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_wallpaper) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context).toMutableList()
+ return keys
+ }
+ }
+ }
+
+ private var mBlurWpPref: Preference? = null
+ private var mBlurWpStylePref: Preference? = null
+ private var mDimPref: Preference? = null
+ private var mDimLvlPref: Preference? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.rising_settings_wallpaper)
+ mBlurWpPref = findPreference("persist.sys.wallpaper.blur_enabled")
+ mBlurWpPref?.onPreferenceChangeListener = this
+ mBlurWpStylePref = findPreference("persist.sys.wallpaper.blur_type")
+ mBlurWpStylePref?.onPreferenceChangeListener = this
+ mDimPref = findPreference("persist.sys.wallpaper.dim_enabled")
+ mDimPref?.onPreferenceChangeListener = this
+ mDimLvlPref = findPreference("persist.sys.wallpaper.dim_level")
+ mDimLvlPref?.onPreferenceChangeListener = this
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
+ // Use safe context access
+ val context = getSafeContext() ?: return false
+
+ return when (preference) {
+ mBlurWpPref, mBlurWpStylePref, mDimPref, mDimLvlPref -> {
+ if (preference == mDimLvlPref) {
+ SystemProperties.set("persist.sys.wallpaper.dim_level", newValue.toString())
+ }
+ SystemRestartUtils.showSystemUIRestartDialog(context)
+ true
+ }
+ else -> false
+ }
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/WallpaperDepth.java b/src/com/rising/settings/fragments/WallpaperDepth.java
deleted file mode 100644
index b268d2e7..00000000
--- a/src/com/rising/settings/fragments/WallpaperDepth.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.MediaStore;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.widget.Toast;
-
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.SwitchPreferenceCompat;
-
-import com.android.internal.logging.nano.MetricsProto;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import com.android.settings.utils.ImageUtils;
-
-import java.util.List;
-
-@SearchIndexable
-public class WallpaperDepth extends SettingsPreferenceFragment
- implements Preference.OnPreferenceChangeListener {
-
- public static final String TAG = "WallpaperDepth";
-
- private Preference mDepthWallpaperCustomImagePicker;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.rising_settings_wallpaper_depth);
-
- mDepthWallpaperCustomImagePicker = findPreference("depth_wallpaper_subject_image_uri");
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- return false;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
-
- @Override
- public boolean onPreferenceTreeClick(Preference preference) {
- if (preference == mDepthWallpaperCustomImagePicker) {
- try {
- Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
- intent.setType("image/*");
- startActivityForResult(intent, 10001);
- } catch(Exception e) {
- Toast.makeText(getContext(), R.string.qs_header_needs_gallery, Toast.LENGTH_LONG).show();
- }
- return true;
- }
- return super.onPreferenceTreeClick(preference);
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent result) {
- if (requestCode == 10001) {
- if (resultCode != Activity.RESULT_OK) {
- return;
- }
-
- final Uri imgUri = result.getData();
- if (imgUri != null) {
- String savedImagePath = ImageUtils.saveImageToInternalStorage(getContext(), imgUri, "depthwallpaper", "DEPTH_WALLPAPER_SUBJECT");
- if (savedImagePath != null) {
- ContentResolver resolver = getContext().getContentResolver();
- Settings.System.putStringForUser(resolver, "depth_wallpaper_subject_image_uri", savedImagePath, UserHandle.USER_CURRENT);
- }
- }
- }
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_wallpaper_depth) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/WallpaperDepth.kt b/src/com/rising/settings/fragments/WallpaperDepth.kt
new file mode 100644
index 00000000..0692ef44
--- /dev/null
+++ b/src/com/rising/settings/fragments/WallpaperDepth.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments
+
+import android.app.Activity
+import android.content.ContentResolver
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.MediaStore
+import android.provider.SearchIndexableResource
+import android.provider.Settings
+import android.text.TextUtils
+import android.widget.Toast
+
+import androidx.preference.ListPreference
+import androidx.preference.Preference
+import androidx.preference.PreferenceCategory
+import androidx.preference.PreferenceScreen
+import androidx.preference.Preference.OnPreferenceChangeListener
+import androidx.preference.SwitchPreferenceCompat
+
+import com.android.internal.logging.nano.MetricsProto
+
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+
+import com.android.settings.utils.ImageUtils
+
+@SearchIndexable
+class WallpaperDepth : OptimizedSettingsFragment(), Preference.OnPreferenceChangeListener {
+
+ private var mDepthWallpaperCustomImagePicker: Preference? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.rising_settings_wallpaper_depth)
+
+ mDepthWallpaperCustomImagePicker = findPreference("depth_wallpaper_subject_image_uri")
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ return false
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+
+ override fun onPreferenceTreeClick(preference: Preference): Boolean {
+ if (preference == mDepthWallpaperCustomImagePicker) {
+ try {
+ val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
+ intent.type = "image/*"
+ startActivityForResult(intent, 10001)
+ } catch (e: Exception) {
+ Toast.makeText(context, R.string.qs_header_needs_gallery, Toast.LENGTH_LONG).show()
+ }
+ return true
+ }
+ return super.onPreferenceTreeClick(preference)
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, result: Intent?) {
+ if (requestCode == 10001) {
+ if (resultCode != Activity.RESULT_OK) {
+ return
+ }
+
+ val imgUri = result?.data
+ if (imgUri != null) {
+ val savedImagePath = context?.let { ctx ->
+ ImageUtils.saveImageToInternalStorage(
+ ctx, imgUri, "depthwallpaper", "DEPTH_WALLPAPER_SUBJECT"
+ )
+ }
+ if (savedImagePath != null) {
+ val resolver = context?.contentResolver
+ resolver?.let {
+ Settings.System.putStringForUser(
+ it, "depth_wallpaper_subject_image_uri",
+ savedImagePath, UserHandle.USER_CURRENT
+ )
+ }
+ }
+ }
+ }
+ }
+
+ companion object {
+ const val TAG = "WallpaperDepth"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_wallpaper_depth) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context)
+ return keys
+ }
+ }
+ }
+}
diff --git a/src/com/rising/settings/fragments/about/ChangelogActivity.java b/src/com/rising/settings/fragments/about/ChangelogActivity.kt
similarity index 60%
rename from src/com/rising/settings/fragments/about/ChangelogActivity.java
rename to src/com/rising/settings/fragments/about/ChangelogActivity.kt
index f2ea562f..c420a400 100644
--- a/src/com/rising/settings/fragments/about/ChangelogActivity.java
+++ b/src/com/rising/settings/fragments/about/ChangelogActivity.kt
@@ -13,17 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.rising.settings.fragments.about;
+package com.rising.settings.fragments.about
-import android.os.Bundle;
-import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
+import android.os.Bundle
+import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity
-public class ChangelogActivity extends CollapsingToolbarBaseActivity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getFragmentManager().beginTransaction().replace(
- com.android.settingslib.collapsingtoolbar.R.id.content_frame,
- new ChangelogFragment()).commit();
+class ChangelogActivity : CollapsingToolbarBaseActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ fragmentManager.beginTransaction().replace(
+ com.android.settingslib.collapsingtoolbar.R.id.content_frame,
+ ChangelogFragment()
+ ).commit()
}
}
diff --git a/src/com/rising/settings/fragments/about/ChangelogFragment.java b/src/com/rising/settings/fragments/about/ChangelogFragment.java
deleted file mode 100644
index ac34c938..00000000
--- a/src/com/rising/settings/fragments/about/ChangelogFragment.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2016-2021 crDroid Android Project
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments.about;
-
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.text.Html;
-import android.text.method.LinkMovementMethod;
-import android.text.SpannableStringBuilder;
-import android.text.style.StyleSpan;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import androidx.preference.PreferenceFragment;
-
-import com.android.settings.R;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class ChangelogFragment extends PreferenceFragment {
-
- TextView textView;
-
- private static final String README_URL = "https://raw.githubusercontent.com/RisingOS-Revived/risingOS_changelogs/fifteen/README.md";
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- return inflater.inflate(R.layout.changelog, container, false);
- }
-
- @Override
- public void onViewCreated(final View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- textView = view.findViewById(R.id.changelog_text);
- new FetchReadmeTask().execute(README_URL);
- }
-
- private class FetchReadmeTask extends AsyncTask {
-
- @Override
- protected String doInBackground(String... params) {
- String readmeUrl = params[0];
- try {
- URL url = new URL(readmeUrl);
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
- connection.setRequestMethod("GET");
- InputStreamReader inputStreamReader = new InputStreamReader(connection.getInputStream());
- BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
- StringBuilder stringBuilder = new StringBuilder();
- String line;
- while ((line = bufferedReader.readLine()) != null) {
- stringBuilder.append(line).append("\n");
- }
- bufferedReader.close();
- inputStreamReader.close();
- return stringBuilder.toString();
- } catch (IOException e) {
- return "";
- }
- }
-
- @Override
- protected void onPostExecute(String result) {
- if (result != null) {
- Pattern pattern = Pattern.compile("\\*\\*(.*?)\\*\\*");
- Matcher matcher = pattern.matcher(result);
- SpannableStringBuilder spannableBuilder = new SpannableStringBuilder();
- int lastEnd = 0;
- while (matcher.find()) {
- int start = matcher.start();
- int end = matcher.end();
- String matchedText = matcher.group(1);
- spannableBuilder.append(result.subSequence(lastEnd, start));
- spannableBuilder.append(matchedText, new StyleSpan(android.graphics.Typeface.BOLD), SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE);
- lastEnd = end;
- }
- spannableBuilder.append(result.subSequence(lastEnd, result.length()));
- textView.setText(spannableBuilder);
- textView.setMovementMethod(LinkMovementMethod.getInstance());
- }
- }
- }
-
- @Override
- public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
- }
-}
diff --git a/src/com/rising/settings/fragments/about/ChangelogFragment.kt b/src/com/rising/settings/fragments/about/ChangelogFragment.kt
new file mode 100644
index 00000000..ab11a291
--- /dev/null
+++ b/src/com/rising/settings/fragments/about/ChangelogFragment.kt
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2016-2021 crDroid Android Project
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments.about
+
+import java.util.concurrent.Executors
+import java.util.concurrent.ExecutorService
+import android.os.Bundle
+import android.text.Html
+import android.text.method.LinkMovementMethod
+import android.text.SpannableStringBuilder
+import android.text.style.StyleSpan
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+
+import androidx.preference.PreferenceFragment
+
+import com.android.settings.R
+
+import java.io.BufferedReader
+import java.io.IOException
+import java.io.InputStreamReader
+import java.net.HttpURLConnection
+import java.net.URL
+import java.util.regex.Pattern
+
+class ChangelogFragment : PreferenceFragment() {
+
+ private lateinit var textView: TextView
+
+ companion object {
+ private const val README_URL = "https://raw.githubusercontent.com/RisingOS-Revived/risingOS_changelogs/fifteen/README.md"
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ return inflater.inflate(R.layout.changelog, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ textView = view.findViewById(R.id.changelog_text)
+ fetchReadmeContent(README_URL)
+ }
+
+ private val executor: ExecutorService = Executors.newSingleThreadExecutor()
+
+ private fun fetchReadmeContent(readmeUrl: String) {
+ executor.execute {
+ val content = try {
+ val url = URL(readmeUrl)
+ val connection = url.openConnection() as HttpURLConnection
+ connection.requestMethod = "GET"
+ val inputStreamReader = InputStreamReader(connection.inputStream)
+ val bufferedReader = BufferedReader(inputStreamReader)
+ val stringBuilder = StringBuilder()
+ var line: String?
+ while (bufferedReader.readLine().also { line = it } != null) {
+ stringBuilder.append(line).append("\n")
+ }
+ bufferedReader.close()
+ inputStreamReader.close()
+ stringBuilder.toString()
+ } catch (e: IOException) {
+ ""
+ }
+
+ // Update UI on main thread
+ activity?.runOnUiThread {
+ if (isAdded && content.isNotEmpty()) {
+ updateTextView(content)
+ }
+ }
+ }
+ }
+
+ private fun updateTextView(content: String) {
+ val pattern = Pattern.compile("\\*\\*(.*?)\\*\\*")
+ val matcher = pattern.matcher(content)
+ val spannableBuilder = SpannableStringBuilder()
+ var lastEnd = 0
+ while (matcher.find()) {
+ val start = matcher.start()
+ val end = matcher.end()
+ val matchedText = matcher.group(1)
+ spannableBuilder.append(content.subSequence(lastEnd, start))
+ spannableBuilder.append(
+ matchedText,
+ StyleSpan(android.graphics.Typeface.BOLD),
+ SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ lastEnd = end
+ }
+ spannableBuilder.append(content.subSequence(lastEnd, content.length))
+ textView.text = spannableBuilder
+ textView.movementMethod = LinkMovementMethod.getInstance()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ executor.shutdown()
+ }
+
+ override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
+ }
+}
diff --git a/src/com/rising/settings/fragments/lockscreen/LockClockFontsPickerPreview.java b/src/com/rising/settings/fragments/lockscreen/LockClockFontsPickerPreview.java
deleted file mode 100644
index 5c7488f8..00000000
--- a/src/com/rising/settings/fragments/lockscreen/LockClockFontsPickerPreview.java
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * Copyright (C) 2023-2024 The risingOS Android Project
- * Copyright (C) 2024-2025 Project Infinity X
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments.lockscreen;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.ColorStateList;
-import android.graphics.Color;
-import android.graphics.PorterDuff;
-import android.graphics.Typeface;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ListView;
-import android.widget.PopupWindow;
-import android.widget.TextClock;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.content.ContextCompat;
-import androidx.viewpager.widget.PagerAdapter;
-import androidx.viewpager.widget.ViewPager;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.utils.SystemRestartUtils;
-
-import com.android.internal.util.android.ThemeUtils;
-import com.rising.settings.fragments.ui.fonts.FontArrayAdapter;
-import com.rising.settings.fragments.ui.fonts.FontManager;
-import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
-
-import java.util.List;
-
-public class LockClockFontsPickerPreview extends SettingsPreferenceFragment {
-
- private static final String TAG = "LockClockFontsPickerPreview";
- private static final String PREF_FIRST_TIME = "first_time_clock_face_access";
-
- private ViewPager viewPager;
- private ClockPagerAdapter pagerAdapter;
- private FontManager fontManager;
- private ExtendedFloatingActionButton applyFab;
- private View highlightGuide;
- private TextView clockNameTextView;
-
- private int mCurrentFontPosition = -1;
- private int mClockPosition = 0;
-
- private ThemeUtils mThemeUtils;
- private Handler mHandler = new Handler();
-
- private final static int[] mCenterClocks = {2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16};
-
- private static final int[] CLOCK_LAYOUTS = {
- R.layout.keyguard_clock_default,
- R.layout.keyguard_clock_oos,
- R.layout.keyguard_clock_center,
- R.layout.keyguard_clock_simple,
- R.layout.keyguard_clock_miui,
- R.layout.keyguard_clock_ide,
- R.layout.keyguard_clock_moto,
- R.layout.keyguard_clock_stylish,
- R.layout.keyguard_clock_stylish2,
- R.layout.keyguard_clock_stylish3,
- R.layout.keyguard_clock_stylish4,
- R.layout.keyguard_clock_stylish5,
- R.layout.keyguard_clock_stylish6,
- R.layout.keyguard_clock_stylish7,
- R.layout.keyguard_clock_stylish8,
- R.layout.keyguard_clock_stylish9,
- R.layout.keyguard_clock_stylish10
- };
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- fontManager = new FontManager(getActivity(), true);
- getActivity().setTitle(getActivity().getString(R.string.theme_customization_lock_clock_title));
- mThemeUtils = ThemeUtils.getInstance(getActivity());
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- View rootView = inflater.inflate(R.layout.lockscreen_font_picker_preview, container, false);
- clockNameTextView = rootView.findViewById(R.id.clock_name);
-
- viewPager = rootView.findViewById(R.id.view_pager);
- pagerAdapter = new ClockPagerAdapter();
- viewPager.setAdapter(pagerAdapter);
- mClockPosition = Settings.Secure.getIntForUser(getContext().getContentResolver(), "clock_style", 0, UserHandle.USER_CURRENT);
- if (mClockPosition < 0 || mClockPosition >= CLOCK_LAYOUTS.length) {
- mClockPosition = 0;
- Settings.Secure.putIntForUser(getContext().getContentResolver(), "clock_style", 0, UserHandle.USER_CURRENT);
- }
- viewPager.setCurrentItem(mClockPosition);
-
- TextView fontMessage = rootView.findViewById(R.id.font_message);
- List fontPackageNames = fontManager.getAllFontPackages();
- TextView fontSelector = rootView.findViewById(R.id.font_selector);
- int backgroundColor = ContextCompat.getColor(getContext(),
- isNightMode() ? R.color.font_drop_down_bg_dark : R.color.font_drop_down_bg_light);
- fontSelector.setTextColor(ContextCompat.getColor(getContext(), isNightMode()
- ? R.color.font_drop_down_bg_light
- : R.color.font_drop_down_bg_dark));
- fontSelector.setBackgroundTintList(ColorStateList.valueOf(backgroundColor));
-
- fontSelector.setOnClickListener(v -> {
- View popupView = LayoutInflater.from(getActivity()).inflate(R.layout.popup_font_selector, null);
- PopupWindow popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
-
- ListView fontListView = popupView.findViewById(R.id.font_list_view);
- FontArrayAdapter fontAdapter = new FontArrayAdapter(
- getActivity(),
- android.R.layout.simple_list_item_1,
- fontPackageNames,
- fontManager,
- isNightMode()
- );
- fontListView.setAdapter(fontAdapter);
-
- fontListView.setOnItemClickListener((parent, view, position, id) -> {
- mCurrentFontPosition = position;
- String fontPackage = fontPackageNames.get(mCurrentFontPosition);
- applyFontToAllPreviews(fontPackage);
- fontSelector.setText(fontManager.getLabel(getContext(), fontPackage));
- popupWindow.dismiss();
- });
-
- popupView.setBackgroundResource(R.drawable.custom_background);
- Drawable backgroundDrawable = popupView.getBackground();
- if (backgroundDrawable != null) {
- backgroundDrawable.setColorFilter(backgroundColor, PorterDuff.Mode.SRC_ATOP);
- }
- popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
- popupWindow.setOutsideTouchable(true);
- popupWindow.setFocusable(true);
- popupWindow.showAsDropDown(v, 0, 10);
- });
-
- if (isStaticClockStyle(mClockPosition)) {
- fontMessage.setVisibility(View.VISIBLE);
- } else {
- fontMessage.setVisibility(View.GONE);
- }
-
- String currentFontPackage = fontManager.getCurrentFontPackage();
- mCurrentFontPosition = fontPackageNames.indexOf(currentFontPackage);
- if (mCurrentFontPosition != -1) {
- if (!isStaticClockStyle(mClockPosition)) {
- String fontPackage = fontPackageNames.get(mCurrentFontPosition);
- fontSelector.setText(fontManager.getLabel(getContext(), fontPackage));
- applyFontToAllPreviews(fontPackage);
- }
- }
-
- applyFab = rootView.findViewById(R.id.apply_extended_fab);
- setupApplyButton(fontPackageNames);
-
- highlightGuide = rootView.findViewById(R.id.highlight_guide);
- if (isFirstTime()) {
- highlightGuide.setVisibility(View.VISIBLE);
- highlightGuide.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- highlightGuide.setVisibility(View.GONE);
- disableHighlight();
- }
- });
- } else {
- highlightGuide.setVisibility(View.GONE);
- }
-
- viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
- @Override
- public void onPageScrollStateChanged(int state) {}
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
- @Override
- public void onPageSelected(int position) {
- mClockPosition = position;
- if (viewPager != null) {
- viewPager.performHapticFeedback(android.view.HapticFeedbackConstants.CLOCK_TICK);
- }
- updateClockName(position);
-
- if (isStaticClockStyle(mClockPosition)) {
- fontMessage.setVisibility(View.VISIBLE);
- } else {
- fontMessage.setVisibility(View.GONE);
- if (mCurrentFontPosition >= 0 && mCurrentFontPosition < fontPackageNames.size()) {
- String fontPackage = fontPackageNames.get(mCurrentFontPosition);
- applyFontToAllPreviews(fontPackage);
- }
- }
- }
- });
- return rootView;
- }
-
- private void updateClockName(int position) {
- String[] clockNames = {
- "Default Clock",
- "OnePlus Clock",
- "IOS Clock",
- "Simple Clock",
- "MIUI Clock",
- "IDE Clock",
- "Moto Clock",
- "Stylish Clock",
- "Stylish Clock 2",
- "Stylish Clock 3",
- "Stylish Clock 4",
- "Stylish Clock 5",
- "Stylish Clock 6",
- "Stylish Clock 7",
- "Stylish Clock 8",
- "Stylish Clock 9",
- "Stylish Clock 10"
- };
- if (clockNameTextView != null && position >= 0 && position < clockNames.length) {
- clockNameTextView.setText(clockNames[position]);
- }
- }
-
- private void setupApplyButton(List fontPackageNames) {
- applyFab.setOnClickListener(new View.OnClickListener() {
- private long lastClickTime = 0;
-
- @Override
- public void onClick(View view) {
- long currentTime = System.currentTimeMillis();
- if (currentTime - lastClickTime < 2000) {
- return;
- }
- lastClickTime = currentTime;
-
- if (mCurrentFontPosition >= 0 && mCurrentFontPosition < fontPackageNames.size()) {
- String fontPackage = fontPackageNames.get(mCurrentFontPosition);
-
- if (!isStaticClockStyle(mClockPosition)) {
- applyFontToAllPreviews(fontPackage);
- fontManager.enableFontPackage(mCurrentFontPosition);
- }
- }
-
- Settings.Secure.putIntForUser(getContext().getContentResolver(),
- "clock_style", mClockPosition, UserHandle.USER_CURRENT);
- Settings.Secure.putIntForUser(getContext().getContentResolver(),
- "lock_screen_custom_clock_face", 0, UserHandle.USER_CURRENT);
-
- applyChangesAndRestart();
- }
- });
- }
-
- private void applyChangesAndRestart() {
- if (applyFab != null) {
- applyFab.setEnabled(false);
- applyFab.setText("Applying...");
- }
-
- updateClockOverlays(mClockPosition);
-
- final Context appContext = getActivity() != null ? getActivity().getApplicationContext() : null;
- final Context fragmentContext = getContext();
-
- if (appContext != null && fragmentContext != null && isAdded() && getActivity() != null && !getActivity().isFinishing()) {
- mHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- try {
- SystemRestartUtils.restartSystemUI(appContext);
- showSuccessMessage();
-
- } catch (Exception e) {
- if (isAdded() && getContext() != null && getActivity() != null && !getActivity().isFinishing()) {
- try {
- SystemRestartUtils.restartSystemUI(getContext());
- showSuccessMessage();
- } catch (Exception ex) {
- showFailureMessage();
- }
- } else {
- showFailureMessage();
- }
- }
- }
- }, 1000);
- } else {
- showFailureMessage();
- }
- }
-
- private void showSuccessMessage() {
- if (getActivity() != null && !getActivity().isFinishing()) {
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (getContext() != null) {
- Toast.makeText(getContext(),
- "Settings applied successfully!",
- Toast.LENGTH_SHORT).show();
- }
- if (applyFab != null) {
- applyFab.setEnabled(true);
- applyFab.setText("Apply");
- }
- }
- });
- }
- }
-
- private void showFailureMessage() {
- if (getActivity() != null && !getActivity().isFinishing()) {
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (applyFab != null) {
- applyFab.setEnabled(true);
- applyFab.setText("Apply");
- }
- if (getContext() != null) {
- Toast.makeText(getContext(),
- "Settings saved. Please restart SystemUI manually if changes don't appear.",
- Toast.LENGTH_LONG).show();
- }
- }
- });
- }
- }
-
- private boolean isNightMode() {
- int nightModeFlags = getContext().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
- return nightModeFlags == Configuration.UI_MODE_NIGHT_YES;
- }
-
- private void updateClockOverlays(int clockStyle) {
- mThemeUtils.setOverlayEnabled(
- "android.theme.customization.hideclock",
- clockStyle != 0 ? "com.android.systemui.clocks.hideclock" : "android",
- "android");
- mThemeUtils.setOverlayEnabled(
- "android.theme.customization.smartspace",
- clockStyle != 0 ? "com.android.systemui.hide.smartspace" : "com.android.systemui",
- "com.android.systemui");
- mThemeUtils.setOverlayEnabled(
- "android.theme.customization.smartspace_offset",
- clockStyle != 0 && isCenterClock(clockStyle)
- ? "com.android.systemui.smartspace_offset.smartspace"
- : "com.android.systemui",
- "com.android.systemui");
- }
-
- private boolean isCenterClock(int clockStyle) {
- for (int centerClock : mCenterClocks) {
- if (centerClock == clockStyle) {
- return true;
- }
- }
- return false;
- }
-
- private boolean isStaticClockStyle(int clockStyle) {
- if (clockStyle < 0 || clockStyle >= CLOCK_LAYOUTS.length) {
- return false;
- }
- return false;
- }
-
- private boolean shouldScaleDown(int position) {
- int layoutId = CLOCK_LAYOUTS[position];
- return layoutId == R.layout.keyguard_clock_stylish
- || layoutId == R.layout.keyguard_clock_stylish2
- || layoutId == R.layout.keyguard_clock_stylish3
- || layoutId == R.layout.keyguard_clock_stylish4
- || layoutId == R.layout.keyguard_clock_stylish5
- || layoutId == R.layout.keyguard_clock_stylish6
- || layoutId == R.layout.keyguard_clock_stylish7
- || layoutId == R.layout.keyguard_clock_stylish8
- || layoutId == R.layout.keyguard_clock_stylish9
- || layoutId == R.layout.keyguard_clock_stylish10;
- }
-
- private boolean isFirstTime() {
- return Settings.System.getIntForUser(
- getContext().getContentResolver(), PREF_FIRST_TIME, 1, UserHandle.USER_CURRENT) != 0;
- }
-
- private void disableHighlight() {
- Settings.System.putIntForUser(getContext().getContentResolver(), PREF_FIRST_TIME, 0, UserHandle.USER_CURRENT);
- }
-
- private class ClockPagerAdapter extends PagerAdapter {
- @NonNull
- @Override
- public Object instantiateItem(@NonNull ViewGroup container, int position) {
- LayoutInflater inflater = LayoutInflater.from(getActivity());
- View layout = inflater.inflate(CLOCK_LAYOUTS[position], container, false);
-
- if (!isStaticClockStyle(position) && mCurrentFontPosition >= 0) {
- String fontPackage = fontManager.getAllFontPackages().get(mCurrentFontPosition);
- applyFontToPreview(fontPackage, layout, position);
- }
-
- int bottomPadding = (int) TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP,
- 150,
- getResources().getDisplayMetrics()
- );
- layout.setPadding(
- layout.getPaddingLeft(),
- layout.getPaddingTop(),
- layout.getPaddingRight(),
- bottomPadding
- );
-
- if (shouldScaleDown(position)) {
- float scaleFactor = 0.70f;
- if (position == 0
- || position == 1
- || position == 2
- || position == 5
- || position == 6
- || position == 7
- || position == 14) {
- scaleFactor = 0.35f;
- }
- layout.setScaleX(scaleFactor);
- layout.setScaleY(scaleFactor);
- }
-
- container.addView(layout);
- return layout;
- }
-
- @Override
- public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
- container.removeView((View) object);
- }
-
- @Override
- public int getCount() {
- return CLOCK_LAYOUTS.length;
- }
-
- @Override
- public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
- return view == object;
- }
- }
-
- private void applyFontToAllPreviews(String font) {
- Typeface typeface = fontManager.getTypeface(getContext(), font);
- int childCount = viewPager.getChildCount();
- if (typeface != null) {
- for (int i = 0; i < childCount; i++) {
- View currentLayout = viewPager.getChildAt(i);
- int currentPosition = viewPager.getCurrentItem();
- if (currentLayout != null) {
- if (!isStaticClockStyle(currentPosition)) {
- updateAllTextViews(currentLayout, typeface);
- }
- }
- }
- }
- }
-
- private void applyFontToPreview(String font, View layout, int position) {
- if (isStaticClockStyle(position)) {
- return;
- }
- Typeface typeface = fontManager.getTypeface(getContext(), font);
- if (typeface != null) {
- updateAllTextViews(layout, typeface);
- }
- }
-
- private void updateAllTextViews(View view, Typeface typeface) {
- if (view instanceof TextView || view instanceof TextClock) {
- ((TextView) view).setTypeface(typeface);
- } else if (view instanceof ViewGroup) {
- ViewGroup viewGroup = (ViewGroup) view;
- for (int i = 0; i < viewGroup.getChildCount(); i++) {
- View child = viewGroup.getChildAt(i);
- updateAllTextViews(child, typeface);
- }
- }
- }
-
- @Override
- public void onConfigurationChanged(@NonNull Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- updateClockName(mClockPosition);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- updateClockName(mClockPosition);
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- if (mHandler != null) {
- mHandler.removeCallbacksAndMessages(null);
- }
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mHandler = null;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-}
diff --git a/src/com/rising/settings/fragments/lockscreen/LockClockFontsPickerPreview.kt b/src/com/rising/settings/fragments/lockscreen/LockClockFontsPickerPreview.kt
new file mode 100644
index 00000000..3840bb97
--- /dev/null
+++ b/src/com/rising/settings/fragments/lockscreen/LockClockFontsPickerPreview.kt
@@ -0,0 +1,508 @@
+/*
+ * Copyright (C) 2023-2024 The risingOS Android Project
+ * Copyright (C) 2024-2025 Project Infinity X
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments.lockscreen
+
+import android.content.Context
+import android.content.res.Configuration
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.graphics.PorterDuff
+import android.graphics.Typeface
+import android.graphics.drawable.ColorDrawable
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.os.Handler
+import android.os.UserHandle
+import android.provider.Settings
+import android.util.TypedValue
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ListView
+import android.widget.PopupWindow
+import android.widget.TextClock
+import android.widget.TextView
+import android.widget.Toast
+
+import androidx.annotation.NonNull
+import androidx.annotation.Nullable
+import androidx.core.content.ContextCompat
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import java.lang.ref.WeakReference
+import com.android.settings.utils.SystemRestartUtils
+
+import com.android.internal.util.android.ThemeUtils
+import com.rising.settings.fragments.ui.fonts.FontArrayAdapter
+import com.rising.settings.fragments.ui.fonts.FontManager
+import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
+
+class LockClockFontsPickerPreview : OptimizedSettingsFragment() {
+
+ companion object {
+ private const val TAG = "LockClockFontsPickerPreview"
+ private const val PREF_FIRST_TIME = "first_time_clock_face_access"
+
+ private val mCenterClocks = intArrayOf(2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16)
+
+ private val CLOCK_LAYOUTS = intArrayOf(
+ R.layout.keyguard_clock_default,
+ R.layout.keyguard_clock_oos,
+ R.layout.keyguard_clock_center,
+ R.layout.keyguard_clock_simple,
+ R.layout.keyguard_clock_miui,
+ R.layout.keyguard_clock_ide,
+ R.layout.keyguard_clock_moto,
+ R.layout.keyguard_clock_stylish,
+ R.layout.keyguard_clock_stylish2,
+ R.layout.keyguard_clock_stylish3,
+ R.layout.keyguard_clock_stylish4,
+ R.layout.keyguard_clock_stylish5,
+ R.layout.keyguard_clock_stylish6,
+ R.layout.keyguard_clock_stylish7,
+ R.layout.keyguard_clock_stylish8,
+ R.layout.keyguard_clock_stylish9,
+ R.layout.keyguard_clock_stylish10
+ )
+ }
+
+ private lateinit var viewPager: ViewPager
+ private lateinit var pagerAdapter: ClockPagerAdapter
+ private lateinit var fontManager: FontManager
+ private lateinit var applyFab: ExtendedFloatingActionButton
+ private lateinit var highlightGuide: View
+ private lateinit var clockNameTextView: TextView
+
+ private var mCurrentFontPosition = -1
+ private var mClockPosition = 0
+
+ override var mThemeUtils: ThemeUtils? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ fontManager = FontManager(requireActivity(), true)
+ activity?.title = activity?.getString(R.string.theme_customization_lock_clock_title)
+ activity?.let {
+ mThemeUtils = ThemeUtils.getInstance(it)
+ }
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ val rootView = inflater.inflate(R.layout.lockscreen_font_picker_preview, container, false)
+ clockNameTextView = rootView.findViewById(R.id.clock_name)
+
+ viewPager = rootView.findViewById(R.id.view_pager)
+ pagerAdapter = ClockPagerAdapter()
+ viewPager.adapter = pagerAdapter
+ mClockPosition = Settings.Secure.getIntForUser(context?.contentResolver, "clock_style", 0, UserHandle.USER_CURRENT)
+ if (mClockPosition < 0 || mClockPosition >= CLOCK_LAYOUTS.size) {
+ mClockPosition = 0
+ Settings.Secure.putIntForUser(context?.contentResolver, "clock_style", 0, UserHandle.USER_CURRENT)
+ }
+ viewPager.currentItem = mClockPosition
+
+ val fontMessage = rootView.findViewById(R.id.font_message)
+ val fontPackageNames = fontManager.allFontPackages
+ val fontSelector = rootView.findViewById(R.id.font_selector)
+ val backgroundColor = ContextCompat.getColor(context!!,
+ if (isNightMode()) R.color.font_drop_down_bg_dark else R.color.font_drop_down_bg_light)
+ fontSelector.setTextColor(ContextCompat.getColor(context!!,
+ if (isNightMode()) R.color.font_drop_down_bg_light else R.color.font_drop_down_bg_dark))
+ fontSelector.backgroundTintList = ColorStateList.valueOf(backgroundColor)
+
+ fontSelector.setOnClickListener { v ->
+ val popupView = LayoutInflater.from(activity).inflate(R.layout.popup_font_selector, null)
+ val popupWindow = PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true)
+
+ val fontListView = popupView.findViewById(R.id.font_list_view)
+ val fontAdapter = FontArrayAdapter(
+ requireActivity(),
+ android.R.layout.simple_list_item_1,
+ fontPackageNames,
+ fontManager,
+ isNightMode()
+ )
+ fontListView.adapter = fontAdapter
+
+ fontListView.setOnItemClickListener { _, _, position, _ ->
+ mCurrentFontPosition = position
+ val fontPackage = fontPackageNames[mCurrentFontPosition]
+ applyFontToAllPreviews(fontPackage)
+ fontSelector.text = fontManager.getLabel(requireContext(), fontPackage)
+ popupWindow.dismiss()
+ }
+
+ popupView.setBackgroundResource(R.drawable.custom_background)
+ val backgroundDrawable = popupView.background
+ backgroundDrawable?.setColorFilter(backgroundColor, PorterDuff.Mode.SRC_ATOP)
+ popupWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ popupWindow.isOutsideTouchable = true
+ popupWindow.isFocusable = true
+ popupWindow.showAsDropDown(v, 0, 10)
+ }
+
+ if (isStaticClockStyle(mClockPosition)) {
+ fontMessage.visibility = View.VISIBLE
+ } else {
+ fontMessage.visibility = View.GONE
+ }
+
+ val currentFontPackage = fontManager.currentFontPackage
+ mCurrentFontPosition = fontPackageNames.indexOf(currentFontPackage)
+ if (mCurrentFontPosition != -1) {
+ if (!isStaticClockStyle(mClockPosition)) {
+ val fontPackage = fontPackageNames[mCurrentFontPosition]
+ fontSelector.text = fontManager.getLabel(requireContext(), fontPackage)
+ applyFontToAllPreviews(fontPackage)
+ }
+ }
+
+ applyFab = rootView.findViewById(R.id.apply_extended_fab)
+ setupApplyButton(fontPackageNames)
+
+ highlightGuide = rootView.findViewById(R.id.highlight_guide)
+ if (isFirstTime()) {
+ highlightGuide.visibility = View.VISIBLE
+ highlightGuide.setOnClickListener {
+ highlightGuide.visibility = View.GONE
+ disableHighlight()
+ }
+ } else {
+ highlightGuide.visibility = View.GONE
+ }
+
+ viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrollStateChanged(state: Int) {}
+ override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
+ override fun onPageSelected(position: Int) {
+ mClockPosition = position
+ viewPager.performHapticFeedback(android.view.HapticFeedbackConstants.CLOCK_TICK)
+ updateClockName(position)
+
+ if (isStaticClockStyle(mClockPosition)) {
+ fontMessage.visibility = View.VISIBLE
+ } else {
+ fontMessage.visibility = View.GONE
+ if (mCurrentFontPosition >= 0 && mCurrentFontPosition < fontPackageNames.size) {
+ val fontPackage = fontPackageNames[mCurrentFontPosition]
+ applyFontToAllPreviews(fontPackage)
+ }
+ }
+ }
+ })
+ return rootView
+ }
+
+ private fun updateClockName(position: Int) {
+ val clockNames = arrayOf(
+ "Default Clock",
+ "OnePlus Clock",
+ "IOS Clock",
+ "Simple Clock",
+ "MIUI Clock",
+ "IDE Clock",
+ "Moto Clock",
+ "Stylish Clock",
+ "Stylish Clock 2",
+ "Stylish Clock 3",
+ "Stylish Clock 4",
+ "Stylish Clock 5",
+ "Stylish Clock 6",
+ "Stylish Clock 7",
+ "Stylish Clock 8",
+ "Stylish Clock 9",
+ "Stylish Clock 10"
+ )
+ if (position >= 0 && position < clockNames.size) {
+ clockNameTextView.text = clockNames[position]
+ }
+ }
+
+ private fun setupApplyButton(fontPackageNames: List) {
+ applyFab.setOnClickListener(object : View.OnClickListener {
+ private var lastClickTime: Long = 0
+
+ override fun onClick(view: View) {
+ val currentTime = System.currentTimeMillis()
+ if (currentTime - lastClickTime < 2000) {
+ return
+ }
+ lastClickTime = currentTime
+
+ if (mCurrentFontPosition >= 0 && mCurrentFontPosition < fontPackageNames.size) {
+ val fontPackage = fontPackageNames[mCurrentFontPosition]
+
+ if (!isStaticClockStyle(mClockPosition)) {
+ applyFontToAllPreviews(fontPackage)
+ fontManager.enableFontPackage(mCurrentFontPosition)
+ }
+ }
+
+ Settings.Secure.putIntForUser(context?.contentResolver,
+ "clock_style", mClockPosition, UserHandle.USER_CURRENT)
+ Settings.Secure.putIntForUser(context?.contentResolver,
+ "lock_screen_custom_clock_face", 0, UserHandle.USER_CURRENT)
+
+ applyChangesAndRestart()
+ }
+ })
+ }
+
+ private fun applyChangesAndRestart() {
+ applyFab.isEnabled = false
+ applyFab.text = "Applying..."
+
+ updateClockOverlays(mClockPosition)
+
+ val appContext = activity?.applicationContext
+ val fragmentContext = context
+
+ if (appContext != null && fragmentContext != null && isAdded && activity != null && !activity!!.isFinishing) {
+ postDelayedSafe({
+ try {
+ SystemRestartUtils.restartSystemUI(appContext)
+ showSuccessMessage()
+ } catch (e: Exception) {
+ if (isAdded && context != null && activity != null && !activity!!.isFinishing) {
+ try {
+ SystemRestartUtils.restartSystemUI(context!!)
+ showSuccessMessage()
+ } catch (ex: Exception) {
+ showFailureMessage()
+ }
+ } else {
+ showFailureMessage()
+ }
+ }
+ }, 1000)
+ } else {
+ showFailureMessage()
+ }
+ }
+
+ private fun showSuccessMessage() {
+ if (activity != null && !activity!!.isFinishing) {
+ activity!!.runOnUiThread {
+ context?.let {
+ Toast.makeText(it,
+ "Settings applied successfully!",
+ Toast.LENGTH_SHORT).show()
+ }
+ applyFab.isEnabled = true
+ applyFab.text = "Apply"
+ }
+ }
+ }
+
+ private fun showFailureMessage() {
+ if (activity != null && !activity!!.isFinishing) {
+ activity!!.runOnUiThread {
+ applyFab.isEnabled = true
+ applyFab.text = "Apply"
+ context?.let {
+ Toast.makeText(it,
+ "Settings saved. Please restart SystemUI manually if changes don't appear.",
+ Toast.LENGTH_LONG).show()
+ }
+ }
+ }
+ }
+
+ private fun isNightMode(): Boolean {
+ val nightModeFlags = context?.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK)
+ return nightModeFlags == Configuration.UI_MODE_NIGHT_YES
+ }
+
+ private fun updateClockOverlays(clockStyle: Int) {
+ mThemeUtils?.setOverlayEnabled(
+ "android.theme.customization.hideclock",
+ if (clockStyle != 0) "com.android.systemui.clocks.hideclock" else "android",
+ "android")
+ mThemeUtils?.setOverlayEnabled(
+ "android.theme.customization.smartspace",
+ if (clockStyle != 0) "com.android.systemui.hide.smartspace" else "com.android.systemui",
+ "com.android.systemui")
+ mThemeUtils?.setOverlayEnabled(
+ "android.theme.customization.smartspace_offset",
+ if (clockStyle != 0 && isCenterClock(clockStyle))
+ "com.android.systemui.smartspace_offset.smartspace"
+ else
+ "com.android.systemui",
+ "com.android.systemui")
+ }
+
+ private fun isCenterClock(clockStyle: Int): Boolean {
+ return mCenterClocks.contains(clockStyle)
+ }
+
+ private fun isStaticClockStyle(clockStyle: Int): Boolean {
+ if (clockStyle < 0 || clockStyle >= CLOCK_LAYOUTS.size) {
+ return false
+ }
+ return false
+ }
+
+ private fun shouldScaleDown(position: Int): Boolean {
+ val layoutId = CLOCK_LAYOUTS[position]
+ return layoutId == R.layout.keyguard_clock_stylish ||
+ layoutId == R.layout.keyguard_clock_stylish2 ||
+ layoutId == R.layout.keyguard_clock_stylish3 ||
+ layoutId == R.layout.keyguard_clock_stylish4 ||
+ layoutId == R.layout.keyguard_clock_stylish5 ||
+ layoutId == R.layout.keyguard_clock_stylish6 ||
+ layoutId == R.layout.keyguard_clock_stylish7 ||
+ layoutId == R.layout.keyguard_clock_stylish8 ||
+ layoutId == R.layout.keyguard_clock_stylish9 ||
+ layoutId == R.layout.keyguard_clock_stylish10
+ }
+
+ private fun isFirstTime(): Boolean {
+ return Settings.System.getIntForUser(
+ context?.contentResolver, PREF_FIRST_TIME, 1, UserHandle.USER_CURRENT) != 0
+ }
+
+ private fun disableHighlight() {
+ Settings.System.putIntForUser(context?.contentResolver, PREF_FIRST_TIME, 0, UserHandle.USER_CURRENT)
+ }
+
+ private inner class ClockPagerAdapter : PagerAdapter() {
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val inflater = LayoutInflater.from(activity)
+ val layout = inflater.inflate(CLOCK_LAYOUTS[position], container, false)
+
+ if (!isStaticClockStyle(position) && mCurrentFontPosition >= 0) {
+ val fontPackage = fontManager.allFontPackages[mCurrentFontPosition]
+ applyFontToPreview(fontPackage, layout, position)
+ }
+
+ val bottomPadding = TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP,
+ 150f,
+ resources.displayMetrics
+ ).toInt()
+ layout.setPadding(
+ layout.paddingLeft,
+ layout.paddingTop,
+ layout.paddingRight,
+ bottomPadding
+ )
+
+ if (shouldScaleDown(position)) {
+ var scaleFactor = 0.70f
+ if (position == 0 ||
+ position == 1 ||
+ position == 2 ||
+ position == 5 ||
+ position == 6 ||
+ position == 7 ||
+ position == 14) {
+ scaleFactor = 0.35f
+ }
+ layout.scaleX = scaleFactor
+ layout.scaleY = scaleFactor
+ }
+
+ container.addView(layout)
+ return layout
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
+ container.removeView(`object` as View)
+ }
+
+ override fun getCount(): Int {
+ return CLOCK_LAYOUTS.size
+ }
+
+ override fun isViewFromObject(view: View, `object`: Any): Boolean {
+ return view == `object`
+ }
+ }
+
+ private fun applyFontToAllPreviews(font: String) {
+ val typeface = fontManager.getTypeface(context, font)
+ val childCount = viewPager.childCount
+ if (typeface != null) {
+ for (i in 0 until childCount) {
+ val currentLayout = viewPager.getChildAt(i)
+ val currentPosition = viewPager.currentItem
+ if (currentLayout != null) {
+ if (!isStaticClockStyle(currentPosition)) {
+ updateAllTextViews(currentLayout, typeface)
+ }
+ }
+ }
+ }
+ }
+
+ private fun applyFontToPreview(font: String, layout: View, position: Int) {
+ if (isStaticClockStyle(position)) {
+ return
+ }
+ val typeface = fontManager.getTypeface(context, font)
+ if (typeface != null) {
+ updateAllTextViews(layout, typeface)
+ }
+ }
+
+ private fun updateAllTextViews(view: View, typeface: Typeface) {
+ when (view) {
+ is TextView, is TextClock -> {
+ (view as TextView).typeface = typeface
+ }
+ is ViewGroup -> {
+ for (i in 0 until view.childCount) {
+ val child = view.getChildAt(i)
+ updateAllTextViews(child, typeface)
+ }
+ }
+ }
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ updateClockName(mClockPosition)
+ }
+
+ override fun onResume() {
+ super.onResume()
+ updateClockName(mClockPosition)
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ // Cleanup handled by OptimizedSettingsFragment
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ // Cleanup ThemeUtils
+ mThemeUtils = null
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/lockscreen/LockScreenWidgets.java b/src/com/rising/settings/fragments/lockscreen/LockScreenWidgets.java
deleted file mode 100644
index 3ab4c2a8..00000000
--- a/src/com/rising/settings/fragments/lockscreen/LockScreenWidgets.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments.lockscreen;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.MediaStore;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.view.View;
-import android.widget.Button;
-import android.widget.Toast;
-
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.SwitchPreferenceCompat;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.utils.SystemRestartUtils;
-import com.android.settingslib.search.SearchIndexable;
-import com.android.settingslib.widget.LayoutPreference;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-@SearchIndexable
-public class LockScreenWidgets extends SettingsPreferenceFragment implements Preference.OnPreferenceChangeListener {
-
- public static final String TAG = "LockScreenWidgets";
-
- private static final String MAIN_WIDGET_1_KEY = "main_custom_widgets1";
- private static final String MAIN_WIDGET_2_KEY = "main_custom_widgets2";
- private static final String EXTRA_WIDGET_1_KEY = "custom_widgets1";
- private static final String EXTRA_WIDGET_2_KEY = "custom_widgets2";
- private static final String EXTRA_WIDGET_3_KEY = "custom_widgets3";
- private static final String EXTRA_WIDGET_4_KEY = "custom_widgets4";
- private static final String KEY_APPLY_CHANGE_BUTTON = "apply_change_button";
-
- private static final String LOCKSCREEN_WIDGETS_KEY = "lockscreen_widgets";
- private static final String LOCKSCREEN_WIDGETS_EXTRAS_KEY = "lockscreen_widgets_extras";
-
- private Preference mMainWidget1;
- private Preference mMainWidget2;
- private Preference mExtraWidget1;
- private Preference mExtraWidget2;
- private Preference mExtraWidget3;
- private Preference mExtraWidget4;
- private Button mApplyChange;
-
- private SwitchPreferenceCompat mLockScreenWidgetsEnabledPref;
- private List mWidgetPreferences;
-
- private Map widgetKeysMap = new HashMap<>();
- private Map initialWidgetKeysMap = new HashMap<>();
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.rising_settings_lockscreen_widgets);
-
- initializePreferences();
- setupListeners();
-
- boolean isLsWidgetsEnabled = Settings.System.getIntForUser(
- getActivity().getContentResolver(),
- "lockscreen_widgets_enabled",
- 0,
- UserHandle.USER_CURRENT) != 0;
-
- mLockScreenWidgetsEnabledPref.setChecked(isLsWidgetsEnabled);
- showWidgetPreferences(isLsWidgetsEnabled);
-
- loadInitialPreferences();
- saveInitialPreferences();
- mApplyChange.setEnabled(false);
- }
-
- private void initializePreferences() {
- mMainWidget1 = findPreference(MAIN_WIDGET_1_KEY);
- mMainWidget2 = findPreference(MAIN_WIDGET_2_KEY);
- mExtraWidget1 = findPreference(EXTRA_WIDGET_1_KEY);
- mExtraWidget2 = findPreference(EXTRA_WIDGET_2_KEY);
- mExtraWidget3 = findPreference(EXTRA_WIDGET_3_KEY);
- mExtraWidget4 = findPreference(EXTRA_WIDGET_4_KEY);
-
- mWidgetPreferences = Arrays.asList(
- mMainWidget1,
- mMainWidget2,
- mExtraWidget1,
- mExtraWidget2,
- mExtraWidget3,
- mExtraWidget4);
-
- mLockScreenWidgetsEnabledPref = findPreference("lockscreen_widgets_enabled");
-
- LayoutPreference layoutPreference = findPreference(KEY_APPLY_CHANGE_BUTTON);
- mApplyChange = layoutPreference.findViewById(R.id.apply_change);
- }
-
- private void setupListeners() {
- for (Preference widgetPref : mWidgetPreferences) {
- widgetPref.setOnPreferenceChangeListener(this);
- widgetKeysMap.put(widgetPref, "");
- }
- mLockScreenWidgetsEnabledPref.setOnPreferenceChangeListener(this);
-
- mApplyChange.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- updateWidgetPreferences();
- saveInitialPreferences();
- mApplyChange.setEnabled(false);
-
- // Restart SystemUI to apply changes
- SystemRestartUtils.restartSystemUI(getContext());
- }
- });
- }
-
- private void showWidgetPreferences(boolean isEnabled) {
- for (Preference widgetPref : mWidgetPreferences) {
- widgetPref.setVisible(isEnabled);
- }
- }
-
- private void loadInitialPreferences() {
- ContentResolver resolver = getActivity().getContentResolver();
- String mainWidgets = Settings.System.getString(resolver, LOCKSCREEN_WIDGETS_KEY);
- setWidgetAndPreferenceValues(mainWidgets, mMainWidget1, mMainWidget2);
- String extraWidgets = Settings.System.getString(resolver, LOCKSCREEN_WIDGETS_EXTRAS_KEY);
- setWidgetAndPreferenceValues(extraWidgets, mExtraWidget1, mExtraWidget2, mExtraWidget3, mExtraWidget4);
- }
-
- private void setWidgetAndPreferenceValues(String widgets, Preference... preferences) {
- if (widgets == null) {
- return;
- }
- List widgetList = Arrays.asList(widgets.split(","));
- for (int i = 0; i < preferences.length && i < widgetList.size(); i++) {
- String value = widgetList.get(i).trim();
- Preference pref = preferences[i];
- widgetKeysMap.put(pref, value);
- if (pref instanceof ListPreference) {
- ((ListPreference) pref).setValue(value);
- }
- }
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (widgetKeysMap.containsKey(preference)) {
- widgetKeysMap.put(preference, String.valueOf(newValue));
- mApplyChange.setEnabled(hasChanges());
- return true;
- } else if (preference == mLockScreenWidgetsEnabledPref) {
- boolean isEnabled = (boolean) newValue;
- showWidgetPreferences(isEnabled);
- mLockScreenWidgetsEnabledPref.setChecked(isEnabled);
- return true;
- }
- return false;
- }
-
- private void updateWidgetPreferences() {
- List mainWidgetsList = Arrays.asList(widgetKeysMap.get(mMainWidget1), widgetKeysMap.get(mMainWidget2));
- List extraWidgetsList = Arrays.asList(widgetKeysMap.get(mExtraWidget1), widgetKeysMap.get(mExtraWidget2), widgetKeysMap.get(mExtraWidget3), widgetKeysMap.get(mExtraWidget4));
-
- mainWidgetsList = replaceEmptyWithNone(mainWidgetsList);
- extraWidgetsList = replaceEmptyWithNone(extraWidgetsList);
-
- String mainWidgets = TextUtils.join(",", mainWidgetsList);
- String extraWidgets = TextUtils.join(",", extraWidgetsList);
-
- ContentResolver resolver = getActivity().getContentResolver();
- Settings.System.putString(resolver, LOCKSCREEN_WIDGETS_KEY, mainWidgets);
- Settings.System.putString(resolver, LOCKSCREEN_WIDGETS_EXTRAS_KEY, extraWidgets);
- }
-
- private List replaceEmptyWithNone(List inputList) {
- return inputList.stream()
- .map(s -> TextUtils.isEmpty(s) ? "none" : s)
- .collect(Collectors.toList());
- }
-
- private void saveInitialPreferences() {
- initialWidgetKeysMap.clear();
- for (Preference widgetPref : mWidgetPreferences) {
- String value = widgetKeysMap.get(widgetPref);
- initialWidgetKeysMap.put(widgetPref, value);
- }
- }
-
- private boolean hasChanges() {
- for (Map.Entry entry : initialWidgetKeysMap.entrySet()) {
- Preference pref = entry.getKey();
- String initialValue = entry.getValue();
- String currentValue = widgetKeysMap.get(pref);
- if (!TextUtils.equals(initialValue, currentValue)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_lockscreen_widgets) {
- @Override
- public List getNonIndexableKeys(Context context) {
- return super.getNonIndexableKeys(context);
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/lockscreen/LockScreenWidgets.kt b/src/com/rising/settings/fragments/lockscreen/LockScreenWidgets.kt
new file mode 100644
index 00000000..86b1c7d7
--- /dev/null
+++ b/src/com/rising/settings/fragments/lockscreen/LockScreenWidgets.kt
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments.lockscreen
+
+import android.app.Activity
+import android.content.ContentResolver
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.MediaStore
+import android.provider.Settings
+import android.text.TextUtils
+import android.view.View
+import android.widget.Button
+import android.widget.Toast
+
+import androidx.preference.ListPreference
+import androidx.preference.Preference
+import androidx.preference.PreferenceCategory
+import androidx.preference.PreferenceScreen
+import androidx.preference.Preference.OnPreferenceChangeListener
+import androidx.preference.SwitchPreferenceCompat
+
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settings.utils.SystemRestartUtils
+import com.android.settingslib.search.SearchIndexable
+import com.android.settingslib.widget.LayoutPreference
+
+@SearchIndexable
+class LockScreenWidgets : OptimizedSettingsFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ const val TAG = "LockScreenWidgets"
+
+ private const val MAIN_WIDGET_1_KEY = "main_custom_widgets1"
+ private const val MAIN_WIDGET_2_KEY = "main_custom_widgets2"
+ private const val EXTRA_WIDGET_1_KEY = "custom_widgets1"
+ private const val EXTRA_WIDGET_2_KEY = "custom_widgets2"
+ private const val EXTRA_WIDGET_3_KEY = "custom_widgets3"
+ private const val EXTRA_WIDGET_4_KEY = "custom_widgets4"
+ private const val KEY_APPLY_CHANGE_BUTTON = "apply_change_button"
+
+ private const val LOCKSCREEN_WIDGETS_KEY = "lockscreen_widgets"
+ private const val LOCKSCREEN_WIDGETS_EXTRAS_KEY = "lockscreen_widgets_extras"
+
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_lockscreen_widgets) {
+ override fun getNonIndexableKeys(context: Context): List {
+ return super.getNonIndexableKeys(context)
+ }
+ }
+ }
+
+ private lateinit var mMainWidget1: Preference
+ private lateinit var mMainWidget2: Preference
+ private lateinit var mExtraWidget1: Preference
+ private lateinit var mExtraWidget2: Preference
+ private lateinit var mExtraWidget3: Preference
+ private lateinit var mExtraWidget4: Preference
+ private lateinit var mApplyChange: Button
+
+ private lateinit var mLockScreenWidgetsEnabledPref: SwitchPreferenceCompat
+ private lateinit var mWidgetPreferences: List
+
+ private val widgetKeysMap = mutableMapOf()
+ private val initialWidgetKeysMap = mutableMapOf()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.rising_settings_lockscreen_widgets)
+
+ initializePreferences()
+ setupListeners()
+
+ val isLsWidgetsEnabled = Settings.System.getIntForUser(
+ activity?.contentResolver,
+ "lockscreen_widgets_enabled",
+ 0,
+ UserHandle.USER_CURRENT
+ ) != 0
+
+ mLockScreenWidgetsEnabledPref.isChecked = isLsWidgetsEnabled
+ showWidgetPreferences(isLsWidgetsEnabled)
+
+ loadInitialPreferences()
+ saveInitialPreferences()
+ mApplyChange.isEnabled = false
+ }
+
+ private fun initializePreferences() {
+ mMainWidget1 = findPreference(MAIN_WIDGET_1_KEY)!!
+ mMainWidget2 = findPreference(MAIN_WIDGET_2_KEY)!!
+ mExtraWidget1 = findPreference(EXTRA_WIDGET_1_KEY)!!
+ mExtraWidget2 = findPreference(EXTRA_WIDGET_2_KEY)!!
+ mExtraWidget3 = findPreference(EXTRA_WIDGET_3_KEY)!!
+ mExtraWidget4 = findPreference(EXTRA_WIDGET_4_KEY)!!
+
+ mWidgetPreferences = listOf(
+ mMainWidget1,
+ mMainWidget2,
+ mExtraWidget1,
+ mExtraWidget2,
+ mExtraWidget3,
+ mExtraWidget4
+ )
+
+ mLockScreenWidgetsEnabledPref = findPreference("lockscreen_widgets_enabled")!!
+
+ val layoutPreference = findPreference(KEY_APPLY_CHANGE_BUTTON)!!
+ mApplyChange = layoutPreference.findViewById(R.id.apply_change)
+ }
+
+ private fun setupListeners() {
+ for (widgetPref in mWidgetPreferences) {
+ widgetPref.onPreferenceChangeListener = this
+ widgetKeysMap[widgetPref] = ""
+ }
+ mLockScreenWidgetsEnabledPref.onPreferenceChangeListener = this
+
+ mApplyChange.setOnClickListener {
+ updateWidgetPreferences()
+ saveInitialPreferences()
+ mApplyChange.isEnabled = false
+
+ // Restart SystemUI to apply changes
+ context?.let { ctx ->
+ SystemRestartUtils.restartSystemUI(ctx)
+ }
+ }
+ }
+
+ private fun showWidgetPreferences(isEnabled: Boolean) {
+ for (widgetPref in mWidgetPreferences) {
+ widgetPref.isVisible = isEnabled
+ }
+ }
+
+ private fun loadInitialPreferences() {
+ val resolver = activity?.contentResolver
+ val mainWidgets = Settings.System.getString(resolver, LOCKSCREEN_WIDGETS_KEY)
+ setWidgetAndPreferenceValues(mainWidgets, mMainWidget1, mMainWidget2)
+ val extraWidgets = Settings.System.getString(resolver, LOCKSCREEN_WIDGETS_EXTRAS_KEY)
+ setWidgetAndPreferenceValues(extraWidgets, mExtraWidget1, mExtraWidget2, mExtraWidget3, mExtraWidget4)
+ }
+
+ private fun setWidgetAndPreferenceValues(widgets: String?, vararg preferences: Preference) {
+ if (widgets == null) {
+ return
+ }
+ val widgetList = widgets.split(",")
+ for (i in preferences.indices) {
+ if (i < widgetList.size) {
+ val value = widgetList[i].trim()
+ val pref = preferences[i]
+ widgetKeysMap[pref] = value
+ if (pref is ListPreference) {
+ pref.value = value
+ }
+ }
+ }
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ return when {
+ widgetKeysMap.containsKey(preference) -> {
+ widgetKeysMap[preference] = newValue.toString()
+ mApplyChange.isEnabled = hasChanges()
+ true
+ }
+ preference == mLockScreenWidgetsEnabledPref -> {
+ val isEnabled = newValue as Boolean
+ showWidgetPreferences(isEnabled)
+ mLockScreenWidgetsEnabledPref.isChecked = isEnabled
+ true
+ }
+ else -> false
+ }
+ }
+
+ private fun updateWidgetPreferences() {
+ var mainWidgetsList = listOf(widgetKeysMap[mMainWidget1], widgetKeysMap[mMainWidget2])
+ var extraWidgetsList = listOf(
+ widgetKeysMap[mExtraWidget1],
+ widgetKeysMap[mExtraWidget2],
+ widgetKeysMap[mExtraWidget3],
+ widgetKeysMap[mExtraWidget4]
+ )
+
+ mainWidgetsList = replaceEmptyWithNone(mainWidgetsList)
+ extraWidgetsList = replaceEmptyWithNone(extraWidgetsList)
+
+ val mainWidgets = TextUtils.join(",", mainWidgetsList)
+ val extraWidgets = TextUtils.join(",", extraWidgetsList)
+
+ val resolver = activity?.contentResolver
+ Settings.System.putString(resolver, LOCKSCREEN_WIDGETS_KEY, mainWidgets)
+ Settings.System.putString(resolver, LOCKSCREEN_WIDGETS_EXTRAS_KEY, extraWidgets)
+ }
+
+ private fun replaceEmptyWithNone(inputList: List): List {
+ return inputList.map { s -> if (TextUtils.isEmpty(s)) "none" else s!! }
+ }
+
+ private fun saveInitialPreferences() {
+ initialWidgetKeysMap.clear()
+ for (widgetPref in mWidgetPreferences) {
+ val value = widgetKeysMap[widgetPref] ?: ""
+ initialWidgetKeysMap[widgetPref] = value
+ }
+ }
+
+ private fun hasChanges(): Boolean {
+ for ((pref, initialValue) in initialWidgetKeysMap) {
+ val currentValue = widgetKeysMap[pref]
+ if (!TextUtils.equals(initialValue, currentValue)) {
+ return true
+ }
+ }
+ return false
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/lockscreen/PeekDisplay.java b/src/com/rising/settings/fragments/lockscreen/PeekDisplay.java
deleted file mode 100644
index 55cb0083..00000000
--- a/src/com/rising/settings/fragments/lockscreen/PeekDisplay.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments.lockscreen;
-
-import android.content.Context;
-import android.os.Bundle;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.List;
-
-@SearchIndexable
-public class PeekDisplay extends SettingsPreferenceFragment {
-
- public static final String TAG = "PeekDisplay";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.rising_settings_peek_display);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_peek_display) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/lockscreen/PeekDisplay.kt b/src/com/rising/settings/fragments/lockscreen/PeekDisplay.kt
new file mode 100644
index 00000000..6ec4f8d4
--- /dev/null
+++ b/src/com/rising/settings/fragments/lockscreen/PeekDisplay.kt
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments.lockscreen
+
+import android.content.ContentResolver
+import android.content.Context
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.provider.Settings
+import androidx.preference.Preference
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.preferences.SecureSettingSeekBarPreference
+import com.android.settings.preferences.SecureSettingListPreference
+import com.android.settings.preferences.SecureSettingSwitchPreference
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+import kotlin.math.abs
+
+@SearchIndexable
+class PeekDisplay : OptimizedSettingsFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ const val TAG = "PeekDisplay"
+
+ // Preference keys
+ private const val KEY_PEEK_DISPLAY_NOTIFICATIONS = "peek_display_notifications"
+ private const val KEY_PEEK_DISPLAY_STYLE = "peek_display_style"
+ private const val KEY_PEEK_DISPLAY_LOCATION = "peek_display_location"
+ private const val KEY_PEEK_DISPLAY_VERTICAL_OFFSET = "peek_display_vertical_offset"
+ private const val KEY_PEEK_DISPLAY_ALWAYS_VISIBLE = "peek_display_always_visible"
+ private const val KEY_PEEK_DISPLAY_TIMEOUT = "peek_display_timeout"
+
+ // Settings keys for SystemUI communication
+ private const val SYSTEMUI_PEEK_DISPLAY_ENABLED = "peek_display_enabled"
+ private const val SYSTEMUI_PEEK_DISPLAY_DISMISSIBLE = "peek_display_dismissible"
+ private const val SYSTEMUI_PEEK_DISPLAY_CLOSE_ENABLED = "peek_display_close_enabled"
+ private const val SYSTEMUI_PEEK_DISPLAY_TIMEOUT = "peek_display_timeout_ms"
+
+ // Position stability constants
+ private const val POSITION_UPDATE_DELAY = 100 // ms
+ private const val DEFAULT_VERTICAL_OFFSET = 50 // percent
+ private const val DEFAULT_TIMEOUT_SECONDS = 3 // seconds
+ private const val DEFAULT_TIMEOUT_MS = DEFAULT_TIMEOUT_SECONDS * 1000 // ms for SystemUI
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_peek_display) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context).toMutableList()
+ return keys
+ }
+ }
+ }
+
+ // Preferences
+ private var mPeekDisplayNotifications: SecureSettingSwitchPreference? = null
+ private var mPeekDisplayStyle: SecureSettingListPreference? = null
+ private var mPeekDisplayLocation: SecureSettingListPreference? = null
+ private var mVerticalOffset: SecureSettingSeekBarPreference? = null
+ private var mAlwaysVisible: SecureSettingSwitchPreference? = null
+ private var mTimeout: SecureSettingSeekBarPreference? = null
+
+ // Position management
+ private var mPositionHandler: Handler? = null
+ private var mLastValidOffset = DEFAULT_VERTICAL_OFFSET
+ private var mIsUpdatingPosition = false
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.rising_settings_peek_display)
+
+ // Initialize position handler
+ mPositionHandler = Handler(Looper.getMainLooper())
+
+ initializePreferences()
+ updatePreferenceDependencies()
+
+ // Ensure close button functionality is enabled
+ enableCloseButtonFunctionality()
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+
+ /**
+ * Initialize all preferences and set up listeners
+ */
+ private fun initializePreferences() {
+ val context = getSafeContext() ?: return
+ val resolver = context.contentResolver
+
+ // Get preferences
+ mPeekDisplayNotifications = findCachedPreference(KEY_PEEK_DISPLAY_NOTIFICATIONS)
+ mPeekDisplayStyle = findCachedPreference(KEY_PEEK_DISPLAY_STYLE)
+ mPeekDisplayLocation = findCachedPreference(KEY_PEEK_DISPLAY_LOCATION)
+ mVerticalOffset = findCachedPreference(KEY_PEEK_DISPLAY_VERTICAL_OFFSET)
+ mAlwaysVisible = findCachedPreference(KEY_PEEK_DISPLAY_ALWAYS_VISIBLE)
+ mTimeout = findCachedPreference(KEY_PEEK_DISPLAY_TIMEOUT)
+
+ // Set up listeners
+ mPeekDisplayNotifications?.onPreferenceChangeListener = this
+ mPeekDisplayLocation?.onPreferenceChangeListener = this
+ mVerticalOffset?.let { preference ->
+ preference.onPreferenceChangeListener = this
+ // Load cached position
+ val currentOffset = Settings.Secure.getInt(resolver,
+ KEY_PEEK_DISPLAY_VERTICAL_OFFSET, DEFAULT_VERTICAL_OFFSET)
+ mLastValidOffset = currentOffset
+ }
+ mAlwaysVisible?.onPreferenceChangeListener = this
+ mTimeout?.let { preference ->
+ preference.onPreferenceChangeListener = this
+ // Initialize timeout setting for SystemUI
+ val timeoutSeconds = Settings.Secure.getInt(resolver,
+ KEY_PEEK_DISPLAY_TIMEOUT, DEFAULT_TIMEOUT_SECONDS)
+ val timeoutMs = timeoutSeconds * 1000
+ Settings.Secure.putInt(resolver, SYSTEMUI_PEEK_DISPLAY_TIMEOUT, timeoutMs)
+ }
+ }
+
+ /**
+ * Update preference dependencies based on current state
+ */
+ private fun updatePreferenceDependencies() {
+ val context = getSafeContext() ?: return
+ val resolver = context.contentResolver
+
+ val peekEnabled = Settings.Secure.getInt(resolver,
+ KEY_PEEK_DISPLAY_NOTIFICATIONS, 0) == 1
+ val alwaysVisible = Settings.Secure.getInt(resolver,
+ KEY_PEEK_DISPLAY_ALWAYS_VISIBLE, 0) == 1
+
+ // Update dependent preferences
+ mPeekDisplayStyle?.isEnabled = peekEnabled
+ mPeekDisplayLocation?.isEnabled = peekEnabled
+ mVerticalOffset?.isEnabled = peekEnabled
+ mAlwaysVisible?.isEnabled = peekEnabled
+
+ mTimeout?.let { timeout ->
+ // Timeout is disabled when always visible is enabled
+ timeout.isEnabled = peekEnabled && !alwaysVisible
+ timeout.summary = if (alwaysVisible) {
+ "${getString(R.string.peek_display_timeout_summary)} (disabled - always visible enabled)"
+ } else {
+ getString(R.string.peek_display_timeout_summary)
+ }
+ }
+ }
+
+ /**
+ * Enable close button functionality for peek display
+ * This is the key method to fix the close button issue and configure timeout behavior
+ */
+ private fun enableCloseButtonFunctionality() {
+ val context = getSafeContext() ?: return
+ val resolver = context.contentResolver
+
+ // Check if always visible is enabled
+ val alwaysVisible = Settings.Secure.getInt(resolver,
+ KEY_PEEK_DISPLAY_ALWAYS_VISIBLE, 0) == 1
+
+ // Enable dismissible peek display notifications (unless always visible)
+ Settings.Secure.putInt(resolver, SYSTEMUI_PEEK_DISPLAY_DISMISSIBLE, if (alwaysVisible) 0 else 1)
+
+ // Enable close button functionality
+ Settings.Secure.putInt(resolver, SYSTEMUI_PEEK_DISPLAY_CLOSE_ENABLED, 1)
+
+ // Set timeout behavior
+ if (!alwaysVisible) {
+ // Get timeout in seconds and convert to milliseconds for SystemUI
+ val timeoutSeconds = Settings.Secure.getInt(resolver,
+ KEY_PEEK_DISPLAY_TIMEOUT, DEFAULT_TIMEOUT_SECONDS)
+ val timeoutMs = timeoutSeconds * 1000
+
+ Settings.Secure.putInt(resolver, SYSTEMUI_PEEK_DISPLAY_TIMEOUT, timeoutMs)
+
+ // Notify SystemUI of timeout changes
+ resolver.notifyChange(Settings.Secure.getUriFor(SYSTEMUI_PEEK_DISPLAY_TIMEOUT), null)
+ } else {
+ // When always visible, disable timeout (set to 0 or very high value)
+ Settings.Secure.putInt(resolver, SYSTEMUI_PEEK_DISPLAY_TIMEOUT, 0)
+ resolver.notifyChange(Settings.Secure.getUriFor(SYSTEMUI_PEEK_DISPLAY_TIMEOUT), null)
+ }
+
+ // Notify SystemUI of the changes
+ resolver.notifyChange(Settings.Secure.getUriFor(SYSTEMUI_PEEK_DISPLAY_DISMISSIBLE), null)
+ resolver.notifyChange(Settings.Secure.getUriFor(SYSTEMUI_PEEK_DISPLAY_CLOSE_ENABLED), null)
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
+ val context = getSafeContext() ?: return false
+ val key = preference.key
+ val resolver = context.contentResolver
+
+ return when (key) {
+ KEY_PEEK_DISPLAY_NOTIFICATIONS -> {
+ val enabled = newValue as Boolean
+
+ // Update SystemUI settings for peek display
+ Settings.Secure.putInt(resolver, SYSTEMUI_PEEK_DISPLAY_ENABLED, if (enabled) 1 else 0)
+
+ // Ensure close button functionality is maintained when peek display is enabled
+ if (enabled) {
+ postDelayedSafe(100) { enableCloseButtonFunctionality() }
+ }
+
+ // Update dependencies immediately
+ postDelayedSafe(50) { updatePreferenceDependencies() }
+ true
+ }
+
+ KEY_PEEK_DISPLAY_VERTICAL_OFFSET -> {
+ handleVerticalOffsetChange(newValue as Int)
+ }
+
+ KEY_PEEK_DISPLAY_LOCATION -> {
+ // Reset offset when location changes to prevent position conflicts
+ postDelayedSafe(POSITION_UPDATE_DELAY.toLong()) {
+ mVerticalOffset?.let { offset ->
+ offset.setValue(DEFAULT_VERTICAL_OFFSET)
+ mLastValidOffset = DEFAULT_VERTICAL_OFFSET
+ }
+ }
+ true
+ }
+
+ KEY_PEEK_DISPLAY_ALWAYS_VISIBLE -> {
+ val alwaysVisible = newValue as Boolean
+
+ // Update dependencies when always visible changes
+ postDelayedSafe(50) { updatePreferenceDependencies() }
+
+ // Apply the always visible setting
+ Settings.Secure.putInt(resolver, KEY_PEEK_DISPLAY_ALWAYS_VISIBLE, if (alwaysVisible) 1 else 0)
+
+ // When always visible is disabled, ensure close button works
+ if (!alwaysVisible) {
+ postDelayedSafe(100) { enableCloseButtonFunctionality() }
+ }
+
+ // Force refresh of the system UI to apply changes
+ postDelayedSafe(50) {
+ resolver.notifyChange(Settings.Secure.getUriFor(KEY_PEEK_DISPLAY_ALWAYS_VISIBLE), null)
+ }
+
+ true
+ }
+
+ KEY_PEEK_DISPLAY_TIMEOUT -> {
+ var timeoutSeconds = newValue as Int
+ // Validate timeout range (1-10 seconds)
+ timeoutSeconds = timeoutSeconds.coerceIn(1, 10)
+
+ // Convert to milliseconds for SystemUI
+ val timeoutMs = timeoutSeconds * 1000
+
+ // Update SystemUI timeout setting
+ Settings.Secure.putInt(resolver, SYSTEMUI_PEEK_DISPLAY_TIMEOUT, timeoutMs)
+
+ // Notify SystemUI of timeout changes
+ postDelayedSafe(100) {
+ resolver.notifyChange(Settings.Secure.getUriFor(SYSTEMUI_PEEK_DISPLAY_TIMEOUT), null)
+ // Ensure close button and timeout behavior work together
+ enableCloseButtonFunctionality()
+ }
+
+ true
+ }
+
+ else -> true
+ }
+ }
+
+ /**
+ * Handle vertical offset changes with stability measures
+ */
+ private fun handleVerticalOffsetChange(newOffset: Int): Boolean {
+ if (mIsUpdatingPosition) {
+ return false // Prevent recursive updates
+ }
+
+ val context = getSafeContext() ?: return false
+
+ // Validate offset range
+ val validOffset = newOffset.coerceIn(0, 100)
+
+ // Check for rapid changes (potential instability)
+ return if (abs(validOffset - mLastValidOffset) > 20) {
+ // Large jump detected - use delayed update for stability
+ mIsUpdatingPosition = true
+
+ mPositionHandler?.removeCallbacksAndMessages(null)
+ mPositionHandler?.postDelayed({
+ applyStableVerticalOffset(validOffset)
+ mIsUpdatingPosition = false
+ }, POSITION_UPDATE_DELAY.toLong())
+
+ false // Don't apply immediately
+ } else {
+ // Small change - apply immediately
+ applyStableVerticalOffset(validOffset)
+ }
+ }
+
+ /**
+ * Apply vertical offset with stability checks
+ */
+ private fun applyStableVerticalOffset(offset: Int): Boolean {
+ val context = getSafeContext() ?: return false
+ val resolver = context.contentResolver
+
+ // Cache the position for stability
+ mLastValidOffset = offset
+
+ // Apply the setting
+ Settings.Secure.putInt(resolver, KEY_PEEK_DISPLAY_VERTICAL_OFFSET, offset)
+
+ // Force refresh of the system UI to apply changes
+ postDelayedSafe(50) {
+ // Notify system of the change
+ resolver.notifyChange(Settings.Secure.getUriFor(KEY_PEEK_DISPLAY_VERTICAL_OFFSET), null)
+ }
+
+ return true
+ }
+
+ override fun onResume() {
+ super.onResume()
+
+ // Restore cached position on resume to prevent drift
+ mVerticalOffset?.let { verticalOffset ->
+ val context = getSafeContext()
+ if (context != null) {
+ val resolver = context.contentResolver
+ val currentOffset = Settings.Secure.getInt(resolver,
+ KEY_PEEK_DISPLAY_VERTICAL_OFFSET, DEFAULT_VERTICAL_OFFSET)
+
+ // Check if position has drifted
+ if (abs(currentOffset - mLastValidOffset) > 5) {
+ // Position has drifted - restore stable position
+ postDelayedSafe(100) {
+ Settings.Secure.putInt(resolver, KEY_PEEK_DISPLAY_VERTICAL_OFFSET, mLastValidOffset)
+ verticalOffset.setValue(mLastValidOffset)
+ }
+ } else {
+ mLastValidOffset = currentOffset
+ }
+ }
+ }
+
+ updatePreferenceDependencies()
+
+ // Ensure close button functionality is always enabled on resume
+ enableCloseButtonFunctionality()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+
+ // Clean up position handler
+ mPositionHandler?.removeCallbacksAndMessages(null)
+ }
+}
diff --git a/src/com/rising/settings/fragments/lockscreen/UdfpsAnimation.java b/src/com/rising/settings/fragments/lockscreen/UdfpsAnimation.java
deleted file mode 100644
index 0b944315..00000000
--- a/src/com/rising/settings/fragments/lockscreen/UdfpsAnimation.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2022-2024 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.rising.settings.fragments.lockscreen;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.PreferenceViewHolder;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.bumptech.glide.Glide;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.SettingsPreferenceFragment;
-
-import java.util.Arrays;
-
-public class UdfpsAnimation extends SettingsPreferenceFragment {
-
- private RecyclerView mRecyclerView;
- private String mPkg = "com.crdroid.udfps.animations";
- private AnimationDrawable animation;
-
- private Resources udfpsRes;
-
- private String[] mAnims;
- private String[] mAnimPreviews;
- private String[] mTitles;
-
- private UdfpsAnimAdapter mUdfpsAnimAdapter;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getActivity().setTitle(R.string.udfps_recog_animation_effect_title);
-
- loadResources();
- }
-
- private void loadResources() {
- try {
- PackageManager pm = getActivity().getPackageManager();
- udfpsRes = pm.getResourcesForApplication(mPkg);
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
-
- mAnims = udfpsRes.getStringArray(udfpsRes.getIdentifier("udfps_animation_styles",
- "array", mPkg));
- mAnimPreviews = udfpsRes.getStringArray(udfpsRes.getIdentifier("udfps_animation_previews",
- "array", mPkg));
- mTitles = udfpsRes.getStringArray(udfpsRes.getIdentifier("udfps_animation_titles",
- "array", mPkg));
- }
-
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(
- R.layout.item_view, container, false);
-
- mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
- GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
- mRecyclerView.setLayoutManager(gridLayoutManager);
- mUdfpsAnimAdapter = new UdfpsAnimAdapter(getActivity());
- mRecyclerView.setAdapter(mUdfpsAnimAdapter);
-
- return view;
- }
-
- public static void reset(Context mContext) {
- ContentResolver resolver = mContext.getContentResolver();
- Settings.System.putIntForUser(resolver,
- Settings.System.UDFPS_ANIM_STYLE, 0, UserHandle.USER_CURRENT);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.VIEW_UNKNOWN;
- }
-
- public class UdfpsAnimAdapter extends RecyclerView.Adapter {
- Context context;
- String mSelectedAnim;
- String mAppliedAnim;
-
- public UdfpsAnimAdapter(Context context) {
- this.context = context;
- }
-
- @Override
- public UdfpsAnimViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_option, parent, false);
- UdfpsAnimViewHolder vh = new UdfpsAnimViewHolder(v);
- return vh;
- }
-
- @Override
- public void onBindViewHolder(UdfpsAnimViewHolder holder, final int position) {
- String animName = mAnims[position];
-
- Glide.with(holder.image.getContext())
- .load("")
- .placeholder(getDrawable(holder.image.getContext(), mAnimPreviews[position]))
- .into(holder.image);
-
- holder.name.setText(mTitles[position]);
-
- if (position == Settings.System.getInt(context.getContentResolver(),
- Settings.System.UDFPS_ANIM_STYLE, 0)) {
- mAppliedAnim = animName;
- if (mSelectedAnim == null) {
- mSelectedAnim = animName;
- }
- }
-
- holder.itemView.setActivated(animName == mSelectedAnim);
- holder.itemView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- updateActivatedStatus(mSelectedAnim, false);
- updateActivatedStatus(animName, true);
- mSelectedAnim = animName;
- holder.image.setBackgroundDrawable(getDrawable(v.getContext(), mAnims[position]));
- animation = (AnimationDrawable) holder.image.getBackground();
- animation.setOneShot(true);
- animation.start();
- Settings.System.putInt(getActivity().getContentResolver(),
- Settings.System.UDFPS_ANIM_STYLE, position);
- }
- });
- }
-
- @Override
- public int getItemCount() {
- return mAnims.length;
- }
-
- public class UdfpsAnimViewHolder extends RecyclerView.ViewHolder {
- TextView name;
- ImageView image;
- public UdfpsAnimViewHolder(View itemView) {
- super(itemView);
- name = (TextView) itemView.findViewById(R.id.option_label);
- image = (ImageView) itemView.findViewById(R.id.option_thumbnail);
- }
- }
-
- private void updateActivatedStatus(String anim, boolean isActivated) {
- int index = Arrays.asList(mAnims).indexOf(anim);
- if (index < 0) {
- return;
- }
- RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(index);
- if (holder != null && holder.itemView != null) {
- holder.itemView.setActivated(isActivated);
- }
- }
- }
-
- public Drawable getDrawable(Context context, String drawableName) {
- try {
- PackageManager pm = context.getPackageManager();
- Resources res = pm.getResourcesForApplication(mPkg);
- return res.getDrawable(res.getIdentifier(drawableName, "drawable", mPkg));
- }
- catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
-}
diff --git a/src/com/rising/settings/fragments/lockscreen/UdfpsAnimation.kt b/src/com/rising/settings/fragments/lockscreen/UdfpsAnimation.kt
new file mode 100644
index 00000000..b7edd7da
--- /dev/null
+++ b/src/com/rising/settings/fragments/lockscreen/UdfpsAnimation.kt
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2022-2024 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings.fragments.lockscreen
+
+import android.content.ContentResolver
+import android.content.Context
+import android.content.pm.PackageManager
+import android.content.res.Resources
+import android.graphics.drawable.AnimationDrawable
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.Settings
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+
+import androidx.annotation.NonNull
+import androidx.annotation.Nullable
+import androidx.preference.Preference.OnPreferenceChangeListener
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+import androidx.preference.PreferenceViewHolder
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
+import androidx.recyclerview.widget.RecyclerView
+
+import com.bumptech.glide.Glide
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent
+import com.android.settings.R
+import com.android.settings.SettingsActivity
+import com.android.settings.SettingsPreferenceFragment
+
+import java.util.Arrays
+import java.util.concurrent.ConcurrentHashMap
+import android.os.Handler
+import android.os.Looper
+import java.lang.ref.WeakReference
+
+class UdfpsAnimation : SettingsPreferenceFragment() {
+
+ private var mRecyclerView: RecyclerView? = null
+ private val mPkg = "com.crdroid.udfps.animations"
+ private var animation: AnimationDrawable? = null
+
+ private var udfpsRes: Resources? = null
+
+ private var mAnims: Array? = null
+ private var mAnimPreviews: Array? = null
+ private var mTitles: Array? = null
+
+ private var mUdfpsAnimAdapter: UdfpsAnimAdapter? = null
+
+ // Cache for drawable resources to prevent repeated loading
+ private val mDrawableCache: MutableMap = ConcurrentHashMap()
+
+ // Handler for animation cleanup
+ private var mAnimationHandler: Handler? = null
+
+ // Track active animations to prevent memory leaks
+ private var mCurrentAnimation: AnimationDrawable? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ activity?.setTitle(R.string.udfps_recog_animation_effect_title)
+
+ // Initialize handler for animation management
+ mAnimationHandler = Handler(Looper.getMainLooper())
+
+ loadResources()
+ }
+
+ private fun loadResources() {
+ val activity = activity ?: return
+
+ try {
+ val pm = activity.packageManager
+ udfpsRes = pm.getResourcesForApplication(mPkg)
+
+ udfpsRes?.let { res ->
+ mAnims = res.getStringArray(res.getIdentifier("udfps_animation_styles", "array", mPkg))
+ mAnimPreviews = res.getStringArray(res.getIdentifier("udfps_animation_previews", "array", mPkg))
+ mTitles = res.getStringArray(res.getIdentifier("udfps_animation_titles", "array", mPkg))
+ }
+ } catch (e: PackageManager.NameNotFoundException) {
+ e.printStackTrace()
+ }
+ }
+
+ override fun onCreateView(
+ @NonNull inflater: LayoutInflater,
+ @Nullable container: ViewGroup?,
+ @Nullable savedInstanceState: Bundle?
+ ): View {
+ val view = inflater.inflate(R.layout.item_view, container, false)
+
+ mRecyclerView = view.findViewById(R.id.recycler_view)?.apply {
+ val gridLayoutManager = GridLayoutManager(activity, 3)
+ layoutManager = gridLayoutManager
+ mUdfpsAnimAdapter = UdfpsAnimAdapter(activity!!)
+ adapter = mUdfpsAnimAdapter
+ }
+
+ return view
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsEvent.VIEW_UNKNOWN
+ }
+
+ inner class UdfpsAnimAdapter(private val context: Context) : RecyclerView.Adapter() {
+ private var mSelectedAnim: String? = null
+ private var mAppliedAnim: String? = null
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UdfpsAnimViewHolder {
+ val v = LayoutInflater.from(parent.context).inflate(R.layout.item_option, parent, false)
+ return UdfpsAnimViewHolder(v)
+ }
+
+ override fun onBindViewHolder(holder: UdfpsAnimViewHolder, position: Int) {
+ val anims = mAnims ?: return
+ val animPreviews = mAnimPreviews ?: return
+ val titles = mTitles ?: return
+
+ if (position >= anims.size || position >= animPreviews.size || position >= titles.size) {
+ return
+ }
+
+ val animName = anims[position]
+
+ // Use cached drawable if available
+ val previewDrawable = getCachedDrawable(holder.image.context, animPreviews[position])
+ if (previewDrawable != null) {
+ Glide.with(holder.image.context)
+ .load("")
+ .placeholder(previewDrawable)
+ .into(holder.image)
+ }
+
+ holder.name.text = titles[position]
+
+ if (position == Settings.System.getInt(context.contentResolver,
+ Settings.System.UDFPS_ANIM_STYLE, 0)) {
+ mAppliedAnim = animName
+ if (mSelectedAnim == null) {
+ mSelectedAnim = animName
+ }
+ }
+
+ holder.itemView.isActivated = animName == mSelectedAnim
+ holder.itemView.setOnClickListener { v ->
+ // Stop current animation before starting new one
+ stopCurrentAnimation()
+
+ updateActivatedStatus(mSelectedAnim, false)
+ updateActivatedStatus(animName, true)
+ mSelectedAnim = animName
+
+ val animDrawable = getCachedDrawable(v.context, anims[position])
+ if (animDrawable != null) {
+ holder.image.background = animDrawable
+ mCurrentAnimation = holder.image.background as? AnimationDrawable
+ mCurrentAnimation?.let { animation ->
+ animation.setOneShot(true)
+ animation.start()
+
+ // Auto-stop animation after reasonable time to prevent memory leaks
+ mAnimationHandler?.postDelayed({ stopCurrentAnimation() }, 5000)
+ }
+ }
+
+ activity?.let { activity ->
+ Settings.System.putInt(activity.contentResolver,
+ Settings.System.UDFPS_ANIM_STYLE, position)
+ }
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return mAnims?.size ?: 0
+ }
+
+ inner class UdfpsAnimViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val name: TextView = itemView.findViewById(R.id.option_label)
+ val image: ImageView = itemView.findViewById(R.id.option_thumbnail)
+ }
+
+ private fun updateActivatedStatus(anim: String?, isActivated: Boolean) {
+ val anims = mAnims ?: return
+ val index = anims.indexOf(anim)
+ if (index < 0) {
+ return
+ }
+ val holder = mRecyclerView?.findViewHolderForAdapterPosition(index)
+ holder?.itemView?.isActivated = isActivated
+ }
+ }
+
+ // Optimized drawable loading with caching
+ private fun getCachedDrawable(context: Context?, drawableName: String?): Drawable? {
+ if (drawableName == null || context == null) {
+ return null
+ }
+
+ // Check cache first
+ val cached = mDrawableCache[drawableName]
+ if (cached != null) {
+ return cached
+ }
+
+ // Load and cache drawable
+ val drawable = getDrawable(context, drawableName)
+ if (drawable != null) {
+ mDrawableCache[drawableName] = drawable
+ }
+ return drawable
+ }
+
+ private fun getDrawable(context: Context, drawableName: String): Drawable? {
+ return try {
+ val pm = context.packageManager
+ val res = pm.getResourcesForApplication(mPkg)
+ res.getDrawable(res.getIdentifier(drawableName, "drawable", mPkg))
+ } catch (e: PackageManager.NameNotFoundException) {
+ e.printStackTrace()
+ null
+ }
+ }
+
+ private fun stopCurrentAnimation() {
+ mCurrentAnimation?.let { animation ->
+ if (animation.isRunning) {
+ animation.stop()
+ }
+ }
+ mCurrentAnimation = null
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ // Cleanup animations and caches
+ stopCurrentAnimation()
+ mAnimationHandler?.removeCallbacksAndMessages(null)
+ mDrawableCache.clear()
+ udfpsRes = null
+ }
+
+ override fun onDetach() {
+ super.onDetach()
+ // Additional cleanup
+ stopCurrentAnimation()
+ mDrawableCache.clear()
+ }
+
+ companion object {
+ @JvmStatic
+ fun reset(mContext: Context) {
+ val resolver = mContext.contentResolver
+ Settings.System.putIntForUser(resolver,
+ Settings.System.UDFPS_ANIM_STYLE, 0, UserHandle.USER_CURRENT)
+ }
+ }
+}
diff --git a/src/com/rising/settings/fragments/lockscreen/UdfpsIconPicker.java b/src/com/rising/settings/fragments/lockscreen/UdfpsIconPicker.java
deleted file mode 100644
index cfed6e51..00000000
--- a/src/com/rising/settings/fragments/lockscreen/UdfpsIconPicker.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2022-2024 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.rising.settings.fragments.lockscreen;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.net.Uri;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.content.res.ResourcesCompat;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.PreferenceViewHolder;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.bumptech.glide.Glide;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.Indexable;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-public class UdfpsIconPicker extends SettingsPreferenceFragment {
-
- private RecyclerView mRecyclerView;
-
- private Resources udfpsRes;
-
- private String mPkg = "com.crdroid.udfps.icons";
-
- private String[] mIcons;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getActivity().setTitle(R.string.udfps_icon_picker_title);
-
- loadResources();
- }
-
- private void loadResources() {
- try {
- PackageManager pm = getActivity().getPackageManager();
- udfpsRes = pm.getResourcesForApplication(mPkg);
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
-
- mIcons = udfpsRes.getStringArray(udfpsRes.getIdentifier("udfps_icons",
- "array", mPkg));
- }
-
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(
- R.layout.item_view, container, false);
-
- mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
- GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
- mRecyclerView.setLayoutManager(gridLayoutManager);
- UdfpsIconAdapter mUdfpsIconAdapter = new UdfpsIconAdapter(getActivity());
- mRecyclerView.setAdapter(mUdfpsIconAdapter);
-
- return view;
- }
-
- public static void reset(Context mContext) {
- ContentResolver resolver = mContext.getContentResolver();
- Settings.System.putIntForUser(resolver,
- "udfps_icon", 0, UserHandle.USER_CURRENT);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.VIEW_UNKNOWN;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- }
-
- public class UdfpsIconAdapter extends RecyclerView.Adapter {
- Context context;
- String mSelectedIcon;
- String mAppliedIcon;
-
- public UdfpsIconAdapter(Context context) {
- this.context = context;
- }
-
- @Override
- public UdfpsIconViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_option, parent, false);
- UdfpsIconViewHolder vh = new UdfpsIconViewHolder(v);
- return vh;
- }
-
- @Override
- public void onBindViewHolder(UdfpsIconViewHolder holder, final int position) {
- String iconRes = mIcons[position];
-
- Glide.with(holder.image.getContext())
- .load("")
- .placeholder(getDrawable(holder.image.getContext(), mIcons[position]))
- .into(holder.image);
-
- holder.image.setPadding(20,20,20,20);
-
- holder.name.setVisibility(View.GONE);
-
- if (position == Settings.System.getInt(context.getContentResolver(),
- "udfps_icon", 0)) {
- mAppliedIcon = iconRes;
- if (mSelectedIcon == null) {
- mSelectedIcon = iconRes;
- }
- }
- holder.itemView.setActivated(iconRes == mSelectedIcon);
- holder.itemView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- updateActivatedStatus(mSelectedIcon, false);
- updateActivatedStatus(iconRes, true);
- mSelectedIcon = iconRes;
- Settings.System.putInt(getActivity().getContentResolver(),
- "udfps_icon", position);
- }
- });
- }
-
- @Override
- public int getItemCount() {
- return mIcons.length;
- }
-
- public class UdfpsIconViewHolder extends RecyclerView.ViewHolder {
- TextView name;
- ImageView image;
- public UdfpsIconViewHolder(View itemView) {
- super(itemView);
- name = (TextView) itemView.findViewById(R.id.option_label);
- image = (ImageView) itemView.findViewById(R.id.option_thumbnail);
- }
- }
-
- private void updateActivatedStatus(String icon, boolean isActivated) {
- int index = Arrays.asList(mIcons).indexOf(icon);
- if (index < 0) {
- return;
- }
- RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(index);
- if (holder != null && holder.itemView != null) {
- holder.itemView.setActivated(isActivated);
- }
- }
- }
-
- public Drawable getDrawable(Context context, String drawableName) {
- try {
- PackageManager pm = context.getPackageManager();
- Resources res = pm.getResourcesForApplication(mPkg);
- Context ctx = context.createPackageContext(
- mPkg, Context.CONTEXT_IGNORE_SECURITY);
- return ctx.getDrawable(res.getIdentifier(drawableName, "drawable", mPkg));
- }
- catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
-}
diff --git a/src/com/rising/settings/fragments/lockscreen/UdfpsIconPicker.kt b/src/com/rising/settings/fragments/lockscreen/UdfpsIconPicker.kt
new file mode 100644
index 00000000..6e9c3303
--- /dev/null
+++ b/src/com/rising/settings/fragments/lockscreen/UdfpsIconPicker.kt
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2022-2024 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings.fragments.lockscreen
+
+import android.app.Activity
+import android.content.ContentResolver
+import android.content.Context
+import android.content.pm.PackageManager
+import android.content.res.Resources
+import android.graphics.drawable.AnimationDrawable
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.os.UserHandle
+import android.net.Uri
+import android.provider.SearchIndexableResource
+import android.provider.Settings
+import android.text.TextUtils
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup.LayoutParams
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.TextView
+import android.widget.Toast
+
+import androidx.annotation.NonNull
+import androidx.annotation.Nullable
+import androidx.core.content.res.ResourcesCompat
+import androidx.preference.Preference.OnPreferenceChangeListener
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+import androidx.preference.PreferenceViewHolder
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
+import androidx.recyclerview.widget.RecyclerView
+
+import com.bumptech.glide.Glide
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.Indexable
+
+import java.util.ArrayList
+import java.util.Arrays
+import java.util.List
+
+import org.json.JSONException
+import org.json.JSONObject
+
+class UdfpsIconPicker : OptimizedSettingsFragment() {
+
+ private lateinit var mRecyclerView: RecyclerView
+ private var udfpsRes: Resources? = null
+ private val mPkg = "com.crdroid.udfps.icons"
+ private lateinit var mIcons: Array
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ activity?.setTitle(R.string.udfps_icon_picker_title)
+
+ loadResources()
+ }
+
+ private fun loadResources() {
+ try {
+ val context = getSafeContext()
+ if (context != null) {
+ udfpsRes = context.packageManager?.getResourcesForApplication(mPkg)
+ }
+ } catch (e: PackageManager.NameNotFoundException) {
+ // Handle silently - package not found
+ }
+
+ udfpsRes?.let { res ->
+ mIcons = res.getStringArray(res.getIdentifier("udfps_icons", "array", mPkg))
+ }
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ val view = inflater.inflate(R.layout.item_view, container, false)
+
+ mRecyclerView = view.findViewById(R.id.recycler_view)
+ val gridLayoutManager = GridLayoutManager(activity, 3)
+ mRecyclerView.layoutManager = gridLayoutManager
+ val mUdfpsIconAdapter = UdfpsIconAdapter(activity!!)
+ mRecyclerView.adapter = mUdfpsIconAdapter
+
+ return view
+ }
+
+ companion object {
+ @JvmStatic
+ fun reset(mContext: Context) {
+ val resolver = mContext.contentResolver
+ Settings.System.putIntForUser(resolver,
+ "udfps_icon", 0, UserHandle.USER_CURRENT)
+ }
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsEvent.VIEW_UNKNOWN
+ }
+
+ override fun onResume() {
+ super.onResume()
+ }
+
+ inner class UdfpsIconAdapter(val context: Context) : RecyclerView.Adapter() {
+ private var mSelectedIcon: String? = null
+ private var mAppliedIcon: String? = null
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UdfpsIconViewHolder {
+ val v = LayoutInflater.from(parent.context).inflate(R.layout.item_option, parent, false)
+ return UdfpsIconViewHolder(v)
+ }
+
+ override fun onBindViewHolder(holder: UdfpsIconViewHolder, position: Int) {
+ val iconRes = mIcons[position]
+
+ Glide.with(holder.image.context)
+ .load("")
+ .placeholder(getDrawable(holder.image.context, mIcons[position]))
+ .into(holder.image)
+
+ holder.image.setPadding(20, 20, 20, 20)
+ holder.name.visibility = View.GONE
+
+ if (position == Settings.System.getInt(context.contentResolver, "udfps_icon", 0)) {
+ mAppliedIcon = iconRes
+ if (mSelectedIcon == null) {
+ mSelectedIcon = iconRes
+ }
+ }
+ holder.itemView.isActivated = iconRes == mSelectedIcon
+ holder.itemView.setOnClickListener {
+ updateActivatedStatus(mSelectedIcon, false)
+ updateActivatedStatus(iconRes, true)
+ mSelectedIcon = iconRes
+ Settings.System.putInt(activity?.contentResolver,
+ "udfps_icon", position)
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return mIcons.size
+ }
+
+ inner class UdfpsIconViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val name: TextView = itemView.findViewById(R.id.option_label)
+ val image: ImageView = itemView.findViewById(R.id.option_thumbnail)
+ }
+
+ private fun updateActivatedStatus(icon: String?, isActivated: Boolean) {
+ val index = mIcons.indexOf(icon)
+ if (index < 0) {
+ return
+ }
+ val holder = mRecyclerView.findViewHolderForAdapterPosition(index)
+ holder?.itemView?.isActivated = isActivated
+ }
+ }
+
+ private fun getDrawable(context: Context, drawableName: String): Drawable? {
+ return try {
+ val pm = context.packageManager
+ val res = pm.getResourcesForApplication(mPkg)
+ val ctx = context.createPackageContext(mPkg, Context.CONTEXT_IGNORE_SECURITY)
+ ctx.getDrawable(res.getIdentifier(drawableName, "drawable", mPkg))
+ } catch (e: PackageManager.NameNotFoundException) {
+ // Handle silently - package not found
+ null
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ udfpsRes = null
+ }
+}
diff --git a/src/com/rising/settings/fragments/lockscreen/doze/AODSchedule.java b/src/com/rising/settings/fragments/lockscreen/doze/AODSchedule.java
deleted file mode 100644
index c63ec87b..00000000
--- a/src/com/rising/settings/fragments/lockscreen/doze/AODSchedule.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2021 Yet Another AOSP Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments.lockscreen.doze;
-
-import android.app.TimePickerDialog;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.text.format.DateFormat;
-import android.widget.TimePicker;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.logging.nano.MetricsProto;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-import com.android.settings.preferences.SecureSettingListPreference;
-
-import java.time.format.DateTimeFormatter;
-import java.time.LocalTime;
-
-public class AODSchedule extends SettingsPreferenceFragment implements
- Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
-
- private static final String TAG = "AODSchedule";
- private static final String MODE_KEY = "doze_always_on_auto_mode";
- private static final String SINCE_PREF_KEY = "doze_always_on_auto_since";
- private static final String TILL_PREF_KEY = "doze_always_on_auto_till";
-
- private static final int MODE_DISABLED = 0;
- private static final int MODE_NIGHT = 1;
- private static final int MODE_TIME = 2;
- private static final int MODE_MIXED_SUNSET = 3;
- private static final int MODE_MIXED_SUNRISE = 4;
-
- private SecureSettingListPreference mModePref;
- private Preference mSincePref;
- private Preference mTillPref;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.always_on_display_schedule);
-
- ContentResolver resolver = getActivity().getContentResolver();
-
- mSincePref = findPreference(SINCE_PREF_KEY);
- mSincePref.setOnPreferenceClickListener(this);
- mTillPref = findPreference(TILL_PREF_KEY);
- mTillPref.setOnPreferenceClickListener(this);
-
- int mode = Settings.Secure.getIntForUser(resolver,
- MODE_KEY, MODE_DISABLED, UserHandle.USER_CURRENT);
- mModePref = (SecureSettingListPreference) findPreference(MODE_KEY);
- mModePref.setValue(String.valueOf(mode));
- mModePref.setSummary(mModePref.getEntry());
- mModePref.setOnPreferenceChangeListener(this);
-
- updateTimeEnablement(mode);
- updateTimeSummary(mode);
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object objValue) {
- int value = Integer.parseInt((String) objValue);
- int index = mModePref.findIndexOfValue((String) objValue);
- mModePref.setSummary(mModePref.getEntries()[index]);
- Settings.Secure.putIntForUser(getActivity().getContentResolver(),
- MODE_KEY, value, UserHandle.USER_CURRENT);
- updateTimeEnablement(value);
- updateTimeSummary(value);
- return true;
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- String[] times = getCustomTimeSetting();
- boolean isSince = preference == mSincePref;
- int hour, minute;
- TimePickerDialog.OnTimeSetListener listener = (view, hourOfDay, minute1) -> {
- updateTimeSetting(isSince, hourOfDay, minute1);
- };
- if (isSince) {
- String[] sinceValues = times[0].split(":", 0);
- hour = Integer.parseInt(sinceValues[0]);
- minute = Integer.parseInt(sinceValues[1]);
- } else {
- String[] tillValues = times[1].split(":", 0);
- hour = Integer.parseInt(tillValues[0]);
- minute = Integer.parseInt(tillValues[1]);
- }
- TimePickerDialog dialog = new TimePickerDialog(getContext(), listener,
- hour, minute, DateFormat.is24HourFormat(getContext()));
- dialog.show();
- return true;
- }
-
- private String[] getCustomTimeSetting() {
- String value = Settings.Secure.getStringForUser(getActivity().getContentResolver(),
- Settings.Secure.DOZE_ALWAYS_ON_AUTO_TIME, UserHandle.USER_CURRENT);
- if (value == null || value.equals("")) value = "20:00,07:00";
- return value.split(",", 0);
- }
-
- private void updateTimeEnablement(int mode) {
- mSincePref.setEnabled(mode == MODE_TIME || mode == MODE_MIXED_SUNRISE);
- mTillPref.setEnabled(mode == MODE_TIME || mode == MODE_MIXED_SUNSET);
- }
-
- private void updateTimeSummary(int mode) {
- updateTimeSummary(getCustomTimeSetting(), mode);
- }
-
- private void updateTimeSummary(String[] times, int mode) {
- if (mode == MODE_DISABLED) {
- mSincePref.setSummary("-");
- mTillPref.setSummary("-");
- return;
- }
-
- if (mode == MODE_NIGHT) {
- mSincePref.setSummary(R.string.always_on_display_schedule_sunset);
- mTillPref.setSummary(R.string.always_on_display_schedule_sunrise);
- return;
- }
-
- String outputFormat = DateFormat.is24HourFormat(getContext()) ? "HH:mm" : "hh:mm a";
- DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern(outputFormat);
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
- LocalTime sinceDT = LocalTime.parse(times[0], formatter);
- LocalTime tillDT = LocalTime.parse(times[1], formatter);
-
- if (mode == MODE_MIXED_SUNSET) {
- mSincePref.setSummary(R.string.always_on_display_schedule_sunset);
- mTillPref.setSummary(tillDT.format(outputFormatter));
- } else if (mode == MODE_MIXED_SUNRISE) {
- mTillPref.setSummary(R.string.always_on_display_schedule_sunrise);
- mSincePref.setSummary(sinceDT.format(outputFormatter));
- } else {
- mSincePref.setSummary(sinceDT.format(outputFormatter));
- mTillPref.setSummary(tillDT.format(outputFormatter));
- }
- }
-
- private void updateTimeSetting(boolean since, int hour, int minute) {
- String[] times = getCustomTimeSetting();
- String nHour = "";
- String nMinute = "";
- if (hour < 10) nHour += "0";
- if (minute < 10) nMinute += "0";
- nHour += String.valueOf(hour);
- nMinute += String.valueOf(minute);
- times[since ? 0 : 1] = nHour + ":" + nMinute;
- Settings.Secure.putStringForUser(getActivity().getContentResolver(),
- Settings.Secure.DOZE_ALWAYS_ON_AUTO_TIME,
- times[0] + "," + times[1], UserHandle.USER_CURRENT);
- updateTimeSummary(times, Integer.parseInt(mModePref.getValue()));
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-}
diff --git a/src/com/rising/settings/fragments/lockscreen/doze/AODSchedule.kt b/src/com/rising/settings/fragments/lockscreen/doze/AODSchedule.kt
new file mode 100644
index 00000000..72af6cf7
--- /dev/null
+++ b/src/com/rising/settings/fragments/lockscreen/doze/AODSchedule.kt
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2021 Yet Another AOSP Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments.lockscreen.doze
+
+import android.app.TimePickerDialog
+import android.content.ContentResolver
+import android.content.Context
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.Settings
+import android.text.format.DateFormat
+import android.widget.TimePicker
+
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+
+import com.android.internal.logging.nano.MetricsProto
+
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+
+import com.android.settings.preferences.SecureSettingListPreference
+
+import java.time.format.DateTimeFormatter
+import java.time.LocalTime
+
+class AODSchedule : OptimizedSettingsFragment(),
+ Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
+
+ companion object {
+ private const val TAG = "AODSchedule"
+ private const val MODE_KEY = "doze_always_on_auto_mode"
+ private const val SINCE_PREF_KEY = "doze_always_on_auto_since"
+ private const val TILL_PREF_KEY = "doze_always_on_auto_till"
+
+ private const val MODE_DISABLED = 0
+ private const val MODE_NIGHT = 1
+ private const val MODE_TIME = 2
+ private const val MODE_MIXED_SUNSET = 3
+ private const val MODE_MIXED_SUNRISE = 4
+ }
+
+ private lateinit var mModePref: SecureSettingListPreference
+ private lateinit var mSincePref: Preference
+ private lateinit var mTillPref: Preference
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.always_on_display_schedule)
+
+ val resolver = activity?.contentResolver
+
+ mSincePref = findPreference(SINCE_PREF_KEY)!!
+ mSincePref.onPreferenceClickListener = this
+ mTillPref = findPreference(TILL_PREF_KEY)!!
+ mTillPref.onPreferenceClickListener = this
+
+ val mode = Settings.Secure.getIntForUser(resolver,
+ MODE_KEY, MODE_DISABLED, UserHandle.USER_CURRENT)
+ mModePref = findPreference(MODE_KEY)!!
+ mModePref.value = mode.toString()
+ mModePref.summary = mModePref.entry
+ mModePref.onPreferenceChangeListener = this
+
+ updateTimeEnablement(mode)
+ updateTimeSummary(mode)
+ }
+
+ override fun onPreferenceChange(preference: Preference, objValue: Any): Boolean {
+ val value = (objValue as String).toInt()
+ val index = mModePref.findIndexOfValue(objValue)
+ mModePref.summary = mModePref.entries[index]
+ Settings.Secure.putIntForUser(activity?.contentResolver,
+ MODE_KEY, value, UserHandle.USER_CURRENT)
+ updateTimeEnablement(value)
+ updateTimeSummary(value)
+ return true
+ }
+
+ override fun onPreferenceClick(preference: Preference): Boolean {
+ val times = getCustomTimeSetting()
+ val isSince = preference == mSincePref
+ val hour: Int
+ val minute: Int
+ val listener = TimePickerDialog.OnTimeSetListener { _, hourOfDay, minute1 ->
+ updateTimeSetting(isSince, hourOfDay, minute1)
+ }
+ if (isSince) {
+ val sinceValues = times[0].split(":")
+ hour = sinceValues[0].toInt()
+ minute = sinceValues[1].toInt()
+ } else {
+ val tillValues = times[1].split(":")
+ hour = tillValues[0].toInt()
+ minute = tillValues[1].toInt()
+ }
+ val dialog = TimePickerDialog(context, listener,
+ hour, minute, DateFormat.is24HourFormat(context))
+ dialog.show()
+ return true
+ }
+
+ private fun getCustomTimeSetting(): Array {
+ var value = Settings.Secure.getStringForUser(activity?.contentResolver,
+ Settings.Secure.DOZE_ALWAYS_ON_AUTO_TIME, UserHandle.USER_CURRENT)
+ if (value.isNullOrEmpty()) value = "20:00,07:00"
+ return value.split(",").toTypedArray()
+ }
+
+ private fun updateTimeEnablement(mode: Int) {
+ mSincePref.isEnabled = mode == MODE_TIME || mode == MODE_MIXED_SUNRISE
+ mTillPref.isEnabled = mode == MODE_TIME || mode == MODE_MIXED_SUNSET
+ }
+
+ private fun updateTimeSummary(mode: Int) {
+ updateTimeSummary(getCustomTimeSetting(), mode)
+ }
+
+ private fun updateTimeSummary(times: Array, mode: Int) {
+ if (mode == MODE_DISABLED) {
+ mSincePref.summary = "-"
+ mTillPref.summary = "-"
+ return
+ }
+
+ if (mode == MODE_NIGHT) {
+ mSincePref.setSummary(R.string.always_on_display_schedule_sunset)
+ mTillPref.setSummary(R.string.always_on_display_schedule_sunrise)
+ return
+ }
+
+ val outputFormat = if (DateFormat.is24HourFormat(context)) "HH:mm" else "hh:mm a"
+ val outputFormatter = DateTimeFormatter.ofPattern(outputFormat)
+ val formatter = DateTimeFormatter.ofPattern("HH:mm")
+ val sinceDT = LocalTime.parse(times[0], formatter)
+ val tillDT = LocalTime.parse(times[1], formatter)
+
+ when (mode) {
+ MODE_MIXED_SUNSET -> {
+ mSincePref.setSummary(R.string.always_on_display_schedule_sunset)
+ mTillPref.summary = tillDT.format(outputFormatter)
+ }
+ MODE_MIXED_SUNRISE -> {
+ mTillPref.setSummary(R.string.always_on_display_schedule_sunrise)
+ mSincePref.summary = sinceDT.format(outputFormatter)
+ }
+ else -> {
+ mSincePref.summary = sinceDT.format(outputFormatter)
+ mTillPref.summary = tillDT.format(outputFormatter)
+ }
+ }
+ }
+
+ private fun updateTimeSetting(since: Boolean, hour: Int, minute: Int) {
+ val times = getCustomTimeSetting()
+ var nHour = ""
+ var nMinute = ""
+ if (hour < 10) nHour += "0"
+ if (minute < 10) nMinute += "0"
+ nHour += hour.toString()
+ nMinute += minute.toString()
+ times[if (since) 0 else 1] = "$nHour:$nMinute"
+ Settings.Secure.putStringForUser(activity?.contentResolver,
+ Settings.Secure.DOZE_ALWAYS_ON_AUTO_TIME,
+ "${times[0]},${times[1]}", UserHandle.USER_CURRENT)
+ updateTimeSummary(times, mModePref.value.toInt())
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/lockscreen/doze/AODSettings.java b/src/com/rising/settings/fragments/lockscreen/doze/AODSettings.java
deleted file mode 100644
index 782e168e..00000000
--- a/src/com/rising/settings/fragments/lockscreen/doze/AODSettings.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2023 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments.lockscreen.doze;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.MediaStore;
-import android.provider.Settings;
-import android.widget.Toast;
-
-import com.android.internal.logging.nano.MetricsProto;
-
-import androidx.preference.Preference;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.utils.ImageUtils;
-
-public class AODSettings extends SettingsPreferenceFragment {
-
- private static final String CUSTOM_IMAGE_REQUEST_CODE_KEY = "lockscreen_custom_image";
- private static final int CUSTOM_IMAGE_REQUEST_CODE = 1001;
-
- private Preference mCustomImagePreference;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.rising_aod_settings);
- mCustomImagePreference = findPreference(CUSTOM_IMAGE_REQUEST_CODE_KEY);
- int clockStyle = Settings.Secure.getIntForUser(getContext().getContentResolver(), "clock_style", 0, UserHandle.USER_CURRENT);
- String imagePath = Settings.System.getString(getContext().getContentResolver(), "custom_aod_image_uri");
- if (imagePath != null && clockStyle > 0) {
- mCustomImagePreference.setSummary(imagePath);
- mCustomImagePreference.setEnabled(true);
- } else if (clockStyle == 0) {
- mCustomImagePreference.setSummary(getContext().getString(R.string.custom_aod_image_not_supported));
- mCustomImagePreference.setEnabled(false);
- }
- }
-
- @Override
- public boolean onPreferenceTreeClick(Preference preference) {
- if (preference == mCustomImagePreference) {
- try {
- Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
- intent.setType("image/*");
- startActivityForResult(intent, CUSTOM_IMAGE_REQUEST_CODE);
- } catch(Exception e) {
- Toast.makeText(getContext(), R.string.qs_header_needs_gallery, Toast.LENGTH_LONG).show();
- }
- return true;
- }
- return super.onPreferenceTreeClick(preference);
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent result) {
- super.onActivityResult(requestCode, resultCode, result);
- if (requestCode == CUSTOM_IMAGE_REQUEST_CODE && resultCode == Activity.RESULT_OK && result != null) {
- Uri imgUri = result.getData();
- if (imgUri != null) {
- String savedImagePath = ImageUtils.saveImageToInternalStorage(getContext(), imgUri, "lockscreen_aod_image", "LOCKSCREEN_CUSTOM_AOD_IMAGE");
- if (savedImagePath != null) {
- ContentResolver resolver = getContext().getContentResolver();
- Settings.System.putStringForUser(resolver, "custom_aod_image_uri", savedImagePath, UserHandle.USER_CURRENT);
- mCustomImagePreference.setSummary(savedImagePath);
- }
- }
- }
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-}
diff --git a/src/com/rising/settings/fragments/lockscreen/doze/AODSettings.kt b/src/com/rising/settings/fragments/lockscreen/doze/AODSettings.kt
new file mode 100644
index 00000000..9696580b
--- /dev/null
+++ b/src/com/rising/settings/fragments/lockscreen/doze/AODSettings.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2023 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments.lockscreen.doze
+
+import android.app.Activity
+import android.content.ContentResolver
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.net.Uri
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.MediaStore
+import android.provider.Settings
+import android.widget.Toast
+
+import com.android.internal.logging.nano.MetricsProto
+
+import androidx.preference.Preference
+
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import com.android.settings.utils.ImageUtils
+
+class AODSettings : OptimizedSettingsFragment() {
+
+ companion object {
+ private const val CUSTOM_IMAGE_REQUEST_CODE_KEY = "lockscreen_custom_image"
+ private const val CUSTOM_IMAGE_REQUEST_CODE = 1001
+ }
+
+ private lateinit var mCustomImagePreference: Preference
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.rising_aod_settings)
+ mCustomImagePreference = findCachedPreference(CUSTOM_IMAGE_REQUEST_CODE_KEY)!!
+ val context = getSafeContext()
+ val clockStyle = context?.let { ctx ->
+ Settings.Secure.getIntForUser(ctx.contentResolver, "clock_style", 0, UserHandle.USER_CURRENT)
+ } ?: 0
+ val imagePath = Settings.System.getString(context?.contentResolver, "custom_aod_image_uri")
+ if (imagePath != null && clockStyle.compareTo(0) > 0) {
+ mCustomImagePreference.summary = imagePath
+ mCustomImagePreference.isEnabled = true
+ } else if (clockStyle == 0) {
+ mCustomImagePreference.summary = context?.getString(R.string.custom_aod_image_not_supported)
+ mCustomImagePreference.isEnabled = false
+ }
+ }
+
+ override fun onPreferenceTreeClick(preference: Preference): Boolean {
+ if (preference == mCustomImagePreference) {
+ try {
+ val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
+ intent.type = "image/*"
+ startActivityForResult(intent, CUSTOM_IMAGE_REQUEST_CODE)
+ } catch (e: Exception) {
+ Toast.makeText(context, R.string.qs_header_needs_gallery, Toast.LENGTH_LONG).show()
+ }
+ return true
+ }
+ return super.onPreferenceTreeClick(preference)
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, result: Intent?) {
+ super.onActivityResult(requestCode, resultCode, result)
+ if (requestCode == CUSTOM_IMAGE_REQUEST_CODE && resultCode == Activity.RESULT_OK && result != null) {
+ val imgUri = result.data
+ if (imgUri != null) {
+ val savedImagePath = context?.let { ctx ->
+ ImageUtils.saveImageToInternalStorage(ctx, imgUri, "lockscreen_aod_image", "LOCKSCREEN_CUSTOM_AOD_IMAGE")
+ }
+ if (savedImagePath != null) {
+ val resolver = context?.contentResolver
+ Settings.System.putStringForUser(resolver, "custom_aod_image_uri", savedImagePath, UserHandle.USER_CURRENT)
+ mCustomImagePreference.summary = savedImagePath
+ }
+ }
+ }
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/lockscreen/doze/EdgeLightSettings.java b/src/com/rising/settings/fragments/lockscreen/doze/EdgeLightSettings.kt
similarity index 52%
rename from src/com/rising/settings/fragments/lockscreen/doze/EdgeLightSettings.java
rename to src/com/rising/settings/fragments/lockscreen/doze/EdgeLightSettings.kt
index 8a4de1b8..c8b8bbd0 100644
--- a/src/com/rising/settings/fragments/lockscreen/doze/EdgeLightSettings.java
+++ b/src/com/rising/settings/fragments/lockscreen/doze/EdgeLightSettings.kt
@@ -13,25 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.rising.settings.fragments.lockscreen.doze;
+package com.rising.settings.fragments.lockscreen.doze
-import android.os.Bundle;
+import android.os.Bundle
-import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.logging.nano.MetricsProto
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
-public class EdgeLightSettings extends SettingsPreferenceFragment {
+class EdgeLightSettings : OptimizedSettingsFragment() {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.edge_light_settings);
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.edge_light_settings)
}
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
}
}
diff --git a/src/com/rising/settings/fragments/popup/PopUpViewSettingsFragment.java b/src/com/rising/settings/fragments/popup/PopUpViewSettingsFragment.java
deleted file mode 100644
index 4d6aa69b..00000000
--- a/src/com/rising/settings/fragments/popup/PopUpViewSettingsFragment.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2023-2024 The Nameless-AOSP Project
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package com.rising.settings.fragments.popup;
-
-import android.content.Intent;
-import android.os.Bundle;
-
-import androidx.preference.Preference;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.internal.util.android.PopUpSettingsHelper;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-import com.android.settings.preferences.SystemSettingListPreference;
-import com.android.settings.preferences.SystemSettingSwitchPreference;
-
-public class PopUpViewSettingsFragment extends SettingsPreferenceFragment implements
- Preference.OnPreferenceChangeListener {
-
- private static final String KEY_KEEP_MUTE = "pop_up_keep_mute_in_mini";
- private static final String KEY_SINGLE_TAP_ACTION = "pop_up_single_tap_action";
- private static final String KEY_DOUBLE_TAP_ACTION = "pop_up_double_tap_action";
- private static final String KEY_NOTIFICATION_PORTRAIT = "pop_up_notification_jump_portrait";
- private static final String KEY_NOTIFICATION_LANDSCAPE = "pop_up_notification_jump_landscape";
- private static final String KEY_NOTIFICATION_BLACKLIST = "pop_up_notification_blacklist";
-
-
- private SystemSettingSwitchPreference mKeepMuteInMini;
- private SystemSettingListPreference mSingleTapAction;
- private SystemSettingListPreference mDoubleTapAction;
- private SystemSettingSwitchPreference mNotifPortrait;
- private SystemSettingSwitchPreference mNotifLandscape;
- private Preference mNotifBlacklist;
-
- @Override
- public void onCreate(Bundle savedInstance) {
- super.onCreate(savedInstance);
- addPreferencesFromResource(R.xml.pop_up_view_settings);
-
-
- mKeepMuteInMini = (SystemSettingSwitchPreference) findPreference(KEY_KEEP_MUTE);
- mSingleTapAction = (SystemSettingListPreference) findPreference(KEY_SINGLE_TAP_ACTION);
- mDoubleTapAction = (SystemSettingListPreference) findPreference(KEY_DOUBLE_TAP_ACTION);
- mNotifPortrait = (SystemSettingSwitchPreference) findPreference(KEY_NOTIFICATION_PORTRAIT);
- mNotifLandscape = (SystemSettingSwitchPreference) findPreference(KEY_NOTIFICATION_LANDSCAPE);
- mNotifBlacklist = (Preference) findPreference(KEY_NOTIFICATION_BLACKLIST);
-
- mSingleTapAction.setOnPreferenceChangeListener(this);
-
- mDoubleTapAction.setOnPreferenceChangeListener(this);
-
- mNotifPortrait.setOnPreferenceChangeListener(this);
-
- mNotifLandscape.setOnPreferenceChangeListener(this);
-
- mNotifBlacklist.setEnabled(mNotifPortrait.isChecked() || mNotifLandscape.isChecked());
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (preference == mSingleTapAction) {
- mSingleTapAction.setSummary(mSingleTapAction.getEntries()[Integer.parseInt((String) newValue)]);
- } else if (preference == mDoubleTapAction) {
- mDoubleTapAction.setSummary(mDoubleTapAction.getEntries()[Integer.parseInt((String) newValue)]);
- } else if (preference == mNotifPortrait) {
- mNotifBlacklist.setEnabled((Boolean) newValue || mNotifLandscape.isChecked());
- } else if (preference == mNotifLandscape) {
- mNotifBlacklist.setEnabled(mNotifPortrait.isChecked() || (Boolean) newValue);
- }
- return true;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-}
diff --git a/src/com/rising/settings/fragments/popup/PopUpViewSettingsFragment.kt b/src/com/rising/settings/fragments/popup/PopUpViewSettingsFragment.kt
new file mode 100644
index 00000000..1f091267
--- /dev/null
+++ b/src/com/rising/settings/fragments/popup/PopUpViewSettingsFragment.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2023-2024 The Nameless-AOSP Project
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.rising.settings.fragments.popup
+
+import android.os.Bundle
+import androidx.preference.Preference
+
+import com.android.internal.logging.nano.MetricsProto
+
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+
+import com.android.settings.preferences.SystemSettingListPreference
+import com.android.settings.preferences.SystemSettingSwitchPreference
+
+class PopUpViewSettingsFragment : OptimizedSettingsFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ private const val KEY_KEEP_MUTE = "pop_up_keep_mute_in_mini"
+ private const val KEY_SINGLE_TAP_ACTION = "pop_up_single_tap_action"
+ private const val KEY_DOUBLE_TAP_ACTION = "pop_up_double_tap_action"
+ private const val KEY_NOTIFICATION_PORTRAIT = "pop_up_notification_jump_portrait"
+ private const val KEY_NOTIFICATION_LANDSCAPE = "pop_up_notification_jump_landscape"
+ private const val KEY_NOTIFICATION_BLACKLIST = "pop_up_notification_blacklist"
+ }
+
+ private var mKeepMuteInMini: SystemSettingSwitchPreference? = null
+ private var mSingleTapAction: SystemSettingListPreference? = null
+ private var mDoubleTapAction: SystemSettingListPreference? = null
+ private var mNotifPortrait: SystemSettingSwitchPreference? = null
+ private var mNotifLandscape: SystemSettingSwitchPreference? = null
+ private var mNotifBlacklist: Preference? = null
+
+ override fun onCreate(savedInstance: Bundle?) {
+ super.onCreate(savedInstance)
+ addPreferencesFromResource(R.xml.pop_up_view_settings)
+
+ mKeepMuteInMini = findCachedPreference(KEY_KEEP_MUTE) as? SystemSettingSwitchPreference
+ mSingleTapAction = findCachedPreference(KEY_SINGLE_TAP_ACTION) as? SystemSettingListPreference
+ mDoubleTapAction = findCachedPreference(KEY_DOUBLE_TAP_ACTION) as? SystemSettingListPreference
+ mNotifPortrait = findCachedPreference(KEY_NOTIFICATION_PORTRAIT) as? SystemSettingSwitchPreference
+ mNotifLandscape = findCachedPreference(KEY_NOTIFICATION_LANDSCAPE) as? SystemSettingSwitchPreference
+ mNotifBlacklist = findCachedPreference(KEY_NOTIFICATION_BLACKLIST)
+
+ mSingleTapAction?.onPreferenceChangeListener = this
+ mDoubleTapAction?.onPreferenceChangeListener = this
+ mNotifPortrait?.onPreferenceChangeListener = this
+ mNotifLandscape?.onPreferenceChangeListener = this
+
+ mNotifBlacklist?.isEnabled = (mNotifPortrait?.isChecked == true) || (mNotifLandscape?.isChecked == true)
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ when (preference) {
+ mSingleTapAction -> {
+ val index = (newValue as? String)?.toIntOrNull() ?: 0
+ mSingleTapAction?.entries?.getOrNull(index)?.let { entry ->
+ mSingleTapAction?.summary = entry
+ }
+ }
+ mDoubleTapAction -> {
+ val index = (newValue as? String)?.toIntOrNull() ?: 0
+ mDoubleTapAction?.entries?.getOrNull(index)?.let { entry ->
+ mDoubleTapAction?.summary = entry
+ }
+ }
+ mNotifPortrait -> {
+ mNotifBlacklist?.isEnabled = (newValue as? Boolean == true) || (mNotifLandscape?.isChecked == true)
+ }
+ mNotifLandscape -> {
+ mNotifBlacklist?.isEnabled = (mNotifPortrait?.isChecked == true) || (newValue as? Boolean == true)
+ }
+ }
+ return true
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/quicksettings/QsHeaderImageSettings.java b/src/com/rising/settings/fragments/quicksettings/QsHeaderImageSettings.java
deleted file mode 100644
index 6922bdc9..00000000
--- a/src/com/rising/settings/fragments/quicksettings/QsHeaderImageSettings.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2024 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments.quicksettings;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.MediaStore;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.widget.Toast;
-
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settingslib.search.SearchIndexable;
-
-import com.android.settings.utils.ImageUtils;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-@SearchIndexable
-public class QsHeaderImageSettings extends SettingsPreferenceFragment implements
- OnPreferenceChangeListener {
-
- private static final String CUSTOM_HEADER_BROWSE = "custom_header_browse";
- private static final String DAYLIGHT_HEADER_PACK = "daylight_header_pack";
- private static final String CUSTOM_HEADER_PROVIDER = "qs_header_provider";
- private static final String STATUS_BAR_CUSTOM_HEADER = "status_bar_custom_header";
- private static final String FILE_HEADER_SELECT = "file_header_select";
- private static final int REQUEST_PICK_IMAGE = 0;
-
- private Preference mHeaderBrowse;
- private ListPreference mDaylightHeaderPack;
- private ListPreference mHeaderProvider;
- private String mDaylightHeaderProvider;
- private Preference mFileHeader;
- private String mFileHeaderProvider;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- addPreferencesFromResource(R.xml.qs_header_image_settings);
-
- ContentResolver resolver = getActivity().getContentResolver();
-
- mHeaderBrowse = findPreference(CUSTOM_HEADER_BROWSE);
- mHeaderBrowse.setEnabled(isBrowseHeaderAvailable());
-
- mDaylightHeaderPack = (ListPreference) findPreference(DAYLIGHT_HEADER_PACK);
-
- List entries = new ArrayList();
- List values = new ArrayList();
- getAvailableHeaderPacks(entries, values);
- mDaylightHeaderPack.setEntries(entries.toArray(new String[entries.size()]));
- mDaylightHeaderPack.setEntryValues(values.toArray(new String[values.size()]));
- updateHeaderProviderSummary();
- mDaylightHeaderPack.setOnPreferenceChangeListener(this);
-
- mDaylightHeaderProvider = "daylight";
- mFileHeaderProvider = "file";
- String providerName = Settings.System.getString(resolver,
- Settings.System.STATUS_BAR_CUSTOM_HEADER_PROVIDER);
- if (providerName == null) {
- providerName = mDaylightHeaderProvider;
- }
- mHeaderBrowse.setEnabled(isBrowseHeaderAvailable() && !providerName.equals(mFileHeaderProvider));
-
- mHeaderProvider = (ListPreference) findPreference(CUSTOM_HEADER_PROVIDER);
- int valueIndex = mHeaderProvider.findIndexOfValue(providerName);
- mHeaderProvider.setValueIndex(valueIndex >= 0 ? valueIndex : 0);
- mHeaderProvider.setSummary(mHeaderProvider.getEntry());
- mHeaderProvider.setOnPreferenceChangeListener(this);
- mDaylightHeaderPack.setEnabled(providerName.equals(mDaylightHeaderProvider));
-
- mFileHeader = findPreference(FILE_HEADER_SELECT);
- mFileHeader.setEnabled(providerName.equals(mFileHeaderProvider));
- }
-
- private void updateHeaderProviderSummary() {
- String settingHeaderPackage = Settings.System.getString(getActivity().getContentResolver(),
- Settings.System.STATUS_BAR_DAYLIGHT_HEADER_PACK);
- int valueIndex = mDaylightHeaderPack.findIndexOfValue(settingHeaderPackage);
- if (valueIndex >= 0) {
- mDaylightHeaderPack.setValueIndex(valueIndex >= 0 ? valueIndex : 0);
- mDaylightHeaderPack.setSummary(mDaylightHeaderPack.getEntry());
- }
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- ContentResolver resolver = getActivity().getContentResolver();
- switch (preference.getKey()) {
- case DAYLIGHT_HEADER_PACK:
- String dhvalue = (String) newValue;
- Settings.System.putString(resolver,
- Settings.System.STATUS_BAR_DAYLIGHT_HEADER_PACK, dhvalue);
- int dhvalueIndex = mDaylightHeaderPack.findIndexOfValue(dhvalue);
- mDaylightHeaderPack.setSummary(mDaylightHeaderPack.getEntries()[dhvalueIndex]);
- return true;
-
- case CUSTOM_HEADER_PROVIDER:
- String value = (String) newValue;
- Settings.System.putString(resolver,
- Settings.System.STATUS_BAR_CUSTOM_HEADER_PROVIDER, value);
- int valueIndex = mHeaderProvider.findIndexOfValue(value);
- mHeaderProvider.setSummary(mHeaderProvider.getEntries()[valueIndex]);
- mDaylightHeaderPack.setEnabled(value.equals(mDaylightHeaderProvider));
- mHeaderBrowse.setEnabled(!value.equals(mFileHeaderProvider));
- mHeaderBrowse.setTitle(valueIndex == 0 ? R.string.qs_header_browse_title : R.string.qs_header_pick_title);
- mHeaderBrowse.setSummary(valueIndex == 0 ? R.string.qs_header_browse_summary : R.string.qs_header_pick_summary);
- mFileHeader.setEnabled(value.equals(mFileHeaderProvider));
- return true;
-
- default:
- return false;
- }
- }
-
- @Override
- public boolean onPreferenceTreeClick(Preference preference) {
- if (preference == mFileHeader) {
- try {
- Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
- intent.setType("image/*");
- startActivityForResult(intent, 10001);
- } catch(Exception e) {
- Toast.makeText(getContext(), R.string.qs_header_needs_gallery, Toast.LENGTH_LONG).show();
- }
- return true;
- }
- return super.onPreferenceTreeClick(preference);
- }
-
- private boolean isBrowseHeaderAvailable() {
- PackageManager pm = getActivity().getPackageManager();
- Intent browse = new Intent();
- browse.setClassName("org.omnirom.omnistyle", "org.omnirom.omnistyle.PickHeaderActivity");
- return pm.resolveActivity(browse, 0) != null;
- }
-
- private void getAvailableHeaderPacks(List entries, List values) {
- Map headerMap = new HashMap();
- Intent i = new Intent();
- PackageManager packageManager = getActivity().getPackageManager();
- i.setAction("org.omnirom.DaylightHeaderPack");
- for (ResolveInfo r : packageManager.queryIntentActivities(i, 0)) {
- String packageName = r.activityInfo.packageName;
- String label = r.activityInfo.loadLabel(getActivity().getPackageManager()).toString();
- if (label == null) {
- label = r.activityInfo.packageName;
- }
- headerMap.put(label, packageName);
- }
- i.setAction("org.omnirom.DaylightHeaderPack1");
- for (ResolveInfo r : packageManager.queryIntentActivities(i, 0)) {
- String packageName = r.activityInfo.packageName;
- String label = r.activityInfo.loadLabel(getActivity().getPackageManager()).toString();
- if (r.activityInfo.name.endsWith(".theme")) {
- continue;
- }
- if (label == null) {
- label = packageName;
- }
- headerMap.put(label, packageName + "/" + r.activityInfo.name);
- }
- List labelList = new ArrayList();
- labelList.addAll(headerMap.keySet());
- Collections.sort(labelList);
- for (String label : labelList) {
- entries.add(label);
- values.add(headerMap.get(label));
- }
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent result) {
- if (requestCode == 10001) {
- if (resultCode != Activity.RESULT_OK) {
- return;
- }
- final Uri imgUri = result.getData();
- if (imgUri != null) {
- String savedImagePath = ImageUtils.saveImageToInternalStorage(getContext(), imgUri, "qs_header_image", "QS_HEADER_IMAGE");
- if (savedImagePath != null) {
- ContentResolver resolver = getContext().getContentResolver();
- Settings.System.putStringForUser(resolver, Settings.System.STATUS_BAR_FILE_HEADER_IMAGE, savedImagePath, UserHandle.USER_CURRENT);
- }
- }
- }
- }
-
- /**
- * For search
- */
- public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider() {
- @Override
- public List getXmlResourcesToIndex(Context context,
- boolean enabled) {
- ArrayList result =
- new ArrayList();
-
- SearchIndexableResource sir = new SearchIndexableResource(context);
- sir.xmlResId = R.xml.qs_header_image_settings;
- result.add(sir);
- return result;
- }
-
- @Override
- public List getNonIndexableKeys(Context context) {
- ArrayList result = new ArrayList();
- return result;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/quicksettings/QsHeaderImageSettings.kt b/src/com/rising/settings/fragments/quicksettings/QsHeaderImageSettings.kt
new file mode 100644
index 00000000..d5c22eab
--- /dev/null
+++ b/src/com/rising/settings/fragments/quicksettings/QsHeaderImageSettings.kt
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2024 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments.quicksettings
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.net.Uri
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.MediaStore
+import android.provider.SearchIndexableResource
+import android.provider.Settings
+import android.widget.Toast
+
+import androidx.preference.ListPreference
+import androidx.preference.Preference
+import androidx.preference.Preference.OnPreferenceChangeListener
+
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.android.settings.search.BaseSearchIndexProvider
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import com.android.settingslib.search.SearchIndexable
+
+import com.android.settings.utils.ImageUtils
+
+@SearchIndexable
+class QsHeaderImageSettings : OptimizedSettingsFragment(), OnPreferenceChangeListener {
+
+ companion object {
+ private const val CUSTOM_HEADER_BROWSE = "custom_header_browse"
+ private const val DAYLIGHT_HEADER_PACK = "daylight_header_pack"
+ private const val CUSTOM_HEADER_PROVIDER = "qs_header_provider"
+ private const val STATUS_BAR_CUSTOM_HEADER = "status_bar_custom_header"
+ private const val FILE_HEADER_SELECT = "file_header_select"
+ private const val REQUEST_PICK_IMAGE = 0
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider() {
+ override fun getXmlResourcesToIndex(context: Context, enabled: Boolean): List {
+ val result = ArrayList()
+ val sir = SearchIndexableResource(context)
+ sir.xmlResId = R.xml.qs_header_image_settings
+ result.add(sir)
+ return result
+ }
+
+ override fun getNonIndexableKeys(context: Context): List {
+ return ArrayList()
+ }
+ }
+ }
+
+ private var mHeaderBrowse: Preference? = null
+ private var mDaylightHeaderPack: ListPreference? = null
+ private var mHeaderProvider: ListPreference? = null
+ private val mDaylightHeaderProvider = "daylight"
+ private var mFileHeader: Preference? = null
+ private val mFileHeaderProvider = "file"
+
+ override fun onCreate(icicle: Bundle?) {
+ super.onCreate(icicle)
+
+ addPreferencesFromResource(R.xml.qs_header_image_settings)
+
+ val resolver = activity?.contentResolver
+
+ mHeaderBrowse = findCachedPreference(CUSTOM_HEADER_BROWSE)
+ mHeaderBrowse?.isEnabled = isBrowseHeaderAvailable()
+
+ mDaylightHeaderPack = findCachedPreference(DAYLIGHT_HEADER_PACK) as? ListPreference
+
+ val entries = ArrayList()
+ val values = ArrayList()
+ getAvailableHeaderPacks(entries, values)
+ mDaylightHeaderPack?.entries = entries.toTypedArray()
+ mDaylightHeaderPack?.entryValues = values.toTypedArray()
+ updateHeaderProviderSummary()
+ mDaylightHeaderPack?.onPreferenceChangeListener = this
+
+ val providerName = Settings.System.getString(resolver, Settings.System.STATUS_BAR_CUSTOM_HEADER_PROVIDER)
+ ?: mDaylightHeaderProvider
+ mHeaderBrowse?.isEnabled = isBrowseHeaderAvailable() && providerName != mFileHeaderProvider
+
+ mHeaderProvider = findCachedPreference(CUSTOM_HEADER_PROVIDER) as? ListPreference
+ val valueIndex = mHeaderProvider?.findIndexOfValue(providerName) ?: -1
+ mHeaderProvider?.setValueIndex(if (valueIndex >= 0) valueIndex else 0)
+ mHeaderProvider?.summary = mHeaderProvider?.entry
+ mHeaderProvider?.onPreferenceChangeListener = this
+ mDaylightHeaderPack?.isEnabled = providerName == mDaylightHeaderProvider
+
+ mFileHeader = findCachedPreference(FILE_HEADER_SELECT)
+ mFileHeader?.isEnabled = providerName == mFileHeaderProvider
+ }
+
+ private fun updateHeaderProviderSummary() {
+ val settingHeaderPackage = Settings.System.getString(
+ activity?.contentResolver,
+ Settings.System.STATUS_BAR_DAYLIGHT_HEADER_PACK
+ )
+ val valueIndex = mDaylightHeaderPack?.findIndexOfValue(settingHeaderPackage) ?: -1
+ if (valueIndex >= 0) {
+ mDaylightHeaderPack?.setValueIndex(valueIndex)
+ mDaylightHeaderPack?.summary = mDaylightHeaderPack?.entry
+ }
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ val resolver = activity?.contentResolver
+ when (preference?.key) {
+ DAYLIGHT_HEADER_PACK -> {
+ val dhvalue = newValue as? String ?: return false
+ Settings.System.putString(resolver, Settings.System.STATUS_BAR_DAYLIGHT_HEADER_PACK, dhvalue)
+ val dhvalueIndex = mDaylightHeaderPack?.findIndexOfValue(dhvalue) ?: -1
+ if (dhvalueIndex >= 0) {
+ mDaylightHeaderPack?.summary = mDaylightHeaderPack?.entries?.get(dhvalueIndex)
+ }
+ return true
+ }
+
+ CUSTOM_HEADER_PROVIDER -> {
+ val value = newValue as? String ?: return false
+ Settings.System.putString(resolver, Settings.System.STATUS_BAR_CUSTOM_HEADER_PROVIDER, value)
+ val valueIndex = mHeaderProvider?.findIndexOfValue(value) ?: -1
+ if (valueIndex >= 0) {
+ mHeaderProvider?.summary = mHeaderProvider?.entries?.get(valueIndex)
+ }
+ mDaylightHeaderPack?.isEnabled = value == mDaylightHeaderProvider
+ mHeaderBrowse?.isEnabled = value != mFileHeaderProvider
+ mHeaderBrowse?.setTitle(if (valueIndex == 0) R.string.qs_header_browse_title else R.string.qs_header_pick_title)
+ mHeaderBrowse?.setSummary(if (valueIndex == 0) R.string.qs_header_browse_summary else R.string.qs_header_pick_summary)
+ mFileHeader?.isEnabled = value == mFileHeaderProvider
+ return true
+ }
+
+ else -> return false
+ }
+ }
+
+ override fun onPreferenceTreeClick(preference: Preference): Boolean {
+ if (preference == mFileHeader) {
+ try {
+ val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
+ intent.type = "image/*"
+ startActivityForResult(intent, 10001)
+ } catch (e: Exception) {
+ Toast.makeText(requireContext(), R.string.qs_header_needs_gallery, Toast.LENGTH_LONG).show()
+ }
+ return true
+ }
+ return super.onPreferenceTreeClick(preference)
+ }
+
+ private fun isBrowseHeaderAvailable(): Boolean {
+ val pm = activity?.packageManager
+ val browse = Intent()
+ browse.setClassName("org.omnirom.omnistyle", "org.omnirom.omnistyle.PickHeaderActivity")
+ return pm?.resolveActivity(browse, 0) != null
+ }
+
+ private fun getAvailableHeaderPacks(entries: MutableList, values: MutableList) {
+ val headerMap = HashMap()
+ val intent = Intent()
+ val packageManager = activity?.packageManager
+
+ intent.action = "org.omnirom.DaylightHeaderPack"
+ packageManager?.queryIntentActivities(intent, 0)?.forEach { r ->
+ val packageName = r.activityInfo.packageName
+ val label = r.activityInfo.loadLabel(packageManager).toString().takeIf { it.isNotEmpty() } ?: packageName
+ headerMap[label] = packageName
+ }
+
+ intent.action = "org.omnirom.DaylightHeaderPack1"
+ packageManager?.queryIntentActivities(intent, 0)?.forEach { r ->
+ val packageName = r.activityInfo.packageName
+ if (r.activityInfo.name.endsWith(".theme")) {
+ return@forEach
+ }
+ val label = r.activityInfo.loadLabel(packageManager).toString().takeIf { it.isNotEmpty() } ?: packageName
+ headerMap[label] = "$packageName/${r.activityInfo.name}"
+ }
+
+ val labelList = headerMap.keys.sorted()
+ labelList.forEach { label ->
+ entries.add(label)
+ values.add(headerMap[label] ?: "")
+ }
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, result: Intent?) {
+ if (requestCode == 10001) {
+ if (resultCode != Activity.RESULT_OK) {
+ return
+ }
+ val imgUri = result?.data
+ if (imgUri != null) {
+ val savedImagePath = ImageUtils.saveImageToInternalStorage(
+ requireContext(), imgUri, "qs_header_image", "QS_HEADER_IMAGE"
+ )
+ if (savedImagePath != null) {
+ val resolver = requireContext().contentResolver
+ Settings.System.putStringForUser(
+ resolver,
+ Settings.System.STATUS_BAR_FILE_HEADER_IMAGE,
+ savedImagePath,
+ UserHandle.USER_CURRENT
+ )
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/rising/settings/fragments/quicksettings/QsTileLayoutSettings.java b/src/com/rising/settings/fragments/quicksettings/QsTileLayoutSettings.java
deleted file mode 100644
index 7e027d03..00000000
--- a/src/com/rising/settings/fragments/quicksettings/QsTileLayoutSettings.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2022 The Nameless-AOSP Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.rising.settings.fragments.quicksettings;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.view.View;
-import android.widget.Button;
-import android.widget.Toast;
-
-import androidx.preference.Preference;
-
-import com.android.internal.logging.nano.MetricsProto;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-import com.android.settingslib.widget.LayoutPreference;
-
-public class QsTileLayoutSettings extends SettingsPreferenceFragment
- implements Preference.OnPreferenceChangeListener {
-
- @Override
- public void onCreate(Bundle savedInstance) {
- super.onCreate(savedInstance);
- addPreferencesFromResource(R.xml.qs_tile_layout);
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- return true;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-}
diff --git a/src/com/rising/settings/fragments/quicksettings/QsTileLayoutSettings.kt b/src/com/rising/settings/fragments/quicksettings/QsTileLayoutSettings.kt
new file mode 100644
index 00000000..d61d2bf0
--- /dev/null
+++ b/src/com/rising/settings/fragments/quicksettings/QsTileLayoutSettings.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Nameless-AOSP Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.rising.settings.fragments.quicksettings
+
+import android.content.Context
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.Settings
+import android.view.View
+import android.widget.Button
+import android.widget.Toast
+
+import androidx.preference.Preference
+
+import com.android.internal.logging.nano.MetricsProto
+
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+
+import com.android.settingslib.widget.LayoutPreference
+
+class QsTileLayoutSettings : OptimizedSettingsFragment(), Preference.OnPreferenceChangeListener {
+
+ override fun onCreate(savedInstance: Bundle?) {
+ super.onCreate(savedInstance)
+ addPreferencesFromResource(R.xml.qs_tile_layout)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ return true
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/sound/AdaptivePlayback.java b/src/com/rising/settings/fragments/sound/AdaptivePlayback.java
deleted file mode 100644
index d20a3f2c..00000000
--- a/src/com/rising/settings/fragments/sound/AdaptivePlayback.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2016-2024 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments.sound;
-
-import android.content.Context;
-import android.content.ContentResolver;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settingslib.widget.MainSwitchPreference;
-
-import com.android.settings.preferences.colorpicker.ColorPickerPreference;
-
-public class AdaptivePlayback extends SettingsPreferenceFragment implements
- Preference.OnPreferenceChangeListener, OnCheckedChangeListener {
-
- private static final String TAG = AdaptivePlayback.class.getSimpleName();
-
- private static final String PREF_KEY_ENABLE = "adaptive_playback_enabled";
-
- private MainSwitchPreference mEnable;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.adaptive_playback_settings);
-
- mEnable = (MainSwitchPreference) findPreference(PREF_KEY_ENABLE);
- boolean enable = Settings.System.getIntForUser(getContext().getContentResolver(),
- Settings.System.ADAPTIVE_PLAYBACK_ENABLED, 0, UserHandle.USER_CURRENT) != 0;
- mEnable.setChecked(enable);
- mEnable.addOnSwitchChangeListener(this);
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- return false;
- }
-
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- mEnable.setChecked(isChecked);
- if (isChecked) {
- Settings.System.putIntForUser(getContext().getContentResolver(),
- Settings.System.ADAPTIVE_PLAYBACK_ENABLED, 1, UserHandle.USER_CURRENT);
- } else {
- Settings.System.putIntForUser(getContext().getContentResolver(),
- Settings.System.ADAPTIVE_PLAYBACK_ENABLED, 0, UserHandle.USER_CURRENT);
- }
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-}
diff --git a/src/com/rising/settings/fragments/sound/AdaptivePlayback.kt b/src/com/rising/settings/fragments/sound/AdaptivePlayback.kt
new file mode 100644
index 00000000..82460e56
--- /dev/null
+++ b/src/com/rising/settings/fragments/sound/AdaptivePlayback.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016-2024 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments.sound
+
+import android.content.Context
+import android.content.ContentResolver
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.Settings
+import android.widget.CompoundButton
+import android.widget.CompoundButton.OnCheckedChangeListener
+
+import androidx.preference.Preference
+import androidx.preference.Preference.OnPreferenceChangeListener
+
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import com.android.settingslib.widget.MainSwitchPreference
+
+import com.android.settings.preferences.colorpicker.ColorPickerPreference
+
+class AdaptivePlayback : OptimizedSettingsFragment(),
+ Preference.OnPreferenceChangeListener, OnCheckedChangeListener {
+
+ companion object {
+ private val TAG = AdaptivePlayback::class.java.simpleName
+ private const val PREF_KEY_ENABLE = "adaptive_playback_enabled"
+ }
+
+ private lateinit var mEnable: MainSwitchPreference
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.adaptive_playback_settings)
+
+ mEnable = findCachedPreference(PREF_KEY_ENABLE)!!
+ val enable = Settings.System.getIntForUser(requireContext().contentResolver,
+ Settings.System.ADAPTIVE_PLAYBACK_ENABLED, 0, UserHandle.USER_CURRENT) != 0
+ mEnable.isChecked = enable
+ mEnable.addOnSwitchChangeListener(this)
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ return false
+ }
+
+ override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) {
+ mEnable.isChecked = isChecked
+ if (isChecked) {
+ Settings.System.putIntForUser(requireContext().contentResolver,
+ Settings.System.ADAPTIVE_PLAYBACK_ENABLED, 1, UserHandle.USER_CURRENT)
+ } else {
+ Settings.System.putIntForUser(requireContext().contentResolver,
+ Settings.System.ADAPTIVE_PLAYBACK_ENABLED, 0, UserHandle.USER_CURRENT)
+ }
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/sound/PulseSettings.java b/src/com/rising/settings/fragments/sound/PulseSettings.java
deleted file mode 100644
index 26d4ed3a..00000000
--- a/src/com/rising/settings/fragments/sound/PulseSettings.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2016-2024 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments.sound;
-
-import android.content.Context;
-import android.content.ContentResolver;
-import android.content.DialogInterface;
-import android.content.res.Resources;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.SwitchPreferenceCompat;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-import com.android.settings.preferences.colorpicker.ColorPickerPreference;
-
-public class PulseSettings extends SettingsPreferenceFragment implements
- Preference.OnPreferenceChangeListener {
-
- private static final String TAG = PulseSettings.class.getSimpleName();
-
- private static final String LOCKSCREEN_PULSE_ENABLED_KEY = "lockscreen_pulse_enabled";
- private static final String AMBIENT_PULSE_ENABLED_KEY = "ambient_pulse_enabled";
- private static final String PULSE_SMOOTHING_KEY = "pulse_smoothing_enabled";
- private static final String PULSE_COLOR_MODE_KEY = "pulse_color_mode";
- private static final String PULSE_COLOR_MODE_CHOOSER_KEY = "pulse_color_user";
- private static final String PULSE_COLOR_MODE_LAVA_SPEED_KEY = "pulse_lavalamp_speed";
- private static final String PULSE_RENDER_CATEGORY_SOLID = "pulse_2";
- private static final String PULSE_RENDER_CATEGORY_FADING = "pulse_fading_bars_category";
- private static final String PULSE_RENDER_MODE_KEY = "pulse_render_style";
- private static final int RENDER_STYLE_FADING_BARS = 0;
- private static final int RENDER_STYLE_SOLID_LINES = 1;
- private static final int COLOR_TYPE_ACCENT = 0;
- private static final int COLOR_TYPE_USER = 1;
- private static final int COLOR_TYPE_LAVALAMP = 2;
- private static final int COLOR_TYPE_AUTO = 3;
-
- private static final String PULSE_SETTINGS_FOOTER = "pulse_settings_footer";
-
- private SwitchPreferenceCompat mLockscreenPulse;
- private SwitchPreferenceCompat mAmbientPulse;
- private SwitchPreferenceCompat mPulseSmoothing;
- private Preference mRenderMode;
- private ListPreference mColorModePref;
- private ColorPickerPreference mColorPickerPref;
- private Preference mLavaSpeedPref;
- private Preference mFooterPref;
-
- private PreferenceCategory mFadingBarsCat;
- private PreferenceCategory mSolidBarsCat;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.pulse_settings);
-
- ContentResolver resolver = getContext().getContentResolver();
-
- mLockscreenPulse = (SwitchPreferenceCompat) findPreference(LOCKSCREEN_PULSE_ENABLED_KEY);
- boolean lockscreenPulse = Settings.Secure.getIntForUser(resolver,
- Settings.Secure.LOCKSCREEN_PULSE_ENABLED, 1, UserHandle.USER_CURRENT) != 0;
- mLockscreenPulse.setChecked(lockscreenPulse);
- mLockscreenPulse.setOnPreferenceChangeListener(this);
-
- mAmbientPulse = (SwitchPreferenceCompat) findPreference(AMBIENT_PULSE_ENABLED_KEY);
- boolean ambientPulse = Settings.Secure.getIntForUser(resolver,
- Settings.Secure.AMBIENT_PULSE_ENABLED, 0, UserHandle.USER_CURRENT) != 0;
- mAmbientPulse.setChecked(ambientPulse);
- mAmbientPulse.setOnPreferenceChangeListener(this);
-
- mColorModePref = (ListPreference) findPreference(PULSE_COLOR_MODE_KEY);
- mColorPickerPref = (ColorPickerPreference) findPreference(PULSE_COLOR_MODE_CHOOSER_KEY);
- mLavaSpeedPref = findPreference(PULSE_COLOR_MODE_LAVA_SPEED_KEY);
- mColorModePref.setOnPreferenceChangeListener(this);
-
- mRenderMode = findPreference(PULSE_RENDER_MODE_KEY);
- mRenderMode.setOnPreferenceChangeListener(this);
-
- mFadingBarsCat = (PreferenceCategory) findPreference(
- PULSE_RENDER_CATEGORY_FADING);
- mSolidBarsCat = (PreferenceCategory) findPreference(
- PULSE_RENDER_CATEGORY_SOLID);
-
- mPulseSmoothing = (SwitchPreferenceCompat) findPreference(PULSE_SMOOTHING_KEY);
-
- mFooterPref = findPreference(PULSE_SETTINGS_FOOTER);
- mFooterPref.setTitle(R.string.pulse_help_policy_notice_summary);
-
- updateAllPrefs();
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- ContentResolver resolver = getContext().getContentResolver();
- if (preference == mLockscreenPulse) {
- boolean val = (Boolean) newValue;
- Settings.Secure.putIntForUser(resolver,
- Settings.Secure.LOCKSCREEN_PULSE_ENABLED, val ? 1 : 0, UserHandle.USER_CURRENT);
- updateAllPrefs();
- return true;
- } else if (preference == mAmbientPulse) {
- boolean val = (Boolean) newValue;
- Settings.Secure.putIntForUser(resolver,
- Settings.Secure.AMBIENT_PULSE_ENABLED, val ? 1 : 0, UserHandle.USER_CURRENT);
- updateAllPrefs();
- return true;
- } else if (preference == mColorModePref) {
- updateColorPrefs(Integer.valueOf(String.valueOf(newValue)));
- return true;
- } else if (preference == mRenderMode) {
- updateRenderCategories(Integer.valueOf(String.valueOf(newValue)));
- return true;
- }
- return false;
- }
-
- private void updateAllPrefs() {
- ContentResolver resolver = getContext().getContentResolver();
-
- boolean lockscreenPulse = Settings.Secure.getIntForUser(resolver,
- Settings.Secure.LOCKSCREEN_PULSE_ENABLED, 1, UserHandle.USER_CURRENT) != 0;
-
- boolean ambientPulse = Settings.Secure.getIntForUser(resolver,
- Settings.Secure.AMBIENT_PULSE_ENABLED, 0, UserHandle.USER_CURRENT) != 0;
-
- mPulseSmoothing.setEnabled(lockscreenPulse || ambientPulse);
-
- mColorModePref.setEnabled(lockscreenPulse || ambientPulse);
- if (lockscreenPulse || ambientPulse) {
- int colorMode = Settings.Secure.getIntForUser(resolver,
- Settings.Secure.PULSE_COLOR_MODE, COLOR_TYPE_LAVALAMP, UserHandle.USER_CURRENT);
- updateColorPrefs(colorMode);
- } else {
- mColorPickerPref.setEnabled(false);
- mLavaSpeedPref.setEnabled(false);
- }
-
- mRenderMode.setEnabled(lockscreenPulse || ambientPulse);
- if (lockscreenPulse || ambientPulse) {
- int renderMode = Settings.Secure.getIntForUser(resolver,
- Settings.Secure.PULSE_RENDER_STYLE, RENDER_STYLE_SOLID_LINES, UserHandle.USER_CURRENT);
- updateRenderCategories(renderMode);
- } else {
- mFadingBarsCat.setEnabled(false);
- mSolidBarsCat.setEnabled(false);
- }
-
- mFooterPref.setEnabled(lockscreenPulse || ambientPulse);
- }
-
- private void updateColorPrefs(int val) {
- switch (val) {
- case COLOR_TYPE_ACCENT:
- mColorPickerPref.setEnabled(false);
- mLavaSpeedPref.setEnabled(false);
- break;
- case COLOR_TYPE_USER:
- mColorPickerPref.setEnabled(true);
- mLavaSpeedPref.setEnabled(false);
- break;
- case COLOR_TYPE_LAVALAMP:
- mColorPickerPref.setEnabled(false);
- mLavaSpeedPref.setEnabled(true);
- break;
- case COLOR_TYPE_AUTO:
- mColorPickerPref.setEnabled(false);
- mLavaSpeedPref.setEnabled(false);
- break;
- }
- }
-
- private void updateRenderCategories(int mode) {
- mFadingBarsCat.setEnabled(mode == RENDER_STYLE_FADING_BARS);
- mSolidBarsCat.setEnabled(mode == RENDER_STYLE_SOLID_LINES);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-}
diff --git a/src/com/rising/settings/fragments/sound/PulseSettings.kt b/src/com/rising/settings/fragments/sound/PulseSettings.kt
new file mode 100644
index 00000000..5e295563
--- /dev/null
+++ b/src/com/rising/settings/fragments/sound/PulseSettings.kt
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2016-2024 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments.sound
+
+import android.content.Context
+import android.content.ContentResolver
+import android.content.DialogInterface
+import android.content.res.Resources
+import android.content.pm.PackageManager
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.Settings
+
+import androidx.preference.ListPreference
+import androidx.preference.Preference
+import androidx.preference.PreferenceCategory
+import androidx.preference.PreferenceScreen
+import androidx.preference.Preference.OnPreferenceChangeListener
+import androidx.preference.SwitchPreferenceCompat
+
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+
+import com.android.settings.preferences.colorpicker.ColorPickerPreference
+
+class PulseSettings : OptimizedSettingsFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ private val TAG = PulseSettings::class.java.simpleName
+
+ private const val LOCKSCREEN_PULSE_ENABLED_KEY = "lockscreen_pulse_enabled"
+ private const val AMBIENT_PULSE_ENABLED_KEY = "ambient_pulse_enabled"
+ private const val PULSE_SMOOTHING_KEY = "pulse_smoothing_enabled"
+ private const val PULSE_COLOR_MODE_KEY = "pulse_color_mode"
+ private const val PULSE_COLOR_MODE_CHOOSER_KEY = "pulse_color_user"
+ private const val PULSE_COLOR_MODE_LAVA_SPEED_KEY = "pulse_lavalamp_speed"
+ private const val PULSE_RENDER_CATEGORY_SOLID = "pulse_2"
+ private const val PULSE_RENDER_CATEGORY_FADING = "pulse_fading_bars_category"
+ private const val PULSE_RENDER_MODE_KEY = "pulse_render_style"
+ private const val RENDER_STYLE_FADING_BARS = 0
+ private const val RENDER_STYLE_SOLID_LINES = 1
+ private const val COLOR_TYPE_ACCENT = 0
+ private const val COLOR_TYPE_USER = 1
+ private const val COLOR_TYPE_LAVALAMP = 2
+ private const val COLOR_TYPE_AUTO = 3
+
+ private const val PULSE_SETTINGS_FOOTER = "pulse_settings_footer"
+ }
+
+ private lateinit var mLockscreenPulse: SwitchPreferenceCompat
+ private lateinit var mAmbientPulse: SwitchPreferenceCompat
+ private lateinit var mPulseSmoothing: SwitchPreferenceCompat
+ private lateinit var mRenderMode: Preference
+ private lateinit var mColorModePref: ListPreference
+ private lateinit var mColorPickerPref: ColorPickerPreference
+ private lateinit var mLavaSpeedPref: Preference
+ private lateinit var mFooterPref: Preference
+
+ private lateinit var mFadingBarsCat: PreferenceCategory
+ private lateinit var mSolidBarsCat: PreferenceCategory
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.pulse_settings)
+
+ val resolver = requireContext().contentResolver
+
+ mLockscreenPulse = findCachedPreference(LOCKSCREEN_PULSE_ENABLED_KEY)!!
+ val lockscreenPulse = Settings.Secure.getIntForUser(resolver,
+ Settings.Secure.LOCKSCREEN_PULSE_ENABLED, 1, UserHandle.USER_CURRENT) != 0
+ mLockscreenPulse.isChecked = lockscreenPulse
+ mLockscreenPulse.onPreferenceChangeListener = this
+
+ mAmbientPulse = findCachedPreference(AMBIENT_PULSE_ENABLED_KEY)!!
+ val ambientPulse = Settings.Secure.getIntForUser(resolver,
+ Settings.Secure.AMBIENT_PULSE_ENABLED, 0, UserHandle.USER_CURRENT) != 0
+ mAmbientPulse.isChecked = ambientPulse
+ mAmbientPulse.onPreferenceChangeListener = this
+
+ mColorModePref = findCachedPreference(PULSE_COLOR_MODE_KEY)!!
+ mColorPickerPref = findCachedPreference(PULSE_COLOR_MODE_CHOOSER_KEY)!!
+ mLavaSpeedPref = findCachedPreference(PULSE_COLOR_MODE_LAVA_SPEED_KEY)!!
+ mColorModePref.onPreferenceChangeListener = this
+
+ mRenderMode = findCachedPreference(PULSE_RENDER_MODE_KEY)!!
+ mRenderMode.onPreferenceChangeListener = this
+
+ mFadingBarsCat = findCachedPreference(PULSE_RENDER_CATEGORY_FADING)!!
+ mSolidBarsCat = findCachedPreference(PULSE_RENDER_CATEGORY_SOLID)!!
+
+ mPulseSmoothing = findCachedPreference(PULSE_SMOOTHING_KEY)!!
+
+ mFooterPref = findCachedPreference(PULSE_SETTINGS_FOOTER)!!
+ mFooterPref.setTitle(R.string.pulse_help_policy_notice_summary)
+
+ updateAllPrefs()
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ val resolver = requireContext().contentResolver
+ when (preference) {
+ mLockscreenPulse -> {
+ val value = newValue as Boolean
+ Settings.Secure.putIntForUser(resolver,
+ Settings.Secure.LOCKSCREEN_PULSE_ENABLED, if (value) 1 else 0, UserHandle.USER_CURRENT)
+ updateAllPrefs()
+ return true
+ }
+ mAmbientPulse -> {
+ val value = newValue as Boolean
+ Settings.Secure.putIntForUser(resolver,
+ Settings.Secure.AMBIENT_PULSE_ENABLED, if (value) 1 else 0, UserHandle.USER_CURRENT)
+ updateAllPrefs()
+ return true
+ }
+ mColorModePref -> {
+ updateColorPrefs(newValue.toString().toInt())
+ return true
+ }
+ mRenderMode -> {
+ updateRenderCategories(newValue.toString().toInt())
+ return true
+ }
+ }
+ return false
+ }
+
+ private fun updateAllPrefs() {
+ val resolver = getSafeContext()?.contentResolver
+
+ val lockscreenPulse = Settings.Secure.getIntForUser(resolver,
+ Settings.Secure.LOCKSCREEN_PULSE_ENABLED, 1, UserHandle.USER_CURRENT) != 0
+
+ val ambientPulse = Settings.Secure.getIntForUser(resolver,
+ Settings.Secure.AMBIENT_PULSE_ENABLED, 0, UserHandle.USER_CURRENT) != 0
+
+ mPulseSmoothing.isEnabled = lockscreenPulse || ambientPulse
+
+ mColorModePref.isEnabled = lockscreenPulse || ambientPulse
+ if (lockscreenPulse || ambientPulse) {
+ val colorMode = Settings.Secure.getIntForUser(resolver,
+ Settings.Secure.PULSE_COLOR_MODE, COLOR_TYPE_LAVALAMP, UserHandle.USER_CURRENT)
+ updateColorPrefs(colorMode)
+ } else {
+ mColorPickerPref.isEnabled = false
+ mLavaSpeedPref.isEnabled = false
+ }
+
+ mRenderMode.isEnabled = lockscreenPulse || ambientPulse
+ if (lockscreenPulse || ambientPulse) {
+ val renderMode = Settings.Secure.getIntForUser(resolver,
+ Settings.Secure.PULSE_RENDER_STYLE, RENDER_STYLE_SOLID_LINES, UserHandle.USER_CURRENT)
+ updateRenderCategories(renderMode)
+ } else {
+ mFadingBarsCat.isEnabled = false
+ mSolidBarsCat.isEnabled = false
+ }
+
+ mFooterPref.isEnabled = lockscreenPulse || ambientPulse
+ }
+
+ private fun updateColorPrefs(value: Int) {
+ when (value) {
+ COLOR_TYPE_ACCENT -> {
+ mColorPickerPref.isEnabled = false
+ mLavaSpeedPref.isEnabled = false
+ }
+ COLOR_TYPE_USER -> {
+ mColorPickerPref.isEnabled = true
+ mLavaSpeedPref.isEnabled = false
+ }
+ COLOR_TYPE_LAVALAMP -> {
+ mColorPickerPref.isEnabled = false
+ mLavaSpeedPref.isEnabled = true
+ }
+ COLOR_TYPE_AUTO -> {
+ mColorPickerPref.isEnabled = false
+ mLavaSpeedPref.isEnabled = false
+ }
+ }
+ }
+
+ private fun updateRenderCategories(mode: Int) {
+ mFadingBarsCat.isEnabled = mode == RENDER_STYLE_FADING_BARS
+ mSolidBarsCat.isEnabled = mode == RENDER_STYLE_SOLID_LINES
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/sound/SoundEngine.java b/src/com/rising/settings/fragments/sound/SoundEngine.kt
similarity index 50%
rename from src/com/rising/settings/fragments/sound/SoundEngine.java
rename to src/com/rising/settings/fragments/sound/SoundEngine.kt
index 6ba36d7d..266504fc 100644
--- a/src/com/rising/settings/fragments/sound/SoundEngine.java
+++ b/src/com/rising/settings/fragments/sound/SoundEngine.kt
@@ -14,27 +14,26 @@
* limitations under the License.
*/
-package com.rising.settings.fragments.sound;
+package com.rising.settings.fragments.sound
-import android.os.Bundle;
+import android.os.Bundle
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
-public class SoundEngine extends SettingsPreferenceFragment {
+class SoundEngine : OptimizedSettingsFragment() {
- private static final String TAG = "SoundEngine";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ companion object {
+ private const val TAG = "SoundEngine"
+ }
- addPreferencesFromResource(R.xml.sound_engine_settings);
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.sound_engine_settings)
}
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
}
}
diff --git a/src/com/rising/settings/fragments/sound/VolumeSteps.java b/src/com/rising/settings/fragments/sound/VolumeSteps.java
deleted file mode 100644
index 924d3567..00000000
--- a/src/com/rising/settings/fragments/sound/VolumeSteps.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2024 Yet Another AOSP Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.rising.settings.fragments.sound;
-
-import android.content.ContentResolver;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-import com.android.settings.preferences.CustomSeekBarPreference;
-
-public class VolumeSteps extends SettingsPreferenceFragment implements
- OnPreferenceChangeListener {
-
- private static final String TAG = "VolumeSteps";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.volume_steps_settings);
-
- ContentResolver resolver = getActivity().getContentResolver();
- PreferenceScreen screen = getPreferenceScreen();
- final int count = screen.getPreferenceCount();
- for (int i = 0; i < count; i++) {
- Preference pref = screen.getPreference(i);
- if (!(pref instanceof CustomSeekBarPreference))
- continue;
- String key = pref.getKey();
- final int def = Settings.System.getIntForUser(resolver, "default_" + key, 15, UserHandle.USER_CURRENT);
- final int value = Settings.System.getIntForUser(resolver, key, def, UserHandle.USER_CURRENT);
- CustomSeekBarPreference sbPref = (CustomSeekBarPreference) pref;
- sbPref.setDefaultValue(def);
- sbPref.setValue(value);
- sbPref.setOnPreferenceChangeListener(this);
- }
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (!(preference instanceof CustomSeekBarPreference))
- return false;
- Settings.System.putIntForUser(getActivity().getContentResolver(),
- preference.getKey(), (Integer) newValue, UserHandle.USER_CURRENT);
- return true;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-}
diff --git a/src/com/rising/settings/fragments/sound/VolumeSteps.kt b/src/com/rising/settings/fragments/sound/VolumeSteps.kt
new file mode 100644
index 00000000..45c165bf
--- /dev/null
+++ b/src/com/rising/settings/fragments/sound/VolumeSteps.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2024 Yet Another AOSP Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings.fragments.sound
+
+import android.content.ContentResolver
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.Settings
+
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+import androidx.preference.Preference.OnPreferenceChangeListener
+
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+
+import com.android.settings.preferences.CustomSeekBarPreference
+
+class VolumeSteps : OptimizedSettingsFragment(), OnPreferenceChangeListener {
+
+ companion object {
+ private const val TAG = "VolumeSteps"
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.volume_steps_settings)
+
+ val resolver = activity?.contentResolver
+ val screen = preferenceScreen
+ val count = screen.preferenceCount
+ for (i in 0 until count) {
+ val pref = screen.getPreference(i)
+ if (pref !is CustomSeekBarPreference) continue
+
+ val key = pref.key
+ val def = Settings.System.getIntForUser(resolver, "default_$key", 15, UserHandle.USER_CURRENT)
+ val value = Settings.System.getIntForUser(resolver, key, def, UserHandle.USER_CURRENT)
+ val sbPref = pref as CustomSeekBarPreference
+ // Set default value - property may not exist in this version
+ sbPref.setValue(value)
+ sbPref.onPreferenceChangeListener = this
+ }
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ if (preference !is CustomSeekBarPreference) return false
+
+ Settings.System.putIntForUser(activity?.contentResolver,
+ preference.key, newValue as Int, UserHandle.USER_CURRENT)
+ return true
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/statusbar/BatteryBar.java b/src/com/rising/settings/fragments/statusbar/BatteryBar.java
deleted file mode 100644
index b0eae07c..00000000
--- a/src/com/rising/settings/fragments/statusbar/BatteryBar.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2016-2024 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments.statusbar;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.SwitchPreferenceCompat;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-import com.android.settings.preferences.colorpicker.ColorPickerPreference;
-import com.android.settings.preferences.CustomSeekBarPreference;
-
-public class BatteryBar extends SettingsPreferenceFragment
- implements Preference.OnPreferenceChangeListener {
-
- private static final String PREF_BATT_BAR = "statusbar_battery_bar";
-
- private SwitchPreferenceCompat mBatteryBar;
-
- private boolean mIsBarSwitchingMode = false;
- private Handler mHandler;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.battery_bar);
-
- PreferenceScreen prefSet = getPreferenceScreen();
- ContentResolver resolver = getActivity().getContentResolver();
-
- int intColor;
- String hexColor;
-
- mBatteryBar = (SwitchPreferenceCompat) findPreference(PREF_BATT_BAR);
- mHandler = new Handler();
-
- boolean showing = Settings.System.getIntForUser(resolver,
- Settings.System.STATUSBAR_BATTERY_BAR, 0, UserHandle.USER_CURRENT) != 0;
- mBatteryBar.setChecked(showing);
- mBatteryBar.setOnPreferenceChangeListener(this);
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- ContentResolver resolver = getActivity().getContentResolver();
- if (preference == mBatteryBar) {
- if (mIsBarSwitchingMode) {
- return false;
- }
- mIsBarSwitchingMode = true;
- boolean value = ((Boolean)newValue);
- Settings.System.putIntForUser(resolver, Settings.System.STATUSBAR_BATTERY_BAR,
- value ? 1 : 0, UserHandle.USER_CURRENT);
- mHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- mIsBarSwitchingMode = false;
- boolean showing = Settings.System.getIntForUser(resolver,
- Settings.System.STATUSBAR_BATTERY_BAR, 0, UserHandle.USER_CURRENT) != 0;
- mBatteryBar.setChecked(showing);
- }
- }, 1500);
- return true;
- }
- return false;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-}
diff --git a/src/com/rising/settings/fragments/statusbar/BatteryBar.kt b/src/com/rising/settings/fragments/statusbar/BatteryBar.kt
new file mode 100644
index 00000000..aa29b066
--- /dev/null
+++ b/src/com/rising/settings/fragments/statusbar/BatteryBar.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016-2024 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments.statusbar
+
+import android.content.ContentResolver
+import android.content.Context
+import android.content.res.Resources
+import android.os.Bundle
+import android.os.Handler
+import android.os.UserHandle
+import android.provider.Settings
+
+import androidx.preference.ListPreference
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+import androidx.preference.Preference.OnPreferenceChangeListener
+import androidx.preference.SwitchPreferenceCompat
+
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+
+import com.android.settings.preferences.colorpicker.ColorPickerPreference
+import com.android.settings.preferences.CustomSeekBarPreference
+
+class BatteryBar : OptimizedSettingsFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ private const val PREF_BATT_BAR = "statusbar_battery_bar"
+ }
+
+ private lateinit var mBatteryBar: SwitchPreferenceCompat
+ private var mIsBarSwitchingMode = false
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.battery_bar)
+
+ val prefSet = preferenceScreen
+ val resolver = activity?.contentResolver
+
+ mBatteryBar = findCachedPreference(PREF_BATT_BAR)!!
+
+ val showing = Settings.System.getIntForUser(resolver,
+ Settings.System.STATUSBAR_BATTERY_BAR, 0, UserHandle.USER_CURRENT) != 0
+ mBatteryBar.isChecked = showing
+ mBatteryBar.onPreferenceChangeListener = this
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ val resolver = activity?.contentResolver
+ if (preference == mBatteryBar) {
+ if (mIsBarSwitchingMode) {
+ return false
+ }
+ mIsBarSwitchingMode = true
+ val value = newValue as Boolean
+ Settings.System.putIntForUser(resolver, Settings.System.STATUSBAR_BATTERY_BAR,
+ if (value) 1 else 0, UserHandle.USER_CURRENT)
+ postDelayedSafe({
+ mIsBarSwitchingMode = false
+ if (isFragmentReady()) {
+ val showing = Settings.System.getIntForUser(resolver,
+ Settings.System.STATUSBAR_BATTERY_BAR, 0, UserHandle.USER_CURRENT) != 0
+ mBatteryBar.isChecked = showing
+ }
+ }, 1500)
+ return true
+ }
+ return false
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/statusbar/Clock.java b/src/com/rising/settings/fragments/statusbar/Clock.java
deleted file mode 100644
index b6ef752d..00000000
--- a/src/com/rising/settings/fragments/statusbar/Clock.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2016-2024 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments.statusbar;
-
-import android.app.AlertDialog;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.text.format.DateFormat;
-import android.view.Menu;
-import android.widget.EditText;
-
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-import com.android.settings.preferences.CustomSeekBarPreference;
-import com.android.settings.preferences.SystemSettingListPreference;
-
-import java.util.Date;
-
-import lineageos.preference.LineageSystemSettingListPreference;
-import lineageos.providers.LineageSettings;
-
-public class Clock extends SettingsPreferenceFragment
- implements Preference.OnPreferenceChangeListener {
-
- private static final String TAG = "Clock";
-
- private static final String STATUS_BAR_AM_PM = "status_bar_am_pm";
- private static final String CLOCK_DATE_DISPLAY = "status_bar_clock_date_display";
- private static final String CLOCK_DATE_POSITION = "status_bar_clock_date_position";
- private static final String CLOCK_DATE_STYLE = "status_bar_clock_date_style";
- private static final String CLOCK_DATE_FORMAT = "status_bar_clock_date_format";
- private static final String CLOCK_SECONDS = "status_bar_clock_seconds";
-
- private static final int CLOCK_DATE_STYLE_LOWERCASE = 1;
- private static final int CLOCK_DATE_STYLE_UPPERCASE = 2;
- private static final int CUSTOM_CLOCK_DATE_FORMAT_INDEX = 18;
-
- private LineageSystemSettingListPreference mStatusBarAmPm;
- private SystemSettingListPreference mClockDateDisplay;
- private SystemSettingListPreference mClockDatePosition;
- private SystemSettingListPreference mClockDateStyle;
- private ListPreference mClockDateFormat;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.status_bar_clock);
-
- ContentResolver resolver = getActivity().getContentResolver();
-
- mStatusBarAmPm =
- (LineageSystemSettingListPreference) findPreference(STATUS_BAR_AM_PM);
-
- if (DateFormat.is24HourFormat(getActivity())) {
- mStatusBarAmPm.setEnabled(false);
- mStatusBarAmPm.setSummary(R.string.status_bar_am_pm_info);
- }
-
- int dateDisplay = Settings.System.getIntForUser(resolver,
- Settings.System.STATUS_BAR_CLOCK_DATE_DISPLAY, 0, UserHandle.USER_CURRENT);
-
- mClockDateDisplay = (SystemSettingListPreference) findPreference(CLOCK_DATE_DISPLAY);
- mClockDateDisplay.setOnPreferenceChangeListener(this);
-
- mClockDatePosition = (SystemSettingListPreference) findPreference(CLOCK_DATE_POSITION);
- mClockDatePosition.setEnabled(dateDisplay > 0);
- mClockDatePosition.setOnPreferenceChangeListener(this);
-
- mClockDateStyle = (SystemSettingListPreference) findPreference(CLOCK_DATE_STYLE);
- mClockDateStyle.setEnabled(dateDisplay > 0);
- mClockDateStyle.setOnPreferenceChangeListener(this);
-
- mClockDateFormat = (ListPreference) findPreference(CLOCK_DATE_FORMAT);
- if (mClockDateFormat.getValue() == null) {
- mClockDateFormat.setValue("EEE");
- }
- parseClockDateFormats();
- mClockDateFormat.setEnabled(dateDisplay > 0);
- mClockDateFormat.setOnPreferenceChangeListener(this);
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- AlertDialog dialog;
- ContentResolver resolver = getActivity().getContentResolver();
- if (preference == mClockDateDisplay) {
- int val = Integer.parseInt((String) newValue);
- if (val == 0) {
- mClockDatePosition.setEnabled(false);
- mClockDateStyle.setEnabled(false);
- mClockDateFormat.setEnabled(false);
- } else {
- mClockDatePosition.setEnabled(true);
- mClockDateStyle.setEnabled(true);
- mClockDateFormat.setEnabled(true);
- }
- return true;
- } else if (preference == mClockDatePosition) {
- parseClockDateFormats();
- return true;
- } else if (preference == mClockDateStyle) {
- parseClockDateFormats();
- return true;
- } else if (preference == mClockDateFormat) {
- int index = mClockDateFormat.findIndexOfValue((String) newValue);
-
- if (index == CUSTOM_CLOCK_DATE_FORMAT_INDEX) {
- AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
- alert.setTitle(R.string.status_bar_date_string_edittext_title);
- alert.setMessage(R.string.status_bar_date_string_edittext_summary);
-
- final EditText input = new EditText(getActivity());
- String oldText = Settings.System.getString(
- resolver,
- Settings.System.STATUS_BAR_CLOCK_DATE_FORMAT);
- if (oldText != null) {
- input.setText(oldText);
- }
- alert.setView(input);
-
- alert.setPositiveButton(R.string.menu_save, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialogInterface, int whichButton) {
- String value = input.getText().toString();
- if (value.equals("")) {
- return;
- }
- Settings.System.putString(resolver,
- Settings.System.STATUS_BAR_CLOCK_DATE_FORMAT, value);
-
- return;
- }
- });
-
- alert.setNegativeButton(R.string.menu_cancel,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialogInterface, int which) {
- return;
- }
- });
- dialog = alert.create();
- dialog.show();
- } else {
- if ((String) newValue != null) {
- Settings.System.putString(resolver,
- Settings.System.STATUS_BAR_CLOCK_DATE_FORMAT, (String) newValue);
- }
- }
- return true;
- }
- return false;
- }
-
- private void parseClockDateFormats() {
- String[] dateEntries = getResources().getStringArray(
- R.array.status_bar_date_format_entries_values);
- CharSequence parsedDateEntries[];
- parsedDateEntries = new String[dateEntries.length];
- Date now = new Date();
-
- int lastEntry = dateEntries.length - 1;
- int dateFormat = Settings.System.getIntForUser(getActivity()
- .getContentResolver(), Settings.System.STATUS_BAR_CLOCK_DATE_STYLE, 0, UserHandle.USER_CURRENT);
- for (int i = 0; i < dateEntries.length; i++) {
- if (i == lastEntry) {
- parsedDateEntries[i] = dateEntries[i];
- } else {
- String newDate;
- CharSequence dateString = DateFormat.format(dateEntries[i], now);
- if (dateFormat == CLOCK_DATE_STYLE_LOWERCASE) {
- newDate = dateString.toString().toLowerCase();
- } else if (dateFormat == CLOCK_DATE_STYLE_UPPERCASE) {
- newDate = dateString.toString().toUpperCase();
- } else {
- newDate = dateString.toString();
- }
-
- parsedDateEntries[i] = newDate;
- }
- }
- mClockDateFormat.setEntries(parsedDateEntries);
- }
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-}
diff --git a/src/com/rising/settings/fragments/statusbar/Clock.kt b/src/com/rising/settings/fragments/statusbar/Clock.kt
new file mode 100644
index 00000000..f53c58a5
--- /dev/null
+++ b/src/com/rising/settings/fragments/statusbar/Clock.kt
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2016-2024 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments.statusbar
+
+import android.app.AlertDialog
+import android.content.ContentResolver
+import android.content.Context
+import android.content.DialogInterface
+import android.content.DialogInterface.OnCancelListener
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.Settings
+import android.text.format.DateFormat
+import android.view.Menu
+import android.widget.EditText
+
+import androidx.preference.ListPreference
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+import androidx.preference.Preference.OnPreferenceChangeListener
+
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+
+import com.android.settings.preferences.CustomSeekBarPreference
+import com.android.settings.preferences.SystemSettingListPreference
+
+import java.util.Date
+
+import lineageos.preference.LineageSystemSettingListPreference
+import lineageos.providers.LineageSettings
+
+class Clock : OptimizedSettingsFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ private const val TAG = "Clock"
+
+ private const val STATUS_BAR_AM_PM = "status_bar_am_pm"
+ private const val CLOCK_DATE_DISPLAY = "status_bar_clock_date_display"
+ private const val CLOCK_DATE_POSITION = "status_bar_clock_date_position"
+ private const val CLOCK_DATE_STYLE = "status_bar_clock_date_style"
+ private const val CLOCK_DATE_FORMAT = "status_bar_clock_date_format"
+ private const val CLOCK_SECONDS = "status_bar_clock_seconds"
+
+ private const val CLOCK_DATE_STYLE_LOWERCASE = 1
+ private const val CLOCK_DATE_STYLE_UPPERCASE = 2
+ private const val CUSTOM_CLOCK_DATE_FORMAT_INDEX = 18
+ }
+
+ private lateinit var mStatusBarAmPm: LineageSystemSettingListPreference
+ private lateinit var mClockDateDisplay: SystemSettingListPreference
+ private lateinit var mClockDatePosition: SystemSettingListPreference
+ private lateinit var mClockDateStyle: SystemSettingListPreference
+ private lateinit var mClockDateFormat: ListPreference
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.status_bar_clock)
+
+ val resolver = activity?.contentResolver
+
+ mStatusBarAmPm = findCachedPreference(STATUS_BAR_AM_PM)!!
+
+ if (DateFormat.is24HourFormat(activity)) {
+ mStatusBarAmPm.isEnabled = false
+ mStatusBarAmPm.setSummary(R.string.status_bar_am_pm_info)
+ }
+
+ val dateDisplay = Settings.System.getIntForUser(resolver,
+ Settings.System.STATUS_BAR_CLOCK_DATE_DISPLAY, 0, UserHandle.USER_CURRENT)
+
+ mClockDateDisplay = findCachedPreference(CLOCK_DATE_DISPLAY)!!
+ mClockDateDisplay.onPreferenceChangeListener = this
+
+ mClockDatePosition = findCachedPreference(CLOCK_DATE_POSITION)!!
+ mClockDatePosition.isEnabled = dateDisplay > 0
+ mClockDatePosition.onPreferenceChangeListener = this
+
+ mClockDateStyle = findCachedPreference(CLOCK_DATE_STYLE)!!
+ mClockDateStyle.isEnabled = dateDisplay > 0
+ mClockDateStyle.onPreferenceChangeListener = this
+
+ mClockDateFormat = findCachedPreference(CLOCK_DATE_FORMAT)!!
+ if (mClockDateFormat.value == null) {
+ mClockDateFormat.value = "EEE"
+ }
+ parseClockDateFormats()
+ mClockDateFormat.isEnabled = dateDisplay > 0
+ mClockDateFormat.onPreferenceChangeListener = this
+ }
+
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ val resolver = activity?.contentResolver
+ when (preference) {
+ mClockDateDisplay -> {
+ val value = (newValue as String).toInt()
+ if (value == 0) {
+ mClockDatePosition.isEnabled = false
+ mClockDateStyle.isEnabled = false
+ mClockDateFormat.isEnabled = false
+ } else {
+ mClockDatePosition.isEnabled = true
+ mClockDateStyle.isEnabled = true
+ mClockDateFormat.isEnabled = true
+ }
+ return true
+ }
+ mClockDatePosition -> {
+ parseClockDateFormats()
+ return true
+ }
+ mClockDateStyle -> {
+ parseClockDateFormats()
+ return true
+ }
+ mClockDateFormat -> {
+ val index = mClockDateFormat.findIndexOfValue(newValue as String)
+
+ if (index == CUSTOM_CLOCK_DATE_FORMAT_INDEX) {
+ val alert = AlertDialog.Builder(activity)
+ alert.setTitle(R.string.status_bar_date_string_edittext_title)
+ alert.setMessage(R.string.status_bar_date_string_edittext_summary)
+
+ val input = EditText(activity)
+ val oldText = Settings.System.getString(
+ resolver,
+ Settings.System.STATUS_BAR_CLOCK_DATE_FORMAT)
+ if (oldText != null) {
+ input.setText(oldText)
+ }
+ alert.setView(input)
+
+ alert.setPositiveButton(R.string.menu_save) { _, _ ->
+ val value = input.text.toString()
+ if (value.isNotEmpty()) {
+ Settings.System.putString(resolver,
+ Settings.System.STATUS_BAR_CLOCK_DATE_FORMAT, value)
+ }
+ }
+
+ alert.setNegativeButton(R.string.menu_cancel) { _, _ ->
+ // Do nothing
+ }
+ val dialog = alert.create()
+ dialog.show()
+ } else {
+ if (newValue.isNotEmpty()) {
+ Settings.System.putString(resolver,
+ Settings.System.STATUS_BAR_CLOCK_DATE_FORMAT, newValue)
+ }
+ }
+ return true
+ }
+ }
+ return false
+ }
+
+ private fun parseClockDateFormats() {
+ val dateEntries = resources.getStringArray(R.array.status_bar_date_format_entries_values)
+ val parsedDateEntries = Array(dateEntries.size) { "" }
+ val now = Date()
+
+ val lastEntry = dateEntries.size - 1
+ val dateFormat = Settings.System.getIntForUser(activity?.contentResolver,
+ Settings.System.STATUS_BAR_CLOCK_DATE_STYLE, 0, UserHandle.USER_CURRENT)
+
+ for (i in dateEntries.indices) {
+ if (i == lastEntry) {
+ parsedDateEntries[i] = dateEntries[i]
+ } else {
+ val dateString = DateFormat.format(dateEntries[i], now)
+ val newDate = when (dateFormat) {
+ CLOCK_DATE_STYLE_LOWERCASE -> dateString.toString().lowercase()
+ CLOCK_DATE_STYLE_UPPERCASE -> dateString.toString().uppercase()
+ else -> dateString.toString()
+ }
+ parsedDateEntries[i] = newDate
+ }
+ }
+ mClockDateFormat.entries = parsedDateEntries
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/statusbar/NetworkTrafficSettings.java b/src/com/rising/settings/fragments/statusbar/NetworkTrafficSettings.java
deleted file mode 100644
index 067d1df2..00000000
--- a/src/com/rising/settings/fragments/statusbar/NetworkTrafficSettings.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2017-2024 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.rising.settings.fragments.statusbar;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.internal.logging.nano.MetricsProto;
-
-public class NetworkTrafficSettings extends SettingsPreferenceFragment {
-
- private static final String TAG = "NetworkTrafficSettings";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.network_traffic_settings);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-}
diff --git a/src/com/rising/settings/fragments/statusbar/NetworkTrafficSettings.kt b/src/com/rising/settings/fragments/statusbar/NetworkTrafficSettings.kt
new file mode 100644
index 00000000..0a907308
--- /dev/null
+++ b/src/com/rising/settings/fragments/statusbar/NetworkTrafficSettings.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017-2024 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings.fragments.statusbar
+
+import android.content.ContentResolver
+import android.content.Context
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.Settings
+
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import com.android.internal.logging.nano.MetricsProto
+
+class NetworkTrafficSettings : OptimizedSettingsFragment() {
+
+ companion object {
+ private const val TAG = "NetworkTrafficSettings"
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.network_traffic_settings)
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/statusbar/StatusbarLyricSettings.java b/src/com/rising/settings/fragments/statusbar/StatusbarLyricSettings.java
deleted file mode 100644
index 525277cb..00000000
--- a/src/com/rising/settings/fragments/statusbar/StatusbarLyricSettings.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2022 Project Kaleidoscope
- * SPDX-License-Identifier: Apache-2.0
- */
-package com.rising.settings.fragments.statusbar;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.List;
-
-@SearchIndexable
-public class StatusbarLyricSettings extends SettingsPreferenceFragment {
-
- public static final String TAG = "StatusbarLyricSettings";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.status_bar_lyric_settings);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.status_bar_lyric_settings) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/statusbar/StatusbarLyricSettings.kt b/src/com/rising/settings/fragments/statusbar/StatusbarLyricSettings.kt
new file mode 100644
index 00000000..52b9f91b
--- /dev/null
+++ b/src/com/rising/settings/fragments/statusbar/StatusbarLyricSettings.kt
@@ -0,0 +1,45 @@
+/*
+ * SPDX-FileCopyrightText: 2022 Project Kaleidoscope
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.rising.settings.fragments.statusbar
+
+import android.content.ContentResolver
+import android.content.Context
+import android.os.Bundle
+import android.os.UserHandle
+import android.provider.Settings
+
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class StatusbarLyricSettings : OptimizedSettingsFragment() {
+
+ companion object {
+ const val TAG = "StatusbarLyricSettings"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.status_bar_lyric_settings) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context)
+ return keys
+ }
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.status_bar_lyric_settings)
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/ui/IconShapes.java b/src/com/rising/settings/fragments/ui/IconShapes.java
deleted file mode 100644
index 9c4ac603..00000000
--- a/src/com/rising/settings/fragments/ui/IconShapes.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2022 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.rising.settings.fragments.ui;
-
-import static com.android.internal.util.android.ThemeUtils.ICON_SHAPE_KEY;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.ShapeDrawable;
-import android.os.Bundle;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.Gravity;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-import android.text.TextUtils;
-import androidx.preference.PreferenceViewHolder;
-import android.view.ViewGroup.LayoutParams;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.graphics.ColorUtils;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.Indexable;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settingslib.Utils;
-
-import com.bumptech.glide.Glide;
-
-import com.android.internal.util.android.ThemeUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Arrays;
-
-import org.json.JSONObject;
-import org.json.JSONException;
-
-public class IconShapes extends SettingsPreferenceFragment {
-
- private RecyclerView mRecyclerView;
- private ThemeUtils mThemeUtils;
-
- private String mCategory = ICON_SHAPE_KEY;
-
- private List mPkgs;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getActivity().setTitle(R.string.theme_customization_icon_shape_title);
-
- mThemeUtils = ThemeUtils.getInstance(getActivity());
- mPkgs = mThemeUtils.getOverlayPackagesForCategory(mCategory, "android");
- }
-
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(
- R.layout.item_view, container, false);
-
- mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
- GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
- mRecyclerView.setLayoutManager(gridLayoutManager);
- Adapter mAdapter = new Adapter(getActivity());
- mRecyclerView.setAdapter(mAdapter);
-
- return view;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.VIEW_UNKNOWN;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- }
-
- public class Adapter extends RecyclerView.Adapter {
- Context context;
- String mSelectedPkg;
- String mAppliedPkg;
-
- public Adapter(Context context) {
- this.context = context;
- }
-
- @Override
- public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_option, parent, false);
- CustomViewHolder vh = new CustomViewHolder(v);
- return vh;
- }
-
- @Override
- public void onBindViewHolder(CustomViewHolder holder, final int position) {
- String pkg = mPkgs.get(position);
-
- holder.image.setBackgroundDrawable(mThemeUtils.createShapeDrawable(pkg));
-
- String currentPackageName = mThemeUtils.getOverlayInfos(mCategory).stream()
- .filter(info -> info.isEnabled())
- .map(info -> info.packageName)
- .findFirst()
- .orElse("android");
-
- holder.name.setText("android".equals(pkg) ? "Default" : getLabel(holder.name.getContext(), pkg));
-
- final boolean isDefault = "android".equals(currentPackageName) && "android".equals(pkg);
- final int color = ColorUtils.setAlphaComponent(
- Utils.getColorAttrDefaultColor(getContext(), android.R.attr.colorAccent),
- pkg.equals(currentPackageName) || isDefault ? 170 : 75);
- holder.image.setBackgroundTintList(ColorStateList.valueOf(color));
-
- holder.itemView.findViewById(R.id.option_tile).setBackgroundDrawable(null);
- holder.itemView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- enableOverlays(position);
- }
- });
- }
-
- @Override
- public int getItemCount() {
- return mPkgs.size();
- }
-
- public class CustomViewHolder extends RecyclerView.ViewHolder {
- TextView name;
- ImageView image;
- public CustomViewHolder(View itemView) {
- super(itemView);
- name = (TextView) itemView.findViewById(R.id.option_label);
- image = (ImageView) itemView.findViewById(R.id.option_thumbnail);
- }
- }
- }
-
- public Drawable getDrawable(Context context, String pkg, String drawableName) {
- try {
- PackageManager pm = context.getPackageManager();
- Resources res = pkg.equals("android") ? Resources.getSystem()
- : pm.getResourcesForApplication(pkg);
- return res.getDrawable(res.getIdentifier(drawableName, "drawable", pkg));
- }
- catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public String getLabel(Context context, String pkg) {
- PackageManager pm = context.getPackageManager();
- try {
- return pm.getApplicationInfo(pkg, 0)
- .loadLabel(pm).toString();
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return pkg;
- }
-
- public void enableOverlays(int position) {
- mThemeUtils.setOverlayEnabled(mCategory, mPkgs.get(position), "android");
- }
-}
diff --git a/src/com/rising/settings/fragments/ui/IconShapes.kt b/src/com/rising/settings/fragments/ui/IconShapes.kt
new file mode 100644
index 00000000..fcdacf91
--- /dev/null
+++ b/src/com/rising/settings/fragments/ui/IconShapes.kt
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2022 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings.fragments.ui
+
+import com.android.internal.util.android.ThemeUtils.ICON_SHAPE_KEY
+
+import android.content.ContentResolver
+import android.content.Context
+import android.content.res.ColorStateList
+import android.content.res.Resources
+import android.content.pm.PackageManager
+import android.graphics.drawable.AnimationDrawable
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.ShapeDrawable
+import android.os.Bundle
+import android.provider.SearchIndexableResource
+import android.provider.Settings
+import android.view.LayoutInflater
+import android.view.View
+import android.view.Gravity
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.FrameLayout
+import android.widget.TextView
+import android.text.TextUtils
+import androidx.preference.PreferenceViewHolder
+import android.view.ViewGroup.LayoutParams
+
+import androidx.annotation.NonNull
+import androidx.annotation.Nullable
+import androidx.core.graphics.ColorUtils
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
+import androidx.recyclerview.widget.RecyclerView
+import androidx.preference.Preference
+import androidx.preference.Preference.OnPreferenceChangeListener
+import androidx.preference.PreferenceScreen
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent
+import com.android.settings.R
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.Indexable
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import com.android.settingslib.Utils
+
+import com.bumptech.glide.Glide
+
+import com.android.internal.util.android.ThemeUtils
+
+import org.json.JSONObject
+import org.json.JSONException
+
+class IconShapes : OptimizedSettingsFragment() {
+
+ private lateinit var mRecyclerView: RecyclerView
+ override var mThemeUtils: ThemeUtils? = null
+ private val mCategory = ICON_SHAPE_KEY
+ private lateinit var mPkgs: List
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ activity?.setTitle(R.string.theme_customization_icon_shape_title)
+
+ mThemeUtils = ThemeUtils.getInstance(activity)
+ mPkgs = mThemeUtils?.getOverlayPackagesForCategory(mCategory, "android") ?: emptyList()
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ val view = inflater.inflate(R.layout.item_view, container, false)
+
+ mRecyclerView = view.findViewById(R.id.recycler_view)
+ val gridLayoutManager = GridLayoutManager(activity, 3)
+ mRecyclerView.layoutManager = gridLayoutManager
+ val mAdapter = Adapter(activity!!)
+ mRecyclerView.adapter = mAdapter
+
+ return view
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsEvent.VIEW_UNKNOWN
+ }
+
+ override fun onResume() {
+ super.onResume()
+ }
+
+ inner class Adapter(val context: Context) : RecyclerView.Adapter() {
+ private var mSelectedPkg: String? = null
+ private var mAppliedPkg: String? = null
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
+ val v = LayoutInflater.from(parent.context).inflate(R.layout.item_option, parent, false)
+ return CustomViewHolder(v)
+ }
+
+ override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
+ val pkg = mPkgs[position]
+
+ holder.image.background = mThemeUtils?.createShapeDrawable(pkg)
+
+ val currentPackageName = mThemeUtils?.getOverlayInfos(mCategory)
+ ?.filter { it.isEnabled }
+ ?.map { it.packageName }
+ ?.firstOrNull() ?: "android"
+
+ holder.name.text = if (pkg == "android") "Default" else getLabel(holder.name.context, pkg)
+
+ val isDefault = currentPackageName == "android" && pkg == "android"
+ val color = ColorUtils.setAlphaComponent(
+ Utils.getColorAttrDefaultColor(context, android.R.attr.colorAccent),
+ if (pkg == currentPackageName || isDefault) 170 else 75
+ )
+ holder.image.backgroundTintList = ColorStateList.valueOf(color)
+
+ holder.itemView.findViewById(R.id.option_tile).background = null
+ holder.itemView.setOnClickListener {
+ enableOverlays(position)
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return mPkgs.size
+ }
+
+ inner class CustomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val name: TextView = itemView.findViewById(R.id.option_label)
+ val image: ImageView = itemView.findViewById(R.id.option_thumbnail)
+ }
+ }
+
+ private fun getDrawable(context: Context, pkg: String, drawableName: String): Drawable? {
+ return try {
+ val pm = context.packageManager
+ val res = if (pkg == "android") {
+ Resources.getSystem()
+ } else {
+ pm.getResourcesForApplication(pkg)
+ }
+ res.getDrawable(res.getIdentifier(drawableName, "drawable", pkg))
+ } catch (e: PackageManager.NameNotFoundException) {
+ e.printStackTrace()
+ null
+ }
+ }
+
+ private fun getLabel(context: Context, pkg: String): String {
+ val pm = context.packageManager
+ return try {
+ pm.getApplicationInfo(pkg, 0).loadLabel(pm).toString()
+ } catch (e: PackageManager.NameNotFoundException) {
+ e.printStackTrace()
+ pkg
+ }
+ }
+
+ private fun enableOverlays(position: Int) {
+ mThemeUtils?.setOverlayEnabled(mCategory, mPkgs[position], "android")
+ }
+}
diff --git a/src/com/rising/settings/fragments/ui/NavbarStyles.java b/src/com/rising/settings/fragments/ui/NavbarStyles.java
deleted file mode 100644
index 7313b1c7..00000000
--- a/src/com/rising/settings/fragments/ui/NavbarStyles.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2022 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.rising.settings.fragments.ui;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.Gravity;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-import android.text.TextUtils;
-import androidx.preference.PreferenceViewHolder;
-import android.view.ViewGroup.LayoutParams;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.Indexable;
-import com.android.settings.SettingsPreferenceFragment;
-
-import com.bumptech.glide.Glide;
-
-import com.android.internal.util.android.ThemeUtils;
-import com.android.internal.util.android.Utils;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Arrays;
-
-import org.json.JSONObject;
-import org.json.JSONException;
-
-public class NavbarStyles extends SettingsPreferenceFragment {
-
- private RecyclerView mRecyclerView;
- private ThemeUtils mThemeUtils;
- private String mCategory = "android.theme.customization.navbar";
-
- private List mPkgs;
- private String mLauncherPackage;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getActivity().setTitle(R.string.theme_customization_navbar_title);
-
- mThemeUtils = ThemeUtils.getInstance(getActivity());
- mLauncherPackage = Utils.isPackageInstalled(getContext(), "com.google.android.apps.nexuslauncher", false)
- ? "com.google.android.apps.nexuslauncher"
- : "com.android.launcher3";
-
- mPkgs = mThemeUtils.getOverlayPackagesForCategory(mCategory, mLauncherPackage);
- }
-
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(
- R.layout.item_view, container, false);
-
- mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
- GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2);
- mRecyclerView.setLayoutManager(gridLayoutManager);
- Adapter mAdapter = new Adapter(getActivity());
- mRecyclerView.setAdapter(mAdapter);
-
- return view;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.VIEW_UNKNOWN;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- }
-
- public class Adapter extends RecyclerView.Adapter {
- Context context;
- String mSelectedPkg;
- String mAppliedPkg;
-
- public Adapter(Context context) {
- this.context = context;
- }
-
- @Override
- public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.navbar_option, parent, false);
- CustomViewHolder vh = new CustomViewHolder(v);
- return vh;
- }
-
- @Override
- public void onBindViewHolder(CustomViewHolder holder, final int position) {
- String navPkg = mPkgs.get(position);
-
- holder.image1.setBackgroundDrawable(getDrawable(holder.image1.getContext(), navPkg, "ic_sysbar_back"));
- holder.image2.setBackgroundDrawable(getDrawable(holder.image2.getContext(), navPkg, "ic_sysbar_home"));
- holder.image3.setBackgroundDrawable(getDrawable(holder.image3.getContext(), navPkg, "ic_sysbar_recent"));
-
- String currentPackageName = mThemeUtils.getOverlayInfos(mCategory, mLauncherPackage).stream()
- .filter(info -> info.isEnabled())
- .map(info -> info.packageName)
- .findFirst()
- .orElse(mLauncherPackage);
-
- holder.name.setText(mLauncherPackage.equals(navPkg) ? "Default" : getLabel(holder.name.getContext(), navPkg));
-
- if (currentPackageName.equals(navPkg)) {
- mAppliedPkg = navPkg;
- if (mSelectedPkg == null) {
- mSelectedPkg = navPkg;
- }
- }
-
- holder.itemView.setActivated(navPkg == mSelectedPkg);
- holder.itemView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- updateActivatedStatus(mSelectedPkg, false);
- updateActivatedStatus(navPkg, true);
- mSelectedPkg = navPkg;
- enableOverlays(position);
- }
- });
- }
-
- @Override
- public int getItemCount() {
- return mPkgs.size();
- }
-
- public class CustomViewHolder extends RecyclerView.ViewHolder {
- TextView name;
- ImageView image1;
- ImageView image2;
- ImageView image3;
- public CustomViewHolder(View itemView) {
- super(itemView);
- name = (TextView) itemView.findViewById(R.id.option_label);
- image1 = (ImageView) itemView.findViewById(R.id.image1);
- image2 = (ImageView) itemView.findViewById(R.id.image2);
- image3 = (ImageView) itemView.findViewById(R.id.image3);
- }
- }
-
- private void updateActivatedStatus(String pkg, boolean isActivated) {
- int index = mPkgs.indexOf(pkg);
- if (index < 0) {
- return;
- }
- RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(index);
- if (holder != null && holder.itemView != null) {
- holder.itemView.setActivated(isActivated);
- }
- }
- }
-
- public Drawable getDrawable(Context context, String pkg, String drawableName) {
- if (pkg.equals("com.android.launcher3") || pkg.equals("com.google.android.apps.nexuslauncher"))
- pkg = "com.android.settings";
- try {
- PackageManager pm = context.getPackageManager();
- Resources res = pm.getResourcesForApplication(pkg);
- int resId = res.getIdentifier(drawableName, "drawable", pkg);
- return res.getDrawable(resId);
- }
- catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public String getLabel(Context context, String pkg) {
- PackageManager pm = context.getPackageManager();
- try {
- return pm.getApplicationInfo(pkg, 0)
- .loadLabel(pm).toString();
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return pkg;
- }
-
- public void enableOverlays(int position) {
- mThemeUtils.setOverlayEnabled(mCategory, mPkgs.get(position), mLauncherPackage);
- }
-}
diff --git a/src/com/rising/settings/fragments/ui/NavbarStyles.kt b/src/com/rising/settings/fragments/ui/NavbarStyles.kt
new file mode 100644
index 00000000..46c5fd20
--- /dev/null
+++ b/src/com/rising/settings/fragments/ui/NavbarStyles.kt
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2022 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings.fragments.ui
+
+import android.content.Context
+import android.content.pm.PackageManager
+import android.content.res.Resources
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.annotation.NonNull
+import androidx.annotation.Nullable
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+
+import com.android.internal.util.android.ThemeUtils
+import com.android.internal.util.android.Utils
+
+class NavbarStyles : OptimizedSettingsFragment() {
+
+ private var mRecyclerView: RecyclerView? = null
+ override var mThemeUtils: ThemeUtils? = null
+ private val mCategory = "android.theme.customization.navbar"
+
+ private var mPkgs: List? = null
+ private var mLauncherPackage: String? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ activity?.setTitle(R.string.theme_customization_navbar_title)
+
+ mThemeUtils = ThemeUtils.getInstance(activity)
+ mLauncherPackage = if (Utils.isPackageInstalled(requireContext(), "com.google.android.apps.nexuslauncher", false)) {
+ "com.google.android.apps.nexuslauncher"
+ } else {
+ "com.android.launcher3"
+ }
+
+ mPkgs = mThemeUtils?.getOverlayPackagesForCategory(mCategory, mLauncherPackage)
+ }
+
+ override fun onCreateView(
+ @NonNull inflater: LayoutInflater,
+ @Nullable container: ViewGroup?,
+ @Nullable savedInstanceState: Bundle?
+ ): View {
+ val view = inflater.inflate(R.layout.item_view, container, false)
+
+ mRecyclerView = view.findViewById(R.id.recycler_view)
+ val gridLayoutManager = GridLayoutManager(activity, 2)
+ mRecyclerView?.layoutManager = gridLayoutManager
+ val mAdapter = Adapter(activity)
+ mRecyclerView?.adapter = mAdapter
+
+ return view
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsEvent.VIEW_UNKNOWN
+ }
+
+ override fun onResume() {
+ super.onResume()
+ }
+
+ inner class Adapter(private val context: Context?) : RecyclerView.Adapter() {
+ private var mSelectedPkg: String? = null
+ private var mAppliedPkg: String? = null
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
+ val v = LayoutInflater.from(parent.context).inflate(R.layout.navbar_option, parent, false)
+ return CustomViewHolder(v)
+ }
+
+ override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
+ val navPkg = mPkgs?.get(position) ?: return
+
+ holder.image1?.background = getDrawable(holder.image1?.context, navPkg, "ic_sysbar_back")
+ holder.image2?.background = getDrawable(holder.image2?.context, navPkg, "ic_sysbar_home")
+ holder.image3?.background = getDrawable(holder.image3?.context, navPkg, "ic_sysbar_recent")
+
+ val currentPackageName = mThemeUtils?.getOverlayInfos(mCategory, mLauncherPackage)
+ ?.filter { it.isEnabled }
+ ?.map { it.packageName }
+ ?.firstOrNull() ?: mLauncherPackage
+
+ holder.name?.text = if (mLauncherPackage == navPkg) "Default" else getLabel(holder.name?.context, navPkg)
+
+ if (currentPackageName == navPkg) {
+ mAppliedPkg = navPkg
+ if (mSelectedPkg == null) {
+ mSelectedPkg = navPkg
+ }
+ }
+
+ holder.itemView.isActivated = navPkg == mSelectedPkg
+ holder.itemView.setOnClickListener {
+ updateActivatedStatus(mSelectedPkg, false)
+ updateActivatedStatus(navPkg, true)
+ mSelectedPkg = navPkg
+ enableOverlays(position)
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return mPkgs?.size ?: 0
+ }
+
+ inner class CustomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val name: TextView? = itemView.findViewById(R.id.option_label)
+ val image1: ImageView? = itemView.findViewById(R.id.image1)
+ val image2: ImageView? = itemView.findViewById(R.id.image2)
+ val image3: ImageView? = itemView.findViewById(R.id.image3)
+ }
+
+ private fun updateActivatedStatus(pkg: String?, isActivated: Boolean) {
+ val index = mPkgs?.indexOf(pkg) ?: -1
+ if (index < 0) {
+ return
+ }
+ val holder = mRecyclerView?.findViewHolderForAdapterPosition(index)
+ holder?.itemView?.isActivated = isActivated
+ }
+ }
+
+ private fun getDrawable(context: Context?, pkg: String, drawableName: String): Drawable? {
+ val actualPkg = if (pkg == "com.android.launcher3" || pkg == "com.google.android.apps.nexuslauncher") {
+ "com.android.settings"
+ } else {
+ pkg
+ }
+
+ return try {
+ val pm = context?.packageManager
+ val res = pm?.getResourcesForApplication(actualPkg)
+ val resId = res?.getIdentifier(drawableName, "drawable", actualPkg) ?: 0
+ res?.getDrawable(resId)
+ } catch (e: PackageManager.NameNotFoundException) {
+ e.printStackTrace()
+ null
+ }
+ }
+
+ private fun getLabel(context: Context?, pkg: String): String {
+ val pm = context?.packageManager
+ return try {
+ pm?.getApplicationInfo(pkg, 0)?.loadLabel(pm)?.toString() ?: pkg
+ } catch (e: PackageManager.NameNotFoundException) {
+ e.printStackTrace()
+ pkg
+ }
+ }
+
+ private fun enableOverlays(position: Int) {
+ val pkg = mPkgs?.get(position)
+ if (pkg != null) {
+ mThemeUtils?.setOverlayEnabled(mCategory, pkg, mLauncherPackage)
+ }
+ }
+}
diff --git a/src/com/rising/settings/fragments/ui/Settings.java b/src/com/rising/settings/fragments/ui/Settings.java
deleted file mode 100644
index 30516d47..00000000
--- a/src/com/rising/settings/fragments/ui/Settings.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2023-2024 the risingOS Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.rising.settings.fragments.ui;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.UserHandle;
-
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-
-import com.android.internal.util.android.SystemRestartUtils;
-import com.android.settings.preferences.SystemSettingListPreference;
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.List;
-
-@SearchIndexable
-public class Settings extends SettingsPreferenceFragment implements
- Preference.OnPreferenceChangeListener {
-
- public static final String SETTINGS_DASHBOARD_STYLE = "settings_dashboard_style";
-
- private SystemSettingListPreference mSettingsDashBoardStyle;
-
- private static final String TAG = "Settings";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.rising_settings_settingsui);
- mSettingsDashBoardStyle = (SystemSettingListPreference) findPreference(SETTINGS_DASHBOARD_STYLE);
- mSettingsDashBoardStyle.setOnPreferenceChangeListener(this);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-
- public boolean onPreferenceChange(Preference preference, Object objValue) {
- final String key = preference.getKey();
- ContentResolver resolver = getActivity().getContentResolver();
- if (preference == mSettingsDashBoardStyle){
- SystemRestartUtils.showSettingsRestartDialog(getContext());
- return true;
- }
- return false;
- }
-
- /**
- * For search
- */
- public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.rising_settings_settingsui) {
-
- @Override
- public List getNonIndexableKeys(Context context) {
- List keys = super.getNonIndexableKeys(context);
-
- return keys;
- }
- };
-}
diff --git a/src/com/rising/settings/fragments/ui/Settings.kt b/src/com/rising/settings/fragments/ui/Settings.kt
new file mode 100644
index 00000000..365d3e50
--- /dev/null
+++ b/src/com/rising/settings/fragments/ui/Settings.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.rising.settings.fragments.ui
+
+import android.content.ContentResolver
+import android.content.Context
+import android.os.Bundle
+import android.os.UserHandle
+
+import androidx.preference.Preference
+import androidx.preference.Preference.OnPreferenceChangeListener
+
+import com.android.internal.util.android.SystemRestartUtils
+import com.android.settings.preferences.SystemSettingListPreference
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+import com.android.settings.search.BaseSearchIndexProvider
+import com.android.settingslib.search.SearchIndexable
+
+@SearchIndexable
+class Settings : OptimizedSettingsFragment(), Preference.OnPreferenceChangeListener {
+
+ companion object {
+ const val SETTINGS_DASHBOARD_STYLE = "settings_dashboard_style"
+ private const val TAG = "Settings"
+
+ /**
+ * For search
+ */
+ @JvmField
+ val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.rising_settings_settingsui) {
+ override fun getNonIndexableKeys(context: Context): List {
+ val keys = super.getNonIndexableKeys(context)
+ return keys
+ }
+ }
+ }
+
+ private lateinit var mSettingsDashBoardStyle: SystemSettingListPreference
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.rising_settings_settingsui)
+ mSettingsDashBoardStyle = findCachedPreference(SETTINGS_DASHBOARD_STYLE)!!
+ mSettingsDashBoardStyle.onPreferenceChangeListener = this
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+
+ override fun onPreferenceChange(preference: Preference, objValue: Any): Boolean {
+ val key = preference.key
+ val resolver = activity?.contentResolver
+ if (preference == mSettingsDashBoardStyle) {
+ SystemRestartUtils.showSettingsRestartDialog(requireContext())
+ return true
+ }
+ return false
+ }
+}
diff --git a/src/com/rising/settings/fragments/ui/SignalIcons.java b/src/com/rising/settings/fragments/ui/SignalIcons.java
deleted file mode 100644
index 1dd30064..00000000
--- a/src/com/rising/settings/fragments/ui/SignalIcons.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2022 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.rising.settings.fragments.ui;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.Gravity;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-import android.text.TextUtils;
-import androidx.preference.PreferenceViewHolder;
-import android.view.ViewGroup.LayoutParams;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.Indexable;
-import com.android.settings.SettingsPreferenceFragment;
-
-import com.bumptech.glide.Glide;
-
-import com.android.internal.util.android.ThemeUtils;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Arrays;
-
-import org.json.JSONObject;
-import org.json.JSONException;
-
-public class SignalIcons extends SettingsPreferenceFragment {
-
- private RecyclerView mRecyclerView;
- private ThemeUtils mThemeUtils;
- private String mCategory = "android.theme.customization.signal_icon";
-
- private List mPkgs;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getActivity().setTitle(R.string.theme_customization_signal_icon_title);
-
- mThemeUtils = ThemeUtils.getInstance(getActivity());
- mPkgs = mThemeUtils.getOverlayPackagesForCategory(mCategory, "android");
- }
-
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(
- R.layout.item_view, container, false);
-
- mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
- GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
- mRecyclerView.setLayoutManager(gridLayoutManager);
- Adapter mAdapter = new Adapter(getActivity());
- mRecyclerView.setAdapter(mAdapter);
-
- return view;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.VIEW_UNKNOWN;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- }
-
- public class Adapter extends RecyclerView.Adapter {
- Context context;
- String mSelectedPkg;
- String mAppliedPkg;
-
- public Adapter(Context context) {
- this.context = context;
- }
-
- @Override
- public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.icon_option, parent, false);
- CustomViewHolder vh = new CustomViewHolder(v);
- return vh;
- }
-
- @Override
- public void onBindViewHolder(CustomViewHolder holder, final int position) {
- String iconPkg = mPkgs.get(position);
-
- holder.image1.setBackgroundDrawable(getDrawable(holder.image1.getContext(), iconPkg, "ic_signal_cellular_0_5_bar"));
- holder.image2.setBackgroundDrawable(getDrawable(holder.image2.getContext(), iconPkg, "ic_signal_cellular_1_5_bar"));
- holder.image3.setBackgroundDrawable(getDrawable(holder.image3.getContext(), iconPkg, "ic_signal_cellular_3_5_bar"));
- holder.image4.setBackgroundDrawable(getDrawable(holder.image4.getContext(), iconPkg, "ic_signal_cellular_5_5_bar"));
-
- String currentPackageName = mThemeUtils.getOverlayInfos(mCategory).stream()
- .filter(info -> info.isEnabled())
- .map(info -> info.packageName)
- .findFirst()
- .orElse("android");
-
- holder.name.setText("android".equals(iconPkg) ? "Default" : getLabel(holder.name.getContext(), iconPkg));
-
- if (currentPackageName.equals(iconPkg)) {
- mAppliedPkg = iconPkg;
- if (mSelectedPkg == null) {
- mSelectedPkg = iconPkg;
- }
- }
-
- holder.itemView.setActivated(iconPkg == mSelectedPkg);
- holder.itemView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- updateActivatedStatus(mSelectedPkg, false);
- updateActivatedStatus(iconPkg, true);
- mSelectedPkg = iconPkg;
- enableOverlays(position);
- }
- });
- }
-
- @Override
- public int getItemCount() {
- return mPkgs.size();
- }
-
- public class CustomViewHolder extends RecyclerView.ViewHolder {
- TextView name;
- ImageView image1;
- ImageView image2;
- ImageView image3;
- ImageView image4;
- public CustomViewHolder(View itemView) {
- super(itemView);
- name = (TextView) itemView.findViewById(R.id.option_label);
- image1 = (ImageView) itemView.findViewById(R.id.image1);
- image2 = (ImageView) itemView.findViewById(R.id.image2);
- image3 = (ImageView) itemView.findViewById(R.id.image3);
- image4 = (ImageView) itemView.findViewById(R.id.image4);
- }
- }
-
- private void updateActivatedStatus(String pkg, boolean isActivated) {
- int index = mPkgs.indexOf(pkg);
- if (index < 0) {
- return;
- }
- RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(index);
- if (holder != null && holder.itemView != null) {
- holder.itemView.setActivated(isActivated);
- }
- }
- }
-
- public Drawable getDrawable(Context context, String pkg, String drawableName) {
- try {
- PackageManager pm = context.getPackageManager();
- Resources res = pkg.equals("android") ? Resources.getSystem()
- : pm.getResourcesForApplication(pkg);
- int resId = res.getIdentifier(drawableName, "drawable", pkg);
- return res.getDrawable(resId);
- }
- catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public String getLabel(Context context, String pkg) {
- PackageManager pm = context.getPackageManager();
- try {
- return pm.getApplicationInfo(pkg, 0)
- .loadLabel(pm).toString();
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return pkg;
- }
-
- public void enableOverlays(int position) {
- mThemeUtils.setOverlayEnabled(mCategory, mPkgs.get(position), "android");
- }
-}
diff --git a/src/com/rising/settings/fragments/ui/SignalIcons.kt b/src/com/rising/settings/fragments/ui/SignalIcons.kt
new file mode 100644
index 00000000..eacff84b
--- /dev/null
+++ b/src/com/rising/settings/fragments/ui/SignalIcons.kt
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2022 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings.fragments.ui
+
+import android.content.Context
+import android.content.pm.PackageManager
+import android.content.res.Resources
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.annotation.NonNull
+import androidx.annotation.Nullable
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+
+import com.android.internal.util.android.ThemeUtils
+
+class SignalIcons : OptimizedSettingsFragment() {
+
+ private var mRecyclerView: RecyclerView? = null
+ override var mThemeUtils: ThemeUtils? = null
+ private val mCategory = "android.theme.customization.signal_icon"
+
+ private var mPkgs: List? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ activity?.setTitle(R.string.theme_customization_signal_icon_title)
+
+ mThemeUtils = ThemeUtils.getInstance(activity)
+ mPkgs = mThemeUtils?.getOverlayPackagesForCategory(mCategory, "android")
+ }
+
+ override fun onCreateView(
+ @NonNull inflater: LayoutInflater,
+ @Nullable container: ViewGroup?,
+ @Nullable savedInstanceState: Bundle?
+ ): View {
+ val view = inflater.inflate(R.layout.item_view, container, false)
+
+ mRecyclerView = view.findViewById(R.id.recycler_view)
+ val gridLayoutManager = GridLayoutManager(activity, 3)
+ mRecyclerView?.layoutManager = gridLayoutManager
+ val mAdapter = Adapter(activity)
+ mRecyclerView?.adapter = mAdapter
+
+ return view
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsEvent.VIEW_UNKNOWN
+ }
+
+ override fun onResume() {
+ super.onResume()
+ }
+
+ inner class Adapter(private val context: Context?) : RecyclerView.Adapter() {
+ private var mSelectedPkg: String? = null
+ private var mAppliedPkg: String? = null
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
+ val v = LayoutInflater.from(parent.context).inflate(R.layout.icon_option, parent, false)
+ return CustomViewHolder(v)
+ }
+
+ override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
+ val iconPkg = mPkgs?.get(position) ?: return
+
+ holder.image1?.background = getDrawable(holder.image1?.context, iconPkg, "ic_signal_cellular_0_5_bar")
+ holder.image2?.background = getDrawable(holder.image2?.context, iconPkg, "ic_signal_cellular_1_5_bar")
+ holder.image3?.background = getDrawable(holder.image3?.context, iconPkg, "ic_signal_cellular_3_5_bar")
+ holder.image4?.background = getDrawable(holder.image4?.context, iconPkg, "ic_signal_cellular_5_5_bar")
+
+ val currentPackageName = mThemeUtils?.getOverlayInfos(mCategory, "android")
+ ?.filter { it.isEnabled }
+ ?.map { it.packageName }
+ ?.firstOrNull() ?: "android"
+
+ holder.name?.text = if ("android" == iconPkg) "Default" else getLabel(holder.name?.context, iconPkg)
+
+ if (currentPackageName == iconPkg) {
+ mAppliedPkg = iconPkg
+ if (mSelectedPkg == null) {
+ mSelectedPkg = iconPkg
+ }
+ }
+
+ holder.itemView.isActivated = iconPkg == mSelectedPkg
+ holder.itemView.setOnClickListener {
+ updateActivatedStatus(mSelectedPkg, false)
+ updateActivatedStatus(iconPkg, true)
+ mSelectedPkg = iconPkg
+ enableOverlays(position)
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return mPkgs?.size ?: 0
+ }
+
+ inner class CustomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val name: TextView? = itemView.findViewById(R.id.option_label)
+ val image1: ImageView? = itemView.findViewById(R.id.image1)
+ val image2: ImageView? = itemView.findViewById(R.id.image2)
+ val image3: ImageView? = itemView.findViewById(R.id.image3)
+ val image4: ImageView? = itemView.findViewById(R.id.image4)
+ }
+
+ private fun updateActivatedStatus(pkg: String?, isActivated: Boolean) {
+ val index = mPkgs?.indexOf(pkg) ?: -1
+ if (index < 0) {
+ return
+ }
+ val holder = mRecyclerView?.findViewHolderForAdapterPosition(index)
+ holder?.itemView?.isActivated = isActivated
+ }
+ }
+
+ private fun getDrawable(context: Context?, pkg: String, drawableName: String): Drawable? {
+ return try {
+ val pm = context?.packageManager
+ val res = if (pkg == "android") {
+ Resources.getSystem()
+ } else {
+ pm?.getResourcesForApplication(pkg)
+ }
+ val resId = res?.getIdentifier(drawableName, "drawable", pkg) ?: 0
+ res?.getDrawable(resId)
+ } catch (e: PackageManager.NameNotFoundException) {
+ e.printStackTrace()
+ null
+ }
+ }
+
+ private fun getLabel(context: Context?, pkg: String): String {
+ val pm = context?.packageManager
+ return try {
+ pm?.getApplicationInfo(pkg, 0)?.loadLabel(pm)?.toString() ?: pkg
+ } catch (e: PackageManager.NameNotFoundException) {
+ e.printStackTrace()
+ pkg
+ }
+ }
+
+ private fun enableOverlays(position: Int) {
+ val pkg = mPkgs?.get(position)
+ if (pkg != null) {
+ mThemeUtils?.setOverlayEnabled(mCategory, pkg, "android")
+ }
+ }
+}
diff --git a/src/com/rising/settings/fragments/ui/SmartPixels.java b/src/com/rising/settings/fragments/ui/SmartPixels.java
deleted file mode 100644
index 3bd2fb5a..00000000
--- a/src/com/rising/settings/fragments/ui/SmartPixels.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2018-2022 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.rising.settings.fragments.ui;
-
-import android.content.Context;
-import android.content.ContentResolver;
-import android.content.res.Resources;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.SwitchPreference;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-public class SmartPixels extends SettingsPreferenceFragment {
-
- private static final String TAG = "SmartPixels";
-
- private static final String SMART_PIXELS_FOOTER = "smart_pixels_footer";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.smart_pixels);
-
- findPreference(SMART_PIXELS_FOOTER).setTitle(R.string.smart_pixels_warning_text);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
- }
-}
diff --git a/src/com/rising/settings/fragments/ui/SmartPixels.kt b/src/com/rising/settings/fragments/ui/SmartPixels.kt
new file mode 100644
index 00000000..148f1db2
--- /dev/null
+++ b/src/com/rising/settings/fragments/ui/SmartPixels.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018-2022 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings.fragments.ui
+
+import android.content.Context
+import android.content.ContentResolver
+import android.content.res.Resources
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.os.UserHandle
+import android.provider.Settings
+
+import androidx.preference.ListPreference
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+import androidx.preference.Preference.OnPreferenceChangeListener
+import androidx.preference.SwitchPreference
+
+import com.android.internal.logging.nano.MetricsProto
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+
+class SmartPixels : OptimizedSettingsFragment() {
+
+ companion object {
+ private const val TAG = "SmartPixels"
+ private const val SMART_PIXELS_FOOTER = "smart_pixels_footer"
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ addPreferencesFromResource(R.xml.smart_pixels)
+
+ findCachedPreference(SMART_PIXELS_FOOTER)?.setTitle(R.string.smart_pixels_warning_text)
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN
+ }
+}
diff --git a/src/com/rising/settings/fragments/ui/StatusbarIcons.java b/src/com/rising/settings/fragments/ui/StatusbarIcons.java
deleted file mode 100644
index e963ccac..00000000
--- a/src/com/rising/settings/fragments/ui/StatusbarIcons.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2022 crDroid Android Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.rising.settings.fragments.ui;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.Gravity;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-import android.text.TextUtils;
-import androidx.preference.PreferenceViewHolder;
-import android.view.ViewGroup.LayoutParams;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.Indexable;
-import com.android.settings.SettingsPreferenceFragment;
-
-import com.bumptech.glide.Glide;
-
-import com.android.internal.util.android.ThemeUtils;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Arrays;
-
-import org.json.JSONObject;
-import org.json.JSONException;
-
-public class StatusbarIcons extends SettingsPreferenceFragment {
-
- private RecyclerView mRecyclerView;
- private ThemeUtils mThemeUtils;
- private String mCategory = "android.theme.customization.icon_pack.android";
-
- private List mPkgs;
-
- Map overlayMap = new HashMap();
- {
- overlayMap.put("com.android.settings", "android.theme.customization.icon_pack.settings");
- overlayMap.put("com.android.systemui", "android.theme.customization.icon_pack.systemui");
- overlayMap.put("com.android.launcher3", "android.theme.customization.icon_pack.launcher");
- overlayMap.put("com.android.wallpaper", "android.theme.customization.icon_pack.themepicker");
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getActivity().setTitle(R.string.theme_customization_icon_pack_title);
-
- mThemeUtils = ThemeUtils.getInstance(getActivity());
- mPkgs = mThemeUtils.getOverlayPackagesForCategory(mCategory, "android");
- }
-
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(
- R.layout.item_view, container, false);
-
- mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
- GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
- mRecyclerView.setLayoutManager(gridLayoutManager);
- Adapter mAdapter = new Adapter(getActivity());
- mRecyclerView.setAdapter(mAdapter);
-
- return view;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.VIEW_UNKNOWN;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- }
-
- public class Adapter extends RecyclerView.Adapter {
- Context context;
- String mSelectedPkg;
- String mAppliedPkg;
-
- public Adapter(Context context) {
- this.context = context;
- }
-
- @Override
- public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.icon_option, parent, false);
- CustomViewHolder vh = new CustomViewHolder(v);
- return vh;
- }
-
- @Override
- public void onBindViewHolder(CustomViewHolder holder, final int position) {
- String iconPkg = mPkgs.get(position);
-
- holder.image1.setBackgroundDrawable(getDrawable(holder.image1.getContext(), iconPkg, "ic_wifi_signal_4"));
- holder.image2.setBackgroundDrawable(getDrawable(holder.image2.getContext(), iconPkg, "ic_signal_cellular_4_4_bar"));
- holder.image3.setBackgroundDrawable(getDrawable(holder.image3.getContext(), iconPkg, "ic_qs_airplane"));
- holder.image4.setBackgroundDrawable(getDrawable(holder.image4.getContext(), iconPkg, "ic_qs_flashlight"));
-
- String currentPackageName = mThemeUtils.getOverlayInfos(mCategory).stream()
- .filter(info -> info.isEnabled())
- .map(info -> info.packageName)
- .findFirst()
- .orElse("android");
-
- holder.name.setText("android".equals(iconPkg) ? "Default" : getLabel(holder.name.getContext(), iconPkg));
-
- if (currentPackageName.equals(iconPkg)) {
- mAppliedPkg = iconPkg;
- if (mSelectedPkg == null) {
- mSelectedPkg = iconPkg;
- }
- }
-
- holder.itemView.setActivated(iconPkg == mSelectedPkg);
- holder.itemView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- updateActivatedStatus(mSelectedPkg, false);
- updateActivatedStatus(iconPkg, true);
- mSelectedPkg = iconPkg;
- enableOverlays(position);
- }
- });
- }
-
- @Override
- public int getItemCount() {
- return mPkgs.size();
- }
-
- public class CustomViewHolder extends RecyclerView.ViewHolder {
- TextView name;
- ImageView image1;
- ImageView image2;
- ImageView image3;
- ImageView image4;
- public CustomViewHolder(View itemView) {
- super(itemView);
- name = (TextView) itemView.findViewById(R.id.option_label);
- image1 = (ImageView) itemView.findViewById(R.id.image1);
- image2 = (ImageView) itemView.findViewById(R.id.image2);
- image3 = (ImageView) itemView.findViewById(R.id.image3);
- image4 = (ImageView) itemView.findViewById(R.id.image4);
- }
- }
-
- private void updateActivatedStatus(String pkg, boolean isActivated) {
- int index = mPkgs.indexOf(pkg);
- if (index < 0) {
- return;
- }
- RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(index);
- if (holder != null && holder.itemView != null) {
- holder.itemView.setActivated(isActivated);
- }
- }
- }
-
- public Drawable getDrawable(Context context, String pkg, String drawableName) {
- try {
- PackageManager pm = context.getPackageManager();
- Resources res = pkg.equals("android") ? Resources.getSystem()
- : pm.getResourcesForApplication(pkg);
- int resId = res.getIdentifier(drawableName, "drawable", pkg);
- return res.getDrawable(resId);
- }
- catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public String getLabel(Context context, String pkg) {
- PackageManager pm = context.getPackageManager();
- try {
- return pm.getApplicationInfo(pkg, 0)
- .loadLabel(pm).toString();
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return pkg;
- }
-
- public void enableOverlays(int position) {
- mThemeUtils.setOverlayEnabled(mCategory, mPkgs.get(position), "android");
- String pattern = "android".equals(mPkgs.get(position)) ? ""
- : mPkgs.get(position).split("\\.")[4];
- for (Map.Entry entry : overlayMap.entrySet()) {
- enableOverlay(entry.getValue(), entry.getKey(), pattern);
- }
- }
-
- public void enableOverlay(String category, String target, String pattern) {
- if (pattern.isEmpty()) {
- mThemeUtils.setOverlayEnabled(category, "android", "android");
- return;
- }
- for (String pkg: mThemeUtils.getOverlayPackagesForCategory(category, target)) {
- if (pkg.contains(pattern)) {
- mThemeUtils.setOverlayEnabled(category, pkg, target);
- }
- }
- }
-}
diff --git a/src/com/rising/settings/fragments/ui/StatusbarIcons.kt b/src/com/rising/settings/fragments/ui/StatusbarIcons.kt
new file mode 100644
index 00000000..19db16a0
--- /dev/null
+++ b/src/com/rising/settings/fragments/ui/StatusbarIcons.kt
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2022 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.rising.settings.fragments.ui
+
+import android.content.Context
+import android.content.pm.PackageManager
+import android.content.res.Resources
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.annotation.NonNull
+import androidx.annotation.Nullable
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent
+import com.android.settings.R
+import com.rising.settings.fragments.OptimizedSettingsFragment
+
+import com.android.internal.util.android.ThemeUtils
+
+class StatusbarIcons : OptimizedSettingsFragment() {
+
+ private var mRecyclerView: RecyclerView? = null
+ override var mThemeUtils: ThemeUtils? = null
+ private val mCategory = "android.theme.customization.icon_pack.android"
+
+ private var mPkgs: List? = null
+
+ private val overlayMap = mapOf(
+ "com.android.settings" to "android.theme.customization.icon_pack.settings",
+ "com.android.systemui" to "android.theme.customization.icon_pack.systemui",
+ "com.android.launcher3" to "android.theme.customization.icon_pack.launcher",
+ "com.android.wallpaper" to "android.theme.customization.icon_pack.themepicker"
+ )
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ activity?.setTitle(R.string.theme_customization_icon_pack_title)
+
+ mThemeUtils = ThemeUtils.getInstance(activity)
+ mPkgs = mThemeUtils?.getOverlayPackagesForCategory(mCategory, "android")
+ }
+
+ override fun onCreateView(
+ @NonNull inflater: LayoutInflater,
+ @Nullable container: ViewGroup?,
+ @Nullable savedInstanceState: Bundle?
+ ): View {
+ val view = inflater.inflate(R.layout.item_view, container, false)
+
+ mRecyclerView = view.findViewById(R.id.recycler_view)
+ val gridLayoutManager = GridLayoutManager(activity, 3)
+ mRecyclerView?.layoutManager = gridLayoutManager
+ val mAdapter = Adapter(activity)
+ mRecyclerView?.adapter = mAdapter
+
+ return view
+ }
+
+ override fun getMetricsCategory(): Int {
+ return MetricsEvent.VIEW_UNKNOWN
+ }
+
+ override fun onResume() {
+ super.onResume()
+ }
+
+ inner class Adapter(private val context: Context?) : RecyclerView.Adapter() {
+ private var mSelectedPkg: String? = null
+ private var mAppliedPkg: String? = null
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
+ val v = LayoutInflater.from(parent.context).inflate(R.layout.icon_option, parent, false)
+ return CustomViewHolder(v)
+ }
+
+ override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
+ val iconPkg = mPkgs?.get(position) ?: return
+
+ holder.image1?.background = getDrawable(holder.image1?.context, iconPkg, "ic_wifi_signal_4")
+ holder.image2?.background = getDrawable(holder.image2?.context, iconPkg, "ic_signal_cellular_4_4_bar")
+ holder.image3?.background = getDrawable(holder.image3?.context, iconPkg, "ic_qs_airplane")
+ holder.image4?.background = getDrawable(holder.image4?.context, iconPkg, "ic_qs_flashlight")
+
+ val currentPackageName = mThemeUtils?.getOverlayInfos(mCategory, "android")
+ ?.filter { it.isEnabled }
+ ?.map { it.packageName }
+ ?.firstOrNull() ?: "android"
+
+ holder.name?.text = if ("android" == iconPkg) "Default" else getLabel(holder.name?.context, iconPkg)
+
+ if (currentPackageName == iconPkg) {
+ mAppliedPkg = iconPkg
+ if (mSelectedPkg == null) {
+ mSelectedPkg = iconPkg
+ }
+ }
+
+ holder.itemView.isActivated = iconPkg == mSelectedPkg
+ holder.itemView.setOnClickListener {
+ updateActivatedStatus(mSelectedPkg, false)
+ updateActivatedStatus(iconPkg, true)
+ mSelectedPkg = iconPkg
+ enableOverlays(position)
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return mPkgs?.size ?: 0
+ }
+
+ inner class CustomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val name: TextView? = itemView.findViewById(R.id.option_label)
+ val image1: ImageView? = itemView.findViewById(R.id.image1)
+ val image2: ImageView? = itemView.findViewById(R.id.image2)
+ val image3: ImageView? = itemView.findViewById(R.id.image3)
+ val image4: ImageView? = itemView.findViewById(R.id.image4)
+ }
+
+ private fun updateActivatedStatus(pkg: String?, isActivated: Boolean) {
+ val index = mPkgs?.indexOf(pkg) ?: -1
+ if (index < 0) {
+ return
+ }
+ val holder = mRecyclerView?.findViewHolderForAdapterPosition(index)
+ holder?.itemView?.isActivated = isActivated
+ }
+ }
+
+ private fun getDrawable(context: Context?, pkg: String, drawableName: String): Drawable? {
+ return try {
+ val pm = context?.packageManager
+ val res = if (pkg == "android") {
+ Resources.getSystem()
+ } else {
+ pm?.getResourcesForApplication(pkg)
+ }
+ val resId = res?.getIdentifier(drawableName, "drawable", pkg) ?: 0
+ res?.getDrawable(resId)
+ } catch (e: PackageManager.NameNotFoundException) {
+ e.printStackTrace()
+ null
+ }
+ }
+
+ private fun getLabel(context: Context?, pkg: String): String {
+ val pm = context?.packageManager
+ return try {
+ pm?.getApplicationInfo(pkg, 0)?.loadLabel(pm)?.toString() ?: pkg
+ } catch (e: PackageManager.NameNotFoundException) {
+ e.printStackTrace()
+ pkg
+ }
+ }
+
+ private fun enableOverlays(position: Int) {
+ val selectedPkg = mPkgs?.get(position) ?: return
+ mThemeUtils?.setOverlayEnabled(mCategory, selectedPkg, "android")
+
+ val pattern = if ("android" == selectedPkg) {
+ ""
+ } else {
+ selectedPkg.split(".").getOrNull(4) ?: ""
+ }
+
+ overlayMap.forEach { (target, category) ->
+ enableOverlay(category, target, pattern)
+ }
+ }
+
+ private fun enableOverlay(category: String, target: String, pattern: String) {
+ if (pattern.isEmpty()) {
+ mThemeUtils?.setOverlayEnabled(category, "android", "android")
+ return
+ }
+
+ mThemeUtils?.getOverlayPackagesForCategory(category, target)?.forEach { pkg ->
+ if (pkg.contains(pattern)) {
+ mThemeUtils?.setOverlayEnabled(category, pkg, target)
+ }
+ }
+ }
+}
diff --git a/src/com/rising/settings/fragments/ui/UIStyles.java b/src/com/rising/settings/fragments/ui/UIStyles.java
deleted file mode 100644
index bebe0d73..00000000
--- a/src/com/rising/settings/fragments/ui/UIStyles.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2021 AospExtended ROM Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.rising.settings.fragments.ui;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.Gravity;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-import android.text.TextUtils;
-import androidx.preference.PreferenceViewHolder;
-import android.view.ViewGroup.LayoutParams;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.Indexable;
-import com.android.settings.SettingsPreferenceFragment;
-
-import com.android.internal.util.android.ThemeUtils;
-
-import java.util.ArrayList;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Arrays;
-
-import org.json.JSONObject;
-import org.json.JSONException;
-
-public class UIStyles extends SettingsPreferenceFragment {
-
- private RecyclerView mRecyclerView;
- private ThemeUtils mThemeUtils;
- private String mCategory = "android.theme.customization.style.android";
-
- private List mPkgs;
-
- private ExecutorService mExecutor = Executors.newSingleThreadExecutor();
- private Handler mHandler = new Handler();
- private final AtomicBoolean mApplyingOverlays = new AtomicBoolean(false);
-
- Map overlayMap = new HashMap