getprop("ro.product.device") == "citrus" || abort("E3004: This package is for \"citrus\" devices; this is a \"" + getprop("ro.product.device") + "\".");
ui_print("Source: POCO/citrus_id/citrus:10/QKQ1.200830.002/V12.0.10.0.QJFIDXM:user/release-keys");
ui_print("Target: POCO/citrus_id/citrus:10/QKQ1.200830.002/V12.0.11.0.QJFIDXM:user/release-keys");
ui_print("Verifying current system...");
getprop("ro.build.fingerprint") == "POCO/citrus_id/citrus:10/QKQ1.200830.002/V12.0.10.0.QJFIDXM:user/release-keys" ||
    getprop("ro.build.fingerprint") == "POCO/citrus_id/citrus:10/QKQ1.200830.002/V12.0.11.0.QJFIDXM:user/release-keys" ||
    abort("E3001: Package expects build fingerprint of POCO/citrus_id/citrus:10/QKQ1.200830.002/V12.0.10.0.QJFIDXM:user/release-keys or POCO/citrus_id/citrus:10/QKQ1.200830.002/V12.0.11.0.QJFIDXM:user/release-keys; this device has " + getprop("ro.build.fingerprint") + ".");
show_progress(0.100000, 10);
patch_partition_check("EMMC:/dev/block/bootdevice/by-name/boot:100663296:827c774743d828a153aef4591bde3c3bedc96d5e",
                      "EMMC:/dev/block/bootdevice/by-name/boot:100663296:112d1425824a0d3ef5c1cec4fb6d5c01dbb3282a") ||
    abort("E3005: \"EMMC:/dev/block/bootdevice/by-name/boot:100663296:827c774743d828a153aef4591bde3c3bedc96d5e\" or \"EMMC:/dev/block/bootdevice/by-name/boot:100663296:112d1425824a0d3ef5c1cec4fb6d5c01dbb3282a\" has unexpected contents.");
