1e41f4b71Sopenharmony_ci# Ability Framework Changelog 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci## cl.ability.1 AreaMode APIs Changed 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ciDuplicate **AreaMode** APIs are deleted. 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci**Change Impact** 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ciJS APIs in API version 9 are affected. Your application needs to adapt these APIs so that it can properly implement features in the SDK environment of the new version. 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci**Key API/Component Changes** 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci| Module | Class | Method/Attribute/Enum/Constant | Change Type| 14e41f4b71Sopenharmony_ci| ------------------------- | ------------------- | ------------------------------------------------------------ | -------- | 15e41f4b71Sopenharmony_ci| @ohos.app.ability.common.d.ts | common.AreaMode | | Deleted | 16e41f4b71Sopenharmony_ci| application/Context.d.ts | AreaMode | | Deleted | 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci**Adaptation Guide** 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ciUse **AreaMode** in **@ohos.app.ability.contextConstant.d.ts**. 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci```ts 24e41f4b71Sopenharmony_ciimport contextConstant from '@ohos.app.ability.contextConstant'; 25e41f4b71Sopenharmony_cilet area: contextConstant.AreaMode = contextConstant.AreaMode.EL1; 26e41f4b71Sopenharmony_ci``` 27e41f4b71Sopenharmony_ci 28e41f4b71Sopenharmony_ci## cl.ability.2 killProcessesBySelf Renamed 29e41f4b71Sopenharmony_ci 30e41f4b71Sopenharmony_ciThe **killProcessesBySelf** API is renamed **killAllProcesses**. 31e41f4b71Sopenharmony_ci 32e41f4b71Sopenharmony_ci**Change Impact** 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ciJS APIs in API version 9 are affected. Your application needs to adapt these APIs so that it can properly implement features in the SDK environment of the new version. 35e41f4b71Sopenharmony_ci 36e41f4b71Sopenharmony_ci**Key API/Component Changes** 37e41f4b71Sopenharmony_ci 38e41f4b71Sopenharmony_ci| Module | Class | Method/Attribute/Enum/Constant | Change Type| 39e41f4b71Sopenharmony_ci| ------------------------------ | ------------------ | ----------------------------------------------------- | -------- | 40e41f4b71Sopenharmony_ci| application/ApplicationContext | ApplicationContext | killProcessesBySelf(): Promise\<void\>; | Deleted | 41e41f4b71Sopenharmony_ci| application/ApplicationContext | ApplicationContext | killProcessesBySelf(callback: AsyncCallback\<void\>); | Deleted | 42e41f4b71Sopenharmony_ci| application/ApplicationContext | ApplicationContext | killAllProcesses(): Promise\<void\>; | Added | 43e41f4b71Sopenharmony_ci| application/ApplicationContext | ApplicationContext | killAllProcesses(callback: AsyncCallback\<void\>); | Added | 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci 46e41f4b71Sopenharmony_ci**Adaptation Guide** 47e41f4b71Sopenharmony_ci 48e41f4b71Sopenharmony_ciThe following code snippet shows how to call **killProcessesBySelf** in an application. 49e41f4b71Sopenharmony_ci 50e41f4b71Sopenharmony_ciCode before the change: 51e41f4b71Sopenharmony_ci 52e41f4b71Sopenharmony_ci```ts 53e41f4b71Sopenharmony_cilet context: common.UIAbilityContext = globalThis.abilityContext; 54e41f4b71Sopenharmony_cilet appContext = context.getApplicationContext(); 55e41f4b71Sopenharmony_ciappContext.killProcessesBySelf() 56e41f4b71Sopenharmony_ci``` 57e41f4b71Sopenharmony_ci 58e41f4b71Sopenharmony_ciCode after the change: 59e41f4b71Sopenharmony_ci 60e41f4b71Sopenharmony_ci```ts 61e41f4b71Sopenharmony_cilet context: common.UIAbilityContext = globalThis.abilityContext; 62e41f4b71Sopenharmony_cilet appContext = context.getApplicationContext(); 63e41f4b71Sopenharmony_ciappContext.killAllProcesses() 64e41f4b71Sopenharmony_ci``` 65e41f4b71Sopenharmony_ci 66e41f4b71Sopenharmony_ci## cl.ability.3 getProcessRunningInformation Renamed 67e41f4b71Sopenharmony_ci 68e41f4b71Sopenharmony_ciThe **getProcessRunningInformation** API is renamed **getRunningProcessInformation**. 69e41f4b71Sopenharmony_ci 70e41f4b71Sopenharmony_ci**Change Impact** 71e41f4b71Sopenharmony_ci 72e41f4b71Sopenharmony_ciJS APIs in API version 9 are affected. Your application needs to adapt these APIs so that it can properly implement features in the SDK environment of the new version. 73e41f4b71Sopenharmony_ci 74e41f4b71Sopenharmony_ci**Key API/Component Changes** 75e41f4b71Sopenharmony_ci 76e41f4b71Sopenharmony_ci| Module | Class | Method/Attribute/Enum/Constant | Change Type| 77e41f4b71Sopenharmony_ci| ----------------------------------- | ------------------ | ------------------------------------------------------------ | -------- | 78e41f4b71Sopenharmony_ci| @ohos.app.ability.appManager.d.ts | appManager | function getProcessRunningInformation(): Promise\<Array\<ProcessRunningInformation\>\>; | Deleted | 79e41f4b71Sopenharmony_ci| @ohos.app.ability.appManager.d.ts | appManager | function getProcessRunningInformation(callback: AsyncCallback\<Array\<ProcessRunningInformation\>\>): void; | Deleted | 80e41f4b71Sopenharmony_ci| @ohos.app.ability.appManager.d.ts | appManager | function getRunningProcessInformation(): Promise\<Array\<ProcessInformation\>\>; | Added | 81e41f4b71Sopenharmony_ci| @ohos.app.ability.appManager.d.ts | appManager | function getRunningProcessInformation(callback: AsyncCallback\<Array\<ProcessInformation\>\>): void; | Added | 82e41f4b71Sopenharmony_ci| application/ApplicationContext.d.ts | ApplicationContext | getProcessRunningInformation(): Promise\<Array\<ProcessRunningInformation\>\>; | Deleted | 83e41f4b71Sopenharmony_ci| application/ApplicationContext.d.ts | ApplicationContext | getProcessRunningInformation(callback: AsyncCallback\<Array\<ProcessRunningInformation\>\>): void; | Deleted | 84e41f4b71Sopenharmony_ci| application/ApplicationContext.d.ts | ApplicationContext | getRunningProcessInformation(): Promise\<Array\<ProcessInformation\>\>; | Added | 85e41f4b71Sopenharmony_ci| application/ApplicationContext.d.ts | ApplicationContext | getRunningProcessInformation(callback: AsyncCallback\<Array\<ProcessInformation\>\>): void; | Added | 86e41f4b71Sopenharmony_ci 87e41f4b71Sopenharmony_ci**Adaptation Guide** 88e41f4b71Sopenharmony_ci 89e41f4b71Sopenharmony_ciThe following code snippet shows how to call **getProcessRunningInformation** in an application. 90e41f4b71Sopenharmony_ci 91e41f4b71Sopenharmony_ciCode before the change: 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ci```ts 94e41f4b71Sopenharmony_cilet context: common.UIAbilityContext = globalThis.abilityContext; 95e41f4b71Sopenharmony_cilet appContext = context.getApplicationContext(); 96e41f4b71Sopenharmony_ciappContext.getProcessRunningInformation() 97e41f4b71Sopenharmony_ci``` 98e41f4b71Sopenharmony_ci 99e41f4b71Sopenharmony_ciCode after the change: 100e41f4b71Sopenharmony_ci 101e41f4b71Sopenharmony_ci```ts 102e41f4b71Sopenharmony_cilet context: common.UIAbilityContext = globalThis.abilityContext; 103e41f4b71Sopenharmony_cilet appContext = context.getApplicationContext(); 104e41f4b71Sopenharmony_ciappContext.getRunningProcessInformation() 105e41f4b71Sopenharmony_ci``` 106e41f4b71Sopenharmony_ci 107e41f4b71Sopenharmony_ci## cl.ability.4 WantConstant.Flags API Changed 108e41f4b71Sopenharmony_ci 109e41f4b71Sopenharmony_ci**WantConstant.Flags** has multiple invalid flag definitions. These invalid flags are deleted. 110e41f4b71Sopenharmony_ci 111e41f4b71Sopenharmony_ci**Change Impact** 112e41f4b71Sopenharmony_ci 113e41f4b71Sopenharmony_ciJS APIs in API version 9 are affected. Your application needs to adapt these APIs so that it can properly implement features in the SDK environment of the new version. 114e41f4b71Sopenharmony_ci 115e41f4b71Sopenharmony_ci**Key API/Component Changes** 116e41f4b71Sopenharmony_ci 117e41f4b71Sopenharmony_ci| Module | Class | Method/Attribute/Enum/Constant | Change Type| 118e41f4b71Sopenharmony_ci| ------------------------- | ------------------- | ------------------------------------------------------------ | -------- | 119e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Flags | FLAG_ABILITY_FORWARD_RESULT | Deleted | 120e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Flags | FLAG_ABILITY_CONTINUATION | Deleted | 121e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Flags | FLAG_NOT_OHOS_COMPONENT | Deleted | 122e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Flags | FLAG_ABILITY_FORM_ENABLED | Deleted | 123e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Flags | FLAG_AUTH_PERSISTABLE_URI_PERMISSION | Deleted | 124e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Flags | FLAG_AUTH_PREFIX_URI_PERMISSION | Deleted | 125e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Flags | FLAG_ABILITYSLICE_MULTI_DEVICE | Deleted | 126e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Flags | FLAG_START_FOREGROUND_ABILITY | Deleted | 127e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Flags | FLAG_ABILITY_CONTINUATION_REVERSIBLE | Deleted | 128e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Flags | FLAG_INSTALL_WITH_BACKGROUND_MODE | Deleted | 129e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Flags | FLAG_ABILITY_CLEAR_MISSION | Deleted | 130e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Flags | FLAG_ABILITY_NEW_MISSION | Deleted | 131e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Flags | FLAG_ABILITY_MISSION_TOP | Deleted | 132e41f4b71Sopenharmony_ci 133e41f4b71Sopenharmony_ci## cl.ability.5 WantConstant.Action API Changed 134e41f4b71Sopenharmony_ci 135e41f4b71Sopenharmony_ci**WantConstant.Action** has multiple invalid action definitions. These invalid actions are deleted. 136e41f4b71Sopenharmony_ci 137e41f4b71Sopenharmony_ci**Change Impact** 138e41f4b71Sopenharmony_ci 139e41f4b71Sopenharmony_ciJS APIs in API version 9 are affected. Your application needs to adapt these APIs so that it can properly implement features in the SDK environment of the new version. 140e41f4b71Sopenharmony_ci 141e41f4b71Sopenharmony_ci**Key API/Component Changes** 142e41f4b71Sopenharmony_ci 143e41f4b71Sopenharmony_ci| Module | Class | Method/Attribute/Enum/Constant | Change Type| 144e41f4b71Sopenharmony_ci| ------------------------- | ------------------- | ------------------------------------------------------------ | -------- | 145e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Action | ACTION_APP_ACCOUNT_AUTH | Deleted | 146e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Action | ACTION_MARKET_DOWNLOAD | Deleted | 147e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Action | ACTION_MARKET_CROWDTEST | Deleted | 148e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Action | DLP_PARAMS_SANDBOX | Deleted | 149e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Action | DLP_PARAMS_BUNDLE_NAME | Deleted | 150e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Action | DLP_PARAMS_MODULE_NAME | Deleted | 151e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Action | DLP_PARAMS_ABILITY_NAME | Deleted | 152e41f4b71Sopenharmony_ci 153e41f4b71Sopenharmony_ci## cl.ability.6 Caller APIs Changed 154e41f4b71Sopenharmony_ci 155e41f4b71Sopenharmony_ciCaller APIs use the **Parcelable** and **MessageSequence** objects provided by RPC in API version 9 to replace the deprecated **Sequenceable** and **MessageParcel** object. 156e41f4b71Sopenharmony_ci 157e41f4b71Sopenharmony_ci**Change Impact** 158e41f4b71Sopenharmony_ci 159e41f4b71Sopenharmony_ciJS APIs in API version 9 are affected. Your application needs to adapt these APIs so that it can properly implement features in the SDK environment of the new version. 160e41f4b71Sopenharmony_ci 161e41f4b71Sopenharmony_ci**Key API/Component Changes** 162e41f4b71Sopenharmony_ci 163e41f4b71Sopenharmony_ci| Module | Class | Method/Attribute/Enum/Constant | Change Type| 164e41f4b71Sopenharmony_ci| ------------------------- | ------------------- | ------------------------------------------------------------ | -------- | 165e41f4b71Sopenharmony_ci| api/@ohos.app.ability.UIAbility.d.ts | CalleeCallback | (indata: rpc.MessageParcel): rpc.Sequenceable; | Changed to **(indata: rpc.MessageSequence): rpc.Parcelable;**. | 166e41f4b71Sopenharmony_ci| api/@ohos.app.ability.UIAbility.d.ts | Caller | call(method: string, data: rpc.Sequenceable): Promise<void>; | Changed to **call(method: string, data: rpc.Parcelable): Promise<void>;**. | 167e41f4b71Sopenharmony_ci| api/@ohos.app.ability.UIAbility.d.ts | Caller | callWithResult(method: string, data: rpc.Sequenceable): Promise<rpc.MessageParcel>; | Changed to **callWithResult(method: string, data: rpc.Parcelable): Promise<rpc.MessageSequence>;**. | 168e41f4b71Sopenharmony_ci 169e41f4b71Sopenharmony_ci**Adaptation Guide** 170e41f4b71Sopenharmony_ci 171e41f4b71Sopenharmony_ciThe following illustrates how to call the caller APIs in your application. 172e41f4b71Sopenharmony_ci 173e41f4b71Sopenharmony_ciCode before the change: 174e41f4b71Sopenharmony_ci 175e41f4b71Sopenharmony_ci```ts 176e41f4b71Sopenharmony_ci class MyMessageAble{ 177e41f4b71Sopenharmony_ci name:"" 178e41f4b71Sopenharmony_ci str:"" 179e41f4b71Sopenharmony_ci num: 1 180e41f4b71Sopenharmony_ci constructor(name, str) { 181e41f4b71Sopenharmony_ci this.name = name; 182e41f4b71Sopenharmony_ci this.str = str; 183e41f4b71Sopenharmony_ci } 184e41f4b71Sopenharmony_ci marshalling(messageParcel) { 185e41f4b71Sopenharmony_ci messageParcel.writeInt(this.num); 186e41f4b71Sopenharmony_ci messageParcel.writeString(this.str); 187e41f4b71Sopenharmony_ci console.log('MyMessageAble marshalling num[' + this.num + '] str[' + this.str + ']'); 188e41f4b71Sopenharmony_ci return true; 189e41f4b71Sopenharmony_ci } 190e41f4b71Sopenharmony_ci unmarshalling(messageParcel) { 191e41f4b71Sopenharmony_ci this.num = messageParcel.readInt(); 192e41f4b71Sopenharmony_ci this.str = messageParcel.readString(); 193e41f4b71Sopenharmony_ci console.log('MyMessageAble unmarshalling num[' + this.num + '] str[' + this.str + ']'); 194e41f4b71Sopenharmony_ci return true; 195e41f4b71Sopenharmony_ci } 196e41f4b71Sopenharmony_ci }; 197e41f4b71Sopenharmony_ci let method = 'call_Function'; 198e41f4b71Sopenharmony_ci function funcCallBack(pdata) { 199e41f4b71Sopenharmony_ci console.log('Callee funcCallBack is called ' + pdata); 200e41f4b71Sopenharmony_ci let msg = new MyMessageAble("test", ""); 201e41f4b71Sopenharmony_ci pdata.readSequenceable(msg); 202e41f4b71Sopenharmony_ci return new MyMessageAble("test1", "Callee test"); 203e41f4b71Sopenharmony_ci } 204e41f4b71Sopenharmony_ci export default class MainUIAbility extends UIAbility { 205e41f4b71Sopenharmony_ci onCreate(want, launchParam) { 206e41f4b71Sopenharmony_ci console.log('Callee onCreate is called'); 207e41f4b71Sopenharmony_ci try { 208e41f4b71Sopenharmony_ci this.callee.on(method, funcCallBack); 209e41f4b71Sopenharmony_ci } catch (error) { 210e41f4b71Sopenharmony_ci console.log('Callee.on catch error, error.code: ' + error.code + 211e41f4b71Sopenharmony_ci ' error.message: ' + error.message); 212e41f4b71Sopenharmony_ci } 213e41f4b71Sopenharmony_ci } 214e41f4b71Sopenharmony_ci } 215e41f4b71Sopenharmony_ci``` 216e41f4b71Sopenharmony_ci 217e41f4b71Sopenharmony_ciCode after the change: 218e41f4b71Sopenharmony_ci 219e41f4b71Sopenharmony_ci```ts 220e41f4b71Sopenharmony_ci class MyMessageAble{ 221e41f4b71Sopenharmony_ci name:"" 222e41f4b71Sopenharmony_ci str:"" 223e41f4b71Sopenharmony_ci num: 1 224e41f4b71Sopenharmony_ci constructor(name, str) { 225e41f4b71Sopenharmony_ci this.name = name; 226e41f4b71Sopenharmony_ci this.str = str; 227e41f4b71Sopenharmony_ci } 228e41f4b71Sopenharmony_ci marshalling(messageSequence) { 229e41f4b71Sopenharmony_ci messageSequence.writeInt(this.num); 230e41f4b71Sopenharmony_ci messageSequence.writeString(this.str); 231e41f4b71Sopenharmony_ci console.log('MyMessageAble marshalling num[' + this.num + '] str[' + this.str + ']'); 232e41f4b71Sopenharmony_ci return true; 233e41f4b71Sopenharmony_ci } 234e41f4b71Sopenharmony_ci unmarshalling(messageSequence) { 235e41f4b71Sopenharmony_ci this.num = messageSequence.readInt(); 236e41f4b71Sopenharmony_ci this.str = messageSequence.readString(); 237e41f4b71Sopenharmony_ci console.log('MyMessageAble unmarshalling num[' + this.num + '] str[' + this.str + ']'); 238e41f4b71Sopenharmony_ci return true; 239e41f4b71Sopenharmony_ci } 240e41f4b71Sopenharmony_ci }; 241e41f4b71Sopenharmony_ci let method = 'call_Function'; 242e41f4b71Sopenharmony_ci function funcCallBack(pdata) { 243e41f4b71Sopenharmony_ci console.log('Callee funcCallBack is called ' + pdata); 244e41f4b71Sopenharmony_ci let msg = new MyMessageAble("test", ""); 245e41f4b71Sopenharmony_ci pdata.readParcelable(msg); 246e41f4b71Sopenharmony_ci return new MyMessageAble("test1", "Callee test"); 247e41f4b71Sopenharmony_ci } 248e41f4b71Sopenharmony_ci export default class MainUIAbility extends UIAbility { 249e41f4b71Sopenharmony_ci onCreate(want, launchParam) { 250e41f4b71Sopenharmony_ci console.log('Callee onCreate is called'); 251e41f4b71Sopenharmony_ci try { 252e41f4b71Sopenharmony_ci this.callee.on(method, funcCallBack); 253e41f4b71Sopenharmony_ci } catch (error) { 254e41f4b71Sopenharmony_ci console.log('Callee.on catch error, error.code: ' + error.code + 255e41f4b71Sopenharmony_ci ' error.message: ' + error.message); 256e41f4b71Sopenharmony_ci } 257e41f4b71Sopenharmony_ci } 258e41f4b71Sopenharmony_ci } 259e41f4b71Sopenharmony_ci``` 260e41f4b71Sopenharmony_ci 261e41f4b71Sopenharmony_ci## cl.ability.7 WantConstant.Flags API Changed 262e41f4b71Sopenharmony_ci 263e41f4b71Sopenharmony_ciThe **wantConstant** API had two similar enums. Now the two enums are combined into one. 264e41f4b71Sopenharmony_ci 265e41f4b71Sopenharmony_ci**Change Impact** 266e41f4b71Sopenharmony_ci 267e41f4b71Sopenharmony_ciJS APIs in API version 9 are affected. Your application needs to adapt these APIs so that it can properly implement features in the SDK environment of the new version. 268e41f4b71Sopenharmony_ci 269e41f4b71Sopenharmony_ci**Key API/Component Changes** 270e41f4b71Sopenharmony_ci 271e41f4b71Sopenharmony_ci| Module | Class | Method/Attribute/Enum/Constant | Change Type| 272e41f4b71Sopenharmony_ci| ----------------------------------- | ---------------------- | ----------------------------------- | -------- | 273e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Parameter | ABILITY_BACK_TO_OTHER_MISSION_STACK | Deleted | 274e41f4b71Sopenharmony_ci| @ohos.app.ability.wantConstant.d.ts | wantConstant.Params | ABILITY_BACK_TO_OTHER_MISSION_STACK | Added | 275e41f4b71Sopenharmony_ci 276e41f4b71Sopenharmony_ci**Adaptation Guide** 277e41f4b71Sopenharmony_ci 278e41f4b71Sopenharmony_ciUse **ABILITY_BACK_TO_OTHER_MISSION_STACK** in **@ohos.app.ability.wantConstant.d.ts**. 279e41f4b71Sopenharmony_ci 280e41f4b71Sopenharmony_ci```ts 281e41f4b71Sopenharmony_ciimport wantConstant from '@ohos.app.ability.wantConstant'; 282e41f4b71Sopenharmony_cilet backToOtherMissionStack: wantConstant.Params = wantParam.Params.ABILITY_BACK_TO_OTHER_MISSION_STACK; 283e41f4b71Sopenharmony_ci``` 284