apply_patch_space(100663296) || abort("E3006: Not enough free space on /cache to apply patches.");
show_progress(0.100000, 70);
if (range_sha1(map_partition("system"), "32,1,32770,32950,98306,98486,163842,164022,229378,229558,246946,246948,294914,295094,338938,338946,348064,348066,348067,348071,354958,354973,467957,469781,549320,549377,720906,720914,738503,740785,752525,752682,752683") == "7c051eab8a8c1c9a1f0dfa9b7d6c42108c2f0c81" || block_image_verify(map_partition("system"), package_extract_file("system.transfer.list"), "system.new.dat", "system.patch.dat")) then
ui_print("Verified system image...");
else
check_first_block(map_partition("system"));
ifelse (block_image_recover(map_partition("system"), "32,1,32770,32950,98306,98486,163842,164022,229378,229558,246946,246948,294914,295094,338938,338946,348064,348066,348067,348071,354958,354973,467957,469781,549320,549377,720906,720914,738503,740785,752525,752682,752683") && block_image_verify(map_partition("system"), package_extract_file("system.transfer.list"), "system.new.dat", "system.patch.dat"), ui_print("system recovered successfully."), abort("E1004: system partition fails to recover"));
endif;
if (range_sha1(map_partition("vendor"), "62,1,106,116,120,125,126,208,212,217,218,1892,1896,2373,2374,2637,2641,2645,2646,2648,2652,2654,2665,2688,2689,2725,2729,2779,2780,2941,2942,2954,2958,2962,2963,2966,2972,2973,2974,2986,2990,2994,3001,3010,3011,4798,32770,32846,98306,98382,163842,163918,229378,229454,294914,294990,295009,295010,312534,313522,318492,318569,318570") == "827b055cca03bf2a611682b99d311bb084e54e2f" || block_image_verify(map_partition("vendor"), package_extract_file("vendor.transfer.list"), "vendor.new.dat", "vendor.patch.dat")) then
ui_print("Verified vendor image...");
else
check_first_block(map_partition("vendor"));
ifelse (block_image_recover(map_partition("vendor"), "62,1,106,116,120,125,126,208,212,217,218,1892,1896,2373,2374,2637,2641,2645,2646,2648,2652,2654,2665,2688,2689,2725,2729,2779,2780,2941,2942,2954,2958,2962,2963,2966,2972,2973,2974,2986,2990,2994,3001,3010,3011,4798,32770,32846,98306,98382,163842,163918,229378,229454,294914,294990,295009,295010,312534,313522,318492,318569,318570") && block_image_verify(map_partition("vendor"), package_extract_file("vendor.transfer.list"), "vendor.new.dat", "vendor.patch.dat"), ui_print("vendor recovered successfully."), abort("E2004: vendor partition fails to recover"));
endif;
if (range_sha1(map_partition("product"), "328,1,95,111,115,119,120,4181,4182,5856,5860,8799,8802,8806,8807,8850,8851,8858,8864,8865,8866,9583,9587,9594,9595,9601,9607,9608,9609,16607,16608,22546,22547,22587,22588,24810,24811,25450,25454,26224,26225,26588,26592,27099,27100,27112,27118,27119,27120,28960,28964,30401,30402,32768,32770,32844,32855,38790,38791,39873,39874,48797,48798,53399,53401,57137,57138,65536,65547,67000,67001,75308,75315,75379,75385,76454,76461,78033,78034,78040,78041,78047,78053,78054,78055,78183,78189,78190,78191,78203,78209,78210,78211,78214,78215,78221,78227,78228,78229,78252,78258,78259,78260,81200,81201,93477,93478,93533,93534,98304,98306,98380,98391,98392,98393,112627,112628,117334,117335,117337,117338,117343,117344,120314,120315,125673,125674,129622,129624,129632,129634,129642,129644,130424,130425,130436,130442,130443,130444,130454,130455,130460,130464,130469,130470,130474,130480,130484,130485,130491,130497,130498,130499,130511,130517,130518,130519,130529,130535,130536,130537,130539,130546,130552,130553,131072,131083,134893,134894,135127,135129,135139,135141,135187,135189,135199,135201,135210,135211,137029,137036,137105,137112,137117,137124,137154,137161,137180,137187,137205,137212,137228,137229,137240,137243,140628,140629,140798,140799,140800,140801,140802,140803,140804,140805,140844,140846,140854,140855,140860,140861,141221,141225,141229,141231,141236,141240,141241,141245,141246,141250,141251,141255,141256,141260,141261,141265,141266,141270,141271,141275,141276,141278,141279,141280,141283,141289,141290,141294,141295,141299,141300,141304,141305,141309,141310,141314,141315,141319,141320,141322,141323,141327,141328,141332,141333,141337,141338,141342,141343,141347,141348,141352,141353,141357,141358,141362,141363,141365,141369,141373,141374,141378,141379,141383,141384,141388,141389,141391,141392,141396,141397,141399,141400,141404,141405,141409,141410,141412,141413,141417,141418,141422,141423,141425,141426,141430,141431,141437,141440,141592,141629,141887,142610,142611,146419,146420,147624,147625,152688,152689,156704,156708,157214,157216,157226,163842,163916,229378,229452,294914,294988,294991,294999,305181,306115,310968,311043,311044") == "06033f0edaf213878623f569395684fbd3f4fefa" || block_image_verify(map_partition("product"), package_extract_file("product.transfer.list"), "product.new.dat", "product.patch.dat")) then
ui_print("Verified product image...");
else
ifelse (block_image_recover(map_partition("product"), "328,1,95,111,115,119,120,4181,4182,5856,5860,8799,8802,8806,8807,8850,8851,8858,8864,8865,8866,9583,9587,9594,9595,9601,9607,9608,9609,16607,16608,22546,22547,22587,22588,24810,24811,25450,25454,26224,26225,26588,26592,27099,27100,27112,27118,27119,27120,28960,28964,30401,30402,32768,32770,32844,32855,38790,38791,39873,39874,48797,48798,53399,53401,57137,57138,65536,65547,67000,67001,75308,75315,75379,75385,76454,76461,78033,78034,78040,78041,78047,78053,78054,78055,78183,78189,78190,78191,78203,78209,78210,78211,78214,78215,78221,78227,78228,78229,78252,78258,78259,78260,81200,81201,93477,93478,93533,93534,98304,98306,98380,98391,98392,98393,112627,112628,117334,117335,117337,117338,117343,117344,120314,120315,125673,125674,129622,129624,129632,129634,129642,129644,130424,130425,130436,130442,130443,130444,130454,130455,130460,130464,130469,130470,130474,130480,130484,130485,130491,130497,130498,130499,130511,130517,130518,130519,130529,130535,130536,130537,130539,130546,130552,130553,131072,131083,134893,134894,135127,135129,135139,135141,135187,135189,135199,135201,135210,135211,137029,137036,137105,137112,137117,137124,137154,137161,137180,137187,137205,137212,137228,137229,137240,137243,140628,140629,140798,140799,140800,140801,140802,140803,140804,140805,140844,140846,140854,140855,140860,140861,141221,141225,141229,141231,141236,141240,141241,141245,141246,141250,141251,141255,141256,141260,141261,141265,141266,141270,141271,141275,141276,141278,141279,141280,141283,141289,141290,141294,141295,141299,141300,141304,141305,141309,141310,141314,141315,141319,141320,141322,141323,141327,141328,141332,141333,141337,141338,141342,141343,141347,141348,141352,141353,141357,141358,141362,141363,141365,141369,141373,141374,141378,141379,141383,141384,141388,141389,141391,141392,141396,141397,141399,141400,141404,141405,141409,141410,141412,141413,141417,141418,141422,141423,141425,141426,141430,141431,141437,141440,141592,141629,141887,142610,142611,146419,146420,147624,147625,152688,152689,156704,156708,157214,157216,157226,163842,163916,229378,229452,294914,294988,294991,294999,305181,306115,310968,311043,311044") && block_image_verify(map_partition("product"), package_extract_file("product.transfer.list"), "product.new.dat", "product.patch.dat"), ui_print("product recovered successfully."), abort("E2004: product partition fails to recover"));
endif;

# ---- start making changes here ----

ui_print("Patching boot image...");
show_progress(0.100000, 10);
patch_partition("EMMC:/dev/block/bootdevice/by-name/boot:100663296:827c774743d828a153aef4591bde3c3bedc96d5e",
                "EMMC:/dev/block/bootdevice/by-name/boot:100663296:112d1425824a0d3ef5c1cec4fb6d5c01dbb3282a",
                package_extract_file("boot.img.p")) ||
    abort("E3008: Failed to apply patch to EMMC:/dev/block/bootdevice/by-name/boot:100663296:112d1425824a0d3ef5c1cec4fb6d5c01dbb3282a");

# ---- radio update tasks ----

ui_print("Patching firmware images...");
package_extract_file("firmware-update/cmnlib64.mbn", "/dev/block/bootdevice/by-name/cmnlib64");
package_extract_file("firmware-update/imagefv.elf", "/dev/block/bootdevice/by-name/imagefv");
package_extract_file("firmware-update/cmnlib.mbn", "/dev/block/bootdevice/by-name/cmnlib");
package_extract_file("firmware-update/hyp.mbn", "/dev/block/bootdevice/by-name/hyp");
package_extract_file("firmware-update/km4.mbn", "/dev/block/bootdevice/by-name/keymaster");
package_extract_file("firmware-update/tz.mbn", "/dev/block/bootdevice/by-name/tz");
package_extract_file("firmware-update/featenabler.mbn", "/dev/block/bootdevice/by-name/featenabler");
package_extract_file("firmware-update/xbl_config.elf", "/dev/block/bootdevice/by-name/xbl_config");
package_extract_file("firmware-update/BTFM.bin", "/dev/block/bootdevice/by-name/bluetooth");
package_extract_file("firmware-update/uefi_sec.mbn", "/dev/block/bootdevice/by-name/uefisecapp");
package_extract_file("firmware-update/NON-HLOS.bin", "/dev/block/bootdevice/by-name/modem");
package_extract_file("firmware-update/qupv3fw.elf", "/dev/block/bootdevice/by-name/qupfw");
package_extract_file("firmware-update/abl.elf", "/dev/block/bootdevice/by-name/abl");
package_extract_file("firmware-update/devcfg.mbn", "/dev/block/bootdevice/by-name/devcfg");
package_extract_file("firmware-update/storsec.mbn", "/dev/block/bootdevice/by-name/storsec");
package_extract_file("firmware-update/xbl.elf", "/dev/block/bootdevice/by-name/xbl");
package_extract_file("firmware-update/rpm.mbn", "/dev/block/bootdevice/by-name/rpm");
package_extract_file("firmware-update/cmnlib64.mbn", "/dev/block/bootdevice/by-name/cmnlib64bak");
package_extract_file("firmware-update/imagefv.elf", "/dev/block/bootdevice/by-name/imagefvbak");
package_extract_file("firmware-update/cmnlib.mbn", "/dev/block/bootdevice/by-name/cmnlibbak");
package_extract_file("firmware-update/hyp.mbn", "/dev/block/bootdevice/by-name/hypbak");
package_extract_file("firmware-update/km4.mbn", "/dev/block/bootdevice/by-name/keymasterbak");
package_extract_file("firmware-update/tz.mbn", "/dev/block/bootdevice/by-name/tzbak");
package_extract_file("firmware-update/xbl_config.elf", "/dev/block/bootdevice/by-name/xbl_configbak");
package_extract_file("firmware-update/uefi_sec.mbn", "/dev/block/bootdevice/by-name/uefisecappbak");
package_extract_file("firmware-update/qupv3fw.elf", "/dev/block/bootdevice/by-name/qupfwbak");
package_extract_file("firmware-update/abl.elf", "/dev/block/bootdevice/by-name/ablbak");
package_extract_file("firmware-update/devcfg.mbn", "/dev/block/bootdevice/by-name/devcfgbak");
package_extract_file("firmware-update/storsec.mbn", "/dev/block/bootdevice/by-name/storsecbak");
package_extract_file("firmware-update/xbl.elf", "/dev/block/bootdevice/by-name/xblbak");
package_extract_file("firmware-update/rpm.mbn", "/dev/block/bootdevice/by-name/rpmbak");
show_progress(0.600000, 600);

# --- Start patching dynamic partitions ---


# Patch partition vendor

ui_print("Patching vendor image after verification.");
block_image_update(map_partition("vendor"), package_extract_file("vendor.transfer.list"), "vendor.new.dat", "vendor.patch.dat") ||
  abort("E2001: Failed to update vendor image.");

# Update dynamic partition metadata

assert(update_dynamic_partitions(package_extract_file("dynamic_partitions_op_list")));

# Patch partition product

ui_print("Patching product image after verification.");
block_image_update(map_partition("product"), package_extract_file("product.transfer.list"), "product.new.dat", "product.patch.dat") ||
  abort("E2001: Failed to update product image.");

# Patch partition system

ui_print("Patching system image after verification.");
block_image_update(map_partition("system"), package_extract_file("system.transfer.list"), "system.new.dat", "system.patch.dat") ||
  abort("E1001: Failed to update system image.");

# --- End patching dynamic partitions ---

show_progress(0.100000, 2);

# ---- radio update tasks 2 ----

ui_print("Patching vbmeta dtbo logo binimages...");
package_extract_file("firmware-update/dtbo.img", "/dev/block/bootdevice/by-name/dtbo");
package_extract_file("firmware-update/vbmeta.img", "/dev/block/bootdevice/by-name/vbmeta");
package_extract_file("firmware-update/vbmeta_system.img", "/dev/block/bootdevice/by-name/vbmeta_system");